Subroutines for join/leave zone boilerplate & thief removal

Warzone now contains a few new methods to make adding and removing players from the zone easier. This was made in response to every join mechanism having to rewrite the same ~25 lines of code to handle adding players to a team. This was also done to replace the even more bulky code used to return stolen structures.

This also removes a few unused jobs as I am trying to transition away from them, as they don't really help if they are not being used for async tasks, batches, or timers.

A better way of managing teleports at the end of a game or when leaving normally has been added.
This commit is contained in:
cmastudios 2013-11-01 17:52:52 -05:00
parent 3791a027a0
commit ceeea15794
11 changed files with 380 additions and 501 deletions

View File

@ -33,8 +33,6 @@ import com.tommytony.war.config.TeamConfig;
import com.tommytony.war.config.TeamConfigBag;
import com.tommytony.war.config.TeamKind;
import com.tommytony.war.config.TeamSpawnStyle;
import com.tommytony.war.structure.Bomb;
import com.tommytony.war.structure.Cake;
import com.tommytony.war.utility.Direction;
import com.tommytony.war.volume.Volume;
@ -446,46 +444,19 @@ public class Team {
return this.name;
}
public boolean removePlayer(String name) {
Player thePlayer = null;
for (Player player : this.players) {
if (player.getName().equals(name)) {
thePlayer = player;
}
public void removePlayer(Player thePlayer) {
this.players.remove(thePlayer);
this.warzone.dropAllStolenObjects(thePlayer, false);
if (War.war.isTagServer()) {
TagAPI.refreshPlayer(thePlayer);
}
if (thePlayer != null) {
this.players.remove(thePlayer);
if (this.warzone.isFlagThief(thePlayer.getName())) {
Team victim = this.warzone.getVictimTeamForFlagThief(thePlayer.getName());
victim.getFlagVolume().resetBlocks();
victim.initializeTeamFlag();
this.warzone.removeFlagThief(thePlayer.getName());
this.warzone.broadcast("drop.flag.broadcast", thePlayer.getName(), ChatColor.GREEN + victim.getName() + ChatColor.WHITE);
}
if (this.warzone.isBombThief(thePlayer.getName())) {
Bomb bomb = this.warzone.getBombForThief(thePlayer.getName());
bomb.getVolume().resetBlocks();
bomb.addBombBlocks();
this.warzone.removeBombThief(thePlayer.getName());
this.warzone.broadcast("drop.bomb.broadcast", thePlayer.getName(), ChatColor.GREEN + bomb.getName() + ChatColor.WHITE);
}
if (this.warzone.isCakeThief(thePlayer.getName())) {
Cake cake = this.warzone.getCakeForThief(thePlayer.getName());
cake.getVolume().resetBlocks();
cake.addCakeBlocks();
this.warzone.removeCakeThief(thePlayer.getName());
this.warzone.broadcast("drop.cake.broadcast", thePlayer.getName(), ChatColor.GREEN + cake.getName() + ChatColor.WHITE);
}
if (War.war.isTagServer()) {
TagAPI.refreshPlayer(thePlayer);
}
return true;
if (War.war.isSpoutServer()) {
War.war.getSpoutDisplayer().updateStats(thePlayer);
}
return false;
thePlayer.setFireTicks(0);
thePlayer.setRemainingAir(300);
this.warzone.restorePlayerState(thePlayer);
this.warzone.getLoadoutSelections().remove(thePlayer);
}
public void setRemainingLives(int remainingLives) {
@ -536,10 +507,12 @@ public class Team {
spawnEntry.getValue().resetBlocks();
this.initializeTeamSpawn(spawnEntry.getKey()); // reset everything instead of just sign
}
if (this.warzone.getLobby() != null) {
this.warzone.getLobby().resetTeamGateSign(this);
}
if (War.war.getWarHub() != null) {
War.war.getWarHub().resetZoneSign(warzone);
}
}
public void setSpawnVolume(Location spawnLocation, Volume volume) {

View File

@ -2,9 +2,12 @@ package com.tommytony.war;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import org.apache.commons.lang.StringUtils;
@ -25,6 +28,7 @@ import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.LeatherArmorMeta;
import org.bukkit.permissions.Permissible;
import org.bukkit.scoreboard.DisplaySlot;
import org.bukkit.scoreboard.Objective;
import org.bukkit.scoreboard.Scoreboard;
@ -47,7 +51,6 @@ import com.tommytony.war.job.InitZoneJob;
import com.tommytony.war.job.LoadoutResetJob;
import com.tommytony.war.job.LogKillsDeathsJob;
import com.tommytony.war.job.LogKillsDeathsJob.KillsDeathsRecord;
import com.tommytony.war.job.ScoreCapReachedJob;
import com.tommytony.war.mapper.LoadoutYmlMapper;
import com.tommytony.war.spout.SpoutDisplayer;
import com.tommytony.war.structure.Bomb;
@ -71,6 +74,13 @@ import com.tommytony.war.volume.ZoneVolume;
* @package com.tommytony.war
*/
public class Warzone {
public enum LeaveCause {
COMMAND, DISCONNECT, SCORECAP, RESET;
public boolean useRallyPoint() {
return this == SCORECAP ? true : false;
}
}
private String name;
private ZoneVolume volume;
private World world;
@ -474,7 +484,7 @@ public class Warzone {
}
}
public void resetInventory(Team team, Player player, HashMap<Integer, ItemStack> loadout) {
public void resetInventory(Team team, Player player, Map<Integer, ItemStack> loadout) {
// Reset inventory to loadout
PlayerInventory playerInv = player.getInventory();
playerInv.clear();
@ -502,14 +512,12 @@ public class Warzone {
}
if (this.getWarzoneConfig().getBoolean(WarzoneConfig.BLOCKHEADS)) {
playerInv.setHelmet(team.getKind().getBlockHead());
} else {
if (!helmetIsInLoadout) {
ItemStack helmet = new ItemStack(Material.LEATHER_HELMET);
LeatherArmorMeta meta = (LeatherArmorMeta) helmet.getItemMeta();
meta.setColor(team.getKind().getBukkitColor());
helmet.setItemMeta(meta);
playerInv.setHelmet(helmet);
}
} else if (!helmetIsInLoadout) {
ItemStack helmet = new ItemStack(Material.LEATHER_HELMET);
LeatherArmorMeta meta = (LeatherArmorMeta) helmet.getItemMeta();
meta.setColor(team.getKind().getBukkitColor());
helmet.setItemMeta(meta);
playerInv.setHelmet(helmet);
}
}
@ -885,31 +893,56 @@ public class Warzone {
return this.lobby;
}
static final Comparator<Team> LEAST_PLAYER_COUNT_ORDER = new Comparator<Team>() {
@Override
public int compare(Team arg0, Team arg1) {
return arg0.getPlayers().size() - arg1.getPlayers().size();
}
};
public Team autoAssign(Player player) {
Collections.sort(teams, LEAST_PLAYER_COUNT_ORDER);
Team lowestNoOfPlayers = null;
for (Team t : this.teams) {
if (lowestNoOfPlayers == null || (lowestNoOfPlayers != null && lowestNoOfPlayers.getPlayers().size() > t.getPlayers().size())) {
if (War.war.canPlayWar(player, t)) {
lowestNoOfPlayers = t;
}
for (Team team : this.teams) {
if (War.war.canPlayWar(player, team)) {
lowestNoOfPlayers = team;
break;
}
}
if (lowestNoOfPlayers != null) {
if (player.getWorld() != this.getWorld()) {
player.teleport(this.getWorld().getSpawnLocation());
}
lowestNoOfPlayers.addPlayer(player);
lowestNoOfPlayers.resetSign();
if (!this.hasPlayerState(player.getName())) {
this.keepPlayerState(player);
}
War.war.msg(player, "join.inventorystored");
this.respawnPlayer(lowestNoOfPlayers, player);
this.broadcast("join.broadcast", player.getName(), lowestNoOfPlayers.getName());
this.assign(player, lowestNoOfPlayers);
}
return lowestNoOfPlayers;
}
/**
* Assign a player to a specific team.
*
* @param player
* Player to assign to team.
* @param team
* Team to add the player to.
* @return false if player does not have permission to join this team.
*/
public boolean assign(Player player, Team team) {
if (!War.war.canPlayWar(player, team)) {
War.war.badMsg(player, "join.permission.single");
return false;
}
if (player.getWorld() != this.getWorld()) {
player.teleport(this.getWorld().getSpawnLocation());
}
team.addPlayer(player);
team.resetSign();
if (!this.hasPlayerState(player.getName())) {
this.keepPlayerState(player);
War.war.msg(player, "join.inventorystored");
}
this.respawnPlayer(team, player);
this.broadcast("join.broadcast", player.getName(), player.getName());
return true;
}
public void handleDeath(Player player) {
// THIS ISN'T THREAD SAFE
// Every death and player movement should ideally occur in sequence because
@ -1104,55 +1137,22 @@ public class Warzone {
}
public void handlePlayerLeave(Player player, Location destination, PlayerMoveEvent event, boolean removeFromTeam) {
this.handlePlayerLeave(player, removeFromTeam);
this.handlePlayerLeave(player);
event.setTo(destination);
}
public void handlePlayerLeave(Player player, Location destination, boolean removeFromTeam) {
this.handlePlayerLeave(player, removeFromTeam);
this.handlePlayerLeave(player);
player.teleport(destination);
}
private void handlePlayerLeave(Player player, boolean removeFromTeam) {
private void handlePlayerLeave(Player player) {
Team playerTeam = Team.getTeamByPlayerName(player.getName());
if (playerTeam != null) {
if (removeFromTeam) {
playerTeam.removePlayer(player.getName());
}
playerTeam.removePlayer(player);
this.broadcast("leave.broadcast", playerTeam.getKind().getColor() + player.getName() + ChatColor.WHITE);
playerTeam.resetSign();
if (this.getLobby() != null) {
this.getLobby().resetTeamGateSign(playerTeam);
}
if (this.hasPlayerState(player.getName())) {
this.restorePlayerState(player);
}
if (this.getLoadoutSelections().containsKey(player.getName())) {
// clear inventory selection
this.getLoadoutSelections().remove(player.getName());
}
player.setFireTicks(0);
player.setRemainingAir(300);
// To hide stats
if (War.war.isSpoutServer()) {
War.war.getSpoutDisplayer().updateStats(player);
}
War.war.msg(player, "leave.inventoryrestore");
if (War.war.getWarHub() != null) {
War.war.getWarHub().resetZoneSign(this);
}
boolean zoneEmpty = true;
for (Team team : this.getTeams()) {
if (team.getPlayers().size() > 0) {
zoneEmpty = false;
break;
}
}
if (zoneEmpty && this.getWarzoneConfig().getBoolean(WarzoneConfig.RESETONEMPTY)) {
if (this.getPlayerCount() == 0 && this.getWarzoneConfig().getBoolean(WarzoneConfig.RESETONEMPTY)) {
// reset the zone for a new game when the last player leaves
for (Team team : this.getTeams()) {
team.resetPoints();
@ -1323,10 +1323,49 @@ public class Warzone {
WarScoreCapEvent event1 = new WarScoreCapEvent(winningTeams);
War.war.getServer().getPluginManager().callEvent(event1);
new ScoreCapReachedJob(this, winnersStr).run(); // run inventory and teleports immediately to avoid inv reset problems
for (Team t : this.getTeams()) {
if (War.war.isSpoutServer()) {
for (Player p : t.getPlayers()) {
SpoutPlayer sp = SpoutManager.getPlayer(p);
if (sp.isSpoutCraftEnabled()) {
sp.sendNotification(
SpoutDisplayer.cleanForNotification("Match won! " + ChatColor.WHITE + "Winners:"),
SpoutDisplayer.cleanForNotification(SpoutDisplayer.addMissingColor(winnersStr, this)),
Material.CAKE,
(short)0,
10000);
}
}
}
String winnersStrAndExtra = "Score cap reached. Game is over! Winning team(s): " + winnersStr;
winnersStrAndExtra += ". Resetting warzone and your inventory...";
t.teamcast(winnersStrAndExtra);
for (Iterator<Player> it = t.getPlayers().iterator(); it.hasNext();) {
Player tp = it.next();
it.remove(); // Remove player from team first to prevent anti-tp
t.removePlayer(tp);
tp.teleport(this.getEndTeleport(LeaveCause.SCORECAP));
if (winnersStr.contains(t.getName())) {
// give reward
rewardPlayer(tp, t.getInventories().resolveReward());
}
}
t.resetPoints();
t.getPlayers().clear(); // empty the team
t.resetSign();
}
this.reinitialize();
}
public void rewardPlayer(Player player, Map<Integer, ItemStack> reward) {
for (Integer slot : reward.keySet()) {
ItemStack item = reward.get(slot);
if (item != null) {
player.getInventory().addItem(item);
}
}
}
public boolean isDeadMan(String playerName) {
if (this.deadMenInventories.containsKey(playerName)) {
return true;
@ -1352,10 +1391,12 @@ public class Warzone {
public void unload() {
War.war.log("Unloading zone " + this.getName() + "...", Level.INFO);
for (Team team : this.getTeams()) {
for (Player player : team.getPlayers()) {
this.handlePlayerLeave(player, this.getTeleport(), false);
for (Iterator<Player> it = team.getPlayers().iterator(); it.hasNext(); ) {
final Player player = it.next();
it.remove();
team.removePlayer(player);
player.teleport(this.getTeleport());
}
team.getPlayers().clear();
}
if (this.getLobby() != null) {
this.getLobby().getVolume().resetBlocks();
@ -1420,8 +1461,8 @@ public class Warzone {
}
if (sortedNames.isEmpty()) {
// Fix for zones that mistakenly only specify a `first' loadout, but do not add any others.
this.handlePlayerLeave(player, this.getTeleport(), true);
War.war.badMsg(player, "We couldn't find a loadout for you! Please alert the warzone maker to add a `default' loadout to this warzone.");
this.resetInventory(playerTeam, player, Collections.<Integer, ItemStack>emptyMap());
War.war.msg(player, "404 No loadouts found");
return;
}
int currentIndex = selection.getSelectedIndex();
@ -1509,22 +1550,6 @@ public class Warzone {
return this.reallyDeadFighters ;
}
public void gameEndTeleport(Player tp) {
if (this.getRallyPoint() != null) {
tp.teleport(this.getRallyPoint());
} else if (this.getWarzoneConfig().getBoolean(WarzoneConfig.AUTOJOIN)) {
tp.teleport(War.war.getWarHub().getLocation());
} else {
tp.teleport(this.getTeleport());
}
tp.setFireTicks(0);
tp.setRemainingAir(300);
if (this.hasPlayerState(tp.getName())) {
this.restorePlayerState(tp);
}
}
public boolean isEndOfGame() {
return this.isEndOfGame;
}
@ -1647,6 +1672,12 @@ public class Warzone {
}
}
/**
* Get a list of all players in the warzone. The list is immutable. If you
* need to modify the player list, you must use the per-team lists
*
* @return list containing all team players.
*/
public List<Player> getPlayers() {
List<Player> players = new ArrayList<Player>();
for (Team team : this.teams) {
@ -1655,6 +1686,11 @@ public class Warzone {
return players;
}
/**
* Get the amount of players in all teams in this warzone.
*
* @return total player count
*/
public int getPlayerCount() {
int count = 0;
for (Team team : this.teams) {
@ -1662,4 +1698,144 @@ public class Warzone {
}
return count;
}
/**
* Get the amount of players in all teams in this warzone. Same as
* {@link #getPlayerCount()}, except only checks teams that the specified
* player has permission to join.
*
* @param target
* Player to check for permissions.
* @return total player count in teams the player has access to.
*/
public int getPlayerCount(Permissible target) {
int playerCount = 0;
for (Team team : this.teams) {
if (target.hasPermission(team.getTeamConfig().resolveString(
TeamConfig.PERMISSION))) {
playerCount += team.getPlayers().size();
}
}
return playerCount;
}
/**
* Get the total capacity of all teams in this zone. This should be
* preferred over {@link TeamConfig#TEAMSIZE} as that can differ per team.
*
* @return capacity of all teams in this zone
*/
public int getTotalCapacity() {
int capacity = 0;
for (Team team : this.teams) {
capacity += team.getTeamConfig().resolveInt(TeamConfig.TEAMSIZE);
}
return capacity;
}
/**
* Get the total capacity of all teams in this zone. Same as
* {@link #getTotalCapacity()}, except only checks teams that the specified
* player has permission to join.
*
* @param target
* Player to check for permissions.
* @return capacity of teams the player has access to.
*/
public int getTotalCapacity(Permissible target) {
int capacity = 0;
for (Team team : this.teams) {
if (target.hasPermission(team.getTeamConfig().resolveString(
TeamConfig.PERMISSION))) {
capacity += team.getTeamConfig()
.resolveInt(TeamConfig.TEAMSIZE);
}
}
return capacity;
}
/**
* Check if all teams are full.
*
* @return true if all teams are full, false otherwise.
*/
public boolean isFull() {
return this.getPlayerCount() == this.getTotalCapacity();
}
/**
* Check if all teams are full. Same as {@link #isFull()}, except only
* checks teams that the specified player has permission to join.
*
* @param target
* Player to check for permissions.
* @return true if all teams are full, false otherwise.
*/
public boolean isFull(Permissible target) {
return this.getPlayerCount(target) == this.getTotalCapacity(target);
}
public void dropAllStolenObjects(Player player, boolean quiet) {
if (this.isFlagThief(player.getName())) {
Team victimTeam = this.getVictimTeamForFlagThief(player.getName());
this.removeFlagThief(player.getName());
// Bring back flag of victim team
victimTeam.getFlagVolume().resetBlocks();
victimTeam.initializeTeamFlag();
if (!quiet) {
this.broadcast("drop.flag.broadcast", player.getName(), ChatColor.GREEN + victimTeam.getName() + ChatColor.WHITE);
}
} else if (this.isCakeThief(player.getName())) {
Cake cake = this.getCakeForThief(player.getName());
this.removeCakeThief(player.getName());
// Bring back cake
cake.getVolume().resetBlocks();
cake.addCakeBlocks();
if (!quiet) {
this.broadcast("drop.cake.broadcast", player.getName(), ChatColor.GREEN + cake.getName() + ChatColor.WHITE);
}
} else if (this.isBombThief(player.getName())) {
Bomb bomb = this.getBombForThief(player.getName());
this.removeBombThief(player.getName());
// Bring back bomb
bomb.getVolume().resetBlocks();
bomb.addBombBlocks();
if (!quiet) {
this.broadcast("drop.bomb.broadcast", player.getName(), ChatColor.GREEN + bomb.getName() + ChatColor.WHITE);
}
}
}
/**
* Get the proper ending teleport location for players leaving the warzone.
* <p>
* Specifically, it gets teleports in this order:
* <ul>
* <li>Rally point (if scorecap)
* <li>Warhub (if autojoin)
* <li>Lobby
* </ul>
* </p>
* @param reason Reason for leaving zone
* @return
*/
public Location getEndTeleport(LeaveCause reason) {
if (reason.useRallyPoint() && this.getRallyPoint() != null) {
return this.getRallyPoint();
}
if (this.getWarzoneConfig().getBoolean(WarzoneConfig.AUTOJOIN)
&& War.war.getWarHub() != null) {
return War.war.getWarHub().getLocation();
}
return this.getTeleport();
}
}

View File

@ -30,13 +30,11 @@ public class JoinCommand extends AbstractWarCommand {
Player player = (Player) this.getSender();
Warzone zone;
if (this.args.length == 0) {
return false;
} else if (this.args.length == 2) {
TeamKind kind;
if (this.args.length == 2) {
// zone by name
zone = Warzone.getZoneByName(this.args[0]);
// move the team-name to first place :)
this.args[0] = this.args[1];
kind = TeamKind.teamKindFromString(this.args[1]);
} else if (this.args.length == 1) {
zone = Warzone.getZoneByLocation((Player) this.getSender());
if (zone == null) {
@ -46,15 +44,13 @@ public class JoinCommand extends AbstractWarCommand {
}
zone = lobby.getZone();
}
kind = TeamKind.teamKindFromString(this.args[0]);
} else {
return false;
}
if (zone == null) {
return false;
}
TeamKind kind = TeamKind.teamKindFromString(this.args[0]);
if (zone.getWarzoneConfig().getBoolean(WarzoneConfig.DISABLED)) {
this.badMsg("join.disabled");
} else if (zone.getWarzoneConfig().getBoolean(WarzoneConfig.AUTOASSIGN)) {
@ -76,25 +72,10 @@ public class JoinCommand extends AbstractWarCommand {
this.badMsg("join.selfteam");
return true;
}
if (!previousTeam.removePlayer(player.getName())) {
War.war.log("Could not remove player " + player.getName() + " from team " + previousTeam.getName(), java.util.logging.Level.WARNING);
}
previousTeam.removePlayer(player);
previousTeam.resetSign();
}
if (player.getWorld() != zone.getWorld()) {
player.teleport(zone.getWorld().getSpawnLocation());
}
if (!zone.hasPlayerState(player.getName())) {
zone.keepPlayerState(player);
this.msg("join.inventorystored");
}
team.addPlayer(player);
team.resetSign();
zone.respawnPlayer(team, player);
if (War.war.getWarHub() != null) {
War.war.getWarHub().resetZoneSign(zone);
}
zone.broadcast("join.broadcast", player.getName(), team.getName());
zone.assign(player, team);
}
}
return true;

View File

@ -3,10 +3,8 @@ package com.tommytony.war.command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.config.WarzoneConfig;
import com.tommytony.war.Warzone.LeaveCause;
/**
* Leaves a game.
@ -35,8 +33,7 @@ public class LeaveCommand extends AbstractWarCommand {
return false;
}
zone.handlePlayerLeave(player, zone.getWarzoneConfig().getBoolean(WarzoneConfig.AUTOJOIN) ?
War.war.getWarHub().getLocation() : zone.getTeleport(), true);
zone.handlePlayerLeave(player, zone.getEndTeleport(LeaveCause.COMMAND), true);
return true;
}
}

View File

@ -1,5 +1,6 @@
package com.tommytony.war.command;
import java.util.Iterator;
import java.util.logging.Level;
import org.bukkit.command.CommandSender;
@ -8,10 +9,8 @@ import org.bukkit.entity.Player;
import com.tommytony.war.Team;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.config.WarzoneConfig;
import com.tommytony.war.Warzone.LeaveCause;
import com.tommytony.war.structure.ZoneLobby;
import java.util.Iterator;
import org.kitteh.tag.TagAPI;
public class ResetZoneCommand extends AbstractZoneMakerCommand {
@ -52,13 +51,8 @@ public class ResetZoneCommand extends AbstractZoneMakerCommand {
for (Iterator<Player> it = team.getPlayers().iterator(); it.hasNext();) {
Player p = it.next();
it.remove();
if (War.war.isTagServer()) {
TagAPI.refreshPlayer(p);
}
zone.restorePlayerState(p);
p.teleport(zone.getWarzoneConfig().getBoolean(WarzoneConfig.AUTOJOIN) ?
War.war.getWarHub().getLocation() : zone.getTeleport());
War.war.msg(p, "You have left the warzone. Your inventory is being restored.");
team.removePlayer(p);
p.teleport(zone.getEndTeleport(LeaveCause.RESET));
}
team.resetPoints();
team.getPlayers().clear();

View File

@ -175,4 +175,14 @@ public enum TeamKind {
Wool wool = (Wool) item.getData();
return wool.getColor() == dyeColor;
}
/**
* Check if a block data is this team's block data.
*
* @param data Wool block data.
* @return true if data is this team's data.
*/
public boolean isTeamBlock(MaterialData data) {
return data instanceof Wool && ((Wool)data).getColor() == this.dyeColor;
}
}

View File

@ -7,12 +7,14 @@ import org.bukkit.ChatColor;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
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.player.PlayerCommandPreprocessEvent;
@ -31,6 +33,7 @@ import org.getspout.spoutapi.player.SpoutPlayer;
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;
@ -46,6 +49,8 @@ import com.tommytony.war.utility.LoadoutSelection;
import com.tommytony.war.volume.Volume;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.logging.Level;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerExpChangeEvent;
@ -68,8 +73,7 @@ public class WarPlayerListener implements Listener {
Player player = event.getPlayer();
Warzone zone = Warzone.getZoneByPlayerName(player.getName());
if (zone != null) {
zone.handlePlayerLeave(player, zone.getWarzoneConfig().getBoolean(WarzoneConfig.AUTOJOIN) ?
War.war.getWarHub().getLocation() : zone.getTeleport(), true);
zone.handlePlayerLeave(player, zone.getEndTeleport(LeaveCause.DISCONNECT), true);
}
if (War.war.isWandBearer(player)) {
@ -105,7 +109,7 @@ public class WarPlayerListener implements Listener {
Item item = event.getItemDrop();
if (item != null) {
ItemStack itemStack = item.getItemStack();
if (itemStack != null && itemStack.getType() == team.getKind().getMaterial() && itemStack.getData() == team.getKind().getBlockData()) {
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);
@ -140,6 +144,7 @@ public class WarPlayerListener implements Listener {
}
}
private static final int MINIMUM_TEAM_BLOCKS = 1;
@EventHandler
public void onPlayerPickupItem(final PlayerPickupItemEvent event) {
if (War.war.isLoaded()) {
@ -155,7 +160,8 @@ public class WarPlayerListener implements Listener {
Item item = event.getItem();
if (item != null) {
ItemStack itemStack = item.getItemStack();
if (itemStack != null && itemStack.getType() == team.getKind().getMaterial() && player.getInventory().contains(new ItemStack(team.getKind().getMaterial(), team.getKind().getData()))) {
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);
return;
@ -200,8 +206,7 @@ public class WarPlayerListener implements Listener {
if (warzone != null) {
// kick player from warzone as well
warzone.handlePlayerLeave(player, warzone.getWarzoneConfig().getBoolean(WarzoneConfig.AUTOJOIN) ?
War.war.getWarHub().getLocation() : warzone.getTeleport(), true);
warzone.handlePlayerLeave(player, warzone.getEndTeleport(LeaveCause.DISCONNECT), true);
}
}
}
@ -229,7 +234,11 @@ public class WarPlayerListener implements Listener {
&& zone.getLoadoutSelections().get(player.getName()).isStillInSpawn()) {
event.setUseItemInHand(Result.DENY);
event.setCancelled(true);
War.war.badMsg(player, "use.item.spawn");
// 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.ITEM_BREAK, 1, 0);
}
if (zone != null && event.getAction() == Action.RIGHT_CLICK_BLOCK && event.getClickedBlock().getType() == Material.ENDER_CHEST) {
event.setCancelled(true);
@ -334,88 +343,39 @@ public class WarPlayerListener implements Listener {
}
// Warzone lobby gates
if (locLobby != null) {
if (locLobby != null && currentTeam == null && locLobby.isInAnyGate(playerLoc)) {
Warzone zone = locLobby.getZone();
Team oldTeam = Team.getTeamByPlayerName(player.getName());
boolean isAutoAssignGate = false;
if (oldTeam == null) { // trying to counter spammy player move
isAutoAssignGate = zone.getLobby().isAutoAssignGate(playerLoc);
if (isAutoAssignGate) {
if (zone.getWarzoneConfig().getBoolean(WarzoneConfig.DISABLED)) {
this.handleDisabledZone(event, player, zone);
} else if (!zone.getWarzoneConfig().getBoolean(WarzoneConfig.JOINMIDBATTLE) && zone.isEnoughPlayers()) {
event.setTo(zone.getTeleport());
War.war.badMsg(player, "join.progress");
} else {
this.dropFromOldTeamIfAny(player);
int noOfPlayers = 0;
int totalCap = 0;
for (Team t : zone.getTeams()) {
noOfPlayers += t.getPlayers().size();
totalCap += t.getTeamConfig().resolveInt(TeamConfig.TEAMSIZE);
}
if (noOfPlayers < totalCap) {
boolean assigned = zone.autoAssign(player) != null ? true : false;
if (!assigned) {
event.setTo(zone.getTeleport());
War.war.badMsg(player, "join.permission.all");
}
if (War.war.getWarHub() != null && assigned) {
War.war.getWarHub().resetZoneSign(zone);
}
} else {
event.setTo(zone.getTeleport());
War.war.badMsg(player, "join.full.all");
}
}
return;
}
// go through all the team gates
for (Team team : zone.getTeams()) {
if (zone.getLobby().isInTeamGate(team, playerLoc)) {
this.dropFromOldTeamIfAny(player);
if (zone.getWarzoneConfig().getBoolean(WarzoneConfig.DISABLED)) {
this.handleDisabledZone(event, player, zone);
} else if (!zone.getWarzoneConfig().getBoolean(WarzoneConfig.JOINMIDBATTLE) && zone.isEnoughPlayers()) {
event.setTo(zone.getTeleport());
War.war.badMsg(player, "join.progress");
} else if (team.getPlayers().size() < team.getTeamConfig().resolveInt(TeamConfig.TEAMSIZE)
&& War.war.canPlayWar(player, team)) {
if (player.getWorld() != zone.getWorld()) {
player.teleport(zone.getWorld().getSpawnLocation());
}
team.addPlayer(player);
team.resetSign();
if (War.war.getWarHub() != null) {
War.war.getWarHub().resetZoneSign(zone);
}
zone.keepPlayerState(player);
War.war.msg(player, "join.inventorystored");
zone.respawnPlayer(event, team, player);
zone.broadcast("join.broadcast", player.getName(), team.getName());
} else if (!War.war.canPlayWar(player, team)) {
event.setTo(zone.getTeleport());
War.war.badMsg(player, "join.permission.single", team.getName());
} else {
event.setTo(zone.getTeleport());
War.war.badMsg(player, "join.full.single", team.getName());
}
return;
}
}
if (War.war.getWarHub() != null && zone.getLobby().isInWarHubLinkGate(playerLoc) && !War.war.getWarHub().getVolume().contains(player.getLocation())) {
this.dropFromOldTeamIfAny(player);
event.setTo(War.war.getWarHub().getLocation());
// player.teleport(war.getWarHub().getLocation());
War.war.msg(player, "warhub.teleport");
return;
}
Team locTeamGate = locLobby.getTeamGate(playerLoc);
if (zone.getWarzoneConfig().getBoolean(WarzoneConfig.DISABLED)) {
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
@ -424,37 +384,21 @@ public class WarPlayerListener implements Listener {
Warzone zone = hub.getDestinationWarzoneForLocation(playerLoc);
if (zone != null && zone.getTeleport() != null) {
if (zone.getWarzoneConfig().getBoolean(WarzoneConfig.AUTOJOIN)
&& zone.getWarzoneConfig().getBoolean(WarzoneConfig.AUTOASSIGN)
&& zone.getTeams().size() >= 1) {
&& zone.getTeams().size() >= 1 && currentTeam == null) {
if (zone.getWarzoneConfig().getBoolean(WarzoneConfig.DISABLED)) {
event.setTo(hub.getLocation());
War.war.badMsg(player, "join.disabled");
} else if (!zone.getWarzoneConfig().getBoolean(WarzoneConfig.JOINMIDBATTLE) && zone.isEnoughPlayers()) {
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 {
this.dropFromOldTeamIfAny(player);
int noOfPlayers = 0;
int totalCap = 0;
for (Team t : zone.getTeams()) {
noOfPlayers += t.getPlayers().size();
totalCap += t.getTeamConfig().resolveInt(TeamConfig.TEAMSIZE);
}
if (noOfPlayers < totalCap) {
boolean assigned = zone.autoAssign(player) != null ? true : false;
if (!assigned) {
event.setTo(hub.getLocation());
War.war.badMsg(player, "join.permission.all");
}
if (War.war.getWarHub() != null && assigned) {
War.war.getWarHub().resetZoneSign(zone);
}
} else {
event.setTo(hub.getLocation());
War.war.badMsg(player, "join.full.all");
}
zone.autoAssign(player);
}
return;
}
@ -511,8 +455,9 @@ public class WarPlayerListener implements Listener {
if (nearestWalls.contains(BlockFace.UP)) {
upDownMove -= moveDistance;
} else if (nearestWalls.contains(BlockFace.DOWN)) {
// fell off the map, back to spawn
event.setTo(playerTeam.getRandomSpawn());
// fell off the map, back to spawn (still need to drop objects)
playerWarzone.dropAllStolenObjects(event.getPlayer(), false);
playerWarzone.respawnPlayer(event, playerTeam, event.getPlayer());
return;
}
@ -525,47 +470,9 @@ public class WarPlayerListener implements Listener {
return;
// Otherwise, send him to spawn (first make sure he drops his flag/cake/bomb to prevent auto-cap and as punishment)
} else if (playerWarzone.isFlagThief(player.getName())) {
Team victimTeam = playerWarzone.getVictimTeamForFlagThief(player.getName());
// Get player back to spawn
playerWarzone.respawnPlayer(event, playerTeam, player);
playerWarzone.removeFlagThief(player.getName());
// Bring back flag of victim team
victimTeam.getFlagVolume().resetBlocks();
victimTeam.initializeTeamFlag();
playerWarzone.broadcast("drop.flag.broadcast", player.getName(), victimTeam.getName());
return;
} else if (playerWarzone.isCakeThief(player.getName())) {
Cake cake = playerWarzone.getCakeForThief(player.getName());
// Get player back to spawn
playerWarzone.respawnPlayer(event, playerTeam, player);
playerWarzone.removeCakeThief(player.getName());
// Bring back cake
cake.getVolume().resetBlocks();
cake.addCakeBlocks();
playerWarzone.broadcast("drop.cake.broadcast", player.getName(), cake.getName());
return;
} else if (playerWarzone.isBombThief(player.getName())) {
Bomb bomb = playerWarzone.getBombForThief(player.getName());
// Get player back to spawn
playerWarzone.respawnPlayer(event, playerTeam, player);
playerWarzone.removeBombThief(player.getName());
// Bring back bomb
bomb.getVolume().resetBlocks();
bomb.addBombBlocks();
playerWarzone.broadcast("drop.bomb.broadcast", player.getName(), bomb.getName());
return;
} else {
// Get player back to spawn
playerWarzone.respawnPlayer(event, playerTeam, player);
playerWarzone.dropAllStolenObjects(event.getPlayer(), false);
playerWarzone.respawnPlayer(event, playerTeam, event.getPlayer());
return;
}
}
@ -924,7 +831,7 @@ public class WarPlayerListener implements Listener {
}
}
@EventHandler
@EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerRespawn(PlayerRespawnEvent event) {
if (War.war.isLoaded()) {
// Anyone who died in warzones needs to go back there pronto!
@ -941,9 +848,8 @@ public class WarPlayerListener implements Listener {
if (zone.hasPlayerState(event.getPlayer().getName())) {
// If not member of a team and zone has your state, then game ended while you were dead
zone.gameEndTeleport(event.getPlayer());
War.war.log("Failed to restore game state to dead player.", Level.WARNING);
}
break;
}
}
@ -961,46 +867,8 @@ public class WarPlayerListener implements Listener {
if (!playerWarzone.getWarzoneConfig().getBoolean(WarzoneConfig.REALDEATHS)) {
War.war.badMsg(event.getPlayer(), "Use /leave (or /war leave) to exit the zone.");
}
if (playerWarzone.isFlagThief(event.getPlayer().getName())) {
Team victimTeam = playerWarzone.getVictimTeamForFlagThief(event.getPlayer().getName());
// Get event.getPlayer() back to spawn
playerWarzone.respawnPlayer(event, playerTeam, event.getPlayer());
playerWarzone.removeFlagThief(event.getPlayer().getName());
// Bring back flag of victim team
victimTeam.getFlagVolume().resetBlocks();
victimTeam.initializeTeamFlag();
playerWarzone.broadcast("drop.flag.broadcast", event.getPlayer().getName(), victimTeam.getName());
} else if (playerWarzone.isCakeThief(event.getPlayer().getName())) {
Cake cake = playerWarzone.getCakeForThief(event.getPlayer().getName());
// Get event.getPlayer() back to spawn
playerWarzone.respawnPlayer(event, playerTeam, event.getPlayer());
playerWarzone.removeCakeThief(event.getPlayer().getName());
// Bring back cake
cake.getVolume().resetBlocks();
cake.addCakeBlocks();
playerWarzone.broadcast("drop.cake.broadcast", event.getPlayer().getName(), cake.getName());
} else if (playerWarzone.isBombThief(event.getPlayer().getName())) {
Bomb bomb = playerWarzone.getBombForThief(event.getPlayer().getName());
// Get event.getPlayer() back to spawn
playerWarzone.respawnPlayer(event, playerTeam, event.getPlayer());
playerWarzone.removeBombThief(event.getPlayer().getName());
// Bring back bomb
bomb.getVolume().resetBlocks();
bomb.addBombBlocks();
playerWarzone.broadcast("drop.bomb.broadcast", event.getPlayer().getName(), bomb.getName());
} else {
// Get event.getPlayer() back to spawn
playerWarzone.respawnPlayer(event, playerTeam, event.getPlayer());
}
playerWarzone.dropAllStolenObjects(event.getPlayer(), false);
playerWarzone.respawnPlayer(event, playerTeam, event.getPlayer());
}
}
}
@ -1019,23 +887,4 @@ public class WarPlayerListener implements Listener {
public void purgeLatestPositions() {
this.latestLocations.clear();
}
private void handleDisabledZone(PlayerMoveEvent event, Player player, Warzone zone) {
if (zone.getLobby() != null) {
War.war.badMsg(player, "join.disabled");
event.setTo(zone.getTeleport());
}
}
private void dropFromOldTeamIfAny(Player player) {
// drop from old team if any
Team previousTeam = Team.getTeamByPlayerName(player.getName());
if (previousTeam != null) {
if (!previousTeam.removePlayer(player.getName())) {
War.war.log("Could not remove player " + player.getName() + " from team " + previousTeam.getName(), java.util.logging.Level.WARNING);
}
}
}
}

View File

@ -1,25 +0,0 @@
package com.tommytony.war.job;
import org.bukkit.entity.Player;
import com.tommytony.war.Team;
import com.tommytony.war.Warzone;
public class RespawnPlayerJob implements Runnable {
private final Team team;
private final Player player;
private final Warzone zone;
public RespawnPlayerJob(Warzone zone, Team playerTeam, Player player) {
this.zone = zone;
// TODO Auto-generated constructor stub
this.team = playerTeam;
this.player = player;
}
public void run() {
this.zone.respawnPlayer(this.team, this.player);
}
}

View File

@ -1,21 +0,0 @@
package com.tommytony.war.job;
import org.bukkit.entity.Player;
import com.tommytony.war.Warzone;
public class RestoreDeadmanInventoryJob implements Runnable {
private final Player player;
private final Warzone zone;
public RestoreDeadmanInventoryJob(Player player, Warzone zone) {
this.player = player;
this.zone = zone;
}
public void run() {
this.zone.restoreDeadmanInventory(this.player);
this.player.teleport(this.zone.getTeleport());
}
}

View File

@ -1,67 +0,0 @@
package com.tommytony.war.job;
import java.util.Iterator;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.getspout.spoutapi.SpoutManager;
import org.getspout.spoutapi.player.SpoutPlayer;
import org.kitteh.tag.TagAPI;
import com.tommytony.war.Team;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.spout.SpoutDisplayer;
public class ScoreCapReachedJob implements Runnable {
private final Warzone zone;
private final String winnersStr;
public ScoreCapReachedJob(Warzone zone, String winnersStr) {
this.zone = zone;
this.winnersStr = winnersStr;
}
public void run() {
for (Team t : this.zone.getTeams()) {
if (War.war.isSpoutServer()) {
for (Player p : t.getPlayers()) {
SpoutPlayer sp = SpoutManager.getPlayer(p);
if (sp.isSpoutCraftEnabled()) {
sp.sendNotification(
SpoutDisplayer.cleanForNotification("Match won! " + ChatColor.WHITE + "Winners:"),
SpoutDisplayer.cleanForNotification(SpoutDisplayer.addMissingColor(winnersStr, zone)),
Material.CAKE,
(short)0,
10000);
}
}
}
String winnersStrAndExtra = "Score cap reached. Game is over! Winning team(s): " + this.winnersStr;
winnersStrAndExtra += ". Resetting warzone and your inventory...";
t.teamcast(winnersStrAndExtra);
for (Iterator<Player> it = t.getPlayers().iterator(); it.hasNext();) {
Player tp = it.next();
it.remove(); // Remove player from team first to prevent anti-tp
if (War.war.isTagServer()) {
TagAPI.refreshPlayer(tp);
}
this.zone.gameEndTeleport(tp);
if (this.winnersStr.contains(t.getName())) {
// give reward
for (Integer slot : t.getInventories().resolveReward().keySet()) {
ItemStack item = t.getInventories().resolveReward().get(slot);
if (item != null) {
tp.getInventory().addItem(item);
}
}
}
}
t.resetPoints();
t.getPlayers().clear(); // empty the team
}
}
}

View File

@ -613,14 +613,26 @@ public class ZoneLobby {
public boolean isAutoAssignGate(Location location) {
if (this.autoAssignGate != null
&& (location.getBlockX() == this.autoAssignGate.getX()
&& location.getBlockY() == this.autoAssignGate.getY()
&& location.getBlockZ() == this.autoAssignGate.getZ())) {
&& location.getBlockY() == this.autoAssignGate.getY()
&& location.getBlockZ() == this.autoAssignGate.getZ())) {
return true;
}
return false;
}
public Team getTeamGate(Location location) {
for (Team team : this.warzone.getTeams()) {
if (this.isInTeamGate(team, location)) {
return team;
}
}
return null;
}
public boolean isInAnyGate(Location location) {
return this.isAutoAssignGate(location) || this.getTeamGate(location) != null;
}
public Volume getVolume() {
return this.volume;
}