Implement the iron wizard boss with tidied up code and the new world event api
This commit is contained in:
parent
4e58fa1e6c
commit
03149fc49b
@ -0,0 +1,47 @@
|
||||
package mineplex.game.clans.clans.worldevent.boss.ironwizard;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import mineplex.core.common.util.F;
|
||||
import mineplex.game.clans.clans.worldevent.WorldEventManager;
|
||||
import mineplex.game.clans.clans.worldevent.boss.BossWorldEvent;
|
||||
|
||||
public class GolemBoss extends BossWorldEvent<GolemCreature>
|
||||
{
|
||||
public GolemBoss(WorldEventManager manager)
|
||||
{
|
||||
super("Iron Wizard", manager.getBossArenaLocationFinder().getIronWizardCenter(), 30, manager.getBossArenaLocationFinder().getIronWizardPads().getLeft(), manager.getBossArenaLocationFinder().getIronWizardPads().getRight(), manager.getDisguiseManager(), manager.getClans().getProjectile(), manager.getClans().getDamageManager(), manager.getBlockRestore(), manager.getClans().getCondition());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void customStart()
|
||||
{
|
||||
Bukkit.broadcastMessage(F.main(getName(), "The mighty " + getName() + " challenges you to face him!"));
|
||||
spawnGolem(getCenterLocation());
|
||||
announceStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeathMessage()
|
||||
{
|
||||
return F.main(getName(), "The mighty " + getName() + " has fallen!");
|
||||
}
|
||||
|
||||
private GolemCreature spawnGolem(Location location)
|
||||
{
|
||||
GolemCreature golemCreature = new GolemCreature(this, location, 3000);
|
||||
registerCreature(golemCreature);
|
||||
setBossCreature(golemCreature);
|
||||
return golemCreature;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void customTick() {}
|
||||
|
||||
@Override
|
||||
public void customCleanup() {}
|
||||
|
||||
@Override
|
||||
protected void customStop() {}
|
||||
}
|
@ -0,0 +1,596 @@
|
||||
package mineplex.game.clans.clans.worldevent.boss.ironwizard;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Arrow;
|
||||
import org.bukkit.entity.IronGolem;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
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;
|
||||
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.game.clans.clans.worldevent.api.BossAbility;
|
||||
import mineplex.game.clans.clans.worldevent.api.EventCreature;
|
||||
import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemBlockHail;
|
||||
import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemBlockShot;
|
||||
import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemDeadlyTremor;
|
||||
import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemEarthquake;
|
||||
import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemExplodingAura;
|
||||
import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemIronHook;
|
||||
import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemMeleeAttack;
|
||||
import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemRupture;
|
||||
import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemSlam;
|
||||
import mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities.GolemSpike;
|
||||
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
|
||||
|
||||
public class GolemCreature extends EventCreature<IronGolem>
|
||||
{
|
||||
private int _lastAbility;
|
||||
private long _lastWalked;
|
||||
private Location _standing;
|
||||
private long _spawnDelay = System.currentTimeMillis();
|
||||
private long _reverseWalk;
|
||||
private Map<Class<? extends BossAbility<GolemCreature, IronGolem>>, Class<?>[]> _preferredCombos = new HashMap<>();
|
||||
private Class<? extends BossAbility<GolemCreature, IronGolem>> _lastAttack;
|
||||
private boolean _usedFinalAttack;
|
||||
private List<BossAbility<GolemCreature, IronGolem>> _currentAbilities = new ArrayList<>();
|
||||
private double _canDeadlyTremor = 225;
|
||||
private Vector _afkWalk = new Vector();
|
||||
private long _lastSlam;
|
||||
|
||||
public GolemCreature(GolemBoss boss, Location location, double maxHealth)
|
||||
{
|
||||
super(boss, location, "Iron Wizard", true, 3000, 30, true, IronGolem.class);
|
||||
|
||||
spawnEntity();
|
||||
|
||||
_preferredCombos.put(GolemEarthquake.class, new Class[]
|
||||
{
|
||||
GolemBlockHail.class, GolemRupture.class
|
||||
});
|
||||
_preferredCombos.put(GolemMeleeAttack.class, new Class[]
|
||||
{
|
||||
GolemEarthquake.class, GolemRupture.class
|
||||
});
|
||||
_preferredCombos.put(GolemDeadlyTremor.class, new Class[]
|
||||
{
|
||||
GolemMeleeAttack.class
|
||||
});
|
||||
_preferredCombos.put(GolemBlockShot.class, new Class[]
|
||||
{
|
||||
GolemEarthquake.class
|
||||
});
|
||||
_preferredCombos.put(GolemRupture.class, new Class[]
|
||||
{
|
||||
GolemBlockShot.class
|
||||
});
|
||||
_preferredCombos.put(GolemBlockHail.class, new Class[]
|
||||
{
|
||||
GolemDeadlyTremor.class
|
||||
});
|
||||
}
|
||||
|
||||
private boolean hasFurther(Map<Player, Double> distances, double range)
|
||||
{
|
||||
for (Player player : distances.keySet())
|
||||
{
|
||||
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Double dist = distances.get(player);
|
||||
if (dist >= range)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void spawnCustom()
|
||||
{
|
||||
UtilEnt.vegetate(getEntity());
|
||||
_standing = getEntity().getLocation();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@EventHandler
|
||||
public void abilityTick(UpdateEvent event)
|
||||
{
|
||||
if (event.getType() != UpdateType.TICK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!UtilTime.elapsed(_spawnDelay, 5000))
|
||||
{
|
||||
_standing = getEntity().getLocation();
|
||||
return;
|
||||
}
|
||||
|
||||
Iterator<BossAbility<GolemCreature, IronGolem>> itel = _currentAbilities.iterator();
|
||||
boolean canDoNew = _currentAbilities.size() < 3;
|
||||
|
||||
while (itel.hasNext())
|
||||
{
|
||||
BossAbility<GolemCreature, IronGolem> ability = itel.next();
|
||||
|
||||
if (ability.hasFinished())
|
||||
{
|
||||
itel.remove();
|
||||
ability.setFinished();
|
||||
_lastAbility = 20;
|
||||
|
||||
HandlerList.unregisterAll(ability);
|
||||
System.out.print("Unregistered golem ability " + ability.getClass().getSimpleName());
|
||||
}
|
||||
else if (!ability.inProgress())
|
||||
{
|
||||
canDoNew = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (_lastAbility-- <= 0 && canDoNew && UtilBlock.solid(getEntity().getLocation().getBlock().getRelative(BlockFace.DOWN)))
|
||||
{
|
||||
Map<Class<? extends BossAbility<GolemCreature, IronGolem>>, Integer> weight = new HashMap<>();
|
||||
Map<Player, Double> dist = new HashMap<>();
|
||||
|
||||
for (Player player : UtilPlayer.getNearby(getEntity().getLocation(), 50, true))
|
||||
{
|
||||
if (player.hasLineOfSight(getEntity()))
|
||||
{
|
||||
dist.put(player, player.getLocation().distance(getEntity().getLocation()));
|
||||
}
|
||||
}
|
||||
|
||||
if (!dist.isEmpty())
|
||||
{
|
||||
double hp = getHealthPercent();
|
||||
|
||||
{ // Melee
|
||||
List<Player> players = getPlayers(dist, UtilMath.r(10) == 0 ? 4 : 3);
|
||||
|
||||
if (!players.isEmpty())
|
||||
{
|
||||
if (players.size() >= 4)
|
||||
{
|
||||
weight.put(GolemEarthquake.class, 999);
|
||||
}
|
||||
else
|
||||
{
|
||||
weight.put(GolemMeleeAttack.class, 999);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasFurther(dist, 15))
|
||||
{ // Iron Hook
|
||||
weight.put(GolemIronHook.class, 6); //6
|
||||
}
|
||||
|
||||
if (hp < 0.7)
|
||||
{ // Earthquake
|
||||
List<Player> players = getPlayers(dist, 10);
|
||||
|
||||
double score = 0;
|
||||
|
||||
for (Player player : players)
|
||||
{
|
||||
score += (8 - dist.get(player)) / 2;
|
||||
}
|
||||
|
||||
if (players.size() >= 3)
|
||||
{
|
||||
score += 7;
|
||||
}
|
||||
|
||||
if (score > 0)
|
||||
{
|
||||
weight.put(GolemEarthquake.class, (int) Math.ceil(score));
|
||||
}
|
||||
}
|
||||
|
||||
{ // Wall explode
|
||||
if (!getPlayers(dist, 20).isEmpty() && getPlayers(dist, 4).isEmpty())
|
||||
{
|
||||
weight.put(GolemSpike.class, 8);
|
||||
}
|
||||
}
|
||||
|
||||
{ // Block Shot
|
||||
List<Player> players = getPlayers(dist, 30);
|
||||
|
||||
for (Player player : players)
|
||||
{
|
||||
if (dist.get(player) > 4)
|
||||
{
|
||||
weight.put(GolemBlockShot.class, 6);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{ // Rupture
|
||||
List<Player> players = getPlayers(dist, 30);
|
||||
|
||||
if (!players.isEmpty())
|
||||
{
|
||||
weight.put(GolemRupture.class, (int) Math.min(5, dist.get(players.get(0))));
|
||||
}
|
||||
}
|
||||
|
||||
{ // Slam
|
||||
List<Player> players = getPlayers(dist, 30);
|
||||
|
||||
if (!players.isEmpty() && UtilTime.elapsed(_lastSlam, 20000))
|
||||
{
|
||||
weight.put(GolemSlam.class, 6);
|
||||
}
|
||||
}
|
||||
|
||||
if (_canDeadlyTremor <= 0) // Deadly Tremor
|
||||
{
|
||||
List<Player> players = getPlayers(dist, 80);
|
||||
|
||||
for (BossAbility<GolemCreature, IronGolem> ability : _currentAbilities)
|
||||
{
|
||||
if (ability instanceof GolemExplodingAura)
|
||||
{
|
||||
players.clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (!players.isEmpty())
|
||||
{
|
||||
weight.put(GolemDeadlyTremor.class, (int) 30);
|
||||
}
|
||||
}
|
||||
|
||||
{// Block Hail
|
||||
List<Player> players = getPlayers(dist, 30);
|
||||
|
||||
if (!players.isEmpty())
|
||||
{
|
||||
int we = _lastAttack == GolemEarthquake.class ? 20 : UtilMath.r(15) - 2;
|
||||
|
||||
if (we > 0)
|
||||
{
|
||||
weight.put(GolemBlockHail.class, we);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!_usedFinalAttack && getHealth() < 90)
|
||||
{
|
||||
_usedFinalAttack = true;
|
||||
weight.clear();
|
||||
|
||||
weight.put(GolemExplodingAura.class, 999);
|
||||
}
|
||||
|
||||
if (_lastAttack != null && _preferredCombos.containsKey(_lastAttack))
|
||||
{
|
||||
weight.remove(_lastAttack);
|
||||
|
||||
for (Class<?> c : _preferredCombos.get(_lastAttack))
|
||||
{
|
||||
if (weight.containsKey(c))
|
||||
{
|
||||
weight.put((Class<? extends BossAbility<GolemCreature, IronGolem>>)c, weight.get(c) * 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (BossAbility<GolemCreature, IronGolem> ability : _currentAbilities)
|
||||
{
|
||||
weight.remove(ability.getClass());
|
||||
}
|
||||
|
||||
BossAbility<GolemCreature, IronGolem> ability = null;
|
||||
|
||||
if (!weight.isEmpty())
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (Integer entry : weight.values())
|
||||
{
|
||||
i += entry;
|
||||
}
|
||||
|
||||
for (int a = 0; a < 10; a++)
|
||||
{
|
||||
int luckyNumber = UtilMath.r(i);
|
||||
|
||||
for (Entry<Class<? extends BossAbility<GolemCreature, IronGolem>>, Integer> entry : weight.entrySet())
|
||||
{
|
||||
luckyNumber -= entry.getValue();
|
||||
|
||||
if (luckyNumber <= 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
ability = entry.getKey().getConstructor(GolemCreature.class).newInstance(this);
|
||||
|
||||
if (ability.getTarget() == null)
|
||||
{
|
||||
ability = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ability != null && ability.getTarget() != null)
|
||||
{
|
||||
_lastAttack = (Class<? extends BossAbility<GolemCreature, IronGolem>>) ability.getClass();
|
||||
|
||||
if (ability instanceof GolemDeadlyTremor)
|
||||
{
|
||||
_canDeadlyTremor = 225;
|
||||
}
|
||||
else if (ability instanceof GolemSlam)
|
||||
{
|
||||
_lastSlam = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(ability, UtilServer.getPlugin());
|
||||
|
||||
if (DEBUG_MODE)
|
||||
{
|
||||
System.out.print("Golem boss is using " + ability.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
_currentAbilities.add(ability);
|
||||
}
|
||||
|
||||
_lastAbility = 10;
|
||||
}
|
||||
|
||||
_lastAttack = null;
|
||||
}
|
||||
|
||||
boolean canMove = true;
|
||||
|
||||
for (BossAbility<GolemCreature, IronGolem> ability : _currentAbilities)
|
||||
{
|
||||
try
|
||||
{
|
||||
ability.tick();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace(); //Keeps the boss from getting stuck if one of the moves throws an error in progression
|
||||
}
|
||||
|
||||
if (!ability.canMove())
|
||||
{
|
||||
canMove = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (canMove)
|
||||
{
|
||||
Player target = null;
|
||||
double dist = 0;
|
||||
|
||||
for (Player player : UtilPlayer.getNearby(getEntity().getLocation(), 50, true))
|
||||
{
|
||||
if (!player.hasLineOfSight(getEntity()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
double d = player.getLocation().distance(getEntity().getLocation());
|
||||
|
||||
if (d > 1.5 && (d < 7 || d > 15) && (target == null || (d < 50 && dist > d)))
|
||||
{
|
||||
target = player;
|
||||
dist = d;
|
||||
}
|
||||
}
|
||||
|
||||
Vector vec = null;
|
||||
boolean superWalk = false;
|
||||
|
||||
if (target != null)
|
||||
{
|
||||
vec = target.getLocation().subtract(getEntity().getLocation()).toVector();
|
||||
vec.setY(getEntity().getLocation().getY());
|
||||
|
||||
double len = vec.length();
|
||||
|
||||
vec.setX(vec.getX() * (UtilMath.random.nextDouble() / 3D));
|
||||
vec.setZ(vec.getZ() * (UtilMath.random.nextDouble() / 3D));
|
||||
|
||||
vec.multiply(len);
|
||||
|
||||
if (target != null && dist < 8)
|
||||
{
|
||||
vec.multiply(-1);
|
||||
superWalk = true;
|
||||
}
|
||||
|
||||
if (!UtilAlg.HasSight(getEntity().getLocation(),
|
||||
getEntity().getLocation().add(vec.clone().normalize().multiply(2))))
|
||||
{
|
||||
_reverseWalk = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
if (!UtilTime.elapsed(_reverseWalk, 4000))
|
||||
{
|
||||
vec.multiply(-1);
|
||||
}
|
||||
|
||||
}
|
||||
else if (!UtilTime.elapsed(_lastWalked, 7000))
|
||||
{
|
||||
vec = _afkWalk;
|
||||
}
|
||||
else if (UtilTime.elapsed(_lastWalked, 12000))
|
||||
{
|
||||
_afkWalk = new Vector();
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
Vector vector = new Vector(UtilMath.r(20) - 10, 0, UtilMath.r(20) - 10);
|
||||
|
||||
if (UtilAlg.HasSight(getEntity().getLocation(),
|
||||
getEntity().getLocation().add(vector.clone().normalize().multiply(2))))
|
||||
{
|
||||
vec = _afkWalk = vector;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_lastWalked = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
if (vec != null)
|
||||
{
|
||||
{
|
||||
UtilEnt.CreatureMoveFast(getEntity(), getEntity().getLocation().add(vec),
|
||||
(target != null ? 1.8F : 1.1F) + (superWalk ? 0.4F : 0));
|
||||
}
|
||||
}
|
||||
|
||||
_standing = getEntity().getLocation();
|
||||
}
|
||||
else
|
||||
{
|
||||
Location l = getEntity().getLocation();
|
||||
|
||||
_standing.setYaw(l.getYaw());
|
||||
_standing.setPitch(l.getPitch());
|
||||
_standing.setY(l.getY());
|
||||
|
||||
getEntity().teleport(_standing);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Player> getPlayers(final Map<Player, Double> map, double maxDist)
|
||||
{
|
||||
List<Player> list = new ArrayList<Player>();
|
||||
|
||||
for (Player p : map.keySet())
|
||||
{
|
||||
if (map.get(p) <= maxDist)
|
||||
{
|
||||
list.add(p);
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(list, (o1, o2) ->
|
||||
{
|
||||
return Double.compare(map.get(o2), map.get(o1));
|
||||
});
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onGolemDamage(CustomDamageEvent event)
|
||||
{
|
||||
if (event.GetDamageeEntity().equals(getEntity()))
|
||||
{
|
||||
event.AddKnockback("Heavy Golem", 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onRangedAttack(CustomDamageEvent event)
|
||||
{
|
||||
if (event.GetDamageeEntity().equals(getEntity()))
|
||||
{
|
||||
if (event.GetDamageePlayer() != null)
|
||||
{
|
||||
if (event.GetProjectile() != null && event.GetProjectile() instanceof Arrow)
|
||||
{
|
||||
if (new Random().nextDouble() <= .5)
|
||||
{
|
||||
event.SetCancelled("Iron Skin Reflection");
|
||||
getEntity().getWorld().playSound(getEntity().getLocation(), Sound.ZOMBIE_METAL, 0.5f, 1.6f);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
double dist = event.GetDamageePlayer().getLocation().distance(getEntity().getLocation());
|
||||
|
||||
double maxRange = _usedFinalAttack ? 20 : 45;
|
||||
|
||||
double modifier = (maxRange - dist) / maxRange;
|
||||
|
||||
if (modifier > 0)
|
||||
{
|
||||
event.AddMod("Ranged Resistance", 1 - modifier);
|
||||
}
|
||||
else
|
||||
{
|
||||
event.SetCancelled("Range too far");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dieCustom()
|
||||
{
|
||||
endAbility();
|
||||
}
|
||||
|
||||
private void endAbility()
|
||||
{
|
||||
for (BossAbility<GolemCreature, IronGolem> ability : _currentAbilities)
|
||||
{
|
||||
ability.setFinished();
|
||||
HandlerList.unregisterAll(ability);
|
||||
}
|
||||
|
||||
_currentAbilities.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHealth(double health)
|
||||
{
|
||||
_canDeadlyTremor -= getHealth() - health;
|
||||
super.setHealth(health);
|
||||
if (getHealth() <= 100 && !_usedFinalAttack)
|
||||
{
|
||||
endAbility();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.IronGolem;
|
||||
|
||||
import mineplex.core.common.util.UtilEnt;
|
||||
import net.minecraft.server.v1_8_R3.DataWatcher;
|
||||
import net.minecraft.server.v1_8_R3.Entity;
|
||||
import net.minecraft.server.v1_8_R3.Packet;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutAttachEntity;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntity;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving;
|
||||
|
||||
public class BlockHailBlock
|
||||
{
|
||||
private int _block = UtilEnt.getNewEntityId();
|
||||
private int _silverfish = UtilEnt.getNewEntityId();
|
||||
private Location _location;
|
||||
private Material _mat;
|
||||
|
||||
public BlockHailBlock(Location loc, Material mat)
|
||||
{
|
||||
_location = loc;
|
||||
_mat = mat;
|
||||
}
|
||||
|
||||
public PacketPlayOutEntityDestroy getDestroyPacket()
|
||||
{
|
||||
return new PacketPlayOutEntityDestroy(new int[]
|
||||
{
|
||||
_silverfish, _block
|
||||
});
|
||||
}
|
||||
|
||||
public Location getLocation()
|
||||
{
|
||||
return _location;
|
||||
}
|
||||
|
||||
public Material getMaterial()
|
||||
{
|
||||
return _mat;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public Packet<?>[] getSpawnPackets(IronGolem entity)
|
||||
{
|
||||
Packet<?>[] packets = new Packet[3];
|
||||
|
||||
PacketPlayOutSpawnEntityLiving packet1 = new PacketPlayOutSpawnEntityLiving();
|
||||
|
||||
DataWatcher watcher = new DataWatcher(null);
|
||||
watcher.a(0, (byte) 32, Entity.META_ENTITYDATA, (byte) 0);
|
||||
watcher.a(1, 0, Entity.META_AIR, 0);
|
||||
|
||||
packet1.a = _silverfish;
|
||||
packet1.b = EntityType.SILVERFISH.getTypeId();
|
||||
packet1.c = (int) Math.floor(_location.getX() * 32);
|
||||
packet1.d = (int) Math.floor(_location.getY() * 32);
|
||||
packet1.e = (int) Math.floor(_location.getZ() * 32);
|
||||
packet1.l = watcher;
|
||||
|
||||
packets[0] = packet1;
|
||||
|
||||
PacketPlayOutSpawnEntity packet2 = new PacketPlayOutSpawnEntity(((CraftEntity) entity).getHandle(), 70, _mat.getId());
|
||||
|
||||
packet2.a = _block;
|
||||
|
||||
packet2.b = (int) Math.floor(_location.getX() * 32);
|
||||
packet2.c = (int) Math.floor(entity.getLocation().getY() * 32);
|
||||
packet2.d = (int) Math.floor(_location.getZ() * 32);
|
||||
|
||||
packets[1] = packet2;
|
||||
|
||||
PacketPlayOutAttachEntity packet3 = new PacketPlayOutAttachEntity();
|
||||
|
||||
packet3.b = _block;
|
||||
packet3.c = _silverfish;
|
||||
|
||||
packets[2] = packet3;
|
||||
|
||||
return packets;
|
||||
}
|
||||
}
|
@ -0,0 +1,475 @@
|
||||
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftIronGolem;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.FallingBlock;
|
||||
import org.bukkit.entity.IronGolem;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
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.UtilParticle;
|
||||
import mineplex.core.common.util.UtilParticle.ParticleType;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
import mineplex.core.common.util.UtilShapes;
|
||||
import mineplex.core.updater.UpdateType;
|
||||
import mineplex.core.updater.event.UpdateEvent;
|
||||
import mineplex.game.clans.clans.worldevent.api.BossAbility;
|
||||
import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature;
|
||||
import net.minecraft.server.v1_8_R3.AxisAlignedBB;
|
||||
import net.minecraft.server.v1_8_R3.EntityIronGolem;
|
||||
import net.minecraft.server.v1_8_R3.MathHelper;
|
||||
import net.minecraft.server.v1_8_R3.MovingObjectPosition;
|
||||
import net.minecraft.server.v1_8_R3.Packet;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy;
|
||||
import net.minecraft.server.v1_8_R3.Vec3D;
|
||||
|
||||
public class GolemBlockHail extends BossAbility<GolemCreature, IronGolem>
|
||||
{
|
||||
private int _currentBlock;
|
||||
private int _currentLevel;
|
||||
private List<FallingBlock> _fallingBlocks = new ArrayList<>();
|
||||
private Map<Integer, List<BlockHailBlock>> _floatingBlocks = new HashMap<>();
|
||||
private Map<String, Integer> _blocks = new HashMap<>();
|
||||
private int _levelToReach;
|
||||
private boolean _spawned;
|
||||
private List<Location> _spawnLocs = new ArrayList<>();
|
||||
private Player _target;
|
||||
private Location _center;
|
||||
private int _ticks;
|
||||
|
||||
public GolemBlockHail(GolemCreature creature)
|
||||
{
|
||||
super(creature);
|
||||
|
||||
_center = getLocation();
|
||||
|
||||
if (creature.getHealthPercent() > 0.75)
|
||||
{
|
||||
_levelToReach = 1;
|
||||
}
|
||||
else if (creature.getHealthPercent() > 0.5)
|
||||
{
|
||||
_levelToReach = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
_levelToReach = 3;
|
||||
}
|
||||
|
||||
_target = getTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player getTarget()
|
||||
{
|
||||
Player target = null;
|
||||
double dist = 0;
|
||||
|
||||
if (inProgress())
|
||||
{
|
||||
for (Player player : UtilPlayer.getNearby(_center, 40, true))
|
||||
{
|
||||
if (!player.hasLineOfSight(getEntity()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (target != null && _blocks.containsKey(player.getName()) && _blocks.get(player.getName()) > 8)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
double d = player.getLocation().distance(_center);
|
||||
|
||||
if (target == null || dist > d)
|
||||
{
|
||||
target = player;
|
||||
dist = d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMove()
|
||||
{
|
||||
return _spawned && _floatingBlocks.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFinished()
|
||||
{
|
||||
return _target == null || !_target.isValid() || ((_fallingBlocks.isEmpty() && _spawned) && _ticks >= 8 * 9)
|
||||
|| _center.distance(_target.getLocation()) > 100;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@EventHandler
|
||||
public void onUpdate(UpdateEvent event)
|
||||
{
|
||||
if (event.getType() != UpdateType.TICK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Iterator<FallingBlock> fallingIterator = _fallingBlocks.iterator();
|
||||
|
||||
while (fallingIterator.hasNext())
|
||||
{
|
||||
FallingBlock cur = fallingIterator.next();
|
||||
|
||||
if (cur.isDead() || !cur.isValid() || cur.getTicksLived() > 400
|
||||
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
|
||||
{
|
||||
fallingIterator.remove();
|
||||
|
||||
Block block = cur.getLocation().getBlock();
|
||||
block.setTypeIdAndData(0, (byte) 0, true);
|
||||
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
|
||||
|
||||
// Expire
|
||||
if (cur.getTicksLived() > 400
|
||||
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
|
||||
{
|
||||
cur.remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
cur.remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
double distanceToEntity = 0.0D;
|
||||
LivingEntity victim = null;
|
||||
|
||||
net.minecraft.server.v1_8_R3.Entity nmsEntity = ((CraftEntity) cur).getHandle();
|
||||
Vec3D vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
|
||||
Vec3D vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY,
|
||||
nmsEntity.locZ + nmsEntity.motZ);
|
||||
|
||||
MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false);
|
||||
vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
|
||||
vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ);
|
||||
|
||||
if (finalObjectPosition != null)
|
||||
{
|
||||
vec3d1 = new Vec3D(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c);
|
||||
}
|
||||
|
||||
for (Object entity : ((CraftWorld) cur.getWorld()).getHandle().getEntities(((CraftEntity) cur).getHandle(),
|
||||
((CraftEntity) cur).getHandle().getBoundingBox().a(((CraftEntity) cur).getHandle().motX,
|
||||
((CraftEntity) cur).getHandle().motY, ((CraftEntity) cur).getHandle().motZ).grow(2, 2, 2)))
|
||||
{
|
||||
Entity bukkitEntity = ((net.minecraft.server.v1_8_R3.Entity) entity).getBukkitEntity();
|
||||
|
||||
if (bukkitEntity instanceof LivingEntity)
|
||||
{
|
||||
LivingEntity ent = (LivingEntity) bukkitEntity;
|
||||
|
||||
// Avoid Self
|
||||
if (ent.equals(getEntity()))
|
||||
continue;
|
||||
|
||||
// Creative or Spec
|
||||
if (ent instanceof Player)
|
||||
if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent))
|
||||
continue;
|
||||
|
||||
// float f1 = (float)(nmsEntity.boundingBox.a() * 0.6f);
|
||||
AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().getBoundingBox().grow(1F, 1F, 1F);
|
||||
MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1);
|
||||
|
||||
if (entityCollisionPosition != null)
|
||||
{
|
||||
double d1 = vec3d.distanceSquared(entityCollisionPosition.pos);
|
||||
if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D))
|
||||
{
|
||||
victim = ent;
|
||||
distanceToEntity = d1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (victim != null)
|
||||
{
|
||||
cur.getWorld().playEffect(victim.getEyeLocation().subtract(0, 0.5, 0), Effect.STEP_SOUND, cur.getBlockId());
|
||||
{
|
||||
getBoss().getEvent().getDamageManager().NewDamageEvent((LivingEntity) victim, getEntity(), null,
|
||||
DamageCause.CONTACT, 10 * getBoss().getDifficulty(), true, true, false, "Iron Wizard Block Hail",
|
||||
"Iron Wizard Block Hail");
|
||||
}
|
||||
|
||||
if (victim instanceof Player)
|
||||
{
|
||||
getBoss().getEvent().getCondition().Factory().Slow("Iron Wizard Block Hail", (LivingEntity) victim,
|
||||
getEntity(), 3, 2, false, false, false, false);
|
||||
}
|
||||
|
||||
fallingIterator.remove();
|
||||
cur.remove();
|
||||
}
|
||||
else if (finalObjectPosition != null)
|
||||
{
|
||||
Block block = cur.getWorld().getBlockAt(((int) finalObjectPosition.pos.a), ((int) finalObjectPosition.pos.b), ((int) finalObjectPosition.pos.c));
|
||||
|
||||
if (!UtilBlock.airFoliage(block) && !block.isLiquid())
|
||||
{
|
||||
nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX));
|
||||
nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY));
|
||||
nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ));
|
||||
float f2 = MathHelper.sqrt(
|
||||
nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ * nmsEntity.motZ);
|
||||
nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D;
|
||||
nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D;
|
||||
nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D;
|
||||
|
||||
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
|
||||
|
||||
fallingIterator.remove();
|
||||
cur.remove();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0),
|
||||
cur.getLocation().add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL,
|
||||
UtilServer.getPlayers());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFinished()
|
||||
{
|
||||
for (List<BlockHailBlock> floatingBlocks : _floatingBlocks.values())
|
||||
{
|
||||
for (BlockHailBlock falling : floatingBlocks)
|
||||
{
|
||||
PacketPlayOutEntityDestroy packet = falling.getDestroyPacket();
|
||||
|
||||
for (Player player : UtilServer.getPlayers())
|
||||
{
|
||||
UtilPlayer.sendPacket(player, packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (FallingBlock block : _fallingBlocks)
|
||||
{
|
||||
block.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void tick()
|
||||
{
|
||||
if (inProgress())
|
||||
{
|
||||
for (Player player : UtilPlayer.getNearby(_center, 5, true))
|
||||
{
|
||||
Location loc = player.getLocation();
|
||||
|
||||
if (Math.abs(loc.getY() - (_center.getY() + 1)) <= 1)
|
||||
{
|
||||
loc.setY(_center.getY());
|
||||
|
||||
if (loc.distance(_center) < 2.8 + (_currentLevel * 0.75))
|
||||
{
|
||||
if (canDamage(player))
|
||||
{
|
||||
getBoss().getEvent().getDamageManager().NewDamageEvent(player, getEntity(), null,
|
||||
DamageCause.CONTACT, 10 * getBoss().getDifficulty(), true, true, false,
|
||||
"Iron Wizard Protection", "Iron Wizard Protection");
|
||||
|
||||
loc.getWorld().playEffect(player.getLocation(), Effect.STEP_SOUND, Material.OBSIDIAN.getId());
|
||||
loc.getWorld().playEffect(player.getEyeLocation(), Effect.STEP_SOUND, Material.OBSIDIAN.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!_spawned)
|
||||
{
|
||||
if (_currentBlock >= _spawnLocs.size())
|
||||
{
|
||||
|
||||
if (_currentLevel + 1 <= _levelToReach)
|
||||
{
|
||||
_currentLevel++;
|
||||
_currentBlock = 0;
|
||||
|
||||
_spawnLocs = UtilShapes.getDistancedCircle(_center.clone().add(0, 2.8 + (_currentLevel * 0.75), 0), 1.3,
|
||||
1 + (_currentLevel * 1.3));
|
||||
|
||||
for (int i = UtilMath.r(_spawnLocs.size()); i > 0; i--)
|
||||
{
|
||||
_spawnLocs.add(_spawnLocs.remove(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_currentBlock < _spawnLocs.size())
|
||||
{
|
||||
if (_ticks % 2 == 0)
|
||||
{
|
||||
IronGolem entity = getEntity();
|
||||
|
||||
Location loc = _spawnLocs.get(_currentBlock++);
|
||||
|
||||
List<BlockHailBlock> floatingBlocks = new ArrayList<>();
|
||||
|
||||
if (_floatingBlocks.containsKey(_currentLevel))
|
||||
{
|
||||
floatingBlocks = _floatingBlocks.get(_currentLevel);
|
||||
}
|
||||
else
|
||||
{
|
||||
_floatingBlocks.put(_currentLevel, floatingBlocks);
|
||||
}
|
||||
|
||||
if (loc.getBlock().getType() == Material.AIR && UtilAlg.HasSight(entity.getLocation(), loc))
|
||||
{
|
||||
|
||||
BlockHailBlock floating = new BlockHailBlock(loc, Material.STONE);
|
||||
UtilEnt.CreatureLook(entity, _target);
|
||||
|
||||
floatingBlocks.add(floating);
|
||||
|
||||
Packet<?>[] packets = floating.getSpawnPackets(entity);
|
||||
|
||||
for (Player player : UtilPlayer.getNearby(loc, 100))
|
||||
{
|
||||
UtilPlayer.sendPacket(player, packets);
|
||||
}
|
||||
|
||||
entity.getWorld().playSound(entity.getLocation(), Sound.DIG_GRASS, 3, 0.9F);
|
||||
}
|
||||
|
||||
if (_floatingBlocks.size() % 2 == 0)
|
||||
{
|
||||
Collections.reverse(floatingBlocks);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_spawned = true;
|
||||
_ticks = -20;
|
||||
}
|
||||
}
|
||||
else if (_ticks > 0 && _ticks % 2 == 0 && !_floatingBlocks.isEmpty())
|
||||
{
|
||||
IronGolem entity = getEntity();
|
||||
|
||||
if (_ticks % 16 == 0)
|
||||
{
|
||||
_target = getTarget();
|
||||
|
||||
if (_target == null)
|
||||
return;
|
||||
}
|
||||
|
||||
EntityIronGolem golem = ((CraftIronGolem) entity).getHandle();
|
||||
|
||||
golem.world.broadcastEntityEffect(golem, (byte) 4);
|
||||
UtilEnt.CreatureLook(entity, _target);
|
||||
|
||||
BlockHailBlock floatingBlock = null;
|
||||
|
||||
for (int i = 1; i <= _currentLevel; i++)
|
||||
{
|
||||
if (_floatingBlocks.containsKey(i) && !_floatingBlocks.get(i).isEmpty())
|
||||
{
|
||||
floatingBlock = _floatingBlocks.get(i).remove(0);
|
||||
|
||||
if (_floatingBlocks.get(i).isEmpty())
|
||||
{
|
||||
_floatingBlocks.remove(i);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PacketPlayOutEntityDestroy packet = floatingBlock.getDestroyPacket();
|
||||
|
||||
for (Player player : UtilServer.getPlayers())
|
||||
{
|
||||
UtilPlayer.sendPacket(player, packet);
|
||||
}
|
||||
|
||||
Location loc = floatingBlock.getLocation();
|
||||
|
||||
FallingBlock b = loc.getWorld().spawnFallingBlock(loc, floatingBlock.getMaterial(), (byte) 0);
|
||||
b.setDropItem(false);
|
||||
|
||||
Vector vec = UtilAlg.calculateVelocity(loc.toVector(),
|
||||
_target.getLocation().toVector().add(new Vector(UtilMath.r(6 + (_currentLevel * 2)) - (2 + _currentLevel), 0,
|
||||
UtilMath.r(6 + (_currentLevel * 2)) - (2 + _currentLevel))),
|
||||
6);
|
||||
|
||||
b.setVelocity(vec);
|
||||
|
||||
_fallingBlocks.add(b);
|
||||
|
||||
entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 3, 0.9F);
|
||||
|
||||
_blocks.put(_target.getName(), _blocks.containsKey(_target.getName()) ? _blocks.get(_target.getName()) + 1 : 1);
|
||||
}
|
||||
|
||||
List<Location> points = new ArrayList<>();
|
||||
|
||||
for (int i = _currentLevel; i <= _currentLevel; i++)
|
||||
{
|
||||
points.addAll(UtilShapes.getDistancedCircle(_center.clone().add(0, 3.3 + (i * 0.75), 0), 0.3, 1 + (i * 1.3)));
|
||||
}
|
||||
|
||||
for (int i = 0; i < points.size(); i++)
|
||||
{
|
||||
if (_spawned || i < _ticks)
|
||||
{
|
||||
Location loc = points.get(i);
|
||||
|
||||
UtilParticle.PlayParticle(
|
||||
ParticleType.BLOCK_DUST.getParticle(_spawned && i < _ticks ? Material.STONE : Material.DIRT, 0), loc, 0,
|
||||
0, 0, 0, 0, UtilParticle.ViewDist.LONG, UtilServer.getPlayers());
|
||||
}
|
||||
}
|
||||
|
||||
_ticks++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inProgress()
|
||||
{
|
||||
return !_spawned || !_floatingBlocks.isEmpty();
|
||||
}
|
||||
}
|
@ -0,0 +1,442 @@
|
||||
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftIronGolem;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.FallingBlock;
|
||||
import org.bukkit.entity.IronGolem;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
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.UtilMath;
|
||||
import mineplex.core.common.util.UtilParticle;
|
||||
import mineplex.core.common.util.UtilParticle.ParticleType;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
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.game.clans.clans.worldevent.api.BossAbility;
|
||||
import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature;
|
||||
import net.minecraft.server.v1_8_R3.AxisAlignedBB;
|
||||
import net.minecraft.server.v1_8_R3.EntityIronGolem;
|
||||
import net.minecraft.server.v1_8_R3.MathHelper;
|
||||
import net.minecraft.server.v1_8_R3.MovingObjectPosition;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityVelocity;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntity;
|
||||
import net.minecraft.server.v1_8_R3.Vec3D;
|
||||
|
||||
public class GolemBlockShot extends BossAbility<GolemCreature, IronGolem>
|
||||
{
|
||||
private Map<Integer, Location> _blockLoc = new HashMap<>();
|
||||
private Map<Integer, Material> _blockType = new HashMap<>();
|
||||
private List<FallingBlock> _current = new ArrayList<>();
|
||||
private Map<Integer, Long> _preshoot = new HashMap<>();
|
||||
private Player _target;
|
||||
private Map<Integer, Player> _targetBlock = new HashMap<>();
|
||||
private Map<UUID, Integer> _shotAt = new HashMap<>();
|
||||
private int _thrown;
|
||||
private int _tick;
|
||||
private int _toThrow;
|
||||
|
||||
public GolemBlockShot(GolemCreature creature)
|
||||
{
|
||||
super(creature);
|
||||
|
||||
if (creature.getHealthPercent() > 0.75)
|
||||
{
|
||||
_toThrow = 3;
|
||||
}
|
||||
else if (creature.getHealthPercent() > 0.5)
|
||||
{
|
||||
_toThrow = 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
_toThrow = 9;
|
||||
}
|
||||
|
||||
_target = getTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMove()
|
||||
{
|
||||
return _current.isEmpty() && _thrown == _toThrow;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player getTarget()
|
||||
{
|
||||
Player target = null;
|
||||
double dist = 0;
|
||||
|
||||
Location loc1 = getLocation();
|
||||
Location loc2 = loc1.clone().add(loc1.getDirection().setY(0).normalize());
|
||||
|
||||
List<Player> players = UtilPlayer.getNearby(getLocation(), 40, true);
|
||||
|
||||
for (Player player : players)
|
||||
{
|
||||
if (_shotAt.containsKey(player.getUniqueId()) && _shotAt.get(player.getUniqueId()) >= 3)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
double dist1 = player.getLocation().distance(loc1);
|
||||
double dist2 = player.getLocation().distance(loc2);
|
||||
|
||||
double dist3 = dist1 - dist2;
|
||||
|
||||
if (dist3 < 0.6 || dist1 > 30 || (target != null && dist3 < dist))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!player.hasLineOfSight(getEntity()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
target = player;
|
||||
dist = dist3;
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFinished()
|
||||
{
|
||||
return _current.isEmpty() && _preshoot.isEmpty() && (_target == null || _thrown >= _toThrow);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@EventHandler
|
||||
public void onUpdate(UpdateEvent event)
|
||||
{
|
||||
if (event.getType() != UpdateType.TICK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Iterator<FallingBlock> fallingIterator = _current.iterator();
|
||||
|
||||
while (fallingIterator.hasNext())
|
||||
{
|
||||
FallingBlock cur = fallingIterator.next();
|
||||
|
||||
if (cur.isDead() || !cur.isValid() || cur.getTicksLived() > 400
|
||||
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
|
||||
{
|
||||
fallingIterator.remove();
|
||||
|
||||
Block block = cur.getLocation().getBlock();
|
||||
block.setTypeIdAndData(0, (byte) 0, true);
|
||||
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
|
||||
|
||||
// Expire
|
||||
if (cur.getTicksLived() > 400
|
||||
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
|
||||
{
|
||||
cur.remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
cur.remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
double distanceToEntity = 0.0D;
|
||||
LivingEntity victim = null;
|
||||
|
||||
net.minecraft.server.v1_8_R3.Entity nmsEntity = ((CraftEntity) cur).getHandle();
|
||||
Vec3D vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
|
||||
Vec3D vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY,
|
||||
nmsEntity.locZ + nmsEntity.motZ);
|
||||
|
||||
MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false);
|
||||
vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
|
||||
vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ);
|
||||
|
||||
if (finalObjectPosition != null)
|
||||
{
|
||||
vec3d1 = new Vec3D(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c);
|
||||
}
|
||||
|
||||
for (Object entity : ((CraftWorld) cur.getWorld()).getHandle().getEntities(((CraftEntity) cur).getHandle(),
|
||||
((CraftEntity) cur).getHandle().getBoundingBox().a(((CraftEntity) cur).getHandle().motX,
|
||||
((CraftEntity) cur).getHandle().motY, ((CraftEntity) cur).getHandle().motZ).grow(2, 2, 2)))
|
||||
{
|
||||
Entity bukkitEntity = ((net.minecraft.server.v1_8_R3.Entity) entity).getBukkitEntity();
|
||||
|
||||
if (bukkitEntity instanceof LivingEntity)
|
||||
{
|
||||
LivingEntity ent = (LivingEntity) bukkitEntity;
|
||||
|
||||
// Avoid Self
|
||||
if (ent.equals(getEntity()))
|
||||
continue;
|
||||
|
||||
// Creative or Spec
|
||||
if (ent instanceof Player)
|
||||
if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent))
|
||||
continue;
|
||||
|
||||
// float f1 = (float)(nmsEntity.boundingBox.a() * 0.6f);
|
||||
AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().getBoundingBox().grow(1F, 1F, 1F);
|
||||
MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1);
|
||||
|
||||
if (entityCollisionPosition != null)
|
||||
{
|
||||
double d1 = vec3d.distanceSquared(entityCollisionPosition.pos);
|
||||
if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D))
|
||||
{
|
||||
victim = ent;
|
||||
distanceToEntity = d1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (victim != null)
|
||||
{
|
||||
cur.getWorld().playEffect(victim.getEyeLocation().subtract(0, 0.5, 0), Effect.STEP_SOUND, cur.getBlockId());
|
||||
|
||||
getBoss().getEvent().getDamageManager().NewDamageEvent((LivingEntity) victim, getEntity(), null,
|
||||
DamageCause.CONTACT, 10 * getBoss().getDifficulty(), true, true, false, "Iron Wizard Block Shot",
|
||||
"Iron Wizard Block Shot");
|
||||
|
||||
cur.remove();
|
||||
fallingIterator.remove();
|
||||
|
||||
Vector vec = UtilAlg.getTrajectory(getEntity(), victim);
|
||||
vec.setY(0).normalize();
|
||||
|
||||
double strength = 1;
|
||||
|
||||
if (!(victim instanceof Player) || !((Player) victim).isBlocking())
|
||||
{
|
||||
strength = 1.3;
|
||||
}
|
||||
|
||||
UtilAction.velocity(victim, vec, strength, true, 0, 0.2, 1, true);
|
||||
}
|
||||
else if (finalObjectPosition != null)
|
||||
{
|
||||
Block block = cur.getWorld().getBlockAt(((int) finalObjectPosition.pos.a), ((int) finalObjectPosition.pos.b), ((int) finalObjectPosition.pos.c));
|
||||
|
||||
if (!UtilBlock.airFoliage(block) && !block.isLiquid())
|
||||
{
|
||||
nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX));
|
||||
nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY));
|
||||
nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ));
|
||||
float f2 = MathHelper.sqrt(
|
||||
nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ * nmsEntity.motZ);
|
||||
nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D;
|
||||
nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D;
|
||||
nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D;
|
||||
|
||||
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
|
||||
cur.remove();
|
||||
fallingIterator.remove();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0),
|
||||
cur.getLocation().add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL,
|
||||
UtilServer.getPlayers());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFinished()
|
||||
{
|
||||
for (FallingBlock falling : _current)
|
||||
{
|
||||
falling.remove();
|
||||
}
|
||||
|
||||
int[] ids = new int[_preshoot.size()];
|
||||
|
||||
int a = 0;
|
||||
for (int id : _preshoot.keySet())
|
||||
{
|
||||
ids[a++] = id;
|
||||
}
|
||||
|
||||
PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(ids);
|
||||
|
||||
for (Player player : Bukkit.getOnlinePlayers())
|
||||
{
|
||||
UtilPlayer.sendPacket(player, packet);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void tick()
|
||||
{
|
||||
if (_target == null || _target.getLocation().distance(getLocation()) > 30 || !_target.hasLineOfSight(getEntity()))
|
||||
{
|
||||
_target = getTarget();
|
||||
}
|
||||
|
||||
Entity entity = getEntity();
|
||||
|
||||
if (_tick++ % 16 == 0 && _target != null && _thrown < _toThrow)
|
||||
{
|
||||
_thrown++;
|
||||
|
||||
UtilEnt.CreatureLook(entity, _target);
|
||||
EntityIronGolem golem = ((CraftIronGolem) entity).getHandle();
|
||||
|
||||
golem.world.broadcastEntityEffect(golem, (byte) 4);
|
||||
|
||||
entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 2, 1);
|
||||
|
||||
Location loc = entity.getLocation();
|
||||
loc.setYaw(loc.getYaw() + (UtilMath.r(150) - 75));
|
||||
loc.add(loc.getDirection().setY(0).normalize());
|
||||
|
||||
Block block = loc.getBlock();
|
||||
|
||||
if (block.getType() == Material.AIR)
|
||||
{
|
||||
block = block.getRelative(BlockFace.DOWN);
|
||||
}
|
||||
|
||||
Material mat = block.getType();
|
||||
|
||||
if (!UtilBlock.solid(block))
|
||||
{
|
||||
mat = Material.STONE;
|
||||
}
|
||||
|
||||
int id = UtilEnt.getNewEntityId();
|
||||
|
||||
_preshoot.put(id, System.currentTimeMillis());
|
||||
_blockType.put(id, mat);
|
||||
_blockLoc.put(id, loc.clone().add(0, 0.6, 0));
|
||||
_targetBlock.put(id, _target);
|
||||
|
||||
PacketPlayOutSpawnEntity packet = new PacketPlayOutSpawnEntity(((CraftEntity) entity).getHandle(), 70, mat.getId());
|
||||
|
||||
packet.a = id;
|
||||
|
||||
packet.b = (int) Math.floor(loc.getX() * 32);
|
||||
packet.c = (int) Math.floor(loc.getY() * 32);
|
||||
packet.d = (int) Math.floor(loc.getZ() * 32);
|
||||
|
||||
packet.g = (int) ((0.45) * 8000);
|
||||
|
||||
PacketPlayOutEntityVelocity packet2 = new PacketPlayOutEntityVelocity(id, 0, 0.45D, 0);
|
||||
|
||||
for (Player player : UtilPlayer.getNearby(loc, 70))
|
||||
{
|
||||
UtilPlayer.sendPacket(player, packet, packet2);
|
||||
}
|
||||
|
||||
_shotAt.put(_target.getUniqueId(),
|
||||
(_shotAt.containsKey(_target.getUniqueId()) ? _shotAt.get(_target.getUniqueId()) : 0) + 1);
|
||||
|
||||
_target = getTarget();
|
||||
}
|
||||
else
|
||||
{
|
||||
Iterator<Entry<Integer, Long>> itel = _preshoot.entrySet().iterator();
|
||||
|
||||
while (itel.hasNext())
|
||||
{
|
||||
Entry<Integer, Long> entry = itel.next();
|
||||
|
||||
if (UtilTime.elapsed(entry.getValue(), 920))
|
||||
{
|
||||
itel.remove();
|
||||
|
||||
int id = entry.getKey();
|
||||
|
||||
PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(new int[]
|
||||
{
|
||||
id
|
||||
});
|
||||
|
||||
for (Player player : Bukkit.getOnlinePlayers())
|
||||
{
|
||||
UtilPlayer.sendPacket(player, packet);
|
||||
}
|
||||
|
||||
Location loc = _blockLoc.get(id);
|
||||
FallingBlock falling = loc.getWorld().spawnFallingBlock(loc, _blockType.get(id), (byte) 0);
|
||||
falling.setDropItem(false);
|
||||
|
||||
_current.add(falling);
|
||||
|
||||
Player target = _targetBlock.get(id);
|
||||
|
||||
UtilEnt.CreatureLook(entity, target);
|
||||
EntityIronGolem golem = ((CraftIronGolem) entity).getHandle();
|
||||
|
||||
golem.world.broadcastEntityEffect(golem, (byte) 4);
|
||||
|
||||
entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 2, 1.2F);
|
||||
entity.getWorld().playEffect(falling.getLocation(), Effect.STEP_SOUND, falling.getBlockId());
|
||||
|
||||
Location l = falling.getLocation();
|
||||
l.setY(entity.getLocation().getY());
|
||||
|
||||
Location loc1 = target.getEyeLocation();
|
||||
|
||||
if (loc1.getY() - l.getY() > 1)
|
||||
{
|
||||
loc1.setY(l.getY() + 1);
|
||||
}
|
||||
|
||||
int dist = (int) Math.ceil(loc1.toVector().setY(0).distance(l.toVector().setY(0)));
|
||||
|
||||
Vector vector = UtilAlg.calculateVelocity(l.toVector(), loc1.toVector(), dist / 13);
|
||||
|
||||
falling.setVelocity(vector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_thrown >= 3 && !UtilPlayer.getNearby(getLocation(), 10, true).isEmpty())
|
||||
{
|
||||
_thrown = 99;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inProgress()
|
||||
{
|
||||
return _thrown < _toThrow || !_current.isEmpty();
|
||||
}
|
||||
}
|
@ -0,0 +1,336 @@
|
||||
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.FallingBlock;
|
||||
import org.bukkit.entity.IronGolem;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import mineplex.core.common.util.UtilAction;
|
||||
import mineplex.core.common.util.UtilAlg;
|
||||
import mineplex.core.common.util.UtilBlock;
|
||||
import mineplex.core.common.util.UtilMath;
|
||||
import mineplex.core.common.util.UtilParticle;
|
||||
import mineplex.core.common.util.UtilParticle.ParticleType;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
import mineplex.core.common.util.UtilShapes;
|
||||
import mineplex.core.updater.UpdateType;
|
||||
import mineplex.core.updater.event.UpdateEvent;
|
||||
import mineplex.game.clans.clans.worldevent.api.BossAbility;
|
||||
import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature;
|
||||
import net.minecraft.server.v1_8_R3.AxisAlignedBB;
|
||||
import net.minecraft.server.v1_8_R3.MathHelper;
|
||||
import net.minecraft.server.v1_8_R3.MovingObjectPosition;
|
||||
import net.minecraft.server.v1_8_R3.Vec3D;
|
||||
|
||||
public class GolemCaveIn extends BossAbility<GolemCreature, IronGolem>
|
||||
{
|
||||
private List<Block> _blocks = new ArrayList<>();
|
||||
private List<FallingBlock> _fallingBlocks = new ArrayList<>();
|
||||
private int _tick;
|
||||
|
||||
public GolemCaveIn(GolemCreature creature)
|
||||
{
|
||||
super(creature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMove()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player getTarget()
|
||||
{
|
||||
if (getTarget(4) == null)
|
||||
{
|
||||
return getTarget(40);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFinished()
|
||||
{
|
||||
return _tick > 60 && _fallingBlocks.isEmpty();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@EventHandler
|
||||
public void onUpdate(UpdateEvent event)
|
||||
{
|
||||
if (event.getType() != UpdateType.TICK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Iterator<FallingBlock> fallingIterator = _fallingBlocks.iterator();
|
||||
|
||||
while (fallingIterator.hasNext())
|
||||
{
|
||||
FallingBlock cur = fallingIterator.next();
|
||||
|
||||
if (cur.isDead() || !cur.isValid() || cur.getTicksLived() > 400
|
||||
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
|
||||
{
|
||||
fallingIterator.remove();
|
||||
|
||||
Block block = cur.getLocation().getBlock();
|
||||
block.setTypeIdAndData(0, (byte) 0, true);
|
||||
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
|
||||
|
||||
// Expire
|
||||
if (cur.getTicksLived() > 400
|
||||
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
|
||||
{
|
||||
cur.remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
cur.remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
double distanceToEntity = 0.0D;
|
||||
LivingEntity victim = null;
|
||||
|
||||
net.minecraft.server.v1_8_R3.Entity nmsEntity = ((CraftEntity) cur).getHandle();
|
||||
Vec3D vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
|
||||
Vec3D vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY,
|
||||
nmsEntity.locZ + nmsEntity.motZ);
|
||||
|
||||
MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false);
|
||||
vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
|
||||
vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ);
|
||||
|
||||
if (finalObjectPosition != null)
|
||||
{
|
||||
vec3d1 = new Vec3D(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c);
|
||||
}
|
||||
|
||||
for (Object entity : ((CraftWorld) cur.getWorld()).getHandle().getEntities(((CraftEntity) cur).getHandle(),
|
||||
((CraftEntity) cur).getHandle().getBoundingBox().a(((CraftEntity) cur).getHandle().motX,
|
||||
((CraftEntity) cur).getHandle().motY, ((CraftEntity) cur).getHandle().motZ).grow(2, 2, 2)))
|
||||
{
|
||||
Entity bukkitEntity = ((net.minecraft.server.v1_8_R3.Entity) entity).getBukkitEntity();
|
||||
|
||||
if (bukkitEntity instanceof LivingEntity)
|
||||
{
|
||||
LivingEntity ent = (LivingEntity) bukkitEntity;
|
||||
|
||||
// Avoid Self
|
||||
if (ent.equals(getEntity()))
|
||||
continue;
|
||||
|
||||
// Creative or Spec
|
||||
if (ent instanceof Player)
|
||||
if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent))
|
||||
continue;
|
||||
|
||||
// float f1 = (float)(nmsEntity.boundingBox.a() * 0.6f);
|
||||
AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().getBoundingBox().grow(1F, 1F, 1F);
|
||||
MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1);
|
||||
|
||||
if (entityCollisionPosition != null)
|
||||
{
|
||||
double d1 = vec3d.distanceSquared(entityCollisionPosition.pos);
|
||||
if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D))
|
||||
{
|
||||
victim = ent;
|
||||
distanceToEntity = d1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (victim != null)
|
||||
{
|
||||
cur.getWorld().playEffect(victim.getEyeLocation().subtract(0, 0.5, 0), Effect.STEP_SOUND, cur.getBlockId());
|
||||
|
||||
if (canDamage(victim))
|
||||
{
|
||||
getBoss().getEvent().getDamageManager().NewDamageEvent((LivingEntity) victim, getEntity(), null,
|
||||
DamageCause.CONTACT, 10 * getBoss().getDifficulty(), true, true, false, "Iron Wizard Cave In",
|
||||
"Iron Wizard Cave In");
|
||||
}
|
||||
|
||||
cur.remove();
|
||||
fallingIterator.remove();
|
||||
}
|
||||
else if (finalObjectPosition != null)
|
||||
{
|
||||
Block block = cur.getWorld().getBlockAt(((int) finalObjectPosition.pos.a), ((int) finalObjectPosition.pos.b), ((int) finalObjectPosition.pos.c));
|
||||
|
||||
if (!UtilBlock.airFoliage(block) && !block.isLiquid())
|
||||
{
|
||||
nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX));
|
||||
nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY));
|
||||
nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ));
|
||||
float f2 = MathHelper.sqrt(
|
||||
nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ * nmsEntity.motZ);
|
||||
nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D;
|
||||
nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D;
|
||||
nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D;
|
||||
|
||||
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
|
||||
cur.remove();
|
||||
fallingIterator.remove();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0),
|
||||
cur.getLocation().add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL,
|
||||
UtilServer.getPlayers());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void setFinished()
|
||||
{
|
||||
for (FallingBlock block : _fallingBlocks)
|
||||
{
|
||||
block.remove();
|
||||
}
|
||||
|
||||
for (Block block : _blocks)
|
||||
{
|
||||
block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getTypeId());
|
||||
block.setType(Material.AIR);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void tick()
|
||||
{
|
||||
if (_tick++ == 0)
|
||||
{
|
||||
Location l = getLocation();
|
||||
|
||||
List<Location> blocks = UtilShapes.getSphereBlocks(l, 3, 3, true);
|
||||
|
||||
for (Location loc : blocks)
|
||||
{
|
||||
if (loc.getBlockY() >= l.getBlockY())
|
||||
{
|
||||
Block b = loc.getBlock();
|
||||
|
||||
if (b.getType() == Material.AIR)
|
||||
{
|
||||
_blocks.add(b);
|
||||
|
||||
loc.setY(l.getY() - 1);
|
||||
|
||||
b.setType(loc.getBlock().getType());
|
||||
|
||||
b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, loc.getBlock().getTypeId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_tick % 5 == 0)
|
||||
|
||||
{
|
||||
for (Player player : UtilPlayer.getNearby(getLocation(), 2.5, true))
|
||||
{
|
||||
player.teleport(player.getLocation().add(0, 4, 0));
|
||||
UtilAction.velocity(player, new Vector(UtilMath.r(10) - 5, 3, UtilMath.r(10) - 5).normalize());
|
||||
}
|
||||
}
|
||||
|
||||
if (_tick < 200)
|
||||
|
||||
{
|
||||
Location loc = getLocation();
|
||||
loc.setY(loc.getY() + 4);
|
||||
|
||||
for (int i = 0; i < 30; i++)
|
||||
{
|
||||
loc.setY(loc.getY() + 1);
|
||||
Block b = loc.getBlock();
|
||||
|
||||
if (UtilBlock.solid(b))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!UtilBlock.solid(loc.getBlock()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<Player> players = UtilPlayer.getNearby(getLocation(), 50, true);
|
||||
|
||||
for (int i = 0; i < players.size() * 2; i++)
|
||||
{
|
||||
int dist = UtilMath.r(10);
|
||||
|
||||
if (dist < 3)
|
||||
{
|
||||
dist = 2;
|
||||
}
|
||||
else if (dist < 5)
|
||||
{
|
||||
dist = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
dist = 10;
|
||||
}
|
||||
|
||||
Location l = players.get(UtilMath.r(players.size())).getLocation().add(UtilMath.r(dist * 2) - dist, 0,
|
||||
UtilMath.r(dist * 2) - dist);
|
||||
l.setY(loc.getY());
|
||||
|
||||
Block b = l.getBlock();
|
||||
l.subtract(0, 1, 0);
|
||||
|
||||
if (UtilBlock.solid(b))
|
||||
{
|
||||
if (l.getBlock().getType() == Material.AIR)
|
||||
{
|
||||
if (UtilAlg.HasSight(l, getLocation().add(0, 4, 0)))
|
||||
{
|
||||
FallingBlock block = b.getWorld().spawnFallingBlock(b.getLocation().add(0.5, -1, 0.5), b.getTypeId(),
|
||||
b.getData());
|
||||
|
||||
block.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, block.getBlockId());
|
||||
block.setDropItem(false);
|
||||
|
||||
_fallingBlocks.add(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inProgress()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
|
||||
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.IronGolem;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import mineplex.core.common.util.UtilAction;
|
||||
import mineplex.core.common.util.UtilBlock;
|
||||
import mineplex.core.common.util.UtilEnt;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.core.common.util.UtilTime;
|
||||
import mineplex.core.recharge.Recharge;
|
||||
import mineplex.game.clans.clans.worldevent.api.BossAbility;
|
||||
import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature;
|
||||
|
||||
public class GolemDeadlyTremor extends BossAbility<GolemCreature, IronGolem>
|
||||
{
|
||||
private static final long ATTACK_DURATION = 10000;
|
||||
private long _start;
|
||||
|
||||
public GolemDeadlyTremor(GolemCreature creature)
|
||||
{
|
||||
super(creature);
|
||||
_start = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMove()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inProgress()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFinished()
|
||||
{
|
||||
return UtilTime.elapsed(_start, ATTACK_DURATION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFinished()
|
||||
{
|
||||
_start = System.currentTimeMillis() - ATTACK_DURATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick()
|
||||
{
|
||||
for (Player player : UtilPlayer.getInRadius(getLocation(), 30).keySet())
|
||||
{
|
||||
player.playSound(player.getLocation(), Sound.MINECART_BASE, 0.2f, 0.2f);
|
||||
|
||||
if (UtilEnt.isGrounded(player))
|
||||
{
|
||||
getBoss().getEvent().getDamageManager().NewDamageEvent(player, getBoss().getEntity(), null, DamageCause.CUSTOM, (1 + 2 * Math.random()) * getBoss().getDifficulty(), false, false, false, getBoss().getEntity().getName(), "Deadly Tremor");
|
||||
|
||||
if (Recharge.Instance.use(player, "Deadly Tremor Hit", 400, false, false))
|
||||
{
|
||||
UtilAction.velocity(player, new Vector(Math.random() - 0.5, Math.random() * 0.2, Math.random() - 0.5),
|
||||
Math.random() * 1 + 1, false, 0, 0.1 + Math.random() * 0.2, 2, true);
|
||||
}
|
||||
}
|
||||
|
||||
for (Block block : UtilBlock.getInRadius(player.getLocation(), 5).keySet())
|
||||
{
|
||||
if (Math.random() < 0.98)
|
||||
continue;
|
||||
|
||||
if (!UtilBlock.solid(block))
|
||||
continue;
|
||||
|
||||
if (!UtilBlock.airFoliage(block.getRelative(BlockFace.UP)))
|
||||
continue;
|
||||
|
||||
player.playEffect(block.getLocation(), Effect.STEP_SOUND, block.getType());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,168 @@
|
||||
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.IronGolem;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import mineplex.core.common.util.UtilAction;
|
||||
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.UtilServer;
|
||||
import mineplex.game.clans.clans.worldevent.api.BossAbility;
|
||||
import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature;
|
||||
|
||||
public class GolemEarthquake extends BossAbility<GolemCreature, IronGolem>
|
||||
{
|
||||
private Location _center;
|
||||
private float _range;
|
||||
private int _tick;
|
||||
private List<UUID> _damaged = new ArrayList<>();
|
||||
private boolean _earthquake;
|
||||
|
||||
public GolemEarthquake(GolemCreature creature)
|
||||
{
|
||||
super(creature);
|
||||
_center = getLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMove()
|
||||
{
|
||||
return !UtilEnt.isGrounded(getEntity()) && _tick > 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player getTarget()
|
||||
{
|
||||
return getTarget(7);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFinished()
|
||||
{
|
||||
return _range > 19;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFinished()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick()
|
||||
{
|
||||
Entity entity = getEntity();
|
||||
|
||||
if (_tick == 0)
|
||||
{
|
||||
entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 4, 0);
|
||||
|
||||
entity.setVelocity(new Vector(0, 1, 0));
|
||||
}
|
||||
else if (!_earthquake)
|
||||
{
|
||||
_earthquake = _tick > 10 && UtilEnt.isGrounded(entity);
|
||||
}
|
||||
|
||||
if (_earthquake)
|
||||
{
|
||||
_range += 0.7;
|
||||
|
||||
for (float range = _range - 2; range <= _range; range++)
|
||||
{
|
||||
if (range <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int x = -1; x <= 1; x++)
|
||||
{
|
||||
for (int z = -1; z <= 1; z++)
|
||||
{
|
||||
if ((x != 0) == (z != 0))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.DIRT, 0),
|
||||
_center.clone().add(x * range, 0.1, z * range), (x != 0) ? 0 : (range / 2), 0.1F,
|
||||
(z != 0) ? 0 : (range / 2), 0, (int) (range * 4), UtilParticle.ViewDist.NORMAL,
|
||||
UtilServer.getPlayers());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_center.getWorld().playSound(_center, Sound.DIG_STONE, 2, 0.8F);
|
||||
|
||||
HashSet<Player> toDamage = new HashSet<Player>();
|
||||
|
||||
Location cornerA = _center.clone().add(-_range, -1, -_range);
|
||||
Location cornerB = _center.clone().add(_range, 1, _range);
|
||||
Location cornerA1 = _center.clone().add(-(_range - 1.5), -1, -(_range - 1.5));
|
||||
Location cornerB1 = _center.clone().add(_range - 1.5, 1, _range - 1.5);
|
||||
|
||||
for (Player player : Bukkit.getOnlinePlayers())
|
||||
{
|
||||
Location pLoc = player.getLocation();
|
||||
|
||||
if (_damaged.contains(player.getUniqueId()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!UtilAlg.inBoundingBox(pLoc, cornerA, cornerB))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (UtilAlg.inBoundingBox(pLoc, cornerA1, cornerB1))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
toDamage.add(player);
|
||||
}
|
||||
|
||||
for (Player player : toDamage)
|
||||
{
|
||||
_damaged.add(player.getUniqueId());
|
||||
|
||||
getBoss().getEvent().getDamageManager().NewDamageEvent((LivingEntity) player, getEntity(), null,
|
||||
DamageCause.CONTACT, 14 * getBoss().getDifficulty(), false, true, false, "Iron Wizard Earthquake",
|
||||
"Iron Wizard Earthquake");
|
||||
|
||||
getBoss().getEvent().getCondition().Factory().Slow("Earthquake", (LivingEntity) player, getEntity(), 3, 1, false,
|
||||
false, false, false);
|
||||
|
||||
// Velocity
|
||||
UtilAction.velocity(player, UtilAlg.getTrajectory2d(getLocation().toVector(), player.getLocation().toVector()),
|
||||
1.8, true, 0, 0.5, 0.5, true);
|
||||
|
||||
// Condition
|
||||
getBoss().getEvent().getCondition().Factory().Falling("Earthquake", player, getEntity(), 10, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
_tick++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inProgress()
|
||||
{
|
||||
return !_earthquake;
|
||||
}
|
||||
}
|
@ -0,0 +1,400 @@
|
||||
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.FallingBlock;
|
||||
import org.bukkit.entity.IronGolem;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
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.UtilMath;
|
||||
import mineplex.core.common.util.UtilParticle;
|
||||
import mineplex.core.common.util.UtilParticle.ParticleType;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
import mineplex.core.updater.UpdateType;
|
||||
import mineplex.core.updater.event.UpdateEvent;
|
||||
import mineplex.game.clans.clans.worldevent.api.BossAbility;
|
||||
import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature;
|
||||
import net.minecraft.server.v1_8_R3.AxisAlignedBB;
|
||||
import net.minecraft.server.v1_8_R3.DataWatcher;
|
||||
import net.minecraft.server.v1_8_R3.MathHelper;
|
||||
import net.minecraft.server.v1_8_R3.MovingObjectPosition;
|
||||
import net.minecraft.server.v1_8_R3.Packet;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutAttachEntity;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntity;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving;
|
||||
import net.minecraft.server.v1_8_R3.Vec3D;
|
||||
|
||||
public class GolemExplodingAura extends BossAbility<GolemCreature, IronGolem>
|
||||
{
|
||||
private Map<Integer, Integer> _blocks = new HashMap<>();
|
||||
private Map<Integer, Location> _blocksLoc = new HashMap<>();
|
||||
private List<FallingBlock> _fallingBlocks = new ArrayList<>();
|
||||
private Map<Integer, Material> _blockMaterial = new HashMap<>();
|
||||
private int _tick;
|
||||
|
||||
public GolemExplodingAura(GolemCreature creature)
|
||||
{
|
||||
super(creature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMove()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFinished()
|
||||
{
|
||||
return _tick > 20 * 30 && _blocks.isEmpty() && _fallingBlocks.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFinished()
|
||||
{
|
||||
for (FallingBlock block : _fallingBlocks)
|
||||
{
|
||||
block.remove();
|
||||
}
|
||||
|
||||
int[] ids = new int[_blocks.size() * 2];
|
||||
|
||||
int i = 0;
|
||||
|
||||
for (Entry<Integer, Integer> id : _blocks.entrySet())
|
||||
{
|
||||
ids[i] = id.getKey();
|
||||
ids[i + 1] = id.getValue();
|
||||
|
||||
i += 2;
|
||||
}
|
||||
|
||||
PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(ids);
|
||||
|
||||
for (Player player : UtilServer.getPlayers())
|
||||
{
|
||||
UtilPlayer.sendPacket(player, packet);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void tick()
|
||||
{
|
||||
if (_tick < 25 * 25 && getBoss().getHealth() > 30)
|
||||
{
|
||||
double angle = (2 * Math.PI) / UtilMath.random.nextDouble();
|
||||
double x = 1.7 * Math.cos(angle);
|
||||
double z = 1.7 * Math.sin(angle);
|
||||
|
||||
Location loc = getLocation().add(x, 1 + (UtilMath.random.nextDouble() * 1.6), z);
|
||||
|
||||
loc.getWorld().playEffect(loc, Effect.STEP_SOUND, Material.DIRT.getId());
|
||||
|
||||
for (Player player : UtilPlayer.getNearby(getLocation(), 3, true))
|
||||
{
|
||||
getBoss().getEvent().getDamageManager().NewDamageEvent(player, getEntity(), null, DamageCause.CONTACT,
|
||||
6 * getBoss().getDifficulty(), true, true, false, "Iron Wizard Protection", "Iron Wizard Protection");
|
||||
UtilAction.velocity(player, UtilAlg.getTrajectory(getEntity(), player), 1, true, 0.3, 0, 0.3, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (_tick < 20 * 30)
|
||||
{
|
||||
int key = UtilEnt.getNewEntityId();
|
||||
int value = UtilEnt.getNewEntityId();
|
||||
|
||||
Location loc = null;
|
||||
|
||||
for (int i = 0; i < 30; i++)
|
||||
{
|
||||
double angle = (2 * Math.PI) / UtilMath.random.nextDouble();
|
||||
double x = 1.7 * Math.cos(angle);
|
||||
double z = 1.7 * Math.sin(angle);
|
||||
|
||||
loc = getLocation().add(x, 1 + (UtilMath.random.nextDouble() * 1.6), z);
|
||||
boolean found = false;
|
||||
|
||||
for (Location l : _blocksLoc.values())
|
||||
{
|
||||
if (l.distance(loc) < 0.3)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
loc = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (loc != null)
|
||||
{
|
||||
_blocks.put(key, value);
|
||||
_blocksLoc.put(key, loc);
|
||||
_blockMaterial.put(key, UtilMath.random.nextBoolean() ? Material.DIRT : Material.STONE);
|
||||
|
||||
Packet<?>[] packets = new Packet[3];
|
||||
|
||||
PacketPlayOutSpawnEntityLiving packet1 = new PacketPlayOutSpawnEntityLiving();
|
||||
|
||||
DataWatcher watcher = new DataWatcher(null);
|
||||
watcher.a(0, (byte) 32, net.minecraft.server.v1_8_R3.Entity.META_ENTITYDATA, (byte) 0);
|
||||
watcher.a(1, 0, net.minecraft.server.v1_8_R3.Entity.META_AIR, 0);
|
||||
|
||||
packet1.a = key;
|
||||
packet1.b = EntityType.SILVERFISH.getTypeId();
|
||||
packet1.c = (int) Math.floor(loc.getX() * 32);
|
||||
packet1.d = (int) Math.floor((loc.getY() - 0.125) * 32);
|
||||
packet1.e = (int) Math.floor(loc.getZ() * 32);
|
||||
packet1.l = watcher;
|
||||
|
||||
packets[0] = packet1;
|
||||
|
||||
PacketPlayOutSpawnEntity packet2 = new PacketPlayOutSpawnEntity(((CraftEntity) getEntity()).getHandle(), 70,
|
||||
_blockMaterial.get(key).getId());
|
||||
|
||||
packet2.a = value;
|
||||
|
||||
packet2.b = (int) Math.floor(loc.getX() * 32);
|
||||
packet2.c = (int) Math.floor(loc.getY() * 32);
|
||||
packet2.d = (int) Math.floor(loc.getZ() * 32);
|
||||
|
||||
packets[1] = packet2;
|
||||
|
||||
PacketPlayOutAttachEntity packet3 = new PacketPlayOutAttachEntity();
|
||||
|
||||
packet3.b = value;
|
||||
packet3.c = key;
|
||||
|
||||
packets[2] = packet3;
|
||||
|
||||
for (Player player : UtilPlayer.getNearby(getLocation(), 70))
|
||||
{
|
||||
UtilPlayer.sendPacket(player, packets);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_tick % 25 == 0)
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
getLocation().getWorld().playSound(getLocation(), Sound.DIG_GRASS, 3, 2);
|
||||
|
||||
for (int key : new ArrayList<Integer>(_blocksLoc.keySet()))
|
||||
{
|
||||
|
||||
PacketPlayOutEntityDestroy destroyPacket = new PacketPlayOutEntityDestroy(new int[]
|
||||
{
|
||||
key, _blocks.remove(key)
|
||||
});
|
||||
|
||||
for (Player player : UtilServer.getPlayers())
|
||||
{
|
||||
UtilPlayer.sendPacket(player, destroyPacket);
|
||||
}
|
||||
|
||||
Location loc = _blocksLoc.remove(key);
|
||||
|
||||
FallingBlock falling = loc.getWorld().spawnFallingBlock(loc, _blockMaterial.remove(key), (byte) 0);
|
||||
|
||||
_fallingBlocks.add(falling);
|
||||
|
||||
Vector vec = UtilAlg.getTrajectory(getLocation().add(0, 1, 0), loc);
|
||||
|
||||
vec.setY(Math.max(0.05, vec.getY()));
|
||||
|
||||
falling.setVelocity(vec);
|
||||
|
||||
loc.getWorld().playEffect(loc, Effect.STEP_SOUND, Material.DIRT.getId());
|
||||
}
|
||||
}
|
||||
|
||||
_tick++;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@EventHandler
|
||||
public void onUpdate(UpdateEvent event)
|
||||
{
|
||||
if (event.getType() != UpdateType.TICK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Iterator<FallingBlock> fallingIterator = _fallingBlocks.iterator();
|
||||
|
||||
while (fallingIterator.hasNext())
|
||||
{
|
||||
FallingBlock cur = fallingIterator.next();
|
||||
|
||||
if (cur.isDead() || !cur.isValid() || cur.getTicksLived() > 400
|
||||
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
|
||||
{
|
||||
fallingIterator.remove();
|
||||
|
||||
Block block = cur.getLocation().getBlock();
|
||||
block.setTypeIdAndData(0, (byte) 0, true);
|
||||
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
|
||||
|
||||
// Expire
|
||||
if (cur.getTicksLived() > 400
|
||||
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
|
||||
{
|
||||
cur.remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
cur.remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
double distanceToEntity = 0.0D;
|
||||
LivingEntity victim = null;
|
||||
|
||||
net.minecraft.server.v1_8_R3.Entity nmsEntity = ((CraftEntity) cur).getHandle();
|
||||
Vec3D vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
|
||||
Vec3D vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY,
|
||||
nmsEntity.locZ + nmsEntity.motZ);
|
||||
|
||||
MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false);
|
||||
vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
|
||||
vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ);
|
||||
|
||||
if (finalObjectPosition != null)
|
||||
{
|
||||
vec3d1 = new Vec3D(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c);
|
||||
}
|
||||
|
||||
for (Object entity : ((CraftWorld) cur.getWorld()).getHandle().getEntities(((CraftEntity) cur).getHandle(),
|
||||
((CraftEntity) cur).getHandle().getBoundingBox().a(((CraftEntity) cur).getHandle().motX,
|
||||
((CraftEntity) cur).getHandle().motY, ((CraftEntity) cur).getHandle().motZ).grow(2, 2, 2)))
|
||||
{
|
||||
Entity bukkitEntity = ((net.minecraft.server.v1_8_R3.Entity) entity).getBukkitEntity();
|
||||
|
||||
if (bukkitEntity instanceof LivingEntity)
|
||||
{
|
||||
LivingEntity ent = (LivingEntity) bukkitEntity;
|
||||
|
||||
// Avoid Self
|
||||
if (ent.equals(getEntity()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Creative or Spec
|
||||
if (ent instanceof Player)
|
||||
{
|
||||
if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().getBoundingBox().grow(1F, 1F, 1F);
|
||||
MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1);
|
||||
|
||||
if (entityCollisionPosition != null)
|
||||
{
|
||||
double d1 = vec3d.distanceSquared(entityCollisionPosition.pos);
|
||||
if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D))
|
||||
{
|
||||
victim = ent;
|
||||
distanceToEntity = d1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (victim != null)
|
||||
{
|
||||
cur.getWorld().playEffect(victim.getEyeLocation().subtract(0, 0.5, 0), Effect.STEP_SOUND, cur.getBlockId());
|
||||
|
||||
{
|
||||
getBoss().getEvent().getDamageManager().NewDamageEvent((LivingEntity) victim, getEntity(), null,
|
||||
DamageCause.CONTACT, 6 * getBoss().getDifficulty(), true, true, false, "Blocky Iron Wizard Aura",
|
||||
"Blocky Iron Wizard Aura");
|
||||
}
|
||||
|
||||
fallingIterator.remove();
|
||||
cur.remove();
|
||||
|
||||
Vector vec = UtilAlg.getTrajectory(getEntity(), victim);
|
||||
vec.setY(0).normalize();
|
||||
|
||||
double strength = 1;
|
||||
|
||||
if (!(victim instanceof Player) || !((Player) victim).isBlocking())
|
||||
{
|
||||
strength = 1.3;
|
||||
}
|
||||
|
||||
UtilAction.velocity(victim, vec, strength, true, 0, 0.2, 1, true);
|
||||
}
|
||||
else if (finalObjectPosition != null)
|
||||
{
|
||||
Block block = cur.getWorld().getBlockAt(((int) finalObjectPosition.pos.a), ((int) finalObjectPosition.pos.b), ((int) finalObjectPosition.pos.c));
|
||||
|
||||
if (!UtilBlock.airFoliage(block) && !block.isLiquid())
|
||||
{
|
||||
nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX));
|
||||
nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY));
|
||||
nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ));
|
||||
float f2 = MathHelper.sqrt(
|
||||
nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ * nmsEntity.motZ);
|
||||
nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D;
|
||||
nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D;
|
||||
nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D;
|
||||
|
||||
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
|
||||
|
||||
fallingIterator.remove();
|
||||
cur.remove();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0),
|
||||
cur.getLocation().add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL,
|
||||
UtilServer.getPlayers());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inProgress()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,590 @@
|
||||
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftIronGolem;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.FallingBlock;
|
||||
import org.bukkit.entity.IronGolem;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
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.UtilParticle;
|
||||
import mineplex.core.common.util.UtilParticle.ParticleType;
|
||||
import mineplex.core.common.util.UtilParticle.ViewDist;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
import mineplex.core.itemstack.ItemBuilder;
|
||||
import mineplex.core.updater.UpdateType;
|
||||
import mineplex.core.updater.event.UpdateEvent;
|
||||
import mineplex.game.clans.clans.worldevent.api.BossAbility;
|
||||
import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature;
|
||||
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
|
||||
import net.minecraft.server.v1_8_R3.AxisAlignedBB;
|
||||
import net.minecraft.server.v1_8_R3.DataWatcher;
|
||||
import net.minecraft.server.v1_8_R3.EntityIronGolem;
|
||||
import net.minecraft.server.v1_8_R3.MathHelper;
|
||||
import net.minecraft.server.v1_8_R3.MovingObjectPosition;
|
||||
import net.minecraft.server.v1_8_R3.Packet;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutAttachEntity;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutEntity;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntity;
|
||||
import net.minecraft.server.v1_8_R3.PacketPlayOutSpawnEntityLiving;
|
||||
import net.minecraft.server.v1_8_R3.Vec3D;
|
||||
|
||||
public class GolemExplosiveBlock extends BossAbility<GolemCreature, IronGolem>
|
||||
{
|
||||
private Map<Integer, Vector> _blocksLocation = new HashMap<>();
|
||||
private Location _center;
|
||||
private int _explosionsLeft;
|
||||
private FallingBlock _fallingBlock;
|
||||
private Map<Integer, Integer> _fallingBlocks = new HashMap<>();
|
||||
private List<Item> _items = new ArrayList<>();
|
||||
private int _strength;
|
||||
private Player _target;
|
||||
private int _tick;
|
||||
|
||||
public GolemExplosiveBlock(GolemCreature creature, int strength)
|
||||
{
|
||||
super(creature);
|
||||
|
||||
_strength = strength;
|
||||
_center = getLocation().add(0, 3, 0);
|
||||
_target = getTarget();
|
||||
|
||||
if (_target != null)
|
||||
{
|
||||
UtilEnt.CreatureLook(getEntity(), _target);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMove()
|
||||
{
|
||||
return _fallingBlock != null;
|
||||
}
|
||||
|
||||
private int clamp(int value)
|
||||
{
|
||||
if (value < -127)
|
||||
{
|
||||
return -127;
|
||||
}
|
||||
|
||||
if (value > 127)
|
||||
{
|
||||
return 127;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player getTarget()
|
||||
{
|
||||
HashMap<Player, Double> locs = new HashMap<Player, Double>();
|
||||
|
||||
for (Player player : UtilServer.getPlayers())
|
||||
{
|
||||
double dist = player.getLocation().distance(_center);
|
||||
|
||||
if (dist < 30)
|
||||
{
|
||||
double score = (dist > 10 ? 30 - dist : 10);
|
||||
|
||||
for (Player p : UtilServer.getPlayers())
|
||||
{
|
||||
if (player.getLocation().distance(p.getLocation()) < 4)
|
||||
{
|
||||
score += 7;
|
||||
}
|
||||
}
|
||||
|
||||
if (player.hasLineOfSight(getEntity()))
|
||||
{
|
||||
score += 10;
|
||||
}
|
||||
|
||||
locs.put(player, score);
|
||||
}
|
||||
}
|
||||
|
||||
Player lowest = null;
|
||||
|
||||
for (Entry<Player, Double> entry : locs.entrySet())
|
||||
{
|
||||
if (lowest == null || locs.get(lowest) > locs.get(entry.getKey()))
|
||||
{
|
||||
lowest = entry.getKey();
|
||||
}
|
||||
}
|
||||
|
||||
return lowest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFinished()
|
||||
{
|
||||
return _target == null || (_fallingBlock != null && !_fallingBlock.isValid() && _explosionsLeft == 0);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onDamage(CustomDamageEvent event)
|
||||
{
|
||||
if (event.GetDamageeEntity().equals(getEntity()))
|
||||
{
|
||||
if (_tick >= 40 + (40 * _strength) && _tick <= 50 + (40 * _strength))
|
||||
{
|
||||
event.SetCancelled("Iron Wizard charging bomb");
|
||||
}
|
||||
|
||||
event.SetKnockback(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void onExplode(final Location loc)
|
||||
{
|
||||
for (int i = 0; i < _strength * 2; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
onSubExplode(loc);
|
||||
}
|
||||
else
|
||||
{
|
||||
_explosionsLeft++;
|
||||
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(UtilServer.getPlugin(), () ->
|
||||
{
|
||||
onSubExplode(loc);
|
||||
_explosionsLeft--;
|
||||
}, 2 * i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void onSubExplode(Location loc)
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
Location l = loc.clone().add(UtilMath.r(_strength * 4) - (_strength * 2), UtilMath.r(_strength * 2),
|
||||
UtilMath.r(_strength * 4) - (_strength * 2));
|
||||
|
||||
UtilParticle.PlayParticle(ParticleType.LARGE_EXPLODE, l, _strength * 3, 1, _strength * 3, 0, _strength * 4,
|
||||
ViewDist.LONG, UtilServer.getPlayers());
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@EventHandler
|
||||
public void onUpdate(UpdateEvent event)
|
||||
{
|
||||
if (event.getType() != UpdateType.TICK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_fallingBlock == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_fallingBlock.isDead()
|
||||
|| !_fallingBlock.isValid()
|
||||
|| _fallingBlock.getTicksLived() > 400
|
||||
|| !_fallingBlock.getWorld().isChunkLoaded(_fallingBlock.getLocation().getBlockX() >> 4,
|
||||
_fallingBlock.getLocation().getBlockZ() >> 4))
|
||||
{
|
||||
Block block = _fallingBlock.getLocation().getBlock();
|
||||
block.setTypeIdAndData(0, (byte) 0, true);
|
||||
_fallingBlock.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, _fallingBlock.getBlockId());
|
||||
|
||||
// Expire
|
||||
if (_fallingBlock.getTicksLived() > 400
|
||||
|| !_fallingBlock.getWorld().isChunkLoaded(_fallingBlock.getLocation().getBlockX() >> 4,
|
||||
_fallingBlock.getLocation().getBlockZ() >> 4))
|
||||
{
|
||||
_fallingBlock.remove();
|
||||
return;
|
||||
}
|
||||
|
||||
_fallingBlock.remove();
|
||||
return;
|
||||
}
|
||||
|
||||
double distanceToEntity = 0.0D;
|
||||
LivingEntity victim = null;
|
||||
|
||||
net.minecraft.server.v1_8_R3.Entity nmsEntity = ((CraftEntity) _fallingBlock).getHandle();
|
||||
Vec3D vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
|
||||
Vec3D vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ);
|
||||
|
||||
MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false);
|
||||
vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
|
||||
vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ);
|
||||
|
||||
if (finalObjectPosition != null)
|
||||
{
|
||||
vec3d1 = new Vec3D(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c);
|
||||
}
|
||||
|
||||
for (Object entity : ((CraftWorld) _fallingBlock.getWorld()).getHandle().getEntities(
|
||||
((CraftEntity) _fallingBlock).getHandle(),
|
||||
((CraftEntity) _fallingBlock).getHandle().getBoundingBox().a(((CraftEntity) _fallingBlock).getHandle().motX,
|
||||
((CraftEntity) _fallingBlock).getHandle().motY, ((CraftEntity) _fallingBlock).getHandle().motZ).grow(2,
|
||||
2, 2)))
|
||||
{
|
||||
Entity bukkitEntity = ((net.minecraft.server.v1_8_R3.Entity) entity).getBukkitEntity();
|
||||
|
||||
if (bukkitEntity instanceof LivingEntity)
|
||||
{
|
||||
LivingEntity ent = (LivingEntity) bukkitEntity;
|
||||
|
||||
// Avoid Self
|
||||
if (ent.equals(getEntity()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Creative or Spec
|
||||
if (ent instanceof Player)
|
||||
{
|
||||
if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// float f1 = (float)(nmsEntity.boundingBox.a() * 0.6f);
|
||||
AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().getBoundingBox().grow(1F, 1F, 1F);
|
||||
MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1);
|
||||
|
||||
if (entityCollisionPosition != null)
|
||||
{
|
||||
double d1 = vec3d.distanceSquared(entityCollisionPosition.pos);
|
||||
if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D))
|
||||
{
|
||||
victim = ent;
|
||||
distanceToEntity = d1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (victim != null)
|
||||
{
|
||||
onExplode(victim.getEyeLocation());
|
||||
|
||||
_fallingBlock.remove();
|
||||
}
|
||||
else if (finalObjectPosition != null)
|
||||
{
|
||||
Block block = _fallingBlock.getWorld()
|
||||
.getBlockAt(((int) finalObjectPosition.pos.a), ((int) finalObjectPosition.pos.b), ((int) finalObjectPosition.pos.c));
|
||||
|
||||
if (!UtilBlock.airFoliage(block) && !block.isLiquid())
|
||||
{
|
||||
nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX));
|
||||
nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY));
|
||||
nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ));
|
||||
float f2 = MathHelper.sqrt(nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ
|
||||
* nmsEntity.motZ);
|
||||
nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D;
|
||||
nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D;
|
||||
nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D;
|
||||
|
||||
onExplode(block.getLocation().add(0.5, 0.5, 0.5));
|
||||
|
||||
_fallingBlock.remove();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0),
|
||||
_fallingBlock.getLocation().add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL,
|
||||
UtilServer.getPlayers());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFinished()
|
||||
{
|
||||
int[] ids = new int[_fallingBlocks.size() * 2];
|
||||
|
||||
int index = 0;
|
||||
|
||||
for (Entry<Integer, Integer> entry : _fallingBlocks.entrySet())
|
||||
{
|
||||
ids[index] = entry.getKey();
|
||||
ids[index + 1] = entry.getValue();
|
||||
index += 2;
|
||||
}
|
||||
|
||||
PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(ids);
|
||||
|
||||
for (Player player : Bukkit.getOnlinePlayers())
|
||||
{
|
||||
UtilPlayer.sendPacket(player, packet);
|
||||
}
|
||||
|
||||
for (Item item : _items)
|
||||
{
|
||||
item.remove();
|
||||
}
|
||||
|
||||
if (_fallingBlock != null)
|
||||
{
|
||||
_fallingBlock.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void tick()
|
||||
{
|
||||
IronGolem entity = getEntity();
|
||||
|
||||
Iterator<Item> itel = _items.iterator();
|
||||
|
||||
while (itel.hasNext())
|
||||
{
|
||||
Item item = itel.next();
|
||||
|
||||
Vector vec = item.getVelocity();
|
||||
Location loc = item.getLocation();
|
||||
|
||||
if (item.getTicksLived() > 100 || vec.getY() <= 0 || loc.distance(_center) > loc.add(vec).distance(_center)
|
||||
|| UtilEnt.isGrounded(item))
|
||||
{
|
||||
itel.remove();
|
||||
}
|
||||
}
|
||||
|
||||
// This spawns a floating block
|
||||
if (_tick >= 20 && _tick % 60 == 0 && _fallingBlocks.size() < _strength)
|
||||
{
|
||||
int id = UtilEnt.getNewEntityId();
|
||||
int id2 = UtilEnt.getNewEntityId();
|
||||
|
||||
_fallingBlocks.put(id, id2);
|
||||
_blocksLocation.put(id, _center.toVector());
|
||||
|
||||
Packet<?>[] packets = new Packet[3];
|
||||
|
||||
PacketPlayOutSpawnEntityLiving packet1 = new PacketPlayOutSpawnEntityLiving();
|
||||
|
||||
DataWatcher watcher = new DataWatcher(null);
|
||||
watcher.a(0, (byte) 32, net.minecraft.server.v1_8_R3.Entity.META_ENTITYDATA, (byte) 0);
|
||||
watcher.a(1, 0, net.minecraft.server.v1_8_R3.Entity.META_AIR, 0);
|
||||
|
||||
packet1.a = id;
|
||||
packet1.b = EntityType.SILVERFISH.getTypeId();
|
||||
packet1.c = (int) Math.floor(_center.getX() * 32);
|
||||
packet1.d = (int) Math.floor((_center.getY() - 0.125) * 32);
|
||||
packet1.e = (int) Math.floor(_center.getZ() * 32);
|
||||
packet1.l = watcher;
|
||||
|
||||
packets[0] = packet1;
|
||||
|
||||
PacketPlayOutSpawnEntity packet2 = new PacketPlayOutSpawnEntity(((CraftEntity) entity).getHandle(), 70,
|
||||
Material.DIRT.getId());
|
||||
|
||||
packet2.a = id2;
|
||||
|
||||
packet2.b = (int) Math.floor(_center.getX() * 32);
|
||||
packet2.c = (int) Math.floor(_center.getY() * 32);
|
||||
packet2.d = (int) Math.floor(_center.getZ() * 32);
|
||||
|
||||
packets[1] = packet2;
|
||||
|
||||
PacketPlayOutAttachEntity packet3 = new PacketPlayOutAttachEntity();
|
||||
|
||||
packet3.b = id2;
|
||||
packet3.c = id;
|
||||
|
||||
packets[2] = packet3;
|
||||
|
||||
for (Player player : UtilServer.getPlayers())
|
||||
{
|
||||
if (player.getLocation().distance(_center) < 80)
|
||||
{
|
||||
UtilPlayer.sendPacket(player, packets);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This spawns a item that flies above the golem's head and disappears
|
||||
if (UtilMath.r(6) == 0 && _tick < 40 + (_strength * 40))
|
||||
{
|
||||
double angle = ((2 * Math.PI) / 30) * UtilMath.r(30);
|
||||
double x = 5 * Math.cos(angle);
|
||||
double z = 5 * Math.sin(angle);
|
||||
Location loc = _center.clone().add(x, -3, z);
|
||||
|
||||
Material mat = null;
|
||||
|
||||
switch (UtilMath.r(3))
|
||||
{
|
||||
case 0:
|
||||
mat = Material.DIRT;
|
||||
break;
|
||||
case 1:
|
||||
mat = Material.STONE;
|
||||
break;
|
||||
case 2:
|
||||
mat = Material.COBBLESTONE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Item item = loc.getWorld().dropItem(loc, new ItemBuilder(mat).setTitle(System.currentTimeMillis() + "").build());
|
||||
|
||||
item.setPickupDelay(999999);
|
||||
|
||||
Vector vec = UtilAlg.getTrajectory(_center, item.getLocation());
|
||||
|
||||
vec.normalize().multiply(5);
|
||||
|
||||
item.setVelocity(vec);
|
||||
|
||||
// TODO Fix velocity
|
||||
|
||||
_items.add(item);
|
||||
}
|
||||
|
||||
// 10 being when items no longer fly in, 0 being when its shot.
|
||||
int ticksTillFired = (60 + (40 * _strength)) - _tick;
|
||||
|
||||
if (ticksTillFired > 20)
|
||||
{
|
||||
int strength = (int) Math.floor(_tick / 20D);
|
||||
|
||||
int nine = 8 - strength;
|
||||
|
||||
if (_tick % nine == 0)
|
||||
{
|
||||
_center.getWorld().playSound(_center, Sound.DIG_GRASS, strength + 1, 1F);
|
||||
}
|
||||
}
|
||||
else if (ticksTillFired < 0)
|
||||
{
|
||||
if (_tick % 3 == 0)
|
||||
{
|
||||
_center.getWorld().playSound(_fallingBlock.getLocation(), Sound.WOOD_CLICK, _strength + 1, 0.4F);
|
||||
}
|
||||
}
|
||||
|
||||
// The location the falling blocks need to stick by
|
||||
Vector blockCenter = _center.toVector();
|
||||
|
||||
if (ticksTillFired >= 0 && ticksTillFired <= 20)
|
||||
{
|
||||
Vector vec = entity.getLocation().add(entity.getLocation().getDirection().setY(0).normalize().multiply(1.2))
|
||||
.add(0, 1, 0).toVector();
|
||||
|
||||
blockCenter = UtilAlg.getTrajectory(_center.toVector(), blockCenter);
|
||||
vec.multiply(ticksTillFired / 10D);
|
||||
|
||||
_center.getWorld().playSound(_center, Sound.DIG_SNOW, _strength + 1, 0);
|
||||
}
|
||||
else if (_fallingBlock != null)
|
||||
{
|
||||
blockCenter = _fallingBlock.getLocation().add(0, 0.5, 0).toVector();
|
||||
}
|
||||
|
||||
// Move the fake floating blocks
|
||||
for (Entry<Integer, Integer> entry : _fallingBlocks.entrySet())
|
||||
{
|
||||
int id = entry.getKey();
|
||||
Vector vec = _blocksLocation.get(id);
|
||||
|
||||
int x = clamp((int) ((blockCenter.getX() - vec.getX()) * 32) + (UtilMath.r(8) - 4));
|
||||
int y = clamp((int) ((blockCenter.getY() - vec.getY()) * 32) + (UtilMath.r(8) - 4));
|
||||
int z = clamp((int) ((blockCenter.getZ() - vec.getZ()) * 32) + (UtilMath.r(8) - 4));
|
||||
|
||||
vec.add(new Vector(x, y, z));
|
||||
|
||||
PacketPlayOutEntity.PacketPlayOutRelEntityMove packet = new PacketPlayOutEntity.PacketPlayOutRelEntityMove();
|
||||
|
||||
packet.a = id;
|
||||
|
||||
packet.b = (byte) x;
|
||||
packet.c = (byte) y;
|
||||
packet.d = (byte) z;
|
||||
|
||||
for (Player player : UtilServer.getPlayers())
|
||||
{
|
||||
if (player.getLocation().distance(_center) < 70)
|
||||
{
|
||||
UtilPlayer.sendPacket(player, packet);
|
||||
|
||||
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0),
|
||||
vec.toLocation(_center.getWorld()), 0.7F, 0.7F, 0.7F, 0, 11, ViewDist.NORMAL, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ticksTillFired == 0)
|
||||
{
|
||||
int id = _fallingBlocks.keySet().iterator().next();
|
||||
|
||||
PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(new int[]
|
||||
{
|
||||
id, _fallingBlocks.get(id)
|
||||
});
|
||||
|
||||
for (Player player : Bukkit.getOnlinePlayers())
|
||||
{
|
||||
UtilPlayer.sendPacket(player, packet);
|
||||
}
|
||||
|
||||
_fallingBlocks.remove(id);
|
||||
|
||||
_fallingBlock = _center.getWorld().spawnFallingBlock(_blocksLocation.get(id).toLocation(_center.getWorld()),
|
||||
Material.STONE, (byte) 0);
|
||||
|
||||
Vector vec1 = _fallingBlock.getLocation().toVector();
|
||||
Vector vec2 = _target.getLocation().toVector();
|
||||
|
||||
Vector vec = UtilAlg.calculateVelocity(vec1, vec2, (int) (vec1.distanceSquared(vec2) / 4));
|
||||
|
||||
_fallingBlock.setVelocity(vec);
|
||||
|
||||
EntityIronGolem golem = ((CraftIronGolem) entity).getHandle();
|
||||
|
||||
golem.world.broadcastEntityEffect(golem, (byte) 4);
|
||||
}
|
||||
|
||||
_tick++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inProgress()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,163 @@
|
||||
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.IronGolem;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import mineplex.core.common.util.UtilAction;
|
||||
import mineplex.core.common.util.UtilAlg;
|
||||
import mineplex.core.common.util.UtilParticle.ParticleType;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
import mineplex.core.itemstack.ItemStackFactory;
|
||||
import mineplex.core.updater.UpdateType;
|
||||
import mineplex.game.clans.clans.worldevent.api.BossAbility;
|
||||
import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature;
|
||||
|
||||
public class GolemIronHook extends BossAbility<GolemCreature, IronGolem>
|
||||
{
|
||||
private static final Integer MAX_TARGETS = 3;
|
||||
private boolean _shot, _complete;
|
||||
|
||||
private List<Item> _hooks = new ArrayList<>();
|
||||
|
||||
public GolemIronHook(GolemCreature creature)
|
||||
{
|
||||
super(creature);
|
||||
_shot = false;
|
||||
_complete = false;
|
||||
}
|
||||
|
||||
private int getPosition(Player toAdd, List<Player> ordered, Map<Player, Double> distances)
|
||||
{
|
||||
int position = ordered.size();
|
||||
int index = 0;
|
||||
for (Player player : ordered)
|
||||
{
|
||||
if (distances.get(player) < distances.get(toAdd))
|
||||
{
|
||||
position = index;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
private void shoot()
|
||||
{
|
||||
IronGolem wizard = getBoss().getEntity();
|
||||
List<Player> selections = new LinkedList<>();
|
||||
List<Player> targeted = new ArrayList<>();
|
||||
|
||||
Map<Player, Double> near = UtilPlayer.getInRadius(wizard.getLocation(), 40D);
|
||||
|
||||
for (Player nearby : near.keySet())
|
||||
{
|
||||
if (nearby.getGameMode() == GameMode.CREATIVE || nearby.getGameMode() == GameMode.SPECTATOR)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (selections.isEmpty())
|
||||
{
|
||||
selections.add(nearby);
|
||||
}
|
||||
else
|
||||
{
|
||||
selections.add(getPosition(nearby, selections, near), nearby);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_TARGETS; i++)
|
||||
{
|
||||
if (i < selections.size())
|
||||
{
|
||||
targeted.add(selections.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
if (targeted.isEmpty())
|
||||
{
|
||||
_complete = true;
|
||||
setFinished();
|
||||
return;
|
||||
}
|
||||
|
||||
for (Player target : targeted)
|
||||
{
|
||||
Item item = wizard.getWorld().dropItem(wizard.getEyeLocation().add(UtilAlg.getTrajectory(wizard, target)), ItemStackFactory.Instance.CreateStack(131));
|
||||
UtilAction.velocity(item, UtilAlg.getTrajectory(wizard, target).normalize(),
|
||||
2, false, 0, 0.2, 20, false);
|
||||
|
||||
getBoss().getEvent().getProjectileManager().AddThrow(item, getBoss().getEntity(), new IronHook(getBoss().getEvent()), -1, true, true, true, true,
|
||||
Sound.FIRE_IGNITE, 1.4f, 0.8f, ParticleType.CRIT, UpdateType.TICK, 1f);
|
||||
|
||||
item.getWorld().playSound(item.getLocation(), Sound.IRONGOLEM_THROW, 2f, 0.8f);
|
||||
_hooks.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCooldown()
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMove()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inProgress()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFinished()
|
||||
{
|
||||
return _complete;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFinished()
|
||||
{
|
||||
for (Item hook : _hooks)
|
||||
{
|
||||
if (!hook.isDead() && hook.isValid())
|
||||
{
|
||||
getBoss().getEvent().getProjectileManager().deleteThrown(hook);
|
||||
hook.remove();
|
||||
}
|
||||
}
|
||||
|
||||
_hooks.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick()
|
||||
{
|
||||
if (_shot)
|
||||
{
|
||||
return;
|
||||
}
|
||||
shoot();
|
||||
_shot = true;
|
||||
Bukkit.getScheduler().runTaskLater(UtilServer.getPlugin(), () ->
|
||||
{
|
||||
_complete = true;
|
||||
setFinished();
|
||||
}, 2 * 20);
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
|
||||
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftIronGolem;
|
||||
import org.bukkit.entity.IronGolem;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import mineplex.core.common.util.UtilAction;
|
||||
import mineplex.core.common.util.UtilEnt;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.game.clans.clans.worldevent.api.BossAbility;
|
||||
import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature;
|
||||
import net.minecraft.server.v1_8_R3.EntityIronGolem;
|
||||
|
||||
public class GolemMeleeAttack extends BossAbility<GolemCreature, IronGolem>
|
||||
{
|
||||
private boolean _attacked;
|
||||
|
||||
public GolemMeleeAttack(GolemCreature creature)
|
||||
{
|
||||
super(creature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMove()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCooldown()
|
||||
{
|
||||
return 20;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player getTarget()
|
||||
{
|
||||
return getTarget(4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFinished()
|
||||
{
|
||||
return _attacked;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFinished() {}
|
||||
|
||||
@Override
|
||||
public void tick()
|
||||
{
|
||||
_attacked = true;
|
||||
|
||||
for (Player target : UtilPlayer.getNearby(getLocation(), 4, true))
|
||||
{
|
||||
if (target.getVelocity().length() > 0.5)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
UtilEnt.CreatureLook(getEntity(), target);
|
||||
|
||||
getBoss().getEvent().getDamageManager().NewDamageEvent(target, getEntity(), null, DamageCause.ENTITY_ATTACK,
|
||||
10 * getBoss().getDifficulty(), false, true, false, "Iron Wizard Melee Attack", "Iron Wizard Melee Attack");
|
||||
|
||||
Vector vec = getLocation().getDirection();
|
||||
vec.setY(0).normalize().setY(0.5).multiply(2.4);
|
||||
|
||||
UtilAction.velocity(target, vec);
|
||||
|
||||
getBoss().getEvent().getCondition().Factory().Falling("Iron Wizard Throw", target, getEntity(), 3, false, false);
|
||||
|
||||
target.getWorld().playSound(target.getLocation(), Sound.IRONGOLEM_THROW, 3, 0.9F);
|
||||
|
||||
EntityIronGolem golem = ((CraftIronGolem) getEntity()).getHandle();
|
||||
|
||||
golem.world.broadcastEntityEffect(golem, (byte) 4);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inProgress()
|
||||
{
|
||||
return _attacked;
|
||||
}
|
||||
}
|
@ -0,0 +1,238 @@
|
||||
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftIronGolem;
|
||||
import org.bukkit.entity.Damageable;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.IronGolem;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
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.UtilPlayer;
|
||||
import mineplex.game.clans.clans.worldevent.api.BossAbility;
|
||||
import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature;
|
||||
import net.minecraft.server.v1_8_R3.EntityIronGolem;
|
||||
|
||||
/**
|
||||
* Rumble is where the golem picks a target then starts playing a animation for a second where its obviously preparing to use it.
|
||||
* Copy this from Wizards
|
||||
*/
|
||||
public class GolemRumble extends BossAbility<GolemCreature, IronGolem>
|
||||
{
|
||||
private Location _loc;
|
||||
private int _ticks;
|
||||
private int _travelled;
|
||||
private Vector _vec;
|
||||
private int _width = 1;
|
||||
private Location _target;
|
||||
|
||||
public GolemRumble(GolemCreature creature)
|
||||
{
|
||||
super(creature);
|
||||
|
||||
Player target = getTarget();
|
||||
|
||||
if (target != null)
|
||||
{
|
||||
_target = target.getLocation();
|
||||
|
||||
UtilEnt.CreatureLook(getEntity(), _target);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMove()
|
||||
{
|
||||
return _ticks >= 20;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFinished()
|
||||
{
|
||||
return _travelled > 35;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFinished() {}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void tick()
|
||||
{
|
||||
if (_ticks++ < 14)
|
||||
{
|
||||
IronGolem entity = getEntity();
|
||||
EntityIronGolem golem = ((CraftIronGolem) entity).getHandle();
|
||||
|
||||
golem.world.broadcastEntityEffect(golem, (byte) 4);
|
||||
|
||||
if (_ticks % 2 == 0)
|
||||
{
|
||||
entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 3, 2F);
|
||||
}
|
||||
}
|
||||
else if (_ticks % 2 == 0)
|
||||
{
|
||||
int oldWidth = _width;
|
||||
|
||||
if ((_width <= 3 || _ticks % 4 == 0) && _width <= 6)
|
||||
{
|
||||
_width++;
|
||||
}
|
||||
|
||||
Location newLoc;
|
||||
boolean validBlock = false;
|
||||
List<Block> current = new ArrayList<>();
|
||||
|
||||
if (_vec == null)
|
||||
{
|
||||
_vec = _target.subtract(getLocation()).toVector().setY(0).normalize();
|
||||
_loc = getLocation().subtract(0, 1, 0).getBlock().getLocation().add(0, 0.99, 0);
|
||||
newLoc = _loc;
|
||||
current.add(_loc.getBlock());
|
||||
|
||||
validBlock = true;
|
||||
}
|
||||
else
|
||||
{ // Move rumble
|
||||
newLoc = _loc.clone().add(_vec);
|
||||
|
||||
// Check if the rumble needs to go up or drop a block or two
|
||||
for (int y : new int[] {0, 1, -1})
|
||||
{
|
||||
for (int a = 1; a <= 2; a++)
|
||||
{
|
||||
Block b = newLoc.clone().add(_vec.clone().multiply(a)).getBlock().getRelative(0, y, 0);
|
||||
|
||||
if (UtilBlock.solid(b) && !UtilBlock.solid(b.getRelative(0, 1, 0)))
|
||||
{
|
||||
validBlock = true;
|
||||
newLoc.add(0, y, 0);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (validBlock)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int width = -_width; width <= _width; width++)
|
||||
{
|
||||
if (Math.abs(width) <= oldWidth)
|
||||
{
|
||||
Block b = _loc.clone().add(UtilAlg.getRight(_vec).multiply(width)).getBlock();
|
||||
|
||||
if (!current.contains(b))
|
||||
{
|
||||
current.add(b);
|
||||
}
|
||||
}
|
||||
|
||||
if (validBlock)
|
||||
{
|
||||
Block b = newLoc.clone().add(UtilAlg.getRight(_vec).multiply(width)).getBlock();
|
||||
|
||||
if (!current.contains(b))
|
||||
{
|
||||
current.add(b);
|
||||
|
||||
b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, b.getTypeId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UtilEnt.CreatureLook(getEntity(), _loc);
|
||||
|
||||
for (Entity entity : getEntity().getWorld().getEntities())
|
||||
{
|
||||
if (entity instanceof Damageable && !UtilPlayer.isSpectator(entity) && entity != getEntity())
|
||||
{
|
||||
Block b = entity.getLocation().getBlock();
|
||||
boolean canDamage = false;
|
||||
|
||||
for (int y = -1; y <= 0; y++)
|
||||
{
|
||||
if (current.contains(b.getRelative(0, y, 0)))
|
||||
{
|
||||
canDamage = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!canDamage)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (canDamage(entity))
|
||||
{
|
||||
getBoss().getEvent().getDamageManager().NewDamageEvent((LivingEntity) entity, getEntity(), null,
|
||||
DamageCause.CONTACT, 8 * getBoss().getDifficulty(), false, true, false, "Iron Wizard Rumble",
|
||||
"Iron Wizard Rumble");
|
||||
}
|
||||
|
||||
UtilAction.velocity(entity, _vec.clone(), 1.5, true, 0, 0.2, 1, true);
|
||||
|
||||
if (entity instanceof Player)
|
||||
{
|
||||
getBoss().getEvent().getCondition().Factory().Slow("Rumble", (LivingEntity) entity, getEntity(), 3, 1,
|
||||
false, false, false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_travelled++ > 35 || !validBlock)
|
||||
{
|
||||
_travelled = 100;
|
||||
}
|
||||
|
||||
_loc = newLoc;
|
||||
}
|
||||
}
|
||||
|
||||
public Player getTarget()
|
||||
{
|
||||
Player target = null;
|
||||
double dist = 0;
|
||||
|
||||
for (Player player : UtilPlayer.getNearby(getLocation(), 30, true))
|
||||
{
|
||||
if (!player.hasLineOfSight(getEntity()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
double d = player.getLocation().distance(getLocation());
|
||||
|
||||
if (d > 2 && (target == null || dist > d))
|
||||
{
|
||||
target = player;
|
||||
dist = d;
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inProgress()
|
||||
{
|
||||
return _ticks < 14;
|
||||
}
|
||||
}
|
@ -0,0 +1,367 @@
|
||||
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Effect;
|
||||
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.CraftIronGolem;
|
||||
import org.bukkit.entity.IronGolem;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.event.inventory.InventoryPickupItemEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import mineplex.core.common.Pair;
|
||||
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.UtilMath;
|
||||
import mineplex.core.common.util.UtilParticle;
|
||||
import mineplex.core.common.util.UtilParticle.ParticleType;
|
||||
import mineplex.core.common.util.UtilParticle.ViewDist;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
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.game.clans.clans.worldevent.api.BossAbility;
|
||||
import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature;
|
||||
import net.minecraft.server.v1_8_R3.EntityIronGolem;
|
||||
|
||||
public class GolemRupture extends BossAbility<GolemCreature, IronGolem>
|
||||
{
|
||||
private List<Pair<Location, Location>> _ruptures = new ArrayList<>();
|
||||
private Map<Location, Long> _ruptureTime = new HashMap<>();
|
||||
private List<String> _targetted = new ArrayList<>();
|
||||
private int _rupturesLeft;
|
||||
private int _tick;
|
||||
private List<Item> _items = new ArrayList<>();
|
||||
private int _ticksFinished;
|
||||
|
||||
public GolemRupture(GolemCreature creature)
|
||||
{
|
||||
super(creature);
|
||||
|
||||
if (creature.getHealthPercent() > 0.75)
|
||||
{
|
||||
_rupturesLeft = 2;
|
||||
}
|
||||
else if (creature.getHealthPercent() > 0.5)
|
||||
{
|
||||
_rupturesLeft = 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
_rupturesLeft = 10;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMove()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void HopperPickup(InventoryPickupItemEvent event)
|
||||
{
|
||||
if (_items.contains(event.getItem()))
|
||||
{
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@EventHandler
|
||||
public void ItemDestroy(UpdateEvent event)
|
||||
{
|
||||
if (event.getType() != UpdateType.TICK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_items.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Iterator<Item> itemIterator = _items.iterator();
|
||||
|
||||
while (itemIterator.hasNext())
|
||||
{
|
||||
Item item = itemIterator.next();
|
||||
|
||||
if (item.isDead() || !item.isValid())
|
||||
{
|
||||
item.remove();
|
||||
itemIterator.remove();
|
||||
}
|
||||
else if (UtilEnt.isGrounded(item) || item.getTicksLived() > 60)
|
||||
{
|
||||
item.getWorld().playEffect(item.getLocation(), Effect.STEP_SOUND, item.getItemStack().getTypeId());
|
||||
item.remove();
|
||||
itemIterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inProgress()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFinished()
|
||||
{
|
||||
return _rupturesLeft <= 0 && _ruptures.isEmpty() && --_ticksFinished <= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFinished()
|
||||
{
|
||||
for (Item item : _items)
|
||||
{
|
||||
item.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick()
|
||||
{
|
||||
Iterator<Pair<Location, Location>> itel = _ruptures.iterator();
|
||||
|
||||
while (itel.hasNext())
|
||||
{
|
||||
Pair<Location, Location> pair = itel.next();
|
||||
|
||||
if (pair.getLeft().distance(pair.getRight()) > 0)
|
||||
{
|
||||
Vector vec = pair.getRight().toVector().subtract(pair.getLeft().toVector());
|
||||
|
||||
if (vec.length() > 1)
|
||||
{
|
||||
vec = vec.normalize();
|
||||
}
|
||||
|
||||
pair.getLeft().add(vec);
|
||||
}
|
||||
|
||||
if (pair.getLeft().distance(pair.getRight()) < 0.1)
|
||||
{
|
||||
if (!_ruptureTime.containsKey(pair.getLeft()))
|
||||
{
|
||||
_ruptureTime.put(pair.getLeft(), System.currentTimeMillis());
|
||||
}
|
||||
else if (UtilTime.elapsed(_ruptureTime.get(pair.getLeft()), 150))
|
||||
{
|
||||
itel.remove();
|
||||
|
||||
explodeRupture(pair.getLeft());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_tick % 10 == 0 && _rupturesLeft > 0)
|
||||
{
|
||||
_rupturesLeft--;
|
||||
|
||||
Location loc = getLocation().add(UtilMath.random.nextFloat() - 0.5, 0, UtilMath.random.nextFloat() - 0.5);
|
||||
|
||||
loc.setY(loc.getBlockY());
|
||||
|
||||
for (int y = 0; y > -3; y--)
|
||||
{
|
||||
if (!UtilBlock.airFoliage(loc.getBlock().getRelative(0, y, 0)))
|
||||
{
|
||||
loc.setY(loc.getY() + y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Player player = getTarget();
|
||||
|
||||
if (player != null)
|
||||
{
|
||||
_targetted.add(player.getName());
|
||||
|
||||
Location target = player.getLocation();
|
||||
target.setY(loc.getY());
|
||||
|
||||
_ruptures.add(Pair.create(loc, target));
|
||||
|
||||
UtilEnt.CreatureLook(getEntity(), player.getLocation());
|
||||
|
||||
EntityIronGolem golem = ((CraftIronGolem) getEntity()).getHandle();
|
||||
|
||||
golem.world.broadcastEntityEffect(golem, (byte) 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
_rupturesLeft = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (Pair<Location, Location> pair : _ruptures)
|
||||
{
|
||||
pair.getLeft().getWorld().playSound(pair.getLeft(), Sound.DIG_GRAVEL, 2.5F, 0.9F);
|
||||
|
||||
{
|
||||
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.DIRT, 0),
|
||||
pair.getLeft().clone().add(0, 1.1, 0), 1F, 0, 1F, 0, 70, ViewDist.NORMAL, UtilServer.getPlayers());
|
||||
}
|
||||
}
|
||||
|
||||
_tick++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player getTarget()
|
||||
{
|
||||
Player target = null;
|
||||
double dist = 0;
|
||||
|
||||
for (Player player : UtilPlayer.getNearby(getLocation(), 30, true))
|
||||
{
|
||||
if (!player.hasLineOfSight(getEntity()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_targetted.contains(player.getName()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
double d = player.getLocation().distance(getLocation());
|
||||
|
||||
if (d < 7)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean valid = true;
|
||||
|
||||
for (Pair<Location, Location> loc : _ruptures)
|
||||
{
|
||||
if (loc.getRight().distance(player.getLocation()) < 1.5)
|
||||
{
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!valid)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (target == null || dist > d)
|
||||
{
|
||||
target = player;
|
||||
dist = d;
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private void explodeRupture(Location loc)
|
||||
{
|
||||
loc.add(0, 1.1, 0);
|
||||
loc.setX(loc.getBlockX() + 0.5);
|
||||
loc.setZ(loc.getBlockZ() + 0.5);
|
||||
|
||||
// Fling
|
||||
HashMap<LivingEntity, Double> targets = UtilEnt.getInRadius(loc, 3.5);
|
||||
for (LivingEntity cur : targets.keySet())
|
||||
{
|
||||
// Velocity
|
||||
UtilAction.velocity(cur,
|
||||
UtilAlg.getTrajectory2d(loc.toVector().add(new Vector(0.5, 0, 0.5)), cur.getLocation().toVector()),
|
||||
0.8 + 0.8 * targets.get(cur), true, 0, 0.4 + 1.0 * targets.get(cur), 1.4, true);
|
||||
|
||||
// Condition
|
||||
getBoss().getEvent().getCondition().Factory().Falling("Rupture", cur, getEntity(), 10, false, true);
|
||||
|
||||
// Damage Event
|
||||
getBoss().getEvent().getDamageManager().NewDamageEvent(cur, getEntity(), null, DamageCause.CUSTOM,
|
||||
8 * getBoss().getDifficulty(), false, true, false, "Iron Wizard", "Rupture");
|
||||
}
|
||||
|
||||
List<Block> blocks = new ArrayList<>();
|
||||
|
||||
for (int x = -3; x <= 3; x++)
|
||||
{
|
||||
for (int z = -3; z <= 3; z++)
|
||||
{
|
||||
for (int y = 0; y <= 1; y++)
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (Math.sqrt(x * x + z * z + y * y) <= 3)
|
||||
{
|
||||
blocks.add(loc.clone().add(x, y, z).getBlock());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Collections.shuffle(blocks);
|
||||
|
||||
// Blocks
|
||||
int done = 0;
|
||||
Iterator<Block> itel = blocks.iterator();
|
||||
|
||||
while (done < 30 && itel.hasNext())
|
||||
{
|
||||
Block block = itel.next();
|
||||
|
||||
Vector vec = new Vector(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5).normalize();
|
||||
|
||||
if (!UtilBlock.airFoliage(block))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add Directional
|
||||
vec.add(UtilAlg.getTrajectory(loc.getBlock().getLocation(), block.getLocation().add(0.5, 0, 0.5)));
|
||||
|
||||
// Add Up
|
||||
vec.add(new Vector(0, 1.6, 0));
|
||||
|
||||
vec.normalize();
|
||||
|
||||
// Scale
|
||||
vec.multiply(0.1 + 0.3 * Math.random() + 0.6);
|
||||
|
||||
// Block!
|
||||
Item item = loc.getWorld().dropItem(block.getLocation().add(0.5, 0, 0.5), new ItemStack(Material.DIRT, 0));
|
||||
item.setVelocity(vec);
|
||||
item.setPickupDelay(50000);
|
||||
_items.add(item);
|
||||
|
||||
// Effect
|
||||
loc.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, Material.STONE.getId());
|
||||
|
||||
done++;
|
||||
}
|
||||
|
||||
_ticksFinished = 20;
|
||||
}
|
||||
}
|
@ -0,0 +1,271 @@
|
||||
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.IronGolem;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.event.inventory.InventoryPickupItemEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
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.UtilPlayer;
|
||||
import mineplex.core.updater.UpdateType;
|
||||
import mineplex.core.updater.event.UpdateEvent;
|
||||
import mineplex.game.clans.clans.worldevent.api.BossAbility;
|
||||
import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature;
|
||||
|
||||
public class GolemSlam extends BossAbility<GolemCreature, IronGolem>
|
||||
{
|
||||
private List<Item> _items = new ArrayList<>();
|
||||
private int _ticksFinished;
|
||||
private int _stage;
|
||||
private Vector _target;
|
||||
private int _ticksJumped;
|
||||
|
||||
public GolemSlam(GolemCreature creature)
|
||||
{
|
||||
super(creature);
|
||||
|
||||
Player target = getTarget();
|
||||
|
||||
if (target != null)
|
||||
{
|
||||
_target = UtilAlg.calculateVelocity(getLocation().toVector(),
|
||||
target.getLocation().toVector().setY(getLocation().getY()), 2, getEntity());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMove()
|
||||
{
|
||||
return !UtilEnt.isGrounded(getEntity()) && _stage == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFinished()
|
||||
{
|
||||
return _stage == 2 && --_ticksFinished <= 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFinished()
|
||||
{
|
||||
for (Item item : _items)
|
||||
{
|
||||
item.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick()
|
||||
{
|
||||
Entity entity = getEntity();
|
||||
|
||||
if (_stage == 0)
|
||||
{
|
||||
UtilEnt.CreatureLook(getEntity(), getLocation().add(_target));
|
||||
|
||||
entity.getWorld().playSound(entity.getLocation(), Sound.IRONGOLEM_THROW, 4, 0);
|
||||
|
||||
entity.setVelocity(_target);
|
||||
_stage++;
|
||||
}
|
||||
else if (_stage == 1)
|
||||
{
|
||||
_ticksJumped++;
|
||||
|
||||
if (_ticksJumped > 4 && getLocation().subtract(0, 0.2, 0).getBlock().getType() != Material.AIR)
|
||||
{
|
||||
explodeRupture(getLocation());
|
||||
|
||||
_stage = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void HopperPickup(InventoryPickupItemEvent event)
|
||||
{
|
||||
if (_items.contains(event.getItem()))
|
||||
{
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@EventHandler
|
||||
public void ItemDestroy(UpdateEvent event)
|
||||
{
|
||||
if (event.getType() != UpdateType.TICK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_items.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Iterator<Item> itemIterator = _items.iterator();
|
||||
|
||||
while (itemIterator.hasNext())
|
||||
{
|
||||
Item item = itemIterator.next();
|
||||
|
||||
if (item.isDead() || !item.isValid())
|
||||
{
|
||||
item.remove();
|
||||
itemIterator.remove();
|
||||
}
|
||||
else if (UtilEnt.isGrounded(item) || item.getTicksLived() > 60)
|
||||
{
|
||||
item.getWorld().playEffect(item.getLocation(), Effect.STEP_SOUND, item.getItemStack().getTypeId());
|
||||
item.remove();
|
||||
itemIterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inProgress()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player getTarget()
|
||||
{
|
||||
Player target = null;
|
||||
double dist = 0;
|
||||
|
||||
for (Player player : UtilPlayer.getNearby(getLocation(), 30, true))
|
||||
{
|
||||
if (!player.hasLineOfSight(getEntity()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
double d = player.getLocation().distance(getLocation());
|
||||
|
||||
if (d < 10)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (target == null || dist > d)
|
||||
{
|
||||
target = player;
|
||||
dist = d;
|
||||
}
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private void explodeRupture(Location loc)
|
||||
{
|
||||
loc.add(0, 1.1, 0);
|
||||
loc.setX(loc.getBlockX() + 0.5);
|
||||
loc.setZ(loc.getBlockZ() + 0.5);
|
||||
|
||||
// Fling
|
||||
Map<LivingEntity, Double> targets = UtilEnt.getInRadius(loc, 3.5);
|
||||
for (LivingEntity cur : targets.keySet())
|
||||
{
|
||||
if (cur.equals(getEntity()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Velocity
|
||||
UtilAction.velocity(cur,
|
||||
UtilAlg.getTrajectory2d(loc.toVector().add(new Vector(0.5, 0, 0.5)), cur.getLocation().toVector()),
|
||||
0.8 + 0.8 * targets.get(cur), true, 0, 0.4 + 1.0 * targets.get(cur), 1.4, true);
|
||||
|
||||
// Condition
|
||||
getBoss().getEvent().getCondition().Factory().Falling("Rupture", cur, getEntity(), 10, false, true);
|
||||
|
||||
// Damage Event
|
||||
getBoss().getEvent().getDamageManager().NewDamageEvent(cur, getEntity(), null, DamageCause.CUSTOM,
|
||||
8 * getBoss().getDifficulty(), false, true, false, "Iron Wizard", "Rupture");
|
||||
}
|
||||
|
||||
List<Block> blocks = new ArrayList<Block>();
|
||||
|
||||
for (int x = -3; x <= 3; x++)
|
||||
{
|
||||
for (int z = -3; z <= 3; z++)
|
||||
{
|
||||
for (int y = 0; y <= 1; y++)
|
||||
{
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (Math.sqrt(x * x + z * z + y * y) <= 3)
|
||||
{
|
||||
blocks.add(loc.clone().add(x, y, z).getBlock());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Collections.shuffle(blocks);
|
||||
|
||||
// Blocks
|
||||
int done = 0;
|
||||
Iterator<Block> itel = blocks.iterator();
|
||||
|
||||
while (done < 30 && itel.hasNext())
|
||||
{
|
||||
Block block = itel.next();
|
||||
|
||||
Vector vec = new Vector(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5).normalize();
|
||||
|
||||
if (!UtilBlock.airFoliage(block))
|
||||
continue;
|
||||
|
||||
// Add Directional
|
||||
vec.add(UtilAlg.getTrajectory(loc.getBlock().getLocation(), block.getLocation().add(0.5, 0, 0.5)));
|
||||
|
||||
// Add Up
|
||||
vec.add(new Vector(0, 1.6, 0));
|
||||
|
||||
vec.normalize();
|
||||
|
||||
// Scale
|
||||
vec.multiply(0.1 + 0.3 * Math.random() + 0.6);
|
||||
|
||||
// Block!
|
||||
Item item = loc.getWorld().dropItem(block.getLocation().add(0.5, 0, 0.5), new ItemStack(Material.DIRT, 0));
|
||||
item.setVelocity(vec);
|
||||
item.setPickupDelay(50000);
|
||||
_items.add(item);
|
||||
|
||||
// Effect
|
||||
loc.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, Material.DIRT.getId());
|
||||
|
||||
done++;
|
||||
}
|
||||
|
||||
_ticksFinished = 20;
|
||||
}
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.IronGolem;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import mineplex.core.common.util.UtilAction;
|
||||
import mineplex.core.common.util.UtilEnt;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.core.common.util.UtilTime;
|
||||
import mineplex.game.clans.clans.worldevent.api.BossAbility;
|
||||
import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature;
|
||||
|
||||
public class GolemSpike extends BossAbility<GolemCreature, IronGolem>
|
||||
{
|
||||
private static final int SPIKE_HEIGHT = 2;
|
||||
private static final long ATTACK_DURATION = 1000 + (500 * SPIKE_HEIGHT * 2);
|
||||
private static final long SPIKE_REMAIN = 1000;
|
||||
private long _start;
|
||||
private List<GroundSpike> _spikes;
|
||||
|
||||
public GolemSpike(GolemCreature creature)
|
||||
{
|
||||
super(creature);
|
||||
_start = System.currentTimeMillis();
|
||||
_spikes = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCooldown()
|
||||
{
|
||||
return 15;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMove()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inProgress()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFinished()
|
||||
{
|
||||
return UtilTime.elapsed(_start, ATTACK_DURATION) && _spikes.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFinished()
|
||||
{
|
||||
_start = System.currentTimeMillis() - ATTACK_DURATION;
|
||||
for (GroundSpike spike : _spikes)
|
||||
{
|
||||
spike.finish();
|
||||
}
|
||||
_spikes.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick()
|
||||
{
|
||||
if (_spikes.isEmpty())
|
||||
{
|
||||
for (Player player : UtilPlayer.getInRadius(getLocation(), 20).keySet())
|
||||
{
|
||||
if (UtilEnt.isGrounded(player))
|
||||
{
|
||||
player.playSound(player.getLocation(), Sound.STEP_STONE, 0.2f, 0.2f);
|
||||
getBoss().getEvent().getDamageManager().NewDamageEvent(player, getBoss().getEntity(), null, DamageCause.CUSTOM, 5 * getBoss().getDifficulty(), false, false, false, getBoss().getEntity().getName(), "Stone Spike");
|
||||
player.teleport(player.getLocation().add(0, SPIKE_HEIGHT, 0));
|
||||
UtilAction.velocity(player, player.getLocation().toVector().normalize().add(new Vector(0, 0.02, 0)).normalize());
|
||||
_spikes.add(new GroundSpike(player.getLocation().getBlock(), player.getLocation().getBlock().getRelative(0, -1, 0).getType(), new Random().nextInt(SPIKE_HEIGHT) + 2, SPIKE_REMAIN));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
List<GroundSpike> toRemove = new ArrayList<>();
|
||||
for (GroundSpike spike : _spikes)
|
||||
{
|
||||
spike.tick();
|
||||
if (spike.isFinished())
|
||||
{
|
||||
toRemove.add(spike);
|
||||
}
|
||||
}
|
||||
for (GroundSpike remove : toRemove)
|
||||
{
|
||||
_spikes.remove(remove);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,419 @@
|
||||
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.FallingBlock;
|
||||
import org.bukkit.entity.IronGolem;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
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.UtilMath;
|
||||
import mineplex.core.common.util.UtilParticle;
|
||||
import mineplex.core.common.util.UtilParticle.ParticleType;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
import mineplex.core.common.util.UtilShapes;
|
||||
import mineplex.core.common.util.UtilTime;
|
||||
import mineplex.core.updater.UpdateType;
|
||||
import mineplex.core.updater.event.UpdateEvent;
|
||||
import mineplex.game.clans.clans.worldevent.api.BossAbility;
|
||||
import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemCreature;
|
||||
import net.minecraft.server.v1_8_R3.AxisAlignedBB;
|
||||
import net.minecraft.server.v1_8_R3.MathHelper;
|
||||
import net.minecraft.server.v1_8_R3.MovingObjectPosition;
|
||||
import net.minecraft.server.v1_8_R3.Vec3D;
|
||||
|
||||
public class GolemWallExplode extends BossAbility<GolemCreature, IronGolem>
|
||||
{
|
||||
private Map<BlockFace, List<Block>> _blockWalls = new HashMap<>();
|
||||
private List<String> _dontTarget = new ArrayList<>();
|
||||
private List<FallingBlock> _fallingBlocks = new ArrayList<>();
|
||||
private int _maxTimes = UtilMath.r(2) + 1;
|
||||
private int _tick;
|
||||
private int _timesDone;
|
||||
private Map<BlockFace, Long> _wallTimers = new HashMap<>();
|
||||
|
||||
public GolemWallExplode(GolemCreature creature)
|
||||
{
|
||||
super(creature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMove()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCooldown()
|
||||
{
|
||||
return 20;
|
||||
}
|
||||
|
||||
private float getMod(int div)
|
||||
{
|
||||
return UtilMath.random.nextFloat() / div;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player getTarget()
|
||||
{
|
||||
for (Player player : UtilPlayer.getNearby(getLocation(), 15, true))
|
||||
{
|
||||
if (_dontTarget.contains(player.getName()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (player.getLocation().distance(getLocation()) <= 4)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return player;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFinished()
|
||||
{
|
||||
return _wallTimers.isEmpty() && _fallingBlocks.isEmpty() && _timesDone >= _maxTimes;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@EventHandler
|
||||
public void onUpdate(UpdateEvent event)
|
||||
{
|
||||
if (event.getType() != UpdateType.TICK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Iterator<FallingBlock> fallingIterator = _fallingBlocks.iterator();
|
||||
|
||||
while (fallingIterator.hasNext())
|
||||
{
|
||||
FallingBlock cur = fallingIterator.next();
|
||||
|
||||
if (cur.isDead() || !cur.isValid() || cur.getTicksLived() > 400
|
||||
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
|
||||
{
|
||||
fallingIterator.remove();
|
||||
|
||||
Block block = cur.getLocation().getBlock();
|
||||
block.setTypeIdAndData(0, (byte) 0, true);
|
||||
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
|
||||
|
||||
// Expire
|
||||
if (cur.getTicksLived() > 400
|
||||
|| !cur.getWorld().isChunkLoaded(cur.getLocation().getBlockX() >> 4, cur.getLocation().getBlockZ() >> 4))
|
||||
{
|
||||
cur.remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
cur.remove();
|
||||
continue;
|
||||
}
|
||||
|
||||
double distanceToEntity = 0.0D;
|
||||
LivingEntity victim = null;
|
||||
|
||||
net.minecraft.server.v1_8_R3.Entity nmsEntity = ((CraftEntity) cur).getHandle();
|
||||
Vec3D vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
|
||||
Vec3D vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY,
|
||||
nmsEntity.locZ + nmsEntity.motZ);
|
||||
|
||||
MovingObjectPosition finalObjectPosition = nmsEntity.world.rayTrace(vec3d, vec3d1, false, true, false);
|
||||
vec3d = new Vec3D(nmsEntity.locX, nmsEntity.locY, nmsEntity.locZ);
|
||||
vec3d1 = new Vec3D(nmsEntity.locX + nmsEntity.motX, nmsEntity.locY + nmsEntity.motY, nmsEntity.locZ + nmsEntity.motZ);
|
||||
|
||||
if (finalObjectPosition != null)
|
||||
{
|
||||
vec3d1 = new Vec3D(finalObjectPosition.pos.a, finalObjectPosition.pos.b, finalObjectPosition.pos.c);
|
||||
}
|
||||
|
||||
for (Object entity : ((CraftWorld) cur.getWorld()).getHandle().getEntities(((CraftEntity) cur).getHandle(),
|
||||
((CraftEntity) cur).getHandle().getBoundingBox().a(((CraftEntity) cur).getHandle().motX,
|
||||
((CraftEntity) cur).getHandle().motY, ((CraftEntity) cur).getHandle().motZ).grow(2, 2, 2)))
|
||||
{
|
||||
Entity bukkitEntity = ((net.minecraft.server.v1_8_R3.Entity) entity).getBukkitEntity();
|
||||
|
||||
if (bukkitEntity instanceof LivingEntity)
|
||||
{
|
||||
LivingEntity ent = (LivingEntity) bukkitEntity;
|
||||
|
||||
// Avoid Self
|
||||
if (ent.equals(getEntity()))
|
||||
continue;
|
||||
|
||||
// Creative or Spec
|
||||
if (ent instanceof Player)
|
||||
if (((Player) ent).getGameMode() == GameMode.CREATIVE || UtilPlayer.isSpectator(ent))
|
||||
continue;
|
||||
|
||||
// float f1 = (float)(nmsEntity.boundingBox.a() * 0.6f);
|
||||
AxisAlignedBB axisalignedbb1 = ((CraftEntity) ent).getHandle().getBoundingBox().grow(1F, 1F, 1F);
|
||||
MovingObjectPosition entityCollisionPosition = axisalignedbb1.a(vec3d, vec3d1);
|
||||
|
||||
if (entityCollisionPosition != null)
|
||||
{
|
||||
double d1 = vec3d.distanceSquared(entityCollisionPosition.pos);
|
||||
if ((d1 < distanceToEntity) || (distanceToEntity == 0.0D))
|
||||
{
|
||||
victim = ent;
|
||||
distanceToEntity = d1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (victim != null)
|
||||
{
|
||||
cur.getWorld().playEffect(victim.getEyeLocation().subtract(0, 0.5, 0), Effect.STEP_SOUND, cur.getBlockId());
|
||||
|
||||
if (canDamage(victim))
|
||||
{
|
||||
getBoss().getEvent().getDamageManager().NewDamageEvent((LivingEntity) victim, getEntity(), null,
|
||||
DamageCause.CONTACT, 10 * getBoss().getDifficulty(), true, true, false, "Iron Wizard Wall Explosion",
|
||||
"Iron Wizard Wall Explosion");
|
||||
}
|
||||
|
||||
cur.remove();
|
||||
fallingIterator.remove();
|
||||
|
||||
Vector vec = cur.getVelocity();
|
||||
|
||||
UtilAction.velocity(victim, vec, 1.5, true, 0, 0.2, 1, true);
|
||||
}
|
||||
else if (finalObjectPosition != null)
|
||||
{
|
||||
Block block = cur.getWorld().getBlockAt(((int) finalObjectPosition.pos.a), ((int) finalObjectPosition.pos.b), ((int) finalObjectPosition.pos.c));
|
||||
|
||||
if (!UtilBlock.airFoliage(block) && !block.isLiquid())
|
||||
{
|
||||
nmsEntity.motX = ((float) (finalObjectPosition.pos.a - nmsEntity.locX));
|
||||
nmsEntity.motY = ((float) (finalObjectPosition.pos.b - nmsEntity.locY));
|
||||
nmsEntity.motZ = ((float) (finalObjectPosition.pos.c - nmsEntity.locZ));
|
||||
float f2 = MathHelper.sqrt(
|
||||
nmsEntity.motX * nmsEntity.motX + nmsEntity.motY * nmsEntity.motY + nmsEntity.motZ * nmsEntity.motZ);
|
||||
nmsEntity.locX -= nmsEntity.motX / f2 * 0.0500000007450581D;
|
||||
nmsEntity.locY -= nmsEntity.motY / f2 * 0.0500000007450581D;
|
||||
nmsEntity.locZ -= nmsEntity.motZ / f2 * 0.0500000007450581D;
|
||||
|
||||
cur.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, cur.getBlockId());
|
||||
cur.remove();
|
||||
fallingIterator.remove();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UtilParticle.PlayParticle(ParticleType.BLOCK_DUST.getParticle(Material.STONE, 0),
|
||||
cur.getLocation().add(0, 0.5, 0), 0.3F, 0.3F, 0.3F, 0, 2, UtilParticle.ViewDist.NORMAL,
|
||||
UtilServer.getPlayers());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFinished()
|
||||
{
|
||||
for (FallingBlock block : _fallingBlocks)
|
||||
{
|
||||
block.remove();
|
||||
}
|
||||
|
||||
for (List<Block> list : _blockWalls.values())
|
||||
{
|
||||
for (Block b : list)
|
||||
{
|
||||
b.setType(Material.AIR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void tick()
|
||||
{
|
||||
if (_tick++ % 30 == 0 && _timesDone < _maxTimes)
|
||||
{
|
||||
_dontTarget.clear();
|
||||
|
||||
_timesDone++;
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
Player target = getTarget();
|
||||
|
||||
if (target == null)
|
||||
{
|
||||
if (_dontTarget.isEmpty())
|
||||
{
|
||||
_timesDone = _maxTimes;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_dontTarget.add(target.getName());
|
||||
|
||||
UtilEnt.CreatureLook(getEntity(), target);
|
||||
|
||||
BlockFace face = UtilShapes.getFacing(getLocation().getYaw());
|
||||
|
||||
if (_wallTimers.containsKey(face))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ArrayList<Block> blocks = new ArrayList<Block>();
|
||||
|
||||
Location loc = getLocation().getBlock().getLocation().add(0.5, 0, 0.5);
|
||||
|
||||
int mul = (face.getModX() != 0 && face.getModZ() != 0) ? 2 : 3;
|
||||
|
||||
loc.add(face.getModX() * mul, 0, face.getModZ() * mul);
|
||||
|
||||
Block b = loc.getBlock();
|
||||
|
||||
BlockFace sideFace = UtilShapes.getSideBlockFaces(face, true)[0];
|
||||
boolean invalid = false;
|
||||
|
||||
for (int mult = -3; mult <= 3; mult++)
|
||||
{
|
||||
Block block = b;
|
||||
|
||||
if (Math.abs(mult) < 3)
|
||||
{
|
||||
block = block.getRelative(face);
|
||||
}
|
||||
|
||||
block = block.getRelative(sideFace, mult);
|
||||
|
||||
if (Math.abs(mult) == 3 && face.getModX() != 0 && face.getModZ() != 0)
|
||||
{
|
||||
block = block.getRelative(UtilShapes.getSideBlockFaces(face, false)[mult < 0 ? 0 : 1]);
|
||||
}
|
||||
|
||||
if (!UtilAlg.HasSight(getLocation(), block.getLocation()))
|
||||
{
|
||||
invalid = true;
|
||||
break;
|
||||
}
|
||||
|
||||
Block under = block.getRelative(0, -1, 0);
|
||||
|
||||
if (!UtilBlock.solid(under))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int y = 0; y <= 1; y++)
|
||||
{
|
||||
block = block.getRelative(0, y, 0);
|
||||
|
||||
if (block.getType() != Material.AIR)
|
||||
{
|
||||
invalid = true;
|
||||
break;
|
||||
}
|
||||
|
||||
blocks.add(block);
|
||||
}
|
||||
|
||||
if (invalid)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (invalid)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (Block block : blocks)
|
||||
{
|
||||
block.setType(block.getWorld().getBlockAt(block.getX(), b.getY() - 1, block.getZ()).getType());
|
||||
block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getTypeId());
|
||||
}
|
||||
|
||||
_blockWalls.put(face, blocks);
|
||||
_wallTimers.put(face, System.currentTimeMillis());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Iterator<Entry<BlockFace, List<Block>>> itel = _blockWalls.entrySet().iterator();
|
||||
boolean doExplode = false;
|
||||
|
||||
while (itel.hasNext())
|
||||
{
|
||||
Entry<BlockFace, List<Block>> entry = itel.next();
|
||||
BlockFace face = entry.getKey();
|
||||
|
||||
if (UtilTime.elapsed(_wallTimers.get(face), 1000))
|
||||
{
|
||||
doExplode = true;
|
||||
itel.remove();
|
||||
_wallTimers.remove(face);
|
||||
|
||||
for (Block b : entry.getValue())
|
||||
{
|
||||
FallingBlock block = getEntity().getWorld().spawnFallingBlock(b.getLocation().add(0.5, 0, 0.5), b.getType(),
|
||||
(byte) 0);
|
||||
|
||||
block.setDropItem(false);
|
||||
|
||||
int index = entry.getValue().indexOf(b);
|
||||
|
||||
BlockFace f = index == 8 || index == 9 ? BlockFace.SELF
|
||||
: UtilShapes.getSideBlockFaces(face, true)[index > 6 ? 0 : 1];
|
||||
|
||||
block.setVelocity(new Vector((face.getModX() * 0.6) + (f.getModX() * (0.05 + getMod(10))), 0.2 + getMod(15),
|
||||
(face.getModZ() * 0.6) + (f.getModZ() * (0.05 + getMod(10)))));
|
||||
|
||||
_fallingBlocks.add(block);
|
||||
|
||||
b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, b.getTypeId());
|
||||
b.setType(Material.AIR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (doExplode)
|
||||
{
|
||||
onUpdate(new UpdateEvent(UpdateType.TICK));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean inProgress()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,122 @@
|
||||
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
import mineplex.core.common.util.UtilTime;
|
||||
|
||||
public class GroundSpike
|
||||
{
|
||||
private Block _initial;
|
||||
private Material _type;
|
||||
private int _max, _height;
|
||||
private long _lastTick, _remain;
|
||||
private LinkedList<Block> _blocks;
|
||||
private boolean _shrinking, _finished;
|
||||
|
||||
public GroundSpike(Block first, Material type, int maxHeight, long remainDuration)
|
||||
{
|
||||
_initial = first;
|
||||
_type = type;
|
||||
_height = 0;
|
||||
_max = maxHeight;
|
||||
_remain = remainDuration;
|
||||
_lastTick = System.currentTimeMillis();
|
||||
_blocks = new LinkedList<>();
|
||||
_shrinking = false;
|
||||
_finished = false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private void raise()
|
||||
{
|
||||
if ((_height + 1) < _max)
|
||||
{
|
||||
_lastTick = System.currentTimeMillis();
|
||||
Block b = _initial.getRelative(0, _height, 0);
|
||||
for (Player player : UtilServer.getPlayers())
|
||||
{
|
||||
player.sendBlockChange(b.getLocation(), _type, (byte)0);
|
||||
}
|
||||
_blocks.add(b);
|
||||
_height++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (UtilTime.elapsed(_lastTick, _remain))
|
||||
{
|
||||
_shrinking = true;
|
||||
lower();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private void lower()
|
||||
{
|
||||
_height = Math.min(_blocks.size() - 1, _height);
|
||||
if ((_height - 1) >= 0)
|
||||
{
|
||||
_lastTick = System.currentTimeMillis();
|
||||
for (Player player : UtilServer.getPlayers())
|
||||
{
|
||||
player.sendBlockChange(_blocks.get(_height).getLocation(), Material.AIR, (byte)0);
|
||||
}
|
||||
_blocks.remove(_height);
|
||||
_height--;
|
||||
}
|
||||
else
|
||||
{
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFinished()
|
||||
{
|
||||
if (!_blocks.isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return _finished;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void finish()
|
||||
{
|
||||
_finished = true;
|
||||
for (Block block : _blocks)
|
||||
{
|
||||
for (Player player : UtilServer.getPlayers())
|
||||
{
|
||||
player.sendBlockChange(block.getLocation(), Material.AIR, (byte)0);
|
||||
}
|
||||
}
|
||||
_blocks.clear();
|
||||
}
|
||||
|
||||
public void tick()
|
||||
{
|
||||
if (isFinished())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!UtilTime.elapsed(_lastTick, 500))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_shrinking)
|
||||
{
|
||||
lower();
|
||||
}
|
||||
else
|
||||
{
|
||||
raise();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package mineplex.game.clans.clans.worldevent.boss.ironwizard.abilities;
|
||||
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.IronGolem;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
|
||||
import mineplex.core.common.util.UtilAction;
|
||||
import mineplex.core.common.util.UtilAlg;
|
||||
import mineplex.core.projectile.IThrown;
|
||||
import mineplex.core.projectile.ProjectileUser;
|
||||
import mineplex.game.clans.clans.worldevent.api.WorldEvent;
|
||||
|
||||
public class IronHook implements IThrown
|
||||
{
|
||||
private WorldEvent _host;
|
||||
|
||||
public IronHook(WorldEvent event)
|
||||
{
|
||||
_host = event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Collide(LivingEntity target, Block block, ProjectileUser data)
|
||||
{
|
||||
data.getThrown().remove();
|
||||
|
||||
if (!(data.getThrower() instanceof IronGolem))
|
||||
return;
|
||||
|
||||
IronGolem wizard = (IronGolem)data.getThrower();
|
||||
|
||||
if (target == null)
|
||||
return;
|
||||
|
||||
UtilAction.velocity(target, UtilAlg.getTrajectory(target.getLocation(), wizard.getLocation()), 5, false, 0, 0.7, 1.2, true);
|
||||
|
||||
_host.getCondition().Factory().Falling("Iron Hook", target, wizard, 10, false, true);
|
||||
|
||||
_host.getDamageManager().NewDamageEvent(target, wizard, null, DamageCause.CUSTOM, 5, false, true, false, wizard.getName(), "Iron Hook");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Idle(ProjectileUser data)
|
||||
{
|
||||
data.getThrown().remove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Expire(ProjectileUser data)
|
||||
{
|
||||
data.getThrown().remove();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user