Improvements to the targetting system

This commit is contained in:
Sam 2017-05-31 17:09:08 +01:00
parent 70eec9e38c
commit 8a9e113389
14 changed files with 286 additions and 205 deletions

View File

@ -33,7 +33,7 @@ public class FallingBlocks extends MiniPlugin
if (vec.getY() < 0)
{
vec.setY(vec.getY() * -1);
vec.setY(-vec.getY());
}
Spawn(location, type, data, vec);
@ -46,7 +46,6 @@ public class FallingBlocks extends MiniPlugin
UtilAction.velocity(fall, velocity, 0.5 + 0.25 * Math.random(), false, 0, 0.4 + 0.20 * Math.random(), 10, false);
fall.setMetadata(METADATA, new FixedMetadataValue(_plugin, "x"));
UtilEnt.SetMetadata(fall, METADATA, "x");
}

View File

@ -34,6 +34,7 @@ import nautilus.game.arcade.game.games.moba.recall.Recall;
import nautilus.game.arcade.game.games.moba.shop.MobaShop;
import nautilus.game.arcade.game.games.moba.structure.point.CapturePointManager;
import nautilus.game.arcade.game.games.moba.structure.tower.TowerManager;
import nautilus.game.arcade.game.games.moba.util.MobaConstants;
import nautilus.game.arcade.game.modules.CustomScoreboardModule;
import nautilus.game.arcade.game.modules.compass.CompassModule;
import nautilus.game.arcade.kit.Kit;
@ -49,6 +50,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.metadata.FixedMetadataValue;
import java.util.ArrayList;
import java.util.Arrays;
@ -362,6 +364,7 @@ public class Moba extends TeamGame
for (Player player : GetPlayers(true))
{
_playerData.add(new MobaPlayer(player));
player.setMetadata(MobaConstants.TEAM_METADATA, new FixedMetadataValue(Manager.getPlugin(), GetTeam(player).GetName()));
}
}

View File

@ -1,7 +1,5 @@
package nautilus.game.arcade.game.games.moba.ai;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import nautilus.game.arcade.game.GameTeam;
import nautilus.game.arcade.game.games.moba.Moba;
import nautilus.game.arcade.game.games.moba.ai.goal.MobaAIMethod;
@ -10,16 +8,15 @@ import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.entity.LivingEntity;
import java.util.List;
public class MobaAI
{
private static final int TARGET_RANGE = 15;
private static final int TARGET_RANGE_SQUARED = TARGET_RANGE * TARGET_RANGE;
private final Moba _host;
private final GameTeam _owner;
private final float _speedTarget;
private final float _speedHome;
private final List<Location> _boundaries;
private LivingEntity _entity;
private LivingEntity _target;
@ -29,26 +26,26 @@ public class MobaAI
public MobaAI(Moba host, GameTeam owner, LivingEntity entity, Location home, float speedTarget, float speedHome, MobaAIMethod aiMethod)
{
_host = host;
_owner = owner;
_speedTarget = speedTarget;
_speedHome = speedHome;
_entity = entity;
_home = home;
_aiMethod = aiMethod;
_boundaries = host.WorldData.GetDataLocs(getBoundaryKey());
}
public void updateTarget()
{
// Entity not spawned
if (_entity == null || !_entity.isValid())
if (_entity == null || _entity.isDead() || !_entity.isValid())
{
return;
}
if (_target == null || _target.isDead() || !_target.isValid())
{
_target = MobaUtil.getBestEntityTarget(_host, _owner, _entity, _home, _host.WorldData.GetDataLocs(getBoundaryKey()));
_target = MobaUtil.getBestEntityTarget(_owner, _entity, _home, _boundaries);
if (_target == null)
{
@ -56,15 +53,10 @@ public class MobaAI
return;
}
}
else
else if (!MobaUtil.isInBoundary(_owner, _entity, _home, _boundaries, _target))
{
double dist = UtilMath.offsetSquared(_entity, _target);
if (dist > TARGET_RANGE_SQUARED || UtilPlayer.isSpectator(_target))
{
_target = null;
returnToHome();
}
_target = null;
returnToHome();
}
if (_target != null)
@ -75,7 +67,7 @@ public class MobaAI
private void returnToHome()
{
_aiMethod.updateMovement(_entity, _home, _speedTarget);
_aiMethod.updateMovement(_entity, _home, _speedHome);
}
public void setEntity(LivingEntity entity)
@ -88,6 +80,11 @@ public class MobaAI
return _target;
}
public List<Location> getBoundaries()
{
return _boundaries;
}
public String getBoundaryKey()
{
return _owner.GetColor() == ChatColor.RED ? "ORANGE" : "LIGHT_BLUE";

View File

@ -14,7 +14,7 @@ public class MobaDirectAIMethod implements MobaAIMethod
{
Location entityLocation = entity.getLocation();
// Speed is blocks per second
// Speed is number of ticks to travel 1 block
float magnitude = speed / 20F;
// Get the direct vector between the entity and the goal

View File

@ -1,27 +1,38 @@
package nautilus.game.arcade.game.games.moba.boss;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.combat.event.CombatDeathEvent;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import nautilus.game.arcade.game.games.moba.Moba;
import nautilus.game.arcade.game.games.moba.ai.MobaAI;
import nautilus.game.arcade.game.games.moba.util.MobaUtil;
import org.bukkit.Location;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDeathEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
public abstract class MobaBoss implements Listener
{
protected final Moba _host;
protected LivingEntity _entity;
protected Location _location;
protected int _respawnTime;
private int _respawnTime;
private long _lastDeath;
private List<MobaBossAttack> _attacks;
public MobaBoss(Moba host, Location location)
{
this(host, location, -1);
@ -33,6 +44,7 @@ public abstract class MobaBoss implements Listener
_location = location;
_respawnTime = respawnTime;
_lastDeath = -1;
_attacks = new ArrayList<>(3);
}
public void setup()
@ -44,12 +56,36 @@ public abstract class MobaBoss implements Listener
public void cleanup()
{
UtilServer.Unregister(this);
_attacks.forEach(MobaBossAttack::cleanup);
}
public void addAttack(MobaBossAttack attack)
{
_attacks.add(attack);
}
@EventHandler
public void updateAttack(UpdateEvent event)
{
if (event.getType() != UpdateType.SLOW || getAi().getTarget() == null)
{
return;
}
MobaBossAttack attack = UtilAlg.Random(_attacks);
if (attack == null)
{
return;
}
attack.run();
}
@EventHandler
public void updateMovement(UpdateEvent event)
{
if (event.getType() != UpdateType.FASTEST || _entity == null || !_host.IsLive())
if (event.getType() != UpdateType.TICK || _entity == null || !_host.IsLive())
{
return;
}
@ -87,6 +123,13 @@ public abstract class MobaBoss implements Listener
public abstract MobaAI getAi();
public abstract String getName();
public Moba getHost()
{
return _host;
}
public LivingEntity getEntity()
{
return _entity;

View File

@ -0,0 +1,10 @@
package nautilus.game.arcade.game.games.moba.boss;
import org.bukkit.event.Listener;
public interface MobaBossAttack extends Runnable, Listener
{
void cleanup();
}

View File

@ -29,7 +29,6 @@ import nautilus.game.arcade.game.games.moba.util.MobaUtil;
import net.minecraft.server.v1_8_R3.PacketPlayOutAnimation;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityEquipment;
import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
@ -56,6 +55,7 @@ import java.util.concurrent.TimeUnit;
public class PumpkinBoss extends MobaBoss
{
private static final String NAME = "Pumpkin King";
private static final int SPAWN_TIME = (int) TimeUnit.MINUTES.toMillis(5);
private static final int RESPAWN_TIME = (int) TimeUnit.MINUTES.toMillis(5);
private static final MobaAIMethod AI_METHOD = new MobaDirectAIMethod();
@ -70,6 +70,7 @@ public class PumpkinBoss extends MobaBoss
private static final int DAMAGE_DIRECT = 8;
private static final int DAMAGE_DIRECT_RADIUS_SQUARED = 9;
private static final int HEALTH = 400;
private static final int HEALTH_OUT_OF_COMBAT = 10;
private static final Material[] BLOCKS = {
Material.OBSIDIAN,
Material.NETHERRACK,
@ -103,7 +104,7 @@ public class PumpkinBoss extends MobaBoss
Skeleton skeleton = UtilVariant.spawnWitherSkeleton(_location);
skeleton.setCustomName(C.cDRedB + "Pumpkin King");
skeleton.setCustomName(C.cDRedB + NAME);
skeleton.setCustomNameVisible(true);
skeleton.getEquipment().setHelmet(HELMET);
skeleton.getEquipment().setItemInHand(IN_HAND);
@ -115,6 +116,10 @@ public class PumpkinBoss extends MobaBoss
skeleton.getWorld().strikeLightningEffect(skeleton.getLocation());
// preDamage uses getAi() which would have been called in a game long before spawnEntity has
// This is unique to the pumpkin king, so we must manually update the AI's corresponding entity
getAi().setEntity(skeleton);
UtilTextMiddle.display(C.cDRedB + "The Pumpkin King", "Has Awoken!", 10, 40, 10);
_host.Announce(F.main("Game", C.cRedB + "The Pumpkin King Has Awoken!"), false);
@ -147,12 +152,18 @@ public class PumpkinBoss extends MobaBoss
{
if (_ai == null)
{
_ai = new PumpkinBossAI(_host, _entity, _location, AI_METHOD);
_ai = new PumpkinBossAI(_host, _entity, _location, AI_METHOD);
}
return _ai;
}
@Override
public String getName()
{
return NAME;
}
@EventHandler
public void updateSpawn(UpdateEvent event)
{
@ -176,6 +187,17 @@ public class PumpkinBoss extends MobaBoss
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void preDamage(CustomDamageEvent event)
{
if (!event.GetDamageeEntity().equals(_entity) || MobaUtil.isInBoundary(null, _entity, _location, getAi().getBoundaries(), event.GetDamagerPlayer(true)))
{
return;
}
event.SetCancelled("Outside of area");
}
@Override
@EventHandler
public void entityDeath(EntityDeathEvent event)
@ -239,19 +261,29 @@ public class PumpkinBoss extends MobaBoss
return;
}
if (_ai.getTarget() != null && !UtilPlayer.isSpectator(_ai.getTarget()) && UtilMath.offsetSquared(_entity, _ai.getTarget()) < DAMAGE_DIRECT_RADIUS_SQUARED)
LivingEntity target = _ai.getTarget();
if (target != null)
{
_host.getArcadeManager().GetDamage().NewDamageEvent(_ai.getTarget(), _entity, null, DamageCause.CUSTOM, DAMAGE_DIRECT, true, true, false, DAMAGE_REASON, DAMAGE_REASON);
// Send a fake hit packet
// Magic number 0 means swing item/attack
PacketPlayOutAnimation packet = new PacketPlayOutAnimation(((CraftLivingEntity) _entity).getHandle(), 0);
for (Player player : Bukkit.getOnlinePlayers())
if (UtilMath.offsetSquared(_entity, target) < DAMAGE_DIRECT_RADIUS_SQUARED)
{
UtilPlayer.sendPacket(player, packet);
_host.getArcadeManager().GetDamage().NewDamageEvent(target, _entity, null, DamageCause.CUSTOM, DAMAGE_DIRECT, true, true, false, DAMAGE_REASON, DAMAGE_REASON);
// Send a fake hit packet
// Magic number 0 means swing item/attack
PacketPlayOutAnimation packet = new PacketPlayOutAnimation(((CraftLivingEntity) _entity).getHandle(), 0);
for (Player player : Bukkit.getOnlinePlayers())
{
UtilPlayer.sendPacket(player, packet);
}
}
}
else
{
_entity.setHealth(Math.min(_entity.getHealth() + HEALTH_OUT_OF_COMBAT, _entity.getMaxHealth()));
updateDisplay();
}
for (LivingEntity entity : UtilEnt.getInRadius(_entity.getLocation(), DAMAGE_RADIUS).keySet())
{
@ -260,7 +292,7 @@ public class PumpkinBoss extends MobaBoss
continue;
}
_host.getArcadeManager().GetDamage().NewDamageEvent(entity, _entity, null, DamageCause.CUSTOM, DAMAGE_RANGE, false, true, false, DAMAGE_REASON, DAMAGE_REASON);
_host.getArcadeManager().GetDamage().NewDamageEvent(entity, _entity, null, DamageCause.CUSTOM, DAMAGE_RANGE, false, true, false, NAME, DAMAGE_REASON);
UtilAction.velocity(entity, UtilAlg.getTrajectory(_entity, entity).setY(1));
UtilParticle.PlayParticleToAll(ParticleType.FLAME, entity.getLocation().add(0, 1, 0), 0.5F, 0.5F, 0.5F, 0.1F, 5, ViewDist.LONG);
}

View File

@ -9,8 +9,8 @@ import org.bukkit.entity.LivingEntity;
public class PumpkinBossAI extends MobaAI
{
private static final float SPEED_TARGET = 12F;
private static final float SPEED_HOME = 16F;
private static final float SPEED_TARGET = 5F;
private static final float SPEED_HOME = 3F;
public PumpkinBossAI(Moba host, LivingEntity entity, Location home, MobaAIMethod aiMethod)
{

View File

@ -16,6 +16,7 @@ import nautilus.game.arcade.game.games.moba.ai.MobaAI;
import nautilus.game.arcade.game.games.moba.ai.goal.MobaAIMethod;
import nautilus.game.arcade.game.games.moba.ai.goal.MobaDirectAIMethod;
import nautilus.game.arcade.game.games.moba.boss.MobaBoss;
import nautilus.game.arcade.game.games.moba.boss.wither.attack.BossAttackEarthquake;
import nautilus.game.arcade.game.games.moba.structure.tower.Tower;
import nautilus.game.arcade.game.games.moba.structure.tower.TowerDestroyEvent;
import nautilus.game.arcade.game.games.moba.util.MobaUtil;
@ -31,8 +32,9 @@ import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
public class WitherBoss extends MobaBoss
{
private static final float SPEED_TARGET = 7F;
private static final float SPEED_HOME = 9F;
private static final String NAME = "Wither Boss";
private static final float SPEED_TARGET = 4F;
private static final float SPEED_HOME = 6F;
private static final int INITIAL_HEALTH = 1750;
private static final MobaAIMethod AI_METHOD = new MobaDirectAIMethod();
@ -47,6 +49,8 @@ public class WitherBoss extends MobaBoss
_location.setYaw(UtilAlg.GetYaw(UtilAlg.getTrajectory(location, host.GetSpectatorLocation())));
_team = team;
addAttack(new BossAttackEarthquake(this));
}
@Override
@ -81,15 +85,20 @@ public class WitherBoss extends MobaBoss
}
@Override
@EventHandler
public void updateMovement(UpdateEvent event)
public String getName()
{
super.updateMovement(event);
return NAME;
}
if (event.getType() == UpdateType.SEC && _entity != null && _host.IsLive() && getAi().getTarget() != null)
@EventHandler(priority = EventPriority.LOWEST)
public void preDamage(CustomDamageEvent event)
{
if (!event.GetDamageeEntity().equals(_entity) || MobaUtil.isInBoundary(_team, _entity, _location, getAi().getBoundaries(), event.GetDamagerPlayer(true)))
{
new WitherSkullProjectile(_host, _entity, getAi().getTarget(), _team);
return;
}
event.SetCancelled("Outside of area");
}
@EventHandler(priority = EventPriority.HIGHEST)

View File

@ -1,83 +0,0 @@
package nautilus.game.arcade.game.games.moba.boss.wither;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilParticle.ViewDist;
import mineplex.core.projectile.IThrown;
import mineplex.core.projectile.ProjectileUser;
import nautilus.game.arcade.ArcadeManager;
import nautilus.game.arcade.game.GameTeam;
import nautilus.game.arcade.game.games.moba.Moba;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.WitherSkull;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
public class WitherSkullProjectile implements IThrown
{
private static final int DAMAGE = 10;
private final Moba _host;
private final ArcadeManager _manager;
private final GameTeam _owner;
public WitherSkullProjectile(Moba host, LivingEntity shooter, LivingEntity target, GameTeam owner)
{
_host = host;
_manager = host.getArcadeManager();
_owner = owner;
WitherSkull skull = shooter.getWorld().spawn(shooter.getLocation().add(0, 2, 0), WitherSkull.class);
skull.setShooter(shooter);
skull.setYield(0);
skull.setVelocity(skull.getVelocity().add(UtilAlg.getTrajectory(shooter, target)));
_manager.GetProjectile().AddThrow(skull, shooter, this, 2000, true, true, true, false, 0.5F);
}
@Override
public void Collide(LivingEntity target, Block block, ProjectileUser data)
{
if (target == null)
{
Expire(data);
return;
}
if (target instanceof Player)
{
Player targetPlayer = (Player) target;
GameTeam targetTeam = _host.GetTeam(targetPlayer);
// Not team damage
if (!_owner.equals(targetTeam))
{
_manager.GetDamage().NewDamageEvent(target, data.getThrower(), null, DamageCause.CUSTOM, DAMAGE, true, true, false, "Wither Boss", "Wither Skull");
}
Expire(data);
}
}
@Override
public void Idle(ProjectileUser data)
{
}
@Override
public void Expire(ProjectileUser data)
{
Entity thrown = data.getThrown();
thrown.getWorld().playSound(thrown.getLocation(), Sound.EXPLODE, 1, 1.6F);
UtilParticle.PlayParticleToAll(ParticleType.LARGE_EXPLODE, thrown.getLocation(), 0, 0, 0, 0.1F, 1, ViewDist.LONG);
thrown.remove();
}
}

View File

@ -0,0 +1,93 @@
package nautilus.game.arcade.game.games.moba.boss.wither.attack;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilServer;
import nautilus.game.arcade.game.games.moba.boss.MobaBossAttack;
import nautilus.game.arcade.game.games.moba.boss.wither.WitherBoss;
import nautilus.game.arcade.game.games.moba.util.MobaUtil;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityChangeBlockEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import java.util.HashSet;
import java.util.Map.Entry;
import java.util.Set;
public class BossAttackEarthquake implements MobaBossAttack
{
private static final String ATTACK_NAME = "Earthquake";
private static final int RADIUS = 8;
private static final int DAMAGE = 8;
private static final double FALLING_BLOCK_CHANCE = 0.1;
private final WitherBoss _boss;
private final Set<FallingBlock> _entities;
public BossAttackEarthquake(WitherBoss boss)
{
_boss = boss;
_entities = new HashSet<>();
UtilServer.RegisterEvents(this);
}
@Override
public void run()
{
LivingEntity boss = _boss.getEntity();
for (Block block : UtilBlock.getBlocksInRadius(boss.getLocation(), RADIUS))
{
// Only want blocks that are on the floor
if (block.getType() == Material.AIR || block.getRelative(BlockFace.UP).getType() != Material.AIR || Math.random() > FALLING_BLOCK_CHANCE)
{
continue;
}
FallingBlock fallingBlock = block.getWorld().spawnFallingBlock(block.getLocation().add(0.5, 1, 0.5), block.getType(), block.getData());
fallingBlock.setHurtEntities(false);
fallingBlock.setDropItem(false);
fallingBlock.setVelocity(UtilAlg.getTrajectory(boss, fallingBlock).multiply(0.25).setY(1.5));
}
for (Entry<LivingEntity, Double> entry : UtilEnt.getInRadius(boss.getLocation(), RADIUS).entrySet())
{
LivingEntity entity = entry.getKey();
double dist = entry.getValue();
if (MobaUtil.isTeamEntity(entity, _boss.getTeam()))
{
continue;
}
_boss.getHost().getArcadeManager().GetDamage().NewDamageEvent(entity, boss, null, DamageCause.CUSTOM, DAMAGE * (dist + 0.5), false, true, false, _boss.getName(), ATTACK_NAME);
UtilAction.velocity(entity, UtilAlg.getTrajectory(boss, entity).setY(1));
}
}
@Override
public void cleanup()
{
UtilServer.Unregister(this);
}
@EventHandler
public void entityChangeBlock(EntityChangeBlockEvent event)
{
if (_entities.contains(event.getEntity()))
{
event.setCancelled(true);
event.getEntity().remove();
_entities.remove(event.getEntity());
}
}
}

View File

@ -13,13 +13,11 @@ import nautilus.game.arcade.game.games.moba.Moba;
import nautilus.game.arcade.game.games.moba.structure.point.CapturePoint;
import nautilus.game.arcade.game.games.moba.structure.point.CapturePointCaptureEvent;
import nautilus.game.arcade.game.games.moba.structure.tower.TowerDestroyEvent;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

View File

@ -28,6 +28,7 @@ import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.scheduler.BukkitRunnable;
import org.jooq.util.derby.sys.Sys;
import java.util.ArrayList;
import java.util.HashMap;
@ -47,21 +48,20 @@ public class MinionWave implements Listener
private final MinionManager _minionManager;
private final GameTeam _owner;
private final Class<? extends LivingEntity> _clazz;
private final long _startTime;
private final List<Location> _path;
private final List<Minion> _minions;
//private final Map<Entity, Long> _lastDamage;
public MinionWave(Moba host, MinionManager minionManager, GameTeam owner, List<Location> path, Class<? extends LivingEntity> clazz)
{
_host = host;
_minionManager = minionManager;
_owner = owner;
_clazz = clazz;
_startTime = System.currentTimeMillis();
_path = path;
_minions = new ArrayList<>(MAX_MINIONS_PER_WAVE);
//_lastDamage = new HashMap<>(MAX_MINIONS_PER_WAVE);
UtilServer.RegisterEvents(this);
@ -135,7 +135,6 @@ public class MinionWave implements Listener
// Too close
if (UtilMath.offsetSquared(entity.getLocation(), target) < TOO_CLOSE_SQUARED)
{
//Bukkit.broadcastMessage("Too close");
continue;
}
}
@ -146,19 +145,27 @@ public class MinionWave implements Listener
if (newTarget == _path.size())
{
//Bukkit.broadcastMessage("Done");
continue;
}
minion.setTargetIndex(newTarget);
minion.setTarget(_path.get(newTarget));
//Bukkit.broadcastMessage("Advance target " + newTarget);
}
}
}
@EventHandler
public void updateUnregister(UpdateEvent event)
{
if (event.getType() != UpdateType.FAST)
{
return;
}
_minions.removeIf(minion -> minion.getEntity() == null || minion.getEntity().isDead() || !minion.getEntity().isValid());
if (_minions.isEmpty())
// Only should unregister the wave after all entities have spawned
if (_minions.isEmpty() && UtilTime.elapsed(_startTime, 10000))
{
UtilServer.Unregister(this);
_minionManager.unregisterWave(this);
@ -381,19 +388,6 @@ public class MinionWave implements Listener
}
}
// @EventHandler(priority = EventPriority.MONITOR)
// public void damageSound(CustomDamageEvent event)
// {
// LivingEntity damagee = event.GetDamageeEntity();
//
// if (event.isCancelled() || !isMinion(damagee) || !UtilTime.elapsed(_lastDamage.get(damagee), 2000))
// {
// return;
// }
//
// damagee.getWorld().playSound(damagee.getLocation(), Sound.ZOMBIE_HURT, 1, 1.4F);
// }
@EventHandler
public void entityCombust(EntityCombustEvent event)
{

View File

@ -5,6 +5,7 @@ import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import nautilus.game.arcade.game.Game;
import nautilus.game.arcade.game.GameTeam;
import nautilus.game.arcade.game.games.moba.Moba;
import org.bukkit.Bukkit;
@ -13,6 +14,7 @@ import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map.Entry;
@ -22,11 +24,6 @@ public class MobaUtil
{
public static LivingEntity getBestEntityTarget(Moba host, GameTeam owner, LivingEntity source, Location location, int targetRange, boolean targetPlayers)
{
return getBestEntityTarget(host, owner, source, location, targetRange, targetPlayers, false);
}
public static LivingEntity getBestEntityTarget(Moba host, GameTeam owner, LivingEntity source, Location location, int targetRange, boolean targetPlayers, boolean targetPlayersMore)
{
LivingEntity highest = null;
double bestDist = 0;
@ -47,18 +44,13 @@ public class MobaUtil
continue;
}
// Make players more desirable
// Ignore players on the same team
if (entity instanceof Player)
{
if (!targetPlayers || owner.equals(host.GetTeam((Player) entity)))
{
continue;
}
if (targetPlayersMore)
{
dist += 0.5;
}
}
if (bestDist < dist)
@ -71,9 +63,34 @@ public class MobaUtil
return highest;
}
public static LivingEntity getBestEntityTarget(Moba host, GameTeam owner, LivingEntity source, Location center, List<Location> boundaries)
public static boolean isInBoundary(GameTeam owner, LivingEntity source, Location center, List<Location> boundaries, LivingEntity target)
{
Set<Player> ignored = new HashSet<>();
return getEntitiesInBoundary(owner, source, center, boundaries).contains(target);
}
public static LivingEntity getBestEntityTarget(GameTeam owner, LivingEntity source, Location center, List<Location> boundaries)
{
LivingEntity best = null;
double bestDist = Double.MAX_VALUE;
for (LivingEntity entity : getEntitiesInBoundary(owner, source, center, boundaries))
{
double dist = UtilMath.offsetSquared(entity.getLocation(), center);
if (dist < bestDist)
{
best = entity;
bestDist = dist;
}
}
return best;
}
public static Set<LivingEntity> getEntitiesInBoundary(GameTeam owner, LivingEntity source, Location center, List<Location> boundaries)
{
Set<LivingEntity> entities = new HashSet<>();
List<Player> ignored = new ArrayList<>();
if (owner != null)
{
@ -81,15 +98,6 @@ public class MobaUtil
ignored.addAll(owner.GetPlayers(true));
}
// Add all spectators to ignored players
for (Player player : Bukkit.getOnlinePlayers())
{
if (UtilPlayer.isSpectator(player))
{
ignored.add(player);
}
}
// For each boundary
for (Location boundary : boundaries)
{
@ -107,55 +115,28 @@ public class MobaUtil
// Advance the location
checking.add(direction);
LivingEntity highest = null;
double bestDist = 0;
// Check for nearby entities
for (Entry<LivingEntity, Double> entry : UtilEnt.getInRadius(checking, 2).entrySet())
for (LivingEntity entity : UtilEnt.getInRadius(checking, 3).keySet())
{
LivingEntity entity = entry.getKey();
double dist = entry.getValue();
if (source.equals(entity) || ignored.contains(entity))
{
continue;
}
if (owner != null)
// Check for team entities
if (owner != null && isTeamEntity(entity, owner))
{
// Check for team entities
if (entity.hasMetadata(MobaConstants.TEAM_METADATA) && entity.getMetadata(MobaConstants.TEAM_METADATA).get(0).asString().equals(owner.GetName()))
{
continue;
}
// Check for same team players
if (entity instanceof Player)
{
if (owner.equals(host.GetTeam((Player) entity)))
{
continue;
}
}
continue;
}
if (bestDist < dist)
{
highest = entity;
bestDist = dist;
}
}
if (highest != null)
{
return highest;
entities.add(entity);
}
checkedDist++;
}
}
return null;
return entities;
}
public static String getHealthBar(LivingEntity entity, int bars)
@ -203,4 +184,9 @@ public class MobaUtil
return C.cGreenB;
}
public static boolean isTeamEntity(LivingEntity entity, GameTeam team)
{
return entity.hasMetadata(MobaConstants.TEAM_METADATA) && entity.getMetadata(MobaConstants.TEAM_METADATA).get(0).asString().equals(team.GetName());
}
}