war/war/src/main/java/com/tommytony/war/event/WarPlayerListener.java

950 lines
37 KiB
Java

package com.tommytony.war.event;
import com.tommytony.war.Team;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.Warzone.LeaveCause;
import com.tommytony.war.command.ZoneSetter;
import com.tommytony.war.config.FlagReturn;
import com.tommytony.war.config.TeamConfig;
import com.tommytony.war.config.WarConfig;
import com.tommytony.war.config.WarzoneConfig;
import com.tommytony.war.structure.Bomb;
import com.tommytony.war.structure.Cake;
import com.tommytony.war.structure.WarHub;
import com.tommytony.war.structure.ZoneLobby;
import com.tommytony.war.utility.Direction;
import com.tommytony.war.utility.Loadout;
import com.tommytony.war.utility.LoadoutSelection;
import com.tommytony.war.volume.Volume;
import org.apache.commons.lang.Validate;
import org.bukkit.*;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Sign;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.event.Event.Result;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.entity.EntityPickupItemEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.player.*;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
/**
* @author tommytony, Tim Düsterhus
*/
public class WarPlayerListener implements Listener {
private java.util.Random random = new java.util.Random();
private HashMap<String, Location> latestLocations = new HashMap<String, Location>();
/**
* Correctly removes quitting players from warzones
*
* @see PlayerQuitEvent
*/
@EventHandler
public void onPlayerQuit(final PlayerQuitEvent event) {
if (War.war.isLoaded()) {
Player player = event.getPlayer();
Warzone zone = Warzone.getZoneByPlayerName(player.getName());
if (zone != null) {
zone.handlePlayerLeave(player, zone.getEndTeleport(LeaveCause.DISCONNECT), true);
}
if (War.war.isWandBearer(player)) {
War.war.removeWandBearer(player);
}
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onPlayerJoin(final PlayerJoinEvent event) {
String autojoinName = War.war.getWarConfig().getString(WarConfig.AUTOJOIN);
boolean autojoinEnabled = !autojoinName.isEmpty();
if (autojoinEnabled) { // Won't be able to find warzone if unset
Warzone autojoinWarzone = Warzone.getZoneByNameExact(autojoinName);
if (autojoinWarzone == null) {
War.war.getLogger().log(Level.WARNING, "Failed to find autojoin warzone ''{0}''.", new Object[] {autojoinName});
return;
}
if (autojoinWarzone.getWarzoneConfig().getBoolean(WarzoneConfig.DISABLED) || autojoinWarzone.isReinitializing()) {
War.war.badMsg(event.getPlayer(), "join.disabled");
event.getPlayer().teleport(autojoinWarzone.getTeleport());
} else if (!autojoinWarzone.getWarzoneConfig().getBoolean(WarzoneConfig.JOINMIDBATTLE) && autojoinWarzone.isEnoughPlayers()) {
War.war.badMsg(event.getPlayer(), "join.progress");
event.getPlayer().teleport(autojoinWarzone.getTeleport());
} else if (autojoinWarzone.isFull()) {
War.war.badMsg(event.getPlayer(), "join.full.all");
event.getPlayer().teleport(autojoinWarzone.getTeleport());
} else if (autojoinWarzone.isFull(event.getPlayer())) {
War.war.badMsg(event.getPlayer(), "join.permission.all");
event.getPlayer().teleport(autojoinWarzone.getTeleport());
} else { // Player will only ever be autoassigned to a team
autojoinWarzone.autoAssign(event.getPlayer());
}
}
}
@EventHandler
public void onPlayerDropItem(final PlayerDropItemEvent event) {
if (War.war.isLoaded()) {
Player player = event.getPlayer();
Team team = Team.getTeamByPlayerName(player.getName());
if (team != null) {
Warzone zone = Warzone.getZoneByPlayerName(player.getName());
if (zone.isFlagThief(player)) {
// a flag thief can't drop his flag
War.war.badMsg(player, "drop.flag.disabled");
event.setCancelled(true);
} else if (zone.isBombThief(player)) {
// a bomb thief can't drop his bomb
War.war.badMsg(player, "drop.bomb.disabled");
event.setCancelled(true);
} else if (zone.isCakeThief(player)) {
// a cake thief can't drop his cake
War.war.badMsg(player, "drop.cake.disabled");
event.setCancelled(true);
} else if (zone.getWarzoneConfig().getBoolean(WarzoneConfig.NODROPS)) {
War.war.badMsg(player, "drop.item.disabled");
event.setCancelled(true);
} else {
Item item = event.getItemDrop();
if (item != null) {
ItemStack itemStack = item.getItemStack();
if (itemStack != null && team.getKind().isTeamItem(itemStack)) {
// Can't drop your team's kind block
War.war.badMsg(player, "drop.team", team.getName());
event.setCancelled(true);
return;
}
if (zone.isNearWall(player.getLocation()) && itemStack != null
&& !team.getTeamConfig().resolveBoolean(TeamConfig.BORDERDROP)) {
War.war.badMsg(player, "drop.item.border");
event.setCancelled(true);
return;
}
if (zone.getLoadoutSelections().keySet().contains(player.getName())
&& zone.getLoadoutSelections().get(player.getName()).isStillInSpawn()) {
// still at spawn
War.war.badMsg(player, "drop.item.spawn");
event.setCancelled(true);
return;
}
}
}
}
if (War.war.isWandBearer(player)) {
Item item = event.getItemDrop();
if (item.getItemStack().getType() == Material.WOODEN_SWORD) {
String zoneName = War.war.getWandBearerZone(player);
War.war.removeWandBearer(player);
War.war.msg(player, "drop.wand", zoneName);
}
}
}
}
private static final int MINIMUM_TEAM_BLOCKS = 1;
@EventHandler
public void onPlayerPickupItem(final EntityPickupItemEvent event) {
if (War.war.isLoaded()) {
if (!(event.getEntity() instanceof Player)) {
return;
}
Player player = (Player) event.getEntity();
Team team = Team.getTeamByPlayerName(player.getName());
if (team != null) {
Warzone zone = team.getZone();
if (zone.isFlagThief(player)) {
// a flag thief can't pick up anything
event.setCancelled(true);
} else {
Item item = event.getItem();
if (item != null) {
ItemStack itemStack = item.getItemStack();
if (itemStack != null && team.getKind().isTeamItem(itemStack) &&
player.getInventory().containsAtLeast(team.getKind().getBlockHead(), MINIMUM_TEAM_BLOCKS)) {
// Can't pick up a second precious block
event.setCancelled(true);
}
}
}
}
}
}
@EventHandler
public void onPlayerCommandPreprocess(final PlayerCommandPreprocessEvent event) {
if (War.war.isLoaded()) {
Player player = event.getPlayer();
Team talkingPlayerTeam = Team.getTeamByPlayerName(player.getName());
if (talkingPlayerTeam != null) {
String msg = event.getMessage();
String[] split = msg.split(" ");
if (!War.war.isWarAdmin(player) && split.length > 0 && split[0].startsWith("/")) {
String command = split[0].substring(1);
if (!command.equals("war") && !command.equals("zones") && !command.equals("warzones") && !command.equals("zone") && !command.equals("warzone") && !command.equals("teams") && !command.equals("join") && !command.equals("leave") && !command.equals("team") && !command.equals("warhub") && !command.equals("zonemaker")) {
// allow white commands
for (String whiteCommand : War.war.getCommandWhitelist()) {
if (whiteCommand.equals(command)) {
return;
}
}
War.war.badMsg(player, "command.disabled");
event.setCancelled(true);
}
}
}
}
}
@EventHandler
public void onPlayerKick(final PlayerKickEvent event) {
if (War.war.isLoaded()) {
Player player = event.getPlayer();
Warzone warzone = Warzone.getZoneByLocation(player);
if (warzone != null) {
// kick player from warzone as well
warzone.handlePlayerLeave(player, warzone.getEndTeleport(LeaveCause.DISCONNECT), true);
}
}
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
if (War.war.isLoaded()) {
Player player = event.getPlayer();
if (event.getItem() != null && event.getItem().getType() == Material.WOODEN_SWORD && War.war.isWandBearer(player)) {
String zoneName = War.war.getWandBearerZone(player);
ZoneSetter setter = new ZoneSetter(player, zoneName);
if (event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_AIR) {
War.war.badMsg(player, "wand.toofar");
} else if (event.getAction() == Action.LEFT_CLICK_BLOCK) {
setter.placeCorner1(event.getClickedBlock());
event.setUseItemInHand(Result.ALLOW);
} else if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
setter.placeCorner2(event.getClickedBlock());
event.setUseItemInHand(Result.ALLOW);
}
}
Warzone zone = Warzone.getZoneByPlayerName(player.getName());
if (zone != null && zone.getLoadoutSelections().containsKey(player.getName())
&& zone.getLoadoutSelections().get(player.getName()).isStillInSpawn()) {
event.setUseItemInHand(Result.DENY);
event.setCancelled(true);
// Replace message with sound to reduce spamminess.
// Whenever a player dies in the middle of conflict they will
// likely respawn still trying to use their items to attack
// another player.
player.playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, 1, 0);
}
if (zone != null && event.getAction() == Action.RIGHT_CLICK_BLOCK && event.getClickedBlock().getType() == Material.ENDER_CHEST && !zone.getWarzoneConfig().getBoolean(WarzoneConfig.ALLOWENDER)) {
event.setCancelled(true);
War.war.badMsg(player, "use.ender");
}
Team team = Team.getTeamByPlayerName(player.getName());
if (zone != null && team != null && event.getAction() == Action.RIGHT_CLICK_BLOCK && event.getClickedBlock().getType() == Material.ENCHANTING_TABLE && team.getTeamConfig().resolveBoolean(TeamConfig.XPKILLMETER)) {
event.setCancelled(true);
War.war.badMsg(player, "use.enchant");
if (zone.getAuthors().contains(player.getName())) {
War.war.badMsg(player, "use.xpkillmeter");
}
}
if (zone != null && team != null && event.getAction() == Action.RIGHT_CLICK_BLOCK && event.getClickedBlock().getType() == Material.ANVIL && team.getTeamConfig().resolveBoolean(TeamConfig.XPKILLMETER)) {
event.setCancelled(true);
War.war.badMsg(player, "use.anvil");
if (zone.getAuthors().contains(player.getName())) {
War.war.badMsg(player, "use.xpkillmeter");
}
}
if (zone != null && team != null && event.getAction() == Action.RIGHT_CLICK_BLOCK
&& event.getClickedBlock().getState() instanceof InventoryHolder
&& zone.isFlagThief(player)) {
event.setCancelled(true);
War.war.badMsg(player, "drop.flag.disabled");
}
if (zone == null && event.getAction() == Action.RIGHT_CLICK_BLOCK
&& (event.getClickedBlock().getType() == Material.CHEST || event.getClickedBlock().getType() == Material.TRAPPED_CHEST)
&& Warzone.getZoneByLocation(event.getClickedBlock().getLocation()) != null
&& !War.war.isZoneMaker(event.getPlayer())) {
// prevent opening chests inside a warzone if a player is not a zone maker
event.setCancelled(true);
player.playSound(player.getLocation(), Sound.BLOCK_CHEST_LOCKED, 1, 0);
}
}
if (event.getAction() == Action.RIGHT_CLICK_BLOCK
|| event.getAction() == Action.RIGHT_CLICK_AIR) {
Player player = event.getPlayer();
Warzone zone = Warzone.getZoneByPlayerName(player.getName());
if (zone != null && zone.getWarzoneConfig().getBoolean(WarzoneConfig.SOUPHEALING)) {
ItemStack item = event.getItem();
if ((item != null) && (item.getType() == Material.MUSHROOM_STEW)) {
if (player.getHealth() < 20) {
player.setHealth(Math.min(20, player.getHealth() + 7));
item.setType(Material.BOWL);
} else if (player.getFoodLevel() < 20) {
player.setFoodLevel(Math.min(20, player.getFoodLevel() + 6));
player.setSaturation(player.getSaturation() + 7.2f);
item.setType(Material.BOWL);
}
}
}
}
}
@EventHandler
public void onPlayerMove(final PlayerMoveEvent event) {
if (!War.war.isLoaded()) {
return;
}
Player player = event.getPlayer();
Location playerLoc = event.getTo(); // Don't call again we need same result.
Location previousLocation = latestLocations.get(player.getName());
if (previousLocation != null &&
playerLoc.getBlockX() == previousLocation.getBlockX() &&
playerLoc.getBlockY() == previousLocation.getBlockY() &&
playerLoc.getBlockZ() == previousLocation.getBlockZ() &&
playerLoc.getWorld() == previousLocation.getWorld()) {
// we only care when people change location
return;
}
latestLocations.put(player.getName(), playerLoc);
// Signs can automatically teleport you to specific or random warzones
if (playerLoc.getBlock().getType() == Material.SIGN) {
Sign sign = (Sign) playerLoc.getBlock().getState();
if (sign.getLine(0).equals("[zone]")) {
Warzone indicated = Warzone.getZoneByName(sign.getLine(1));
if (indicated != null) {
player.teleport(indicated.getTeleport());
} else if (sign.getLine(1).equalsIgnoreCase("$random")) {
List<Warzone> warzones = War.war.getEnabledWarzones();
if (warzones.size() == 0) return;
int zone = random.nextInt(warzones.size());
Warzone random = warzones.get(zone);
player.teleport(random.getTeleport());
} else if (sign.getLine(1).equalsIgnoreCase("$active")) {
List<Warzone> warzones = War.war.getActiveWarzones();
if (warzones.size() == 0) warzones = War.war.getEnabledWarzones();
if (warzones.size() == 0) return;
int zone = random.nextInt(warzones.size());
Warzone random = warzones.get(zone);
player.teleport(random.getTeleport());
}
}
}
Warzone locZone = Warzone.getZoneByLocation(playerLoc);
ZoneLobby locLobby = ZoneLobby.getLobbyByLocation(playerLoc);
boolean isMaker = War.war.isZoneMaker(player);
// Zone walls
Team currentTeam = Team.getTeamByPlayerName(player.getName());
Warzone playerWarzone = Warzone.getZoneByPlayerName(player.getName()); // this uses the teams, so it asks: get the player's team's warzone
boolean protecting = false;
if (currentTeam != null) {
if (playerWarzone.getWarzoneConfig().getBoolean(WarzoneConfig.GLASSWALLS)) {
protecting = playerWarzone.protectZoneWallAgainstPlayer(player);
}
} else {
Warzone nearbyZone = War.war.zoneOfZoneWallAtProximity(playerLoc);
if (nearbyZone != null && nearbyZone.getWarzoneConfig().getBoolean(WarzoneConfig.GLASSWALLS) && !isMaker) {
protecting = nearbyZone.protectZoneWallAgainstPlayer(player);
}
}
if (!protecting) {
// zone makers still need to delete their walls
// make sure to delete any wall guards as you leave
for (Warzone zone : War.war.getWarzones()) {
zone.dropZoneWallGuardIfAny(player);
}
}
// Warzone lobby gates
if (locLobby != null && currentTeam == null && locLobby.isInAnyGate(playerLoc)) {
Warzone zone = locLobby.getZone();
Team locTeamGate = locLobby.getTeamGate(playerLoc);
if (zone.getWarzoneConfig().getBoolean(WarzoneConfig.DISABLED) || zone.isReinitializing()) {
War.war.badMsg(player, "join.disabled");
event.setTo(zone.getTeleport());
} else if (!zone.getWarzoneConfig().getBoolean(WarzoneConfig.JOINMIDBATTLE) && zone.isEnoughPlayers()) {
War.war.badMsg(player, "join.progress");
event.setTo(zone.getTeleport());
} else if (zone.isFull()) {
War.war.badMsg(player, "join.full.all");
event.setTo(zone.getTeleport());
} else if (zone.isFull(player)) {
War.war.badMsg(player, "join.permission.all");
event.setTo(zone.getTeleport());
} else if (locTeamGate != null && locTeamGate.isFull()) {
War.war.badMsg(player, "join.full.single", locTeamGate.getName());
event.setTo(zone.getTeleport());
} else if (locTeamGate != null && !War.war.canPlayWar(player, locTeamGate)) {
War.war.badMsg(player, "join.permission.single", locTeamGate.getName());
event.setTo(zone.getTeleport());
} else if (zone.getLobby().isAutoAssignGate(playerLoc)) {
zone.autoAssign(player);
} else if (locTeamGate != null) {
zone.assign(player, locTeamGate);
}
return;
} else if (locLobby != null && currentTeam == null
&& locLobby.isInWarHubLinkGate(playerLoc)
&& War.war.getWarHub() != null) {
War.war.msg(player, "warhub.teleport");
event.setTo(War.war.getWarHub().getLocation());
return;
}
// Warhub zone gates
WarHub hub = War.war.getWarHub();
if (hub != null && hub.getVolume().contains(player.getLocation())) {
Warzone zone = hub.getDestinationWarzoneForLocation(playerLoc);
if (zone != null && zone.getTeleport() != null) {
if (zone.getWarzoneConfig().getBoolean(WarzoneConfig.AUTOJOIN)
&& zone.getTeams().size() >= 1 && currentTeam == null) {
if (zone.getWarzoneConfig().getBoolean(WarzoneConfig.DISABLED) || zone.isReinitializing()) {
War.war.badMsg(player, "join.disabled");
event.setTo(hub.getLocation());
} else if (!zone.getWarzoneConfig().getBoolean(WarzoneConfig.JOINMIDBATTLE) && zone.isEnoughPlayers()) {
War.war.badMsg(player, "join.progress");
event.setTo(hub.getLocation());
} else if (zone.isFull()) {
War.war.badMsg(player, "join.full.all");
event.setTo(hub.getLocation());
} else if (zone.isFull(player)) {
War.war.badMsg(player, "join.permission.all");
event.setTo(hub.getLocation());
} else {
zone.autoAssign(player);
}
return;
}
event.setTo(zone.getTeleport());
War.war.msg(player, "zone.teleport", zone.getName());
return;
}
}
boolean isLeaving = playerWarzone != null && playerWarzone.getLobby().isLeavingZone(playerLoc);
Team playerTeam = Team.getTeamByPlayerName(player.getName());
if (isLeaving) { // already in a team and in warzone, leaving
// same as leave
if (playerTeam != null) {
boolean atSpawnAlready = playerTeam.isSpawnLocation(playerLoc);
if (!atSpawnAlready) {
playerWarzone.handlePlayerLeave(player, playerWarzone.getWarzoneConfig().getBoolean(WarzoneConfig.AUTOJOIN) ?
War.war.getWarHub().getLocation() : playerWarzone.getTeleport(), event, true);
return;
}
return;
}
}
if (playerWarzone != null) {
// Player belongs to a warzone team but is outside: he snuck out or is at spawn and died
if (locZone == null && playerTeam != null && playerWarzone.getLobby() != null && !playerWarzone.getLobby().getVolume().contains(playerLoc) && !isLeaving) {
List<BlockFace> nearestWalls = playerWarzone.getNearestWalls(playerLoc);
if (!playerWarzone.getWarzoneConfig().getBoolean(WarzoneConfig.REALDEATHS)) {
War.war.badMsg(player, "zone.leavenotice");
}
if(nearestWalls != null && nearestWalls.size() > 0) {
// First, try to bump the player back in
int northSouthMove = 0;
int eastWestMove = 0;
int upDownMove = 0;
int moveDistance = 1;
if (nearestWalls.contains(Direction.NORTH())) {
// move south
northSouthMove += moveDistance;
} else if (nearestWalls.contains(Direction.SOUTH())) {
// move north
northSouthMove -= moveDistance;
}
if (nearestWalls.contains(Direction.EAST())) {
// move west
eastWestMove += moveDistance;
} else if (nearestWalls.contains(Direction.WEST())) {
// move east
eastWestMove -= moveDistance;
}
if (nearestWalls.contains(BlockFace.UP)) {
upDownMove -= moveDistance;
} else if (nearestWalls.contains(BlockFace.DOWN)) {
// fell off the map, back to spawn (still need to drop objects)
playerWarzone.dropAllStolenObjects(event.getPlayer(), false);
playerWarzone.respawnPlayer(event, playerTeam, event.getPlayer());
return;
}
event.setTo(new Location(playerLoc.getWorld(),
playerLoc.getX() + northSouthMove,
playerLoc.getY() + upDownMove,
playerLoc.getZ() + eastWestMove,
playerLoc.getYaw(),
playerLoc.getPitch()));
return;
// Otherwise, send him to spawn (first make sure he drops his flag/cake/bomb to prevent auto-cap and as punishment)
} else {
playerWarzone.dropAllStolenObjects(event.getPlayer(), false);
playerWarzone.respawnPlayer(event, playerTeam, event.getPlayer());
return;
}
}
LoadoutSelection loadoutSelectionState = playerWarzone.getLoadoutSelections().get(player.getName());
FlagReturn flagReturn = playerTeam.getTeamConfig().resolveFlagReturn();
if (!playerTeam.isSpawnLocation(playerLoc)) {
if (!playerWarzone.isEnoughPlayers() && loadoutSelectionState != null && loadoutSelectionState.isStillInSpawn()) {
// Be sure to keep only players that just respawned locked inside the spawn for minplayer/minteams restrictions - otherwise
// this will conflict with the can't-renter-spawn bump just a few lines below
War.war.badMsg(player, "zone.spawn.minplayers", playerWarzone.getWarzoneConfig().getInt(WarzoneConfig.MINPLAYERS),
playerWarzone.getWarzoneConfig().getInt(WarzoneConfig.MINTEAMS));
event.setTo(playerTeam.getRandomSpawn());
return;
}
if (playerWarzone.isRespawning(player)) {
int rt = playerTeam.getTeamConfig().resolveInt(TeamConfig.RESPAWNTIMER);
War.war.badMsg(player, "zone.spawn.timer", rt);
event.setTo(playerTeam.getRandomSpawn());
return;
}
if (playerWarzone.isReinitializing()) {
// don't let players wander about outside spawns during reset
// (they could mess up the blocks that have already been reset
// before the start of the new battle)
War.war.msg(player, "zone.battle.reset");
event.setTo(playerTeam.getRandomSpawn());
return;
}
} else if (loadoutSelectionState != null && !loadoutSelectionState.isStillInSpawn()
&& !playerWarzone.isCakeThief(player)
&& (flagReturn.equals(FlagReturn.BOTH) || flagReturn.equals(FlagReturn.SPAWN))
&& !playerWarzone.isFlagThief(player)) {
// player is in spawn, but has left already: he should NOT be let back in - kick him out gently
// if he sticks around too long.
// (also, be sure you aren't preventing the flag or cake from being captured)
// if (!CantReEnterSpawnJob.getPlayersUnderSuspicion().contains(player.getName())) {
// CantReEnterSpawnJob job = new CantReEnterSpawnJob(player, playerTeam);
// War.war.getServer().getScheduler().scheduleSyncDelayedTask(War.war, job, 12);
// }
return;
}
// Monuments
if (playerTeam != null && playerWarzone.nearAnyOwnedMonument(playerLoc, playerTeam) && player.getHealth() < 20 && player.getHealth() > 0 // don't heal the dead
&& this.random.nextInt(7) == 3) { // one chance out of many of getting healed
int currentHp = (int) player.getHealth();
int newHp = Math.min(20, currentHp + locZone.getWarzoneConfig().getInt(WarzoneConfig.MONUMENTHEAL));
player.setHealth(newHp);
double heartNum = ((double) newHp - currentHp) / 2;
War.war.msg(player, "zone.monument.voodoo", heartNum);
return;
}
// Flag capture
if (playerWarzone.isFlagThief(player)) {
// smoky
if (System.currentTimeMillis() % 13 == 0) {
playerWarzone.getWorld().playEffect(player.getLocation(), Effect.POTION_BREAK, playerTeam.getKind().getPotionEffectColor());
}
// Make sure game ends can't occur simultaneously.
// See Warzone.handleDeath() for details.
boolean inSpawn = playerTeam.isSpawnLocation(player.getLocation());
boolean inFlag = (playerTeam.getFlagVolume() != null && playerTeam.getFlagVolume().contains(player.getLocation()));
if (playerTeam.getTeamConfig().resolveFlagReturn().equals(FlagReturn.BOTH)) {
if (!inSpawn && !inFlag) {
return;
}
} else if (playerTeam.getTeamConfig().resolveFlagReturn().equals(FlagReturn.SPAWN)) {
if (inFlag) {
War.war.badMsg(player, "zone.flagreturn.spawn");
return;
} else if (!inSpawn) {
return;
}
} else if (playerTeam.getTeamConfig().resolveFlagReturn().equals(FlagReturn.FLAG)) {
if (inSpawn) {
War.war.badMsg(player, "zone.flagreturn.flag");
return;
} else if (!inFlag) {
return;
}
}
if (!playerTeam.getPlayers().contains(player)) {
// Make sure player is still part of team, game may have ended while waiting)
// Ignore the scorers that happened immediately after the game end.
return;
}
if (playerWarzone.isTeamFlagStolen(playerTeam) && playerTeam.getTeamConfig().resolveBoolean(TeamConfig.FLAGMUSTBEHOME)) {
War.war.badMsg(player, "zone.flagreturn.deadlock");
} else {
// flags can be captured at own spawn or own flag pole
if (playerWarzone.isReinitializing()) {
// Battle already ended or interrupted
playerWarzone.respawnPlayer(event, playerTeam, player);
} else {
// All good - proceed with scoring
playerTeam.addPoint();
Team victim = playerWarzone.getVictimTeamForFlagThief(player);
// Notify everyone
for (Team t : playerWarzone.getTeams()) {
t.teamcast("zone.flagcapture.broadcast", playerTeam.getKind().getColor() + player.getName() + ChatColor.WHITE,
victim.getName(), playerTeam.getName());
}
// Detect win conditions
if (playerTeam.getPoints() >= playerTeam.getTeamConfig().resolveInt(TeamConfig.MAXSCORE)) {
if (playerWarzone.hasPlayerState(player.getName())) {
playerWarzone.restorePlayerState(player);
}
playerWarzone.handleScoreCapReached(playerTeam.getName());
event.setTo(playerWarzone.getTeleport());
} else {
// just added a point
victim.getFlagVolume().resetBlocks(); // bring back flag to team that lost it
victim.initializeTeamFlag();
playerWarzone.respawnPlayer(event, playerTeam, player);
playerTeam.resetSign();
playerWarzone.getLobby().resetTeamGateSign(playerTeam);
}
}
playerWarzone.removeFlagThief(player);
return;
}
}
// Bomb detonation
if (playerWarzone.isBombThief(player)) {
// smoky
playerWarzone.getWorld().playEffect(player.getLocation(), Effect.SMOKE, 0);
// Make sure game ends can't occur simultaneously.
// Not thread safe. See Warzone.handleDeath() for details.
boolean inEnemySpawn = false;
Team victim = null;
for (Team team : playerWarzone.getTeams()) {
if (team != playerTeam
&& team.isSpawnLocation(player.getLocation())
&& team.getPlayers().size() > 0) {
inEnemySpawn = true;
victim = team;
break;
}
}
if (inEnemySpawn && playerTeam.getPlayers().contains(player)) {
// Made sure player is still part of team, game may have ended while waiting.
// Ignored the scorers that happened immediately after the game end.
Bomb bomb = playerWarzone.getBombForThief(player);
// Boom!
if (!playerWarzone.getWarzoneConfig().getBoolean(WarzoneConfig.UNBREAKABLE)) {
// Don't blow up if warzone is unbreakable
playerWarzone.getWorld().createExplosion(player.getLocation(), 2F);
}
if (playerWarzone.isReinitializing()) {
// Battle already ended or interrupted
playerWarzone.respawnPlayer(event, playerTeam, player);
} else {
// All good - proceed with scoring
playerTeam.addPoint();
// Notify everyone
for (Team t : playerWarzone.getTeams()) {
t.teamcast("zone.bomb.broadcast", playerTeam.getKind().getColor() + player.getName() + ChatColor.WHITE,
victim.getName(), playerTeam.getName());
}
// Detect win conditions
if (playerTeam.getPoints() >= playerTeam.getTeamConfig().resolveInt(TeamConfig.MAXSCORE)) {
if (playerWarzone.hasPlayerState(player.getName())) {
playerWarzone.restorePlayerState(player);
}
playerWarzone.handleScoreCapReached(playerTeam.getName());
event.setTo(playerWarzone.getTeleport());
} else {
// just added a point
// restore bombed team's spawn
for (Volume spawnVolume : victim.getSpawnVolumes().values()) {
spawnVolume.resetBlocks();
}
victim.initializeTeamSpawns();
// bring back tnt
bomb.getVolume().resetBlocks();
bomb.addBombBlocks();
playerWarzone.respawnPlayer(event, playerTeam, player);
playerTeam.resetSign();
playerWarzone.getLobby().resetTeamGateSign(playerTeam);
}
}
playerWarzone.removeBombThief(player);
return;
}
}
// Cake retrieval
if (playerWarzone.isCakeThief(player)) {
// smoky
if (System.currentTimeMillis() % 13 == 0) {
playerWarzone.getWorld().playEffect(player.getLocation(), Effect.POTION_BREAK, playerTeam.getKind().getPotionEffectColor());
}
// Make sure game ends can't occur simultaneously.
// Not thread safe. See Warzone.handleDeath() for details.
boolean inSpawn = playerTeam.isSpawnLocation(player.getLocation());
if (inSpawn && playerTeam.getPlayers().contains(player)) {
// Made sure player is still part of team, game may have ended while waiting.
// Ignored the scorers that happened immediately after the game end.
boolean hasOpponent = false;
for (Team t : playerWarzone.getTeams()) {
if (t != playerTeam && t.getPlayers().size() > 0) {
hasOpponent = true;
}
}
// Don't let someone alone make points off cakes
if (hasOpponent) {
Cake cake = playerWarzone.getCakeForThief(player);
if (playerWarzone.isReinitializing()) {
// Battle already ended or interrupted
playerWarzone.respawnPlayer(event, playerTeam, player);
} else {
// All good - proceed with scoring
// Woot! Cake effect: 1 pt + full lifepool
playerTeam.addPoint();
playerTeam.setRemainingLives(playerTeam.getTeamConfig().resolveInt(TeamConfig.LIFEPOOL));
// Notify everyone
for (Team t : playerWarzone.getTeams()) {
t.teamcast("zone.cake.broadcast", playerTeam.getKind().getColor() + player.getName() + ChatColor.WHITE,
ChatColor.GREEN + cake.getName() + ChatColor.WHITE, playerTeam.getName());
}
// Detect win conditions
if (playerTeam.getPoints() >= playerTeam.getTeamConfig().resolveInt(TeamConfig.MAXSCORE)) {
if (playerWarzone.hasPlayerState(player.getName())) {
playerWarzone.restorePlayerState(player);
}
playerWarzone.handleScoreCapReached(playerTeam.getName());
event.setTo(playerWarzone.getTeleport());
} else {
// just added a point
// bring back cake
cake.getVolume().resetBlocks();
cake.addCakeBlocks();
playerWarzone.respawnPlayer(event, playerTeam, player);
playerTeam.resetSign();
playerWarzone.getLobby().resetTeamGateSign(playerTeam);
}
}
playerWarzone.removeCakeThief(player);
}
return;
}
}
// Class selection lock
if (!playerTeam.isSpawnLocation(player.getLocation()) &&
playerWarzone.getLoadoutSelections().keySet().contains(player.getName())
&& playerWarzone.getLoadoutSelections().get(player.getName()).isStillInSpawn()) {
playerWarzone.getLoadoutSelections().get(player.getName()).setStillInSpawn(false);
}
} else if (locZone != null && locZone.getLobby() != null && !locZone.getLobby().isLeavingZone(playerLoc) && !isMaker) {
// player is not in any team, but inside warzone boundaries, get him out
Warzone zone = Warzone.getZoneByLocation(playerLoc);
event.setTo(zone.getTeleport());
War.war.badMsg(player, "zone.noteamnotice");
}
}
@EventHandler
public void onPlayerToggleSneak(PlayerToggleSneakEvent event) {
if (War.war.isLoaded() && event.isSneaking()) {
Warzone playerWarzone = Warzone.getZoneByLocation(event.getPlayer());
Team playerTeam = Team.getTeamByPlayerName(event.getPlayer().getName());
if (playerWarzone != null && playerTeam != null && playerTeam.getInventories().resolveLoadouts().keySet().size() > 1 && playerTeam.isSpawnLocation(event.getPlayer().getLocation())) {
if (playerWarzone.getLoadoutSelections().keySet().contains(event.getPlayer().getName())
&& playerWarzone.getLoadoutSelections().get(event.getPlayer().getName()).isStillInSpawn()) {
LoadoutSelection selection = playerWarzone.getLoadoutSelections().get(event.getPlayer().getName());
List<Loadout> loadouts = new ArrayList<Loadout>(playerTeam.getInventories().resolveNewLoadouts());
for (Iterator<Loadout> it = loadouts.iterator(); it.hasNext();) {
Loadout ldt = it.next();
if (ldt.getName().equals("first") ||
(ldt.requiresPermission() && !event.getPlayer().hasPermission(ldt.getPermission()))) {
it.remove();
}
}
int currentIndex = (selection.getSelectedIndex() + 1) % loadouts.size();
selection.setSelectedIndex(currentIndex);
playerWarzone.equipPlayerLoadoutSelection(event.getPlayer(), playerTeam, false, true);
} else {
War.war.badMsg(event.getPlayer(), "zone.loadout.reenter");
}
}
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerRespawn(PlayerRespawnEvent event) {
Warzone playingZone = Warzone.getZoneByPlayerName(event.getPlayer().getName());
Warzone deadZone = Warzone.getZoneForDeadPlayer(event.getPlayer());
if (playingZone == null && deadZone != null) {
// Game ended while player was dead, so restore state
deadZone.getReallyDeadFighters().remove(event.getPlayer().getName());
if (deadZone.hasPlayerState(event.getPlayer().getName())) {
deadZone.restorePlayerState(event.getPlayer());
}
event.setRespawnLocation(deadZone.getEndTeleport(LeaveCause.DISCONNECT));
return;
} else if (playingZone == null) {
// Player not playing war
return;
} else if (deadZone == null) {
// Player is not a 'really' dead player, nothing to do here
return;
}
Team team = playingZone.getPlayerTeam(event.getPlayer().getName());
Validate.notNull(team, String.format(
"Failed to find a team for player %s in warzone %s on respawn.",
event.getPlayer().getName(), playingZone.getName()));
playingZone.getReallyDeadFighters().remove(event.getPlayer().getName());
event.setRespawnLocation(team.getRandomSpawn());
playingZone.respawnPlayer(team, event.getPlayer());
}
@EventHandler
public void onPlayerTeleport(final PlayerTeleportEvent event) {
if (War.war.isLoaded()) {
Warzone playerWarzone = Warzone.getZoneByPlayerName(event.getPlayer().getName());
Team playerTeam = Team.getTeamByPlayerName(event.getPlayer().getName());
if (playerWarzone != null) {
if (!playerWarzone.getVolume().contains(event.getTo())) {
// Prevent teleporting out of the warzone
if (!playerWarzone.getWarzoneConfig().getBoolean(WarzoneConfig.REALDEATHS)) {
War.war.badMsg(event.getPlayer(), "Use /leave (or /war leave) to exit the zone.");
}
playerWarzone.dropAllStolenObjects(event.getPlayer(), false);
playerWarzone.respawnPlayer(event, playerTeam, event.getPlayer());
}
}
}
}
@EventHandler
public void onPlayerExpChange(PlayerExpChangeEvent event) {
if (War.war.isLoaded()) {
Team team = Team.getTeamByPlayerName(event.getPlayer().getName());
if (team != null && team.getTeamConfig().resolveBoolean(TeamConfig.XPKILLMETER)) {
event.setAmount(0);
}
}
}
@EventHandler(priority = EventPriority.LOW)
public void onPlayerChat(final AsyncPlayerChatEvent event) {
Team team = Team.getTeamByPlayerName(event.getPlayer().getName());
if (team != null && team.isInTeamChat(event.getPlayer())) {
event.setCancelled(true);
team.sendTeamChatMessage(event.getPlayer(), event.getMessage());
}
}
@EventHandler
public void onInventoryClick(final InventoryClickEvent event) {
if (!(event.getWhoClicked() instanceof Player)) {
return;
}
Player player = (Player) event.getWhoClicked();
Warzone zone = Warzone.getZoneByPlayerName(player.getName());
if (zone == null) {
return;
}
if (zone.isThief(player)) {
// Prevent thieves from taking their bomb/wool/cake into a chest, etc.
event.setCancelled(true);
player.playSound(player.getLocation(), Sound.BLOCK_LAVA_EXTINGUISH, 10, 10);
} else if (event.getSlotType() == InventoryType.SlotType.ARMOR && event.getSlot() == 39
&& zone.getWarzoneConfig().getBoolean(WarzoneConfig.BLOCKHEADS)) {
// Magically give player a wool block when they click their helmet
ItemStack teamBlock = zone.getPlayerTeam(player.getName()).getKind().getBlockHead();
player.getInventory().remove(teamBlock.getType());
// Deprecated behavior cannot be removed as it is essential to this function
//noinspection deprecation
event.setCursor(teamBlock);
event.setCancelled(true);
}
}
public void purgeLatestPositions() {
this.latestLocations.clear();
}
@EventHandler
public void onBucketEmpty(PlayerBucketEmptyEvent event) {
Player player = (Player) event.getPlayer();
Warzone zone = Warzone.getZoneByPlayerName(player.getName());
if (zone == null) {
return;
}
if (zone.isImportantBlock(event.getBlockClicked())) {
event.setCancelled(true);
player.playSound(player.getLocation(), Sound.BLOCK_LAVA_EXTINGUISH, 10, 10);
}
}
}