Improvements to the targetting system
This commit is contained in:
parent
70eec9e38c
commit
8a9e113389
@ -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");
|
||||
}
|
||||
|
||||
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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";
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user