diff --git a/war/src/main/java/bukkit/tommytony/war/War.java b/war/src/main/java/bukkit/tommytony/war/War.java index 00c2c5f..256f5d6 100644 --- a/war/src/main/java/bukkit/tommytony/war/War.java +++ b/war/src/main/java/bukkit/tommytony/war/War.java @@ -180,5 +180,12 @@ public class War extends JavaPlugin { return name; } + public Warzone zoneOfTooCloseZoneWall(Location location) { + for(Warzone zone : warzones) { + if(zone.isNearWall(location)) return zone; + } + return null; + } + } diff --git a/war/src/main/java/bukkit/tommytony/war/WarPlayerListener.java b/war/src/main/java/bukkit/tommytony/war/WarPlayerListener.java index ea230c5..4ab036e 100644 --- a/war/src/main/java/bukkit/tommytony/war/WarPlayerListener.java +++ b/war/src/main/java/bukkit/tommytony/war/WarPlayerListener.java @@ -15,6 +15,7 @@ import com.tommytony.war.Monument; import com.tommytony.war.Team; import com.tommytony.war.TeamMaterials; import com.tommytony.war.Warzone; +import com.tommytony.war.ZoneWallGuard; import com.tommytony.war.mappers.WarMapper; import com.tommytony.war.mappers.WarzoneMapper; @@ -140,7 +141,7 @@ public class WarPlayerListener extends PlayerListener { } // join new team - String name = arguments[0]; + String name = TeamMaterials.teamMaterialToString(TeamMaterials.teamMaterialFromString(arguments[0])); Warzone warzone = war.warzone(player.getLocation()); List teams = warzone.getTeams(); boolean foundTeam = false; @@ -378,8 +379,8 @@ public class WarPlayerListener extends PlayerListener { " Sets the team spawn to the current location. " + "Must be in a warzone (try /zones and /zone). ")); } else { - String name = arguments[0]; - Material teamMaterial = TeamMaterials.teamMaterialFromString(name); + Material teamMaterial = TeamMaterials.teamMaterialFromString(arguments[0]); + String name = TeamMaterials.teamMaterialToString(teamMaterial); Warzone warzone = war.warzone(player.getLocation()); Team existingTeam = warzone.getTeamByMaterial(teamMaterial); if(existingTeam != null) { @@ -395,8 +396,6 @@ public class WarPlayerListener extends PlayerListener { player.sendMessage(war.str("Team " + name + " created with spawn here.")); } - - WarzoneMapper.save(war, warzone, false); } event.setCancelled(true); @@ -409,7 +408,7 @@ public class WarPlayerListener extends PlayerListener { " Deletes the team and its spawn. " + "Must be in a warzone (try /zones and /zone). ")); } else { - String name = arguments[1]; + String name = TeamMaterials.teamMaterialToString(TeamMaterials.teamMaterialFromString(arguments[1])); Warzone warzone = war.warzone(player.getLocation()); List teams = warzone.getTeams(); Team team = null; @@ -483,39 +482,25 @@ public class WarPlayerListener extends PlayerListener { Location from = event.getFrom(); Location to = event.getTo(); + // Zone walls + if(to != null) { + Warzone nearbyZone = war.zoneOfTooCloseZoneWall(to); + if(nearbyZone != null) { + nearbyZone.protectZoneWallAgainstPlayer(player); + } else { + // make sure to delete any wall guards as you leave + for(Warzone zone : war.getWarzones()) { + zone.dropZoneWallGuardIfAny(player); + } + } + } + Warzone playerWarzone = war.getPlayerWarzone(player.getName()); if(playerWarzone != null) { Team playerTeam = war.getPlayerTeam(player.getName()); - if(player != null && from != null && to != null && - playerTeam != null && !playerWarzone.getVolume().contains(to)) { - player.sendMessage(war.str("Can't go outside the warzone boundary! Use /leave to exit the battle.")); - if(playerWarzone.getVolume().contains(from)){ - player.teleportTo(from); - } else { - // somehow the player made it out of the zone - player.teleportTo(playerTeam.getTeamSpawn()); - player.sendMessage(war.str("Brought you back to your team spawn. Use /leave to exit the battle.")); - } - } - if(player != null && from != null && to != null && - playerTeam == null - && war.inAnyWarzone(from) - && !war.inAnyWarzone(to)) { - // leaving - Warzone zone = war.warzone(from); - player.sendMessage(war.str("Leaving warzone " + zone.getName() + ".")); - } - - if(player != null && from != null && to != null && - playerTeam == null - && !war.inAnyWarzone(from) - && war.inAnyWarzone(to)) { - // entering - Warzone zone = war.warzone(to); - player.sendMessage(war.str("Entering warzone " + zone.getName() + ". Tip: use /teams.")); - } + // Monuments if(to != null && playerTeam != null && playerWarzone.nearAnyOwnedMonument(to, playerTeam) && player.getHealth() < 20 @@ -523,6 +508,41 @@ public class WarPlayerListener extends PlayerListener { player.setHealth(20); player.sendMessage(war.str("Your dance pleases the monument's voodoo. You gain full health!")); } + + + + +// if(player != null && from != null && to != null && +// playerTeam != null && !playerWarzone.getVolume().contains(to)) { +// player.sendMessage(war.str("Can't go outside the warzone boundary! Use /leave to exit the battle.")); +// if(playerWarzone.getVolume().contains(from)){ +// player.teleportTo(from); +// } else { +// // somehow the player made it out of the zone +// player.teleportTo(playerTeam.getTeamSpawn()); +// player.sendMessage(war.str("Brought you back to your team spawn. Use /leave to exit the battle.")); +// } +// } +// +// if(player != null && from != null && to != null && +// playerTeam == null +// && war.inAnyWarzone(from) +// && !war.inAnyWarzone(to)) { +// // leaving +// Warzone zone = war.warzone(from); +// player.sendMessage(war.str("Leaving warzone " + zone.getName() + ".")); +// } +// +// if(player != null && from != null && to != null && +// playerTeam == null +// && !war.inAnyWarzone(from) +// && war.inAnyWarzone(to)) { +// // entering +// Warzone zone = war.warzone(to); +// player.sendMessage(war.str("Entering warzone " + zone.getName() + ". Tip: use /teams.")); +// } + + } } diff --git a/war/src/main/java/com/tommytony/war/Warzone.java b/war/src/main/java/com/tommytony/war/Warzone.java index 8cec885..802e9a1 100644 --- a/war/src/main/java/com/tommytony/war/Warzone.java +++ b/war/src/main/java/com/tommytony/war/Warzone.java @@ -37,9 +37,15 @@ public class Warzone { private HashMap> inventories = new HashMap>(); private World world; + private Material originalSouthEastBlock; + private Material originalNorthWestBlock; + private final int minSafeDistanceFromWall = 5; + private List zoneWallGuards = new ArrayList(); + private War war; public Warzone(War war, World world, String name) { this.world = world; + this.war = war; this.name = name; this.friendlyFire = war.getDefaultFriendlyFire(); this.setLifePool(war.getDefaultLifepool()); @@ -85,7 +91,17 @@ public class Warzone { } public void setNorthwest(Location northwest) { + if(this.northwest != null) { + // reset old corner + int highest = this.world.getHighestBlockYAt(this.northwest.getBlockX(), this.southeast.getBlockZ()) - 1; + Block oldTopNWBlock = this.world.getBlockAt(this.northwest.getBlockX(), highest, this.southeast.getBlockZ()); + oldTopNWBlock.setType(originalNorthWestBlock); + } this.northwest = northwest; + int newHighest = this.world.getHighestBlockYAt(this.northwest.getBlockX(), this.northwest.getBlockZ()) - 1; + Block topNWBlock = this.world.getBlockAt(this.northwest.getBlockX(), newHighest, this.northwest.getBlockZ()); + originalNorthWestBlock = topNWBlock.getType(); // save block for reset + topNWBlock.setType(Material.Glass); this.volume.setCornerOne(world.getBlockAt(northwest.getBlockX(), northwest.getBlockY(), northwest.getBlockZ())); } @@ -95,7 +111,18 @@ public class Warzone { } public void setSoutheast(Location southeast) { + if(this.southeast != null) { + // reset old corner + int highest = this.world.getHighestBlockYAt(this.southeast.getBlockX(), this.southeast.getBlockZ()) - 1; + Block oldTopSEBlock = this.world.getBlockAt(this.southeast.getBlockX(), highest, this.southeast.getBlockZ()); + oldTopSEBlock.setType(originalSouthEastBlock); + } + // change corner this.southeast = southeast; + int newHighest = this.world.getHighestBlockYAt(this.southeast.getBlockX(), this.southeast.getBlockZ()) - 1; + Block topSEBlock = this.world.getBlockAt(this.southeast.getBlockX(), newHighest, this.southeast.getBlockZ()); + originalSouthEastBlock = topSEBlock.getType(); // save block for reset + topSEBlock.setType(Material.Glass); this.volume.setCornerTwo(world.getBlockAt(southeast.getBlockX(), southeast.getBlockY(), southeast.getBlockZ())); } @@ -189,7 +216,7 @@ public class Warzone { Block under = over.getFace(BlockFace.Down); int treeHeight = 0; while(!((over.getType() == Material.Air || over.getType() == Material.Leaves || over.getType() == Material.Wood) - && (under.getType() == Material.Grass || under.getType() == Material.Dirt || under.getType() == Material.Stone)) + && (under.getType() != Material.Air || under.getType() == Material.Leaves || under.getType() == Material.Leaves)) && treeHeight < 40) { over = under; under = over.getFace(BlockFace.Down); @@ -202,16 +229,16 @@ public class Warzone { if(lastBlock != null) { // link the new block and the old vertically if there's a big drop or rise - if(block.getY() - lastBlock.getY() > 2) { // new block too high + if(block.getY() - lastBlock.getY() > 1) { // new block too high Block under = block.getFace(BlockFace.Down); while(under.getY() != lastBlock.getY() - 1) { - block.setType(Material.Glass); + under.setType(Material.Glass); under = under.getFace(BlockFace.Down); } - } else if (block.getY() - lastBlock.getY() < -2) { // new block too low + } else if (lastBlock.getY() - block.getY() > 1) { // new block too low Block over = block.getFace(BlockFace.Up); while(over.getY() != lastBlock.getY() + 1) { - block.setType(Material.Glass); + over.setType(Material.Glass); over = over.getFace(BlockFace.Up); } } @@ -404,7 +431,7 @@ public class Warzone { this.world = world; } - public Volume getVolume() { + public VerticalVolume getVolume() { return volume; } @@ -421,6 +448,84 @@ public class Warzone { return null; } + public boolean isNearWall(Location latestPlayerLocation) { + if(Math.abs(southeast.getBlockZ() - latestPlayerLocation.getBlockZ()) < minSafeDistanceFromWall + && latestPlayerLocation.getBlockX() <= southeast.getBlockX() + && latestPlayerLocation.getBlockX() >= northwest.getBlockX()) { + return true; // near east wall + } else if (Math.abs(southeast.getBlockX() - latestPlayerLocation.getBlockX()) < minSafeDistanceFromWall + && latestPlayerLocation.getBlockZ() <= northwest.getBlockZ() + && latestPlayerLocation.getBlockZ() >= southeast.getBlockZ()) { + return true; // near south wall + } else if (Math.abs(northwest.getBlockX() - latestPlayerLocation.getBlockX()) < minSafeDistanceFromWall + && latestPlayerLocation.getBlockZ() <= northwest.getBlockZ() + && latestPlayerLocation.getBlockZ() >= southeast.getBlockZ()) { + return true; // near north wall + } else if (Math.abs(northwest.getBlockZ() - latestPlayerLocation.getBlockZ()) < minSafeDistanceFromWall + && latestPlayerLocation.getBlockX() <= southeast.getBlockX() + && latestPlayerLocation.getBlockX() >= northwest.getBlockX()) { + return true; // near west wall + } + return false; + } + + public Block getNearestWallBlock(Location latestPlayerLocation) { + if(Math.abs(southeast.getBlockZ() - latestPlayerLocation.getBlockZ()) < minSafeDistanceFromWall + && latestPlayerLocation.getBlockX() <= southeast.getBlockX() + && latestPlayerLocation.getBlockX() >= northwest.getBlockX()) { + // near east wall + Block eastWallBlock = world.getBlockAt(latestPlayerLocation.getBlockX() + 1, latestPlayerLocation.getBlockY(), southeast.getBlockZ()); + return eastWallBlock; + } else if (Math.abs(southeast.getBlockX() - latestPlayerLocation.getBlockX()) < minSafeDistanceFromWall + && latestPlayerLocation.getBlockZ() <= northwest.getBlockZ() + && latestPlayerLocation.getBlockZ() >= southeast.getBlockZ()) { + // near south wall + Block southWallBlock = world.getBlockAt(southeast.getBlockX(), latestPlayerLocation.getBlockY() + 1, latestPlayerLocation.getBlockZ()); + return southWallBlock; + } else if (Math.abs(northwest.getBlockX() - latestPlayerLocation.getBlockX()) < minSafeDistanceFromWall + && latestPlayerLocation.getBlockZ() <= northwest.getBlockZ() + && latestPlayerLocation.getBlockZ() >= southeast.getBlockZ()) { + // near north wall + Block northWallBlock = world.getBlockAt(northwest.getBlockX(), latestPlayerLocation.getBlockY() + 1, latestPlayerLocation.getBlockZ()); + return northWallBlock; + } else if (Math.abs(northwest.getBlockZ() - latestPlayerLocation.getBlockZ()) < minSafeDistanceFromWall + && latestPlayerLocation.getBlockX() <= southeast.getBlockX() + && latestPlayerLocation.getBlockX() >= northwest.getBlockX()) { + // near west wall + Block westWallBlock = world.getBlockAt(latestPlayerLocation.getBlockX(), latestPlayerLocation.getBlockY() + 1, northwest.getBlockZ()); + return westWallBlock; + } + return null; + // note: y + 1 to line up 3 sided square with player eyes + } + + public ZoneWallGuard getPlayerZoneWallGuard(String name) { + for(ZoneWallGuard guard : zoneWallGuards) { + if(guard.getPlayer().getName().equals(name)) { + return guard; + } + } + return null; + + } + + public void protectZoneWallAgainstPlayer(Player player) { + ZoneWallGuard guard = getPlayerZoneWallGuard(player.getName()); + if(guard != null) { + // already protected, need to move the guard + guard.updatePlayerPosition(player.getLocation()); + } else { + // new guard + guard = new ZoneWallGuard(player, war, this); + } + } + + public void dropZoneWallGuardIfAny(Player player) { + ZoneWallGuard guard = getPlayerZoneWallGuard(player.getName()); + guard.updatePlayerPosition(player.getLocation()); // should restore old blocks + zoneWallGuards.remove(guard); + } + } diff --git a/war/src/main/java/com/tommytony/war/ZoneWallGuard.java b/war/src/main/java/com/tommytony/war/ZoneWallGuard.java new file mode 100644 index 0000000..634d259 --- /dev/null +++ b/war/src/main/java/com/tommytony/war/ZoneWallGuard.java @@ -0,0 +1,124 @@ +package com.tommytony.war; + +import org.bukkit.Block; +import org.bukkit.BlockFace; +import org.bukkit.HumanEntity; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Player; + +import bukkit.tommytony.war.War; + +import com.tommytony.war.volumes.CenteredVolume; + +public class ZoneWallGuard { + private Player player; + private Warzone warzone; + private Location playerLocation; + private CenteredVolume volume; + private final War war; + + private final int radius = 3; + + + public ZoneWallGuard(Player player, War war, Warzone warzone) { + this.player = player; + this.war = war; + this.playerLocation = player.getLocation(); + this.warzone = warzone; + this.activate(); + } + + private void activate() { + // save current blocks + Block nearestWallBlock = warzone.getNearestWallBlock(playerLocation); + if(volume == null) { + volume = new CenteredVolume("zoneGuard-" + warzone.getName() + "-" + player.getName(), nearestWallBlock, radius, war, warzone); + } else { + volume.changeCenter(nearestWallBlock, radius); + volume.saveBlocks(); + } + // add wall guard blocks + nearestWallBlock.setType(Material.Glass); + nearestWallBlock.getFace(BlockFace.Up).setType(Material.Glass); + nearestWallBlock.getFace(BlockFace.Down).setType(Material.Glass); + if(warzone.getVolume().isNorthWallBlock(nearestWallBlock.getFace(BlockFace.East)) && + warzone.getVolume().isNorthWallBlock(nearestWallBlock.getFace(BlockFace.West))) { + // north wall guard + toGlass(nearestWallBlock.getFace(BlockFace.East), BlockFace.North); + toGlass(nearestWallBlock.getFace(BlockFace.East).getFace(BlockFace.Up), BlockFace.North); + toGlass(nearestWallBlock.getFace(BlockFace.East).getFace(BlockFace.Down), BlockFace.North); + toGlass(nearestWallBlock.getFace(BlockFace.West), BlockFace.North); + toGlass(nearestWallBlock.getFace(BlockFace.West).getFace(BlockFace.Up), BlockFace.North); + toGlass(nearestWallBlock.getFace(BlockFace.West).getFace(BlockFace.Down), BlockFace.North); + } else if (warzone.getVolume().isSouthWallBlock(nearestWallBlock.getFace(BlockFace.East)) && + warzone.getVolume().isSouthWallBlock(nearestWallBlock.getFace(BlockFace.West))) { + // south wall guard + toGlass(nearestWallBlock.getFace(BlockFace.East), BlockFace.South); + toGlass(nearestWallBlock.getFace(BlockFace.East).getFace(BlockFace.Up), BlockFace.South); + toGlass(nearestWallBlock.getFace(BlockFace.East).getFace(BlockFace.Down), BlockFace.South); + toGlass(nearestWallBlock.getFace(BlockFace.West), BlockFace.South); + toGlass(nearestWallBlock.getFace(BlockFace.West).getFace(BlockFace.Up), BlockFace.South); + toGlass(nearestWallBlock.getFace(BlockFace.West).getFace(BlockFace.Down), BlockFace.South); + // .. + } else if (warzone.getVolume().isEastWallBlock(nearestWallBlock.getFace(BlockFace.North)) && + warzone.getVolume().isEastWallBlock(nearestWallBlock.getFace(BlockFace.South))) { + //east wall guard + toGlass(nearestWallBlock.getFace(BlockFace.North), BlockFace.East); + toGlass(nearestWallBlock.getFace(BlockFace.North).getFace(BlockFace.Up), BlockFace.East); + toGlass(nearestWallBlock.getFace(BlockFace.North).getFace(BlockFace.Down), BlockFace.East); + toGlass(nearestWallBlock.getFace(BlockFace.South), BlockFace.West); + toGlass(nearestWallBlock.getFace(BlockFace.South).getFace(BlockFace.Up), BlockFace.West); + toGlass(nearestWallBlock.getFace(BlockFace.South).getFace(BlockFace.Down), BlockFace.West); + } else if (warzone.getVolume().isWestWallBlock(nearestWallBlock.getFace(BlockFace.North)) && + warzone.getVolume().isWestWallBlock(nearestWallBlock.getFace(BlockFace.South))) { + //west wall guard + toGlass(nearestWallBlock.getFace(BlockFace.North), BlockFace.West); + toGlass(nearestWallBlock.getFace(BlockFace.North).getFace(BlockFace.Up), BlockFace.West); + toGlass(nearestWallBlock.getFace(BlockFace.North).getFace(BlockFace.Down), BlockFace.West); + toGlass(nearestWallBlock.getFace(BlockFace.South), BlockFace.West); + toGlass(nearestWallBlock.getFace(BlockFace.South).getFace(BlockFace.Up), BlockFace.West); + toGlass(nearestWallBlock.getFace(BlockFace.South).getFace(BlockFace.Down), BlockFace.West); + } + } + + private void toGlass(Block block, BlockFace wall) { + // face here means which wall we are working on + if(wall == BlockFace.North) { + if(warzone.getVolume().isNorthWallBlock(block)) { + block.setType(Material.Glass); + } + } else if (wall == BlockFace.South) { + if(warzone.getVolume().isSouthWallBlock(block)) { + block.setType(Material.Glass); + } + } else if (wall == BlockFace.East) { + if(warzone.getVolume().isEastWallBlock(block)) { + block.setType(Material.Glass); + } + } else if (wall == BlockFace.West) { + if(warzone.getVolume().isWestWallBlock(block)) { + block.setType(Material.Glass); + } + } + } + + private void deactivate() { + // restore old blocks + volume.resetBlocks(); + } + + public void updatePlayerPosition(Location location) { + if(warzone.isNearWall(location)) { + deactivate(); + this.playerLocation = location; + activate(); + } else { + deactivate(); + } + } + + public Player getPlayer() { + return player; + } +} diff --git a/war/src/main/java/com/tommytony/war/volumes/VerticalVolume.java b/war/src/main/java/com/tommytony/war/volumes/VerticalVolume.java index 253b407..261ab1b 100644 --- a/war/src/main/java/com/tommytony/war/volumes/VerticalVolume.java +++ b/war/src/main/java/com/tommytony/war/volumes/VerticalVolume.java @@ -26,4 +26,44 @@ public class VerticalVolume extends Volume{ Block bottomBlock = getWorld().getBlockAt(block.getX(), 0, block.getZ()); super.setCornerTwo(bottomBlock); } + + public boolean isWallBlock(Block block){ + return isEastWallBlock(block) || isNorthWallBlock(block) || isSouthWallBlock(block) || isWestWallBlock(block); + } + + public boolean isEastWallBlock(Block block) { + if(getMinZ() == block.getZ() + && block.getX() <= getMaxX() + && block.getX() >= getMinX()) { + return true; // east wall + } + return false; + } + + public boolean isSouthWallBlock(Block block) { + if (getMaxX() == block.getX() + && block.getZ() <= getMaxZ() + && block.getZ() >= getMinZ()) { + return true; // south wall + } + return false; + } + + public boolean isNorthWallBlock(Block block) { + if (getMinX() == block.getX() + && block.getZ() <= getMaxZ() + && block.getZ() >= getMinZ()) { + return true; // north wall + } + return false; + } + + public boolean isWestWallBlock(Block block) { + if (getMaxZ() == block.getZ() + && block.getX() <= getMaxX() + && block.getX() >= getMinX()) { + return true; // west wall + } + return false; + } }