Zone wall guards to keep player from entering or exiting a warzone

This commit is contained in:
taoneill 2011-01-11 23:03:48 -05:00
parent 31bd3523e1
commit 894bbaca43
5 changed files with 336 additions and 40 deletions

View File

@ -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;
}
}

View File

@ -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<Team> 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<Team> 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."));
// }
}
}

View File

@ -37,9 +37,15 @@ public class Warzone {
private HashMap<String, List<ItemStack>> inventories = new HashMap<String, List<ItemStack>>();
private World world;
private Material originalSouthEastBlock;
private Material originalNorthWestBlock;
private final int minSafeDistanceFromWall = 5;
private List<ZoneWallGuard> zoneWallGuards = new ArrayList<ZoneWallGuard>();
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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}