mirror of
https://github.com/taoneill/war.git
synced 2025-03-11 14:09:57 +01:00
Smoother spawn re-entry protection
Closes gh-503. Now letting players just walk through their own spawn really fast (instead of just getting them stuck blindly), and being a bit smarter about where I teleport them (i.e. mostly not in walls anymore). Much less brutal than in v1.7.2.
This commit is contained in:
parent
120af8e817
commit
411021fc35
@ -34,6 +34,7 @@ import com.tommytony.war.command.ZoneSetter;
|
||||
import com.tommytony.war.config.FlagReturn;
|
||||
import com.tommytony.war.config.TeamConfig;
|
||||
import com.tommytony.war.config.WarzoneConfig;
|
||||
import com.tommytony.war.job.CantReEnterSpawnJob;
|
||||
import com.tommytony.war.spout.SpoutDisplayer;
|
||||
import com.tommytony.war.structure.Bomb;
|
||||
import com.tommytony.war.structure.Cake;
|
||||
@ -502,50 +503,15 @@ public class WarPlayerListener implements Listener {
|
||||
} else if (loadoutSelectionState != null && !loadoutSelectionState.isStillInSpawn()
|
||||
&& !playerWarzone.isCakeThief(player.getName())
|
||||
&& (flagReturn.equals(FlagReturn.BOTH) || flagReturn.equals(FlagReturn.SPAWN))
|
||||
&& !playerWarzone.isFlagThief(player.getName())) {
|
||||
&& !playerWarzone.isFlagThief(player.getName())) {
|
||||
|
||||
// player is in spawn, but has left already: he should NOT be let back in - kick him out gently
|
||||
// (also, be sure you aren't preventing the flag or cake from being captured)
|
||||
int diffZ = playerLoc.getBlockZ() - playerTeam.getTeamSpawn().getBlockZ();
|
||||
int diffX = playerLoc.getBlockX() - playerTeam.getTeamSpawn().getBlockX();
|
||||
|
||||
int finalZ = playerLoc.getBlockZ();
|
||||
int finalX = playerLoc.getBlockX();
|
||||
int bumpDistance = 1;
|
||||
if (diffZ == 0 && diffX == 0) {
|
||||
// at spawn already, get him moving
|
||||
finalZ += bumpDistance + 1;
|
||||
finalX += bumpDistance + 1;
|
||||
} else if (diffZ > 0 && diffX > 0) {
|
||||
finalZ += bumpDistance;
|
||||
finalX += bumpDistance;
|
||||
} else if (diffZ == 0 && diffX > 0) {
|
||||
finalX += bumpDistance;
|
||||
}else if (diffZ < 0 && diffX > 0) {
|
||||
finalZ -= bumpDistance;
|
||||
finalX += bumpDistance;
|
||||
} else if (diffZ < 0 && diffX == 0) {
|
||||
finalZ -= bumpDistance;
|
||||
} else if (diffZ > 0 && diffX < 0) {
|
||||
finalZ -= bumpDistance;
|
||||
finalX -= bumpDistance;
|
||||
} else if (diffZ == 0 && diffX < 0) {
|
||||
finalX -= bumpDistance;
|
||||
} else if (diffZ > 0 && diffX < 0) {
|
||||
finalZ += bumpDistance;
|
||||
finalX -= bumpDistance;
|
||||
} else if (diffZ > 0 && diffX == 0) {
|
||||
finalZ += bumpDistance;
|
||||
// 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);
|
||||
}
|
||||
|
||||
event.setTo(new Location(playerLoc.getWorld(),
|
||||
finalX,
|
||||
playerLoc.getY(),
|
||||
finalZ,
|
||||
playerLoc.getYaw(),
|
||||
playerLoc.getPitch()
|
||||
));
|
||||
|
||||
War.war.badMsg(player, "Can't re-enter spawn!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
154
war/src/main/java/com/tommytony/war/job/CantReEnterSpawnJob.java
Normal file
154
war/src/main/java/com/tommytony/war/job/CantReEnterSpawnJob.java
Normal file
@ -0,0 +1,154 @@
|
||||
package com.tommytony.war.job;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.tommytony.war.Team;
|
||||
import com.tommytony.war.War;
|
||||
|
||||
public class CantReEnterSpawnJob implements Runnable {
|
||||
|
||||
private static Random rand = new Random();
|
||||
private static final List<String> playersUnderSuspicion = new ArrayList<String>();
|
||||
private final Player player;
|
||||
private final Team playerTeam;
|
||||
|
||||
public CantReEnterSpawnJob(Player player, Team playerTeam) {
|
||||
this.player = player;
|
||||
this.playerTeam = playerTeam;
|
||||
playersUnderSuspicion.add(player.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Location playerLoc = this.player.getLocation();
|
||||
if (playerTeam.getSpawnVolume().contains(playerLoc)) {
|
||||
int diffZ = playerLoc.getBlockZ() - playerTeam.getTeamSpawn().getBlockZ();
|
||||
int diffX = playerLoc.getBlockX() - playerTeam.getTeamSpawn().getBlockX();
|
||||
|
||||
int finalZ = playerLoc.getBlockZ();
|
||||
int finalX = playerLoc.getBlockX();
|
||||
int bumpDistance = 1;
|
||||
if (diffZ == 0 && diffX == 0) {
|
||||
// at spawn already, get him moving
|
||||
finalZ += (minusOneZeroOrOne() * 2);
|
||||
finalX += (minusOneZeroOrOne() * 2);
|
||||
} else if (diffZ > 0 && diffX > 0) {
|
||||
finalZ += bumpDistance;
|
||||
finalX += bumpDistance;
|
||||
} else if (diffZ == 0 && diffX > 0) {
|
||||
finalX += bumpDistance;
|
||||
}else if (diffZ < 0 && diffX > 0) {
|
||||
finalZ -= bumpDistance;
|
||||
finalX += bumpDistance;
|
||||
} else if (diffZ < 0 && diffX == 0) {
|
||||
finalZ -= bumpDistance;
|
||||
} else if (diffZ > 0 && diffX < 0) {
|
||||
finalZ -= bumpDistance;
|
||||
finalX -= bumpDistance;
|
||||
} else if (diffZ == 0 && diffX < 0) {
|
||||
finalX -= bumpDistance;
|
||||
} else if (diffZ > 0 && diffX < 0) {
|
||||
finalZ += bumpDistance;
|
||||
finalX -= bumpDistance;
|
||||
} else if (diffZ > 0 && diffX == 0) {
|
||||
finalZ += bumpDistance;
|
||||
}
|
||||
|
||||
Location nextCandidate = new Location(playerLoc.getWorld(),
|
||||
finalX,
|
||||
playerLoc.getY(),
|
||||
finalZ,
|
||||
playerLoc.getYaw(),
|
||||
playerLoc.getPitch()
|
||||
);
|
||||
|
||||
Block nextCandidateBlock = nextCandidate.getWorld().getBlockAt(nextCandidate);
|
||||
int attempts = 0;
|
||||
// make sure this isn't the middle of a wall
|
||||
while (attempts < 32
|
||||
&& !playerTeam.getSpawnVolume().contains(nextCandidate)
|
||||
&& (attempts == 0 // fall through the first iteration because we may be still in spawn and with both air blocks
|
||||
|| !nextCandidateBlock.getType().equals(Material.AIR)
|
||||
|| !nextCandidateBlock.getRelative(BlockFace.UP).getType().equals(Material.AIR))) {
|
||||
// not air at destination, lets find somewhere nearby with air
|
||||
int zeroToSeven = rand.nextInt(8);
|
||||
int distanceAwayMultiplier = 3 + attempts/10;
|
||||
|
||||
switch (zeroToSeven) {
|
||||
case 0:
|
||||
nextCandidateBlock = playerTeam.getTeamSpawn().getBlock().getRelative(BlockFace.WEST, distanceAwayMultiplier);
|
||||
break;
|
||||
case 1:
|
||||
nextCandidateBlock = playerTeam.getTeamSpawn().getBlock().getRelative(BlockFace.EAST, distanceAwayMultiplier);
|
||||
break;
|
||||
case 2:
|
||||
nextCandidateBlock = playerTeam.getTeamSpawn().getBlock().getRelative(BlockFace.NORTH, distanceAwayMultiplier);
|
||||
break;
|
||||
case 3:
|
||||
nextCandidateBlock = playerTeam.getTeamSpawn().getBlock().getRelative(BlockFace.SOUTH, distanceAwayMultiplier);
|
||||
break;
|
||||
case 4:
|
||||
nextCandidateBlock = playerTeam.getTeamSpawn().getBlock().getRelative(BlockFace.NORTH_WEST, distanceAwayMultiplier);
|
||||
break;
|
||||
case 5:
|
||||
nextCandidateBlock = playerTeam.getTeamSpawn().getBlock().getRelative(BlockFace.NORTH_EAST, distanceAwayMultiplier);
|
||||
break;
|
||||
case 6:
|
||||
nextCandidateBlock = playerTeam.getTeamSpawn().getBlock().getRelative(BlockFace.SOUTH_WEST, distanceAwayMultiplier);
|
||||
break;
|
||||
default: //7
|
||||
nextCandidateBlock = playerTeam.getTeamSpawn().getBlock().getRelative(BlockFace.SOUTH_EAST, distanceAwayMultiplier);
|
||||
break;
|
||||
}
|
||||
|
||||
nextCandidate = nextCandidateBlock.getLocation();
|
||||
|
||||
attempts++;
|
||||
}
|
||||
|
||||
if (attempts == 32) {
|
||||
// if random air search fails, go up!
|
||||
nextCandidateBlock = nextCandidate.getWorld().getHighestBlockAt(new Location(playerLoc.getWorld(),
|
||||
finalX,
|
||||
playerLoc.getY(),
|
||||
finalZ,
|
||||
playerLoc.getYaw(),
|
||||
playerLoc.getPitch()
|
||||
));
|
||||
nextCandidate = nextCandidateBlock.getLocation();
|
||||
}
|
||||
|
||||
player.teleport(nextCandidate);
|
||||
|
||||
War.war.badMsg(player, "Can't re-enter spawn! after " + attempts + " attemps!");
|
||||
}
|
||||
|
||||
if (playersUnderSuspicion.contains(player.getName())) {
|
||||
playersUnderSuspicion.remove(player.getName());
|
||||
}
|
||||
}
|
||||
|
||||
private int minusOneZeroOrOne() {
|
||||
int zeroToTwo = rand.nextInt(3);
|
||||
switch (zeroToTwo) {
|
||||
case 0:
|
||||
return -1;
|
||||
case 1:
|
||||
return 0;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> getPlayersUnderSuspicion() {
|
||||
return playersUnderSuspicion;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user