Add an overcomplicated system to prevent Necromancer Skeletons from spawning in blocks

This commit is contained in:
Spencer 2018-01-06 20:30:51 -05:00 committed by Alexander Meech
parent 4cd3fa5325
commit 8a389a13a2
2 changed files with 95 additions and 11 deletions

View File

@ -306,6 +306,30 @@ public abstract class SurvivalGames extends Game
}
}
private double getCurrentBorder()
{
// The distance between the old border and the new
double distanceMovedSince = _currentBorder - _previousBorder;
// Multiply that distance depending on how long its been since it moved.
long timeSinceMoved = System.currentTimeMillis() - _borderStartedMoving;
double percentageBorderMoved = Math.min(timeSinceMoved, 1000D) / 1000D;
distanceMovedSince *= percentageBorderMoved;
return (_previousBorder - 0.3D) + distanceMovedSince;
}
public boolean isOutsideBorder(Location loc)
{
double border = getCurrentBorder();
return (loc.getX() > _spawn.getX() + border
|| loc.getX() < _spawn.getX() - border
|| loc.getZ() > _spawn.getZ() + border
|| loc.getZ() < _spawn.getZ() - border);
}
@EventHandler
public void BlockBreak(BlockBreakEvent event)
{
@ -1186,16 +1210,7 @@ public abstract class SurvivalGames extends Game
return;
}
// The distance between the old border and the new
double distanceMovedSince = _currentBorder - _previousBorder;
// Multiply that distance depending on how long its been since it moved.
long timeSinceMoved = System.currentTimeMillis() - _borderStartedMoving;
double percentageBorderMoved = Math.min(timeSinceMoved, 1000D) / 1000D;
distanceMovedSince *= percentageBorderMoved;
double border = (_previousBorder - 0.3D) + distanceMovedSince;
double border = getCurrentBorder();
// 24 @ 100+ reduced to 0 at 32-
double borderAttackDist = Math.max(8,

View File

@ -1,15 +1,19 @@
package nautilus.game.arcade.kit.perks;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftCreature;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftSkeleton;
import org.bukkit.entity.Entity;
@ -24,6 +28,7 @@ import org.bukkit.event.player.PlayerEvent;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
@ -33,6 +38,7 @@ import mineplex.minecraft.game.core.combat.event.CombatDeathEvent;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import nautilus.game.arcade.events.PlayerStateChangeEvent;
import nautilus.game.arcade.game.GameTeam.PlayerState;
import nautilus.game.arcade.game.games.survivalgames.SurvivalGames;
import nautilus.game.arcade.kit.Perk;
import net.minecraft.server.v1_8_R3.EntityCreature;
import net.minecraft.server.v1_8_R3.NavigationAbstract;
@ -73,6 +79,7 @@ public class PerkSkeletons extends Perk
private boolean _name;
private int _maxDist = 8;
private static final int MAX_SPAWN_RADIUS = 5;
public PerkSkeletons(boolean name)
{
@ -83,6 +90,68 @@ public class PerkSkeletons extends Perk
_name = name;
}
/**
* Find whether a given location is a valid
* Skeleton spawnpoint.
*
* A location is valid if it meets the following
* criteria:
* - The block at and 1 y-value above are both air
* - It is within the border on X, Y, and Z
* @param location - The location at which you want to spawn a skeleton.
* @return Whether the location is valid or not
*/
private boolean isValidSpawn(Location location)
{
return location.getBlock().getType() == Material.AIR
&& location.clone().add(0, 1, 0).getBlock().getType() == Material.AIR
&& !((SurvivalGames) Manager.GetGame()).isOutsideBorder(location);
}
private double vectorDistance(Location a, Location b)
{
return a.toVector().distance(b.toVector());
}
private Location getMinionLocation(Location deathLocation)
{
if (isValidSpawn(deathLocation))
{
return deathLocation;
}
/*
Get all blocks within the max spawn radius,
where each block is at the same Y-level as
the death location,
filter locations to those which are valid spawns,
then sort them in ascending order of distance
to the original death location.
*/
List<Block> nearbyBlocks = UtilBlock.getBlocksInRadius(deathLocation, MAX_SPAWN_RADIUS, deathLocation.getBlockY())
.stream()
.filter(b -> isValidSpawn(b.getLocation()))
.sorted(Comparator.comparingDouble(a -> vectorDistance(a.getLocation(), deathLocation)))
.collect(Collectors.toCollection(LinkedList::new));
if (nearbyBlocks.size() > 0)
{
return nearbyBlocks.get(0).getLocation();
}
else
{
Location spawnLocation = deathLocation.clone();
while (!isValidSpawn(spawnLocation) && spawnLocation.getY() < 256)
{
spawnLocation = spawnLocation.add(0, 1, 0);
}
return spawnLocation;
}
}
@EventHandler
public void MinionSpawn(CombatDeathEvent event)
{
@ -103,7 +172,7 @@ public class PerkSkeletons extends Perk
Manager.GetGame().CreatureAllowOverride = true;
Skeleton skel = killed.getWorld().spawn(killed.getLocation(), Skeleton.class);
Skeleton skel = killed.getWorld().spawn(getMinionLocation(killed.getLocation()), Skeleton.class);
Manager.GetGame().CreatureAllowOverride = false;