package in.twizmwaz.cardinal.module.modules.snowflakes; import com.google.common.collect.Lists; import in.twizmwaz.cardinal.Cardinal; import in.twizmwaz.cardinal.GameHandler; import in.twizmwaz.cardinal.chat.UnlocalizedChatMessage; import in.twizmwaz.cardinal.event.CardinalDeathEvent; import in.twizmwaz.cardinal.event.MatchEndEvent; import in.twizmwaz.cardinal.event.SnowflakeChangeEvent; import in.twizmwaz.cardinal.module.Module; import in.twizmwaz.cardinal.module.modules.team.TeamModule; import in.twizmwaz.cardinal.module.modules.wools.WoolObjective; import in.twizmwaz.cardinal.settings.Settings; import in.twizmwaz.cardinal.util.MiscUtil; import in.twizmwaz.cardinal.util.Numbers; import in.twizmwaz.cardinal.util.PacketUtils; import in.twizmwaz.cardinal.util.Teams; import in.twizmwaz.cardinal.util.Watchers; import net.minecraft.server.Packet; import net.minecraft.server.PacketPlayOutEntityDestroy; import net.minecraft.server.PacketPlayOutSpawnEntity; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.DyeColor; import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.entity.Item; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.HandlerList; import org.bukkit.event.entity.EntityDespawnInVoidEvent; import org.bukkit.event.inventory.CraftItemEvent; import org.bukkit.event.player.PlayerDropItemEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.Recipe; import org.bukkit.inventory.ShapedRecipe; import org.bukkit.inventory.ShapelessRecipe; import org.bukkit.material.Wool; import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.util.Vector; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.stream.Collectors; public class Snowflakes implements Module { private static String ITEM_THROWER_META = "item-thrower"; private Map<Player, List<DyeColor>> destroyed = new HashMap<>(); @Override public void unload() { HandlerList.unregisterAll(this); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onPlayerDropItem(PlayerDropItemEvent event) { if (testDestroy(event.getPlayer(), event.getItemDrop().getItemStack())) { event.getItemDrop().setMetadata(ITEM_THROWER_META, new FixedMetadataValue(Cardinal.getInstance(), event.getPlayer().getUniqueId())); } } @EventHandler public void onItemDespawnInVoid(EntityDespawnInVoidEvent event) { if (!(event.getEntity() instanceof Item) || !event.getEntity().hasMetadata(ITEM_THROWER_META)) return; Player player = Bukkit.getPlayer((UUID) event.getEntity().getMetadata(ITEM_THROWER_META).get(0).value()); Item item = (Item) event.getEntity(); if (testDestroy(player, item.getItemStack())) { addDestroyed(player, ((Wool) item.getItemStack().getData()).getColor()); } } @EventHandler public void onPlayerCraft(CraftItemEvent event) { Player player = (Player) event.getWhoClicked(); for (DyeColor color : getColors(event.getRecipe())) { if (testDestroy(player, color)) { addDestroyed(player, color); } } } private boolean testDestroy(Player player, ItemStack item) { return item.getType().equals(Material.WOOL) && testDestroy(player, ((Wool) item.getData()).getColor()); } private boolean testDestroy(Player player, DyeColor dye) { TeamModule team = Teams.getTeamByPlayer(player).orNull(); return team != null && GameHandler.getGameHandler().getMatch().getModules().getModules(WoolObjective.class) .stream().anyMatch(wool -> wool.getTeam() != team && !wool.isComplete() && wool.getColor().equals(dye) && !(destroyed.containsKey(player) && destroyed.get(player).contains(dye))); } private void addDestroyed(Player player, DyeColor dye) { if (!destroyed.containsKey(player)) destroyed.put(player, Lists.newArrayList()); destroyed.get(player).add(dye); Bukkit.getServer().getPluginManager().callEvent(new SnowflakeChangeEvent(player, ChangeReason.DESTROY_WOOL, 8, MiscUtil.convertDyeColorToChatColor(dye) + dye.name().toUpperCase().replaceAll("_", " ") + " WOOL" + ChatColor.GRAY)); } private List<DyeColor> getColors(Recipe recipe) { return recipe instanceof ShapedRecipe ? getColors(((ShapedRecipe) recipe).getIngredientMap().values()) : recipe instanceof ShapelessRecipe ? getColors(((ShapelessRecipe) recipe).getIngredientList()) : Lists.newArrayList(); } private List<DyeColor> getColors(Collection<ItemStack> items) { return items.stream().filter(item -> item != null && item.getType().equals(Material.WOOL)) .map(item -> ((Wool) item.getData()).getColor()).distinct().collect(Collectors.toList()); } @EventHandler public void onCardinalDeath(CardinalDeathEvent event) { if (event.getKiller() != null && Teams.getTeamByPlayer(event.getPlayer()).orNull() != Teams.getTeamByPlayer(event.getKiller()).orNull()) { Bukkit.getServer().getPluginManager().callEvent(new SnowflakeChangeEvent(event.getKiller(), ChangeReason.PLAYER_KILL, 1, event.getPlayer().getName())); } } @EventHandler public void onMatchEnd(MatchEndEvent event) { for (Player player : Bukkit.getOnlinePlayers()) { if (Teams.getTeamByPlayer(player).isPresent() && !Teams.getTeamByPlayer(player).get().isObserver() && event.getTeam().equals(Teams.getTeamByPlayer(player))) { Bukkit.getServer().getPluginManager().callEvent(new SnowflakeChangeEvent(player, ChangeReason.TEAM_WIN, 15, Teams.getTeamByPlayer(player).get().getCompleteName())); } else if (Teams.getTeamByPlayer(player).isPresent() && !Teams.getTeamByPlayer(player).get().isObserver() && !event.getTeam().equals(Teams.getTeamByPlayer(player))) { Bukkit.getServer().getPluginManager().callEvent(new SnowflakeChangeEvent(player, ChangeReason.TEAM_LOYAL, 5, Teams.getTeamByPlayer(player).get().getCompleteName())); } } } @EventHandler public void onSnowflakeChange(SnowflakeChangeEvent event) { if (event.getFinalAmount() != 0) { String reason; if (event.getChangeReason().equals(ChangeReason.PLAYER_KILL)) { reason = "killed " + Teams.getTeamColorByPlayer(Bukkit.getOfflinePlayer(event.get(0))) + event.get(0); } else if (event.getChangeReason().equals(ChangeReason.WOOL_TOUCH)) { reason = "picked up " + event.get(0); } else if (event.getChangeReason().equals(ChangeReason.WOOL_PLACE)) { reason = "placed " + event.get(0); } else if (event.getChangeReason().equals(ChangeReason.CORE_LEAK)) { reason = "you broke a piece of " + event.get(0); } else if (event.getChangeReason().equals(ChangeReason.MONUMENT_DESTROY)) { reason = "you destroyed " + event.get(0) + "% of " + event.get(1); } else if (event.getChangeReason().equals(ChangeReason.TEAM_WIN)) { reason = "your team (" + event.get(0) + ChatColor.GRAY + ") won"; } else if (event.getChangeReason().equals(ChangeReason.TEAM_LOYAL)) { reason = "you were loyal to your team (" + event.get(0) + ChatColor.GRAY + ")"; } else if (event.getChangeReason().equals(ChangeReason.DESTROY_WOOL)) { reason = "you destroyed " + event.get(0); } else { reason = "unknown reason"; } event.getPlayer().sendMessage(new UnlocalizedChatMessage(ChatColor.GREEN + "" + ChatColor.BOLD + "+" + event.getFinalAmount() + ChatColor.WHITE + " Snowflakes" + ChatColor.DARK_PURPLE + " | " + ChatColor.GOLD + "" + ChatColor.ITALIC + event.getMultiplier() + "x" + ChatColor.DARK_PURPLE + " | " + ChatColor.GRAY + reason).getMessage(event.getPlayer().getLocale())); event.getPlayer().playSound(event.getPlayer().getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 1.5F); if (Settings.getSettingByName("Sounds") != null && Settings.getSettingByName("Sounds").getValueByPlayer(event.getPlayer()).getValue().equalsIgnoreCase("on")) { event.getPlayer().playSound(event.getPlayer().getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1, 1.5F); } if (Cardinal.getCardinalDatabase().get(event.getPlayer(), "snowflakes").equals("")) { Cardinal.getCardinalDatabase().put(event.getPlayer(), "snowflakes", event.getFinalAmount() + ""); } else { Cardinal.getCardinalDatabase().put(event.getPlayer(), "snowflakes", (Numbers.parseInt(Cardinal.getCardinalDatabase().get(event.getPlayer(), "snowflakes")) + event.getFinalAmount()) + ""); } if (Settings.getSettingByName("Snowflakes").getValueByPlayer(event.getPlayer()).getValue().equalsIgnoreCase("on")) spawnSnowflakes(event.getPlayer(), event.getFinalAmount()); } } private void spawnSnowflakes(Player player, int count) { count = Math.min(12, Math.max(2, count)); int[] entities = new int[count]; List<Packet> packets = Lists.newArrayList(); Vector loc = player.getLocation().position().plus(0, 2, 0); for (int i = 0; i < count; i++) { int id = Bukkit.allocateEntityId(); entities[i] = id; int motX = (int) ((float) (Math.random() * 0.20000000298023224D - 0.10000000149011612D) * 8000), motY = (int) (0.2D * 8000), motZ = (int) ((float) (Math.random() * 0.20000000298023224D - 0.10000000149011612D) * 8000); packets.add(new PacketPlayOutSpawnEntity( id, UUID.randomUUID(), // Entity id and Entity UUID loc.getX(), loc.getY(), loc.getZ(),// X, Y and Z Position motX, motY, motZ, // X, Y and Z Motion (byte) 2, (byte) 0, // Pitch, Yaw 2, 0 // Type and data )); packets.add(PacketUtils.createMetadataPacket(id, Watchers.toList(Watchers.SNOWFLAKE))); } for (Packet packet : packets) PacketUtils.sendPacket(player, packet); scheduleSnowflakeRemove(player, entities); } private void scheduleSnowflakeRemove(final Player player, final int... id) { Bukkit.getScheduler().scheduleSyncDelayedTask(Cardinal.getInstance(), () -> PacketUtils.sendPacket(player, new PacketPlayOutEntityDestroy(id)), 100L); } public enum ChangeReason { PLAYER_KILL(), WOOL_TOUCH(), WOOL_PLACE(), CORE_LEAK(), MONUMENT_DESTROY(), TEAM_WIN(), TEAM_LOYAL(), DESTROY_WOOL() } }