diff --git a/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemDeadlyTremor.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemDeadlyTremor.java new file mode 100644 index 000000000..fb15c7567 --- /dev/null +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemDeadlyTremor.java @@ -0,0 +1,89 @@ +package mineplex.minecraft.game.core.boss.ironwizard.abilities; + +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.minecraft.game.core.boss.BossAbility; +import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature; + +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; + +public class GolemDeadlyTremor extends BossAbility +{ + private static final long ATTACK_DURATION = 16000; + 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(), 80).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()); + } + } + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemIronHook.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemIronHook.java new file mode 100644 index 000000000..fb8ffd2cc --- /dev/null +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemIronHook.java @@ -0,0 +1,170 @@ +package mineplex.minecraft.game.core.boss.ironwizard.abilities; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; + +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.itemstack.ItemStackFactory; +import mineplex.core.updater.UpdateType; +import mineplex.minecraft.game.core.boss.BossAbility; +import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature; + +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 com.google.common.collect.Lists; + +//2-3 people +//5 impact damage +//High pull velocity +//40 block range +public class GolemIronHook extends BossAbility +{ + private static final Integer MAX_TARGETS = 3; + private boolean _shot, _complete; + + private List _hooks = Lists.newArrayList(); + + public GolemIronHook(GolemCreature creature) + { + super(creature); + _shot = false; + _complete = false; + } + + private int getPosition(Player toAdd, LinkedList ordered, HashMap 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(); + LinkedList selections = new LinkedList<>(); + List targeted = Lists.newArrayList(); + + HashMap 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.addFirst(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(getBoss().getEvent().getPlugin(), new Runnable() + { + public void run() + { + _complete = true; + setFinished(); + } + }, 2 * 20); + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemSpike.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemSpike.java new file mode 100644 index 000000000..4059bb4e9 --- /dev/null +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GolemSpike.java @@ -0,0 +1,105 @@ +package mineplex.minecraft.game.core.boss.ironwizard.abilities; + +import java.util.List; +import java.util.Random; + +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.minecraft.game.core.boss.BossAbility; +import mineplex.minecraft.game.core.boss.ironwizard.GolemCreature; + +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 com.google.common.collect.Lists; + +public class GolemSpike extends BossAbility +{ + 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 _spikes; + + public GolemSpike(GolemCreature creature) + { + super(creature); + _start = System.currentTimeMillis(); + _spikes = Lists.newArrayList(); + } + + @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 toRemove = Lists.newArrayList(); + for (GroundSpike spike : _spikes) + { + spike.tick(); + if (spike.isFinished()) + { + toRemove.add(spike); + } + } + for (GroundSpike remove : toRemove) + { + _spikes.remove(remove); + } + } + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GroundSpike.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GroundSpike.java new file mode 100644 index 000000000..8aedd94de --- /dev/null +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/GroundSpike.java @@ -0,0 +1,102 @@ +package mineplex.minecraft.game.core.boss.ironwizard.abilities; + +import java.util.LinkedList; + +import mineplex.core.common.util.UtilTime; + +import org.bukkit.Material; +import org.bukkit.block.Block; + +public class GroundSpike +{ + private Block _initial; + private Material _type; + private int _max, _height; + private long _lastTick, _remain; + private LinkedList _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; + } + + private void raise() + { + if ((_height + 1) < _max) + { + _lastTick = System.currentTimeMillis(); + Block b = _initial.getRelative(0, _height, 0); + b.setType(_type); + _blocks.add(b); + _height++; + } + else + { + if (UtilTime.elapsed(_lastTick, _remain)) + { + _shrinking = true; + lower(); + } + } + } + + private void lower() + { + _height = Math.min(_blocks.size() - 1, _height); + if ((_height - 1) >= 0) + { + _lastTick = System.currentTimeMillis(); + _blocks.get(_height).setType(Material.AIR); + _blocks.remove(_height); + _height--; + } + else + { + finish(); + } + } + + public boolean isFinished() + { + if (!_blocks.isEmpty()) + return false; + + return _finished; + } + + public void finish() + { + _finished = true; + for (Block block : _blocks) + { + block.setType(Material.AIR); + } + _blocks.clear(); + } + + public void tick() + { + if (isFinished()) + return; + if (!UtilTime.elapsed(_lastTick, 500)) + return; + + if (_shrinking) + { + lower(); + } + else + { + raise(); + } + } +} \ No newline at end of file diff --git a/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/IronHook.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/IronHook.java new file mode 100644 index 000000000..9c402dab6 --- /dev/null +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/boss/ironwizard/abilities/IronHook.java @@ -0,0 +1,54 @@ +package mineplex.minecraft.game.core.boss.ironwizard.abilities; + +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.projectile.IThrown; +import mineplex.core.projectile.ProjectileUser; +import mineplex.minecraft.game.core.boss.WorldEvent; + +import org.bukkit.block.Block; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; + +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(); + } +} \ No newline at end of file