diff --git a/Plugins/.idea/artifacts/Mineplex_Game_Clans_jar.xml b/Plugins/.idea/artifacts/Mineplex_Game_Clans_jar.xml
index 85ea6bec4..d88c9bbd4 100644
--- a/Plugins/.idea/artifacts/Mineplex_Game_Clans_jar.xml
+++ b/Plugins/.idea/artifacts/Mineplex_Game_Clans_jar.xml
@@ -5,7 +5,6 @@
-
@@ -18,6 +17,7 @@
+
\ No newline at end of file
diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/Clans.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/Clans.java
index 6c61713e8..50714d661 100644
--- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/Clans.java
+++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/Clans.java
@@ -27,6 +27,7 @@ import mineplex.core.teleport.Teleport;
import mineplex.core.updater.FileUpdater;
import mineplex.core.updater.Updater;
import mineplex.game.clans.clans.ClansManager;
+import mineplex.game.clans.clans.worldevent.WorldEventManager;
import mineplex.game.clans.shop.building.BuildingShop;
import mineplex.game.clans.shop.pvp.PvpShop;
@@ -90,6 +91,8 @@ public class Clans extends JavaPlugin
new Farming(this);
new BuildingShop(clans, _clientManager, _donationManager);
new PvpShop(clans, _clientManager, _donationManager);
+
+ new WorldEventManager(this);
//Updates
getServer().getScheduler().scheduleSyncRepeatingTask(this, new Updater(this), 1, 1);
diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/AbstractWorldEvent.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/AbstractWorldEvent.java
new file mode 100644
index 000000000..42076e89b
--- /dev/null
+++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/AbstractWorldEvent.java
@@ -0,0 +1,69 @@
+package mineplex.game.clans.clans.worldevent;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class AbstractWorldEvent
+{
+ private List _listeners;
+
+ private boolean _running;
+ private int _ticks;
+
+ public AbstractWorldEvent()
+ {
+ _listeners = new ArrayList();
+ }
+
+ public final void start()
+ {
+ _running = true;
+ customStart();
+ }
+
+ protected abstract void customStart();
+
+ public final void cancel()
+ {
+ _running = false;
+ customCancel();
+ }
+
+ protected abstract void customCancel();
+
+ public void tick()
+ {
+ _ticks++;
+ }
+
+ public boolean isRunning()
+ {
+ return _running;
+ }
+
+ public void addListener(WorldEventListener listener)
+ {
+ _listeners.add(listener);
+ }
+
+ public void removeListener(WorldEventListener listener)
+ {
+ _listeners.remove(listener);
+ }
+
+ protected List getListeners()
+ {
+ return _listeners;
+ }
+
+ public void clearListeners()
+ {
+ _listeners.clear();
+ }
+
+ public int getTicks()
+ {
+ return _ticks;
+ }
+
+}
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
new file mode 100644
index 000000000..c44b682ef
--- /dev/null
+++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/ConcreteWorldEventFactory.java
@@ -0,0 +1,26 @@
+package mineplex.game.clans.clans.worldevent;
+
+import org.bukkit.Location;
+
+import mineplex.game.clans.clans.worldevent.boss.GiantBoss;
+
+public class ConcreteWorldEventFactory implements WorldEventFactory
+{
+ @Override
+ public AbstractWorldEvent fromName(Location location, String name)
+ {
+ return new GiantBoss(location);
+ }
+
+ @Override
+ public AbstractWorldEvent random(Location location)
+ {
+ return null;
+ }
+
+ @Override
+ public AbstractWorldEvent randomFromType(Location locationm, WorldEventType type)
+ {
+ return null;
+ }
+}
diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventFactory.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventFactory.java
new file mode 100644
index 000000000..1c63b90f6
--- /dev/null
+++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventFactory.java
@@ -0,0 +1,12 @@
+package mineplex.game.clans.clans.worldevent;
+
+import org.bukkit.Location;
+
+public interface WorldEventFactory
+{
+ public AbstractWorldEvent fromName(Location location, String name);
+
+ public AbstractWorldEvent random(Location location);
+
+ public AbstractWorldEvent randomFromType(Location locationm, WorldEventType type);
+}
diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventListener.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventListener.java
new file mode 100644
index 000000000..65ccc2331
--- /dev/null
+++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventListener.java
@@ -0,0 +1,6 @@
+package mineplex.game.clans.clans.worldevent;
+
+public interface WorldEventListener
+{
+ public void onComplete(AbstractWorldEvent event);
+}
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
new file mode 100644
index 000000000..34e102d19
--- /dev/null
+++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventManager.java
@@ -0,0 +1,69 @@
+package mineplex.game.clans.clans.worldevent;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.event.EventHandler;
+import org.bukkit.plugin.java.JavaPlugin;
+
+import mineplex.core.MiniPlugin;
+import mineplex.core.updater.UpdateType;
+import mineplex.core.updater.event.UpdateEvent;
+import mineplex.game.clans.clans.worldevent.command.WorldEventCommand;
+
+public class WorldEventManager extends MiniPlugin implements WorldEventListener
+{
+ private final WorldEventFactory _factory;
+ private final Set _events;
+
+ public WorldEventManager(JavaPlugin plugin)
+ {
+ super("World Event", plugin);
+
+ _factory = new ConcreteWorldEventFactory();
+ _events = new HashSet();
+ }
+
+ private void initializeEvent(AbstractWorldEvent event)
+ {
+ assert(event != null);
+
+ event.start();
+ event.addListener(this);
+ _events.add(event);
+ }
+
+ public AbstractWorldEvent startEventFromName(Location location, String name)
+ {
+ AbstractWorldEvent event = _factory.fromName(location, name);
+ if (event != null) initializeEvent(event);
+ return event;
+ }
+
+ @Override
+ public void onComplete(AbstractWorldEvent event)
+ {
+ // TODO
+ Bukkit.broadcastMessage("World Event Manager On Complete");
+ _events.remove(event);
+ }
+
+ @EventHandler
+ public void update(UpdateEvent event)
+ {
+ if (event.getType() != UpdateType.TICK) return;
+
+ for (AbstractWorldEvent e : _events)
+ {
+ e.tick();
+ }
+ }
+
+ @Override
+ public void addCommands()
+ {
+ addCommand(new WorldEventCommand(this));
+ }
+}
diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventType.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventType.java
new file mode 100644
index 000000000..322130393
--- /dev/null
+++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/WorldEventType.java
@@ -0,0 +1,6 @@
+package mineplex.game.clans.clans.worldevent;
+
+public enum WorldEventType
+{
+ BOSS_FIGHT;
+}
diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/AbstractBoss.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/AbstractBoss.java
new file mode 100644
index 000000000..5f48ea7a5
--- /dev/null
+++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/AbstractBoss.java
@@ -0,0 +1,90 @@
+package mineplex.game.clans.clans.worldevent.boss;
+
+import java.util.List;
+
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.entity.Player;
+
+import mineplex.core.common.util.UtilTextBottom;
+import mineplex.game.clans.clans.worldevent.AbstractWorldEvent;
+import mineplex.game.clans.clans.worldevent.WorldEventListener;
+
+public abstract class AbstractBoss extends AbstractWorldEvent
+{
+ private String _name;
+ private double _maxHealth;
+ private double _health;
+ private double _lastHealth;
+
+ // Action Bar Messages
+ private Location _center;
+ private float _radiusSquared;
+
+
+ public AbstractBoss(String name, Location center, float radius, double maxHealth)
+ {
+ _center = center;
+ _name = name;
+ _health = maxHealth;
+ _maxHealth = maxHealth;
+ setRadius(radius);
+ }
+
+ @Override
+ public void tick()
+ {
+ super.tick();
+
+ if (_lastHealth != _health || getTicks() % 20 == 0)
+ {
+ for (Player player : Bukkit.getServer().getOnlinePlayers())
+ {
+ if (player.getWorld().equals(_center.getWorld()) && _center.distanceSquared(player.getLocation()) < _radiusSquared)
+ {
+ UtilTextBottom.displayProgress(_name, _health / _maxHealth, player);
+ }
+ }
+ }
+
+ _lastHealth = _health;
+
+ if (_health <= 0)
+ {
+ onDeath();
+ for (WorldEventListener listener : getListeners()) listener.onComplete(this);
+ }
+ }
+
+ public void setRadius(float radius)
+ {
+ _radiusSquared = radius * radius;
+ }
+
+ protected abstract void onDeath();
+
+ protected void damage(double health)
+ {
+ _health -= health;
+ }
+
+ protected void setMaxHealth(double maxHealth)
+ {
+ _maxHealth = maxHealth;
+ }
+
+ public double getHealth()
+ {
+ return _health;
+ }
+
+ public double getMaxHealth()
+ {
+ return _maxHealth;
+ }
+
+ public boolean inRange(Location loc)
+ {
+ return loc.distanceSquared(_center) <= _radiusSquared;
+ }
+}
diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/GiantBoss.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/GiantBoss.java
new file mode 100644
index 000000000..a2a23b334
--- /dev/null
+++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/boss/GiantBoss.java
@@ -0,0 +1,38 @@
+package mineplex.game.clans.clans.worldevent.boss;
+
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+
+public class GiantBoss extends AbstractBoss
+{
+ public GiantBoss(Location center)
+ {
+ super("Giant", center, 20, 300);
+ }
+
+ @Override
+ protected void customStart()
+ {
+ Bukkit.broadcastMessage("Custom Start");
+ }
+
+ @Override
+ protected void customCancel()
+ {
+ Bukkit.broadcastMessage("Custom Cancel");
+ }
+
+ @Override
+ public void tick()
+ {
+ super.tick();
+
+ damage(0.1);
+ }
+
+ @Override
+ protected void onDeath()
+ {
+ Bukkit.broadcastMessage("GIANT DEATH");
+ }
+}
diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/command/StartCommand.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/command/StartCommand.java
new file mode 100644
index 000000000..0649bd563
--- /dev/null
+++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/command/StartCommand.java
@@ -0,0 +1,34 @@
+package mineplex.game.clans.clans.worldevent.command;
+
+import org.bukkit.entity.Player;
+
+import mineplex.core.command.CommandBase;
+import mineplex.core.common.Rank;
+import mineplex.core.common.util.F;
+import mineplex.core.common.util.UtilPlayer;
+import mineplex.game.clans.clans.worldevent.AbstractWorldEvent;
+import mineplex.game.clans.clans.worldevent.WorldEventManager;
+
+public class StartCommand extends CommandBase
+{
+ public StartCommand(WorldEventManager plugin)
+ {
+ super(plugin, Rank.DEVELOPER, "start", "create");
+ }
+
+ @Override
+ public void Execute(Player caller, String[] args)
+ {
+ // start specific world event type
+ if (args != null && args.length == 1)
+ {
+ AbstractWorldEvent event = Plugin.startEventFromName(caller.getLocation(), args[0]);
+ if (event == null)
+ UtilPlayer.message(caller, F.main("WorldEvent", "Could not find a WorldEvent with the name " + F.elem(args[0])));
+ else
+ {
+ UtilPlayer.message(caller, F.main("worldEvent", "Started WorldEvent " + F.elem(args[0]) + " at your current location"));
+ }
+ }
+ }
+}
diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/command/WorldEventCommand.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/command/WorldEventCommand.java
new file mode 100644
index 000000000..5a3e47de8
--- /dev/null
+++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/command/WorldEventCommand.java
@@ -0,0 +1,23 @@
+package mineplex.game.clans.clans.worldevent.command;
+
+import org.bukkit.entity.Player;
+
+import mineplex.core.command.MultiCommandBase;
+import mineplex.core.common.Rank;
+import mineplex.game.clans.clans.worldevent.WorldEventManager;
+
+public class WorldEventCommand extends MultiCommandBase
+{
+ public WorldEventCommand(WorldEventManager plugin)
+ {
+ super(plugin, Rank.DEVELOPER, "worldevent", "we", "event");
+
+ AddCommand(new StartCommand(Plugin));
+ }
+
+ @Override
+ protected void Help(Player caller, String[] args)
+ {
+
+ }
+}