diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/ConcreteWorldEventFactory.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/ConcreteWorldEventFactory.java index 798574ea1..79ccccc15 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/ConcreteWorldEventFactory.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/ConcreteWorldEventFactory.java @@ -8,10 +8,17 @@ import mineplex.game.clans.clans.worldevent.event.boss.slime.SlimeBoss; public class ConcreteWorldEventFactory implements WorldEventFactory { + private WorldEventManager _eventManager; + + public ConcreteWorldEventFactory(WorldEventManager eventManager) + { + _eventManager = eventManager; + } + @Override public AbstractWorldEvent fromName(Location location, String name) { - return new SlimeBoss(location); + return new SlimeBoss(_eventManager, location); } @Override diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventManager.java index a23b9b2ec..acb47ce5c 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventManager.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventManager.java @@ -6,6 +6,7 @@ import java.util.Set; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; import org.bukkit.plugin.java.JavaPlugin; import mineplex.core.MiniPlugin; @@ -23,7 +24,7 @@ public class WorldEventManager extends MiniPlugin implements WorldEventListener { super("World Event", plugin); - _factory = new ConcreteWorldEventFactory(); + _factory = new ConcreteWorldEventFactory(this); _events = new HashSet(); } @@ -33,6 +34,7 @@ public class WorldEventManager extends MiniPlugin implements WorldEventListener event.start(); event.addListener(this); + getPlugin().getServer().getPluginManager().registerEvents(event, getPlugin()); _events.add(event); } @@ -48,6 +50,7 @@ public class WorldEventManager extends MiniPlugin implements WorldEventListener { // TODO Bukkit.broadcastMessage("World Event Manager On Complete"); + HandlerList.unregisterAll(event); _events.remove(event); } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/AbstractWorldEvent.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/AbstractWorldEvent.java index d79d6f40e..94ed1369f 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/AbstractWorldEvent.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/AbstractWorldEvent.java @@ -5,13 +5,14 @@ import java.util.List; import java.util.Random; import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; import org.bukkit.plugin.java.JavaPlugin; import mineplex.game.clans.clans.worldevent.WorldEventListener; import mineplex.game.clans.clans.worldevent.WorldEventManager; import mineplex.game.clans.clans.worldevent.event.state.EventState; -public abstract class AbstractWorldEvent +public abstract class AbstractWorldEvent implements Listener { private WorldEventManager _eventManager; @@ -101,13 +102,19 @@ public abstract class AbstractWorldEvent { JavaPlugin plugin = _eventManager.getPlugin(); - // Unregister old state listener - HandlerList.unregisterAll(_currentState); - _currentState.onStateStop(); + if (_currentState != null) + { + // Unregister old state listener + HandlerList.unregisterAll(_currentState); + _currentState.onStateStop(); + } - // Register new state listener - plugin.getServer().getPluginManager().registerEvents(state, plugin); - state.onStateStart(); + if (state != null) + { + // Register new state listener + plugin.getServer().getPluginManager().registerEvents(state, plugin); + state.onStateStart(); + } _currentState = state; } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/boss/AbstractBoss.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/boss/AbstractBoss.java index 5e3f133c5..3b888a50d 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/boss/AbstractBoss.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/boss/AbstractBoss.java @@ -86,6 +86,11 @@ public abstract class AbstractBoss extends AbstractWorldEvent return _maxHealth; } + public Location getCenter() + { + return _center; + } + public boolean inRange(Location loc) { return loc.distanceSquared(_center) <= _radiusSquared; diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/boss/slime/SlimeBoss.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/boss/slime/SlimeBoss.java index 33171229f..342c7abcd 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/boss/slime/SlimeBoss.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/boss/slime/SlimeBoss.java @@ -1,15 +1,32 @@ package mineplex.game.clans.clans.worldevent.event.boss.slime; +import java.util.List; + import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Slime; +import org.bukkit.entity.Spider; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent; +import mineplex.game.clans.clans.worldevent.WorldEventManager; import mineplex.game.clans.clans.worldevent.event.boss.AbstractBoss; +import mineplex.game.clans.clans.worldevent.event.boss.state.SlamState; public class SlimeBoss extends AbstractBoss { - public SlimeBoss(Location center) + private Slime _slimeEntity; + + public SlimeBoss(WorldEventManager eventManager, Location center) { - super("Giant", center, 20, 300); + super(eventManager, "Slime King", center, 100, 300); + + _slimeEntity = center.getWorld().spawn(center, Slime.class); + _slimeEntity.setSize(10); + _slimeEntity.setMaxHealth(100); + _slimeEntity.setHealth(100); } @Override @@ -29,12 +46,42 @@ public class SlimeBoss extends AbstractBoss { super.tick(); - damage(0.1); + if (!inRange(_slimeEntity.getLocation())) + { + _slimeEntity.teleport(getCenter()); + } + + if (getTicks() % (20 * 15) == 0) + { + List nearby = _slimeEntity.getNearbyEntities(10, 10, 10); + for (Entity near : nearby) + { + if (near instanceof Player) + { + Player player = ((Player) near); + Bukkit.broadcastMessage("SLAM ON " + player.getDisplayName()); + setState(new SlamState(this, _slimeEntity, player)); + break; + } + } + } + } + + @EventHandler + public void onSlimeDamage(EntityDamageEvent event) + { + if (event.getEntity().equals(_slimeEntity)) + { + _slimeEntity.setHealth(100); + damage(20); + event.setDamage(1); + } } @Override protected void onDeath() { + _slimeEntity.setHealth(0); Bukkit.broadcastMessage("GIANT DEATH"); } } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/boss/state/SlamState.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/boss/state/SlamState.java index 83d69c229..ee7566ac3 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/boss/state/SlamState.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/event/boss/state/SlamState.java @@ -1,23 +1,109 @@ package mineplex.game.clans.clans.worldevent.event.boss.state; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Sound; +import org.bukkit.entity.Creature; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.util.Vector; + +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilParticle; import mineplex.game.clans.clans.worldevent.event.boss.AbstractBoss; public class SlamState extends BossState { - public SlamState(AbstractBoss boss) + private static final int FOLLOW_TICKS = 60; + private static final int JUMP_TICKS = 80; + private static final int DIVE_TICKS = 20 * 5; + + private LivingEntity _entity; + private Player _target; + private Location _targetLocation; + + public SlamState(AbstractBoss boss, LivingEntity entity, Player target) { super(boss); + _entity = entity; + _target = target; } @Override public void onTick() { + if (getTicks() < FOLLOW_TICKS) + { + _targetLocation = _target.getLocation(); + } + else if (getTicks() == FOLLOW_TICKS) + { + Bukkit.broadcastMessage("TARGET LOCKED"); + } + else if (getTicks() == JUMP_TICKS) + { + Bukkit.broadcastMessage("SLIME BOSS JUMPED INTO THE AIR"); + } + else if (getTicks() > JUMP_TICKS && getTicks() < DIVE_TICKS) + { + Location loc = _entity.getLocation(); + loc.setDirection(loc.toVector().add(_targetLocation.toVector()).normalize()); + Vector direction = UtilAlg.getTrajectory2d(_entity.getLocation(), _targetLocation); + direction.multiply(0.4); + direction.setY(2 * (1 - ((getTicks() - 100.0) / 60.0))); + _entity.setVelocity(direction); + } + else if (getTicks() == DIVE_TICKS) + { + _entity.setVelocity(new Vector(0, -3, 0)); + } + if (_entity instanceof Creature) ((Creature) _entity).setTarget(_target); + + // display particles X + + double x = 0.5 * Math.sin(getTicks() / 10.0 * 2 * Math.PI); + double z = 0.5 * Math.cos(getTicks() / 10.0 * 2 * Math.PI); + Location loc = _targetLocation.clone().add(x, 0.1, z); + UtilParticle.PlayParticle(UtilParticle.ParticleType.FIREWORKS_SPARK, loc, 0, 0, 0, 0, 1); } + @Override public void onStateStart() { + Bukkit.broadcastMessage("Target placed on " + _target.getName()); + } + + + @EventHandler + public void onDamage(EntityDamageEvent event) + { + if (event.getEntity().equals(_entity) && event.getCause() == EntityDamageEvent.DamageCause.FALL) + { + Location fallLoc = _entity.getLocation(); + List nearby = _entity.getNearbyEntities(4, 4, 4); + for (Entity near : nearby) + { + if (near instanceof LivingEntity) + { + LivingEntity le = ((LivingEntity) near); + le.damage(4); + le.setVelocity(UtilAlg.getTrajectory2d(fallLoc, le.getLocation()).setY(0.2)); + } + } + + UtilParticle.PlayParticle(UtilParticle.ParticleType.LAVA, fallLoc, 2, 0.5F, 2, 0, 100); + fallLoc.getWorld().playSound(fallLoc, Sound.ANVIL_LAND, 10, 0.5F); + + event.setCancelled(true); + getBoss().setState(null); + } } @Override