package in.twizmwaz.cardinal.module.modules.destroyable; import in.twizmwaz.cardinal.GameHandler; import in.twizmwaz.cardinal.chat.ChatConstant; import in.twizmwaz.cardinal.chat.LocalizedChatMessage; import in.twizmwaz.cardinal.chat.UnlocalizedChatMessage; import in.twizmwaz.cardinal.event.SnowflakeChangeEvent; import in.twizmwaz.cardinal.event.objective.ObjectiveCompleteEvent; import in.twizmwaz.cardinal.event.objective.ObjectiveProximityEvent; import in.twizmwaz.cardinal.event.objective.ObjectiveTouchEvent; import in.twizmwaz.cardinal.module.GameObjective; import in.twizmwaz.cardinal.module.modules.regions.RegionModule; import in.twizmwaz.cardinal.module.modules.scoreboard.GameObjectiveScoreboardHandler; import in.twizmwaz.cardinal.module.modules.snowflakes.Snowflakes; import in.twizmwaz.cardinal.module.modules.team.TeamModule; import in.twizmwaz.cardinal.module.modules.timeLimit.TimeLimit; import in.twizmwaz.cardinal.module.modules.tntTracker.TntTracker; import in.twizmwaz.cardinal.util.ChatUtils; import in.twizmwaz.cardinal.util.FireworkUtil; import in.twizmwaz.cardinal.util.MiscUtils; import in.twizmwaz.cardinal.util.TeamUtils; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.HandlerList; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.player.PlayerMoveEvent; import java.util.*; public class DestroyableObjective implements GameObjective { private final TeamModule team; private final String name; private final String id; private final RegionModule region; private List<Material> types; private List<Integer> damageValues; private final double required; private final boolean showPercent; private final boolean repairable; private final boolean show; private boolean changesModes; private double proximity; private Set<UUID> playersTouched; private double size; private HashMap<UUID, Integer> playersCompleted; private List<Block> monument; private double complete; private boolean completed; private GameObjectiveScoreboardHandler scoreboardHandler; protected DestroyableObjective(final TeamModule team, final String name, final String id, final RegionModule region, List<Material> types, List<Integer> damageValues, final double required, final boolean show, boolean changesModes, boolean showPercent, boolean repairable) { this.team = team; this.name = name; this.id = id; this.region = region; this.types = types; this.damageValues = damageValues; this.showPercent = showPercent; this.repairable = repairable; this.complete = 0; this.required = required; this.show = show; this.changesModes = changesModes; this.completed = false; this.proximity = Double.POSITIVE_INFINITY; this.playersTouched = new HashSet<>(); this.playersCompleted = new HashMap<>(); this.monument = this.getBlocks(); this.size = this.getBlocks().size(); this.scoreboardHandler = new GameObjectiveScoreboardHandler(this); } @Override public TeamModule getTeam() { return this.team; } @Override public String getName() { return this.name; } @Override public String getId() { return this.id; } @Override public boolean isTouched() { return this.complete > 0; } @Override public boolean isComplete() { return this.completed; } @Override public boolean showOnScoreboard() { return show; } @Override public void unload() { HandlerList.unregisterAll(this); } @Override public GameObjectiveScoreboardHandler getScoreboardHandler() { return scoreboardHandler; } @EventHandler(priority = EventPriority.HIGHEST) public void onBlockBreak(BlockBreakEvent event) { if (!event.isCancelled()) { if (getBlocks().contains(event.getBlock())) { if (TeamUtils.getTeamByPlayer(event.getPlayer()) != team) { boolean touchMessage = false; if (!playersTouched.contains(event.getPlayer().getUniqueId())) { playersTouched.add(event.getPlayer().getUniqueId()); TeamModule teamModule = TeamUtils.getTeamByPlayer(event.getPlayer()); if (this.show && !this.completed) { TeamUtils.getTeamChannel(teamModule).sendLocalizedMessage(new LocalizedChatMessage(ChatConstant.UI_OBJECTIVE_DAMAGED, teamModule.getColor() + event.getPlayer().getName() + ChatColor.GRAY, ChatColor.AQUA + name)); for (Player player : Bukkit.getOnlinePlayers()) { if (TeamUtils.getTeamByPlayer(player) != null && TeamUtils.getTeamByPlayer(player).isObserver()) { String message = new LocalizedChatMessage(ChatConstant.UI_OBJECTIVE_DAMAGED_FOR, teamModule.getColor() + event.getPlayer().getName() + ChatColor.GRAY, ChatColor.AQUA + name + ChatColor.GRAY, teamModule.getCompleteName() + ChatColor.GRAY).getMessage(player.getLocale()); if (!teamModule.getOriginalName().equalsIgnoreCase(teamModule.getName())) { message = message.replace(new LocalizedChatMessage(ChatConstant.MISC_THE).getMessage(player.getLocale()) + " ", ""); } player.sendMessage(message); } } } } boolean oldState = this.isTouched(); this.complete++; this.playersCompleted.put(event.getPlayer().getUniqueId(), (playersCompleted.containsKey(event.getPlayer().getUniqueId()) ? playersCompleted.get(event.getPlayer().getUniqueId()) + 1 : 1)); if ((this.complete / size) >= this.required && !this.completed) { this.completed = true; event.setCancelled(false); if (this.show) { for (Player player : Bukkit.getOnlinePlayers()) { String message = ChatColor.GRAY + new UnlocalizedChatMessage("{0}", new LocalizedChatMessage(ChatConstant.UI_OBJECTIVE_DESTROYED, team.getCompleteName() + ChatColor.GRAY, ChatColor.AQUA + name + ChatColor.GRAY, getWhoDestroyed(player.getLocale()))).getMessage(player.getLocale()); if (!team.getOriginalName().equalsIgnoreCase(team.getName())) { message = message.replace(new LocalizedChatMessage(ChatConstant.MISC_THE).getMessage(player.getLocale()) + " ", ""); } player.sendMessage(message); } } FireworkUtil.spawnFirework(event.getPlayer().getLocation(), event.getPlayer().getWorld(), MiscUtils.convertChatColorToColor(team.getColor())); ObjectiveCompleteEvent compEvent = new ObjectiveCompleteEvent(this, event.getPlayer()); Bukkit.getServer().getPluginManager().callEvent(compEvent); } else if (!this.completed) { ObjectiveTouchEvent touchEvent = new ObjectiveTouchEvent(this, event.getPlayer(), !oldState || showPercent, touchMessage); Bukkit.getServer().getPluginManager().callEvent(touchEvent); } } else { event.setCancelled(true); if (this.show) ChatUtils.sendWarningMessage(event.getPlayer(), new LocalizedChatMessage(ChatConstant.ERROR_OWN_OBJECTIVE)); } } } } @EventHandler(priority = EventPriority.HIGHEST) public void onEntityExplode(EntityExplodeEvent event) { if (!event.isCancelled()) { List<Block> objectiveBlownUp = new ArrayList<>(); for (Block block : event.blockList()) { if (getBlocks().contains(block)) { objectiveBlownUp.add(block); } } boolean oldState = this.isTouched(); boolean blownUp = false; Player eventPlayer = null; int originalPercent = getPercent(); boolean touchMessage = false; for (Block block : objectiveBlownUp) { boolean blockDestroyed = false; if (TntTracker.getWhoPlaced(event.getEntity()) != null) { UUID player = TntTracker.getWhoPlaced(event.getEntity()); if (Bukkit.getOfflinePlayer(player).isOnline()) { if (TeamUtils.getTeamByPlayer(Bukkit.getPlayer(player)) == team) { event.blockList().remove(block); } else { if (!playersTouched.contains(player)) { playersTouched.add(player); TeamModule teamModule = TeamUtils.getTeamByPlayer(Bukkit.getPlayer(player)); if (this.show && !this.completed) { TeamUtils.getTeamChannel(teamModule).sendLocalizedMessage(new LocalizedChatMessage(ChatConstant.UI_OBJECTIVE_DAMAGED, teamModule.getColor() + Bukkit.getPlayer(player).getName() + ChatColor.GRAY, ChatColor.AQUA + name + ChatColor.GRAY)); for (Player player1 : Bukkit.getOnlinePlayers()) { if (TeamUtils.getTeamByPlayer(player1) != null && TeamUtils.getTeamByPlayer(player1).isObserver()) { player1.sendMessage(new LocalizedChatMessage(ChatConstant.UI_OBJECTIVE_DAMAGED_FOR, teamModule.getColor() + Bukkit.getPlayer(player).getName() + ChatColor.GRAY, ChatColor.AQUA + name + ChatColor.GRAY, teamModule.getCompleteName() + ChatColor.GRAY).getMessage(player1.getLocale())); } } touchMessage = true; } } blockDestroyed = true; blownUp = true; eventPlayer = Bukkit.getPlayer(player); } } else { if (!playersTouched.contains(player)) { playersTouched.add(player); } blockDestroyed = true; blownUp = true; } } else { blockDestroyed = true; blownUp = true; } if (blockDestroyed) { this.complete++; if (eventPlayer != null) this.playersCompleted.put(eventPlayer.getUniqueId(), (playersCompleted.containsKey(eventPlayer.getUniqueId()) ? playersCompleted.get(eventPlayer.getUniqueId()) + 1 : 1)); if ((this.complete / size) >= this.required && !this.completed) { this.completed = true; if (this.show) { for (Player player : Bukkit.getOnlinePlayers()) player.sendMessage(ChatColor.GRAY + new UnlocalizedChatMessage("{0}", new LocalizedChatMessage(ChatConstant.UI_OBJECTIVE_DESTROYED, team.getCompleteName() + ChatColor.GRAY, ChatColor.AQUA + name + ChatColor.GRAY, getWhoDestroyed(player.getLocale()))).getMessage(player.getLocale())); Bukkit.getLogger().info(ChatColor.GRAY + new UnlocalizedChatMessage("{0}", new LocalizedChatMessage(ChatConstant.UI_OBJECTIVE_DESTROYED, team.getCompleteName() + ChatColor.GRAY, ChatColor.AQUA + name + ChatColor.GRAY, getWhoDestroyed(Locale.getDefault().toString()))).getMessage(Locale.getDefault().toString())); } ObjectiveCompleteEvent compEvent = new ObjectiveCompleteEvent(this, eventPlayer); Bukkit.getServer().getPluginManager().callEvent(compEvent); } } } if (!this.completed && blownUp) { ObjectiveTouchEvent touchEvent = new ObjectiveTouchEvent(this, eventPlayer, !oldState || (getPercent() != originalPercent), touchMessage); Bukkit.getServer().getPluginManager().callEvent(touchEvent); } } } @EventHandler public void onBlockPlace(BlockPlaceEvent event) { if (!repairable && !isComplete()) { if (region.contains(event.getBlock().getLocation()) && partOfObjective(event.getBlock())) { if (TeamUtils.getTeamByPlayer(event.getPlayer()).getName() != team.getName()) { ChatUtils.sendWarningMessage(event.getPlayer(), new LocalizedChatMessage(ChatConstant.ERROR_ENEMY_OBJECTIVE)); event.setCancelled(true); } else { ChatUtils.sendWarningMessage(event.getPlayer(), new LocalizedChatMessage(ChatConstant.ERROR_REPAIR_OBJECTIVE)); event.setCancelled(true); } } } } public int getBlocksRequired() { return (int) Math.ceil(size * required); } public int getBlocksBroken() { return (int) complete; } @EventHandler public void onPlayerDeath(PlayerDeathEvent event) { while (playersTouched.contains(event.getEntity().getUniqueId())) { playersTouched.remove(event.getEntity().getUniqueId()); } } public boolean showPercent() { return showPercent; } public boolean showProximity() { return GameHandler.getGameHandler().getMatch().getModules().getModule(TimeLimit.class).getTimeLimit() != 0 && GameHandler.getGameHandler().getMatch().getModules().getModule(TimeLimit.class).getResult().equals(TimeLimit.Result.MOST_OBJECTIVES); } public boolean isRepairable() { return repairable; } public int getPercent() { double blocksRequired = required * size; if (Math.floor((complete / blocksRequired) * 100) > 100) { return 100; } if (Math.floor((complete / blocksRequired) * 100) < 0) { return 0; } return (int) Math.floor((complete / blocksRequired) * 100); } public int getPercentFromAmount(int amount) { double blocksRequired = required * size; if (Math.floor((amount / blocksRequired) * 100) > 100) { return 100; } if (Math.floor((amount / blocksRequired) * 100) < 0) { return 0; } return (int) Math.floor((amount / blocksRequired) * 100); } public boolean partOfObjective(Block block) { for (int i = 0; i < types.size(); i++) { if (types.get(i).equals(block.getType()) && (damageValues.get(i) == -1 || damageValues.get(i) == (int) block.getState().getData().getData())) { return true; } } return false; } public List<Block> getBlocks() { List<Block> blocks = new ArrayList<>(); for (Block block : region.getBlocks()) { if (partOfObjective(block)) { blocks.add(block); } } return blocks; } public List<Block> getMonument() { return monument; } public String getWhoDestroyed(String locale) { String whoDestroyed = ""; List<String> toCombine = new ArrayList<>(); for (UUID player : MiscUtils.getSortedHashMapKeyset(playersCompleted)) { if (getPercentFromAmount(playersCompleted.get(player)) > (100 / 3)) { toCombine.add(TeamUtils.getTeamColorByPlayer(Bukkit.getPlayer(player)) + Bukkit.getPlayer(player).getName() + ChatColor.GRAY + " (" + getPercentFromAmount(playersCompleted.get(player)) + "%)"); } } if (toCombine.size() == 0) { toCombine.add(ChatColor.DARK_AQUA + new LocalizedChatMessage(ChatConstant.MISC_ENEMY).getMessage(locale)); } if (toCombine.size() < playersCompleted.keySet().size()) { toCombine.add(ChatColor.DARK_AQUA + new LocalizedChatMessage(ChatConstant.MISC_OTHERS).getMessage(locale)); } whoDestroyed = toCombine.get(0); for (int i = 1; i < toCombine.size(); i ++) { whoDestroyed += ChatColor.GRAY + (i == toCombine.size() - 1 ? " " + new LocalizedChatMessage(ChatConstant.MISC_AND).getMessage(locale) + " " : ", ") + toCombine.get(i); } return whoDestroyed; } public boolean changesModes() { return changesModes; } public void setMaterial(Material material, int damageValue) { this.types = new ArrayList<>(); this.damageValues = new ArrayList<>(); this.types.add(material); this.damageValues.add(damageValue); } @EventHandler public void onPlayerMove(PlayerMoveEvent event) { if (GameHandler.getGameHandler().getMatch().isRunning() && !this.isTouched() && TeamUtils.getTeamByPlayer(event.getPlayer()) != null && !TeamUtils.getTeamByPlayer(event.getPlayer()).isObserver() && TeamUtils.getTeamByPlayer(event.getPlayer()) != this.team) { if (event.getPlayer().getLocation().toVector().distance(region.getCenterBlock().getVector()) < proximity) { double old = proximity; proximity = event.getPlayer().getLocation().toVector().distance(region.getCenterBlock().getVector()); Bukkit.getServer().getPluginManager().callEvent(new ObjectiveProximityEvent(this, event.getPlayer(), old, proximity)); } } } @EventHandler public void onMonumentDestroy(ObjectiveCompleteEvent event) { if (event.getObjective().equals(this)) { for (UUID player : playersCompleted.keySet()) { if (Bukkit.getOfflinePlayer(player).isOnline()) { Bukkit.getServer().getPluginManager().callEvent(new SnowflakeChangeEvent(Bukkit.getPlayer(player), Snowflakes.ChangeReason.MONUMENT_DESTROY, getPercentFromAmount(playersCompleted.get(player)) / 10, ChatColor.GREEN + "" + getPercentFromAmount(playersCompleted.get(player)) + ChatColor.GRAY, ChatColor.GREEN + name + ChatColor.GRAY)); } } } } public double getProximity() { return proximity; } }