Lots of world events!

This commit is contained in:
Sam 2017-02-26 17:16:16 +00:00
parent d4bdc3e5d1
commit 7760404b4e
12 changed files with 823 additions and 95 deletions

View File

@ -78,6 +78,7 @@ public class WorldListeners implements Listener
@EventHandler(priority = EventPriority.LOWEST)
public void blockPlace(BlockPlaceEvent event)
{
if (event.getBlockPlaced().getType() != Material.CAKE_BLOCK && event.getItemInHand() != null && event.getItemInHand().getType() != Material.FLINT_AND_STEEL && shouldBlock(event.getPlayer()))
{
event.setCancelled(true);
}

View File

@ -11,10 +11,15 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import mineplex.core.Managers;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTextMiddle;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.gemhunters.loot.LootModule;
import mineplex.gemhunters.world.WorldDataModule;
import mineplex.minecraft.game.core.damage.DamageManager;
public abstract class WorldEvent implements Listener
{
@ -23,12 +28,14 @@ public abstract class WorldEvent implements Listener
private WorldEventState _eventState;
protected final DamageManager _damage;
protected final LootModule _loot;
protected final WorldDataModule _worldData;
protected final WorldEventModule _worldEvent;
protected final Set<LivingEntity> _entities;
protected final long _start;
protected long _start;
private long _complete;
public WorldEvent(WorldEventType eventType)
@ -36,11 +43,12 @@ public abstract class WorldEvent implements Listener
_eventType = eventType;
_eventState = null;
_damage = Managers.get(DamageManager.class);
_loot = Managers.get(LootModule.class);
_worldData = Managers.get(WorldDataModule.class);
_worldEvent = Managers.get(WorldEventModule.class);
_entities = new HashSet<>();
_start = System.currentTimeMillis();
_worldEvent.registerEvents(this);
}
@ -51,23 +59,34 @@ public abstract class WorldEvent implements Listener
public abstract void onEnd();
public abstract Location getCurrentLocation();
public abstract Location[] getEventLocations();
public final void start()
private final void start()
{
if (isLive())
{
return;
}
UtilTextMiddle.display(C.cRed + _eventType.getName(), C.cGray + "World Event is starting!", 20, 60, 20);
UtilServer.broadcast(F.main(_worldEvent.getName(), "The " + F.elem(_eventType.getName()) + " world event is starting!"));
_start = System.currentTimeMillis();
onStart();
}
public final void end()
private final void end()
{
_complete = System.currentTimeMillis();
UtilServer.broadcast(F.main(_worldEvent.getName(), "The " + F.elem(_eventType.getName()) + " world event is over!"));
for (LivingEntity entity : _entities)
{
entity.damage(Double.MAX_VALUE);
entity.remove();
}
UtilServer.Unregister(this);
_entities.clear();
onEnd();
}
@ -108,6 +127,11 @@ public abstract class WorldEvent implements Listener
{
_eventState = eventState;
if (eventState == null)
{
return;
}
switch (eventState)
{
case WARMUP:
@ -115,14 +139,30 @@ public abstract class WorldEvent implements Listener
break;
case COMPLETE:
end();
break;
default:
break;
}
}
public boolean isEnabled()
{
return _eventState != null;
}
public boolean isWarmup()
{
return _eventState == WorldEventState.WARMUP;
}
public boolean isLive()
{
return _eventState == WorldEventState.LIVE;
}
public boolean isInProgress()
{
return _eventState == WorldEventState.WARMUP || _eventState == WorldEventState.LIVE;
return isWarmup() || isLive();
}
public WorldEventState getEventState()

View File

@ -1,6 +1,7 @@
package mineplex.gemhunters.worldevent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@ -15,14 +16,19 @@ import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilTime;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.gemhunters.worldevent.blizzard.BlizzardWorldEvent;
import mineplex.gemhunters.worldevent.command.WorldEventCommand;
import mineplex.gemhunters.worldevent.giant.GiantWorldEvent;
import mineplex.gemhunters.worldevent.gwenmart.GwenMartWorldEvent;
import mineplex.gemhunters.worldevent.nether.NetherPortalWorldEvent;
import mineplex.gemhunters.worldevent.wither.WitherWorldEvent;
@ReflectivelyCreateMiniPlugin
public class WorldEventModule extends MiniPlugin
{
private static final long EVENT_TIMER = TimeUnit.MINUTES.toMillis(30);
private static final long EVENT_COOLDOWN_TIMER = TimeUnit.MINUTES.toMillis(20);
private static final long EVENT_COOLDOWN_TIMER = TimeUnit.MINUTES.toMillis(40);
private static final long COMPLETE_TIMER = TimeUnit.SECONDS.toMillis(30);
private final List<WorldEvent> _events;
@ -32,7 +38,16 @@ public class WorldEventModule extends MiniPlugin
{
super("World Event");
_events = new ArrayList<>();
_events = Arrays.asList(
new GiantWorldEvent(),
new BlizzardWorldEvent(),
new NetherPortalWorldEvent(),
new WitherWorldEvent(),
new GwenMartWorldEvent()
);
_lastEventComplete = System.currentTimeMillis();
}
@ -44,9 +59,7 @@ public class WorldEventModule extends MiniPlugin
public void startEvent(WorldEventType eventType)
{
WorldEvent event = eventType.createInstance();
_events.add(event);
WorldEvent event = getEvent(eventType);
event.setEventState(WorldEventState.WARMUP);
}
@ -54,12 +67,11 @@ public class WorldEventModule extends MiniPlugin
public void startRandomEvent()
{
WorldEventType[] eventTypes = WorldEventType.values();
Set<WorldEventType> possibleWorldEvents = new HashSet<>();
for (WorldEventType eventType : eventTypes)
{
if (UtilTime.elapsed(eventType.getLast(), EVENT_COOLDOWN_TIMER))
if (UtilTime.elapsed(eventType.getLast(), EVENT_COOLDOWN_TIMER) || eventType.getPriority() == WorldEventPriority.TRIGGERED)
{
continue;
}
@ -91,10 +103,9 @@ public class WorldEventModule extends MiniPlugin
if (worldEvent.getEventState() == WorldEventState.COMPLETE && UtilTime.elapsed(worldEvent.getCompleteTime(), COMPLETE_TIMER))
{
iterator.remove();
worldEvent.setEventState(null);
}
if (worldEvent.getEventState() == WorldEventState.LIVE && worldEvent.checkToEnd())
else if (worldEvent.getEventState() == WorldEventState.LIVE && worldEvent.checkToEnd())
{
_lastEventComplete = System.currentTimeMillis();
worldEvent.setEventState(WorldEventState.COMPLETE);
@ -107,27 +118,37 @@ public class WorldEventModule extends MiniPlugin
}
}
public boolean isEventActive()
{
return !_events.isEmpty();
}
public boolean isGlboalEventActive()
public WorldEvent getEvent(WorldEventType eventType)
{
for (WorldEvent event : _events)
{
if (event.getEventType().getPriority() == WorldEventPriority.GLOBAL)
if (event.getEventType() == eventType)
{
return true;
return event;
}
}
return false;
return null;
}
public boolean isEventActive()
{
return !getActiveEvents().isEmpty();
}
public List<WorldEvent> getActiveEvents()
{
return _events;
List<WorldEvent> events = new ArrayList<>();
for (WorldEvent event : _events)
{
if (event.isInProgress())
{
events.add(event);
}
}
return events;
}
public long getLastEventComplete()

View File

@ -9,7 +9,7 @@ public enum WorldEventState
public String getName()
{
return Character.toUpperCase(name().charAt(0)) + name().substring(1);
return name().charAt(0) + name().toLowerCase().substring(1);
}
}

View File

@ -1,42 +1,27 @@
package mineplex.gemhunters.worldevent;
import mineplex.gemhunters.worldevent.giant.GiantWorldEvent;
public enum WorldEventType
{
GIANT("Zombie Awakening", GiantWorldEvent.class, WorldEventPriority.GLOBAL),
GIANT("Zombie Awakening", WorldEventPriority.TRIGGERED),
BLZZARD("Hurricane", WorldEventPriority.GLOBAL),
NETHER("Dark Portal", WorldEventPriority.TRIGGERED),
WITHER("Wither Temple", WorldEventPriority.TRIGGERED),
GWEN_MART("Gwen-Mart Mega Sale", WorldEventPriority.GLOBAL),
;
private String _name;
private Class<? extends WorldEvent> _clazz;
private WorldEventPriority _priority;
private long _last;
private WorldEventType(String name, Class<? extends WorldEvent> clazz, WorldEventPriority priority)
private WorldEventType(String name, WorldEventPriority priority)
{
_name = name;
_clazz = clazz;
_priority = priority;
_last = 0;
}
@SuppressWarnings("unchecked")
public <T> T createInstance()
{
try
{
_last = System.currentTimeMillis();
return (T) _clazz.getConstructor(this.getClass()).newInstance(this);
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
public String getName()
{
return _name;

View File

@ -0,0 +1,139 @@
package mineplex.gemhunters.worldevent.blizzard;
import java.util.concurrent.TimeUnit;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.weather.WeatherChangeEvent;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilItem;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTextBottom;
import mineplex.core.common.util.UtilTime;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.gemhunters.worldevent.WorldEvent;
import mineplex.gemhunters.worldevent.WorldEventState;
import mineplex.gemhunters.worldevent.WorldEventType;
public class BlizzardWorldEvent extends WorldEvent
{
private static final long MAX_TIME = TimeUnit.MINUTES.toMillis(10);
private static final long GRACE_TIME = TimeUnit.SECONDS.toMillis(60);
private static final int DAMAGE = 2;
private static final String TIP = "EQUIP LEATHER ARMOUR OR GET NEAR A FIRE";
private boolean _colour;
public BlizzardWorldEvent()
{
super(WorldEventType.BLZZARD);
}
@EventHandler
public void weatherChange(WeatherChangeEvent event)
{
if (event.toWeatherState() && isEnabled())
{
event.setCancelled(false);
}
}
@EventHandler
public void damage(UpdateEvent event)
{
if (!isInProgress())
{
return;
}
if (!UtilTime.elapsed(_start, GRACE_TIME))
{
if (event.getType() == UpdateType.SEC)
{
_colour = !_colour;
UtilTextBottom.display((_colour ? C.cRedB : C.cWhiteB) + "STORM COMING IN " + UtilTime.MakeStr(_start + GRACE_TIME - System.currentTimeMillis()) + " " + TIP, UtilServer.getPlayers());
}
}
else if (isWarmup())
{
setEventState(WorldEventState.LIVE);
World world = _worldData.World;
world.setStorm(true);
world.setThundering(true);
}
else if (event.getType() == UpdateType.SEC_05 && isLive())
{
for (Player player : Bukkit.getOnlinePlayers())
{
if (shouldDamage(player))
{
_damage.NewDamageEvent(player, null, null, DamageCause.CUSTOM, DAMAGE, false, true, true, "Hurricane", "Frostbite");
}
}
}
}
private boolean shouldDamage(Player player)
{
for (Block block : UtilBlock.getInBoundingBox(player.getLocation().add(4, 2, 4), player.getLocation().subtract(4, 0, 4)))
{
if (block.getType() == Material.FIRE)
{
return false;
}
}
for (ItemStack itemStack : player.getInventory().getArmorContents())
{
if (!UtilItem.isLeatherProduct(itemStack))
{
UtilTextBottom.display(C.cRedB + TIP, player);
player.sendMessage(F.main(_worldEvent.getName(), "Equip leather armor or get near a fire to stop taking damage!"));
return true;
}
}
return false;
}
@Override
public void onStart()
{
}
@Override
public boolean checkToEnd()
{
return UtilTime.elapsed(_start, MAX_TIME);
}
@Override
public void onEnd()
{
World world = _worldData.World;
world.setStorm(false);
world.setThundering(false);
}
@Override
public Location[] getEventLocations()
{
return null;
}
}

View File

@ -27,11 +27,20 @@ public class StartCommand extends CommandBase<WorldEventModule>
return;
}
String name = "";
for (int i = 0; i < args.length; i++)
{
name += args[i] + " ";
}
name = name.trim();
for (WorldEventType eventType : WorldEventType.values())
{
if (args[0].equalsIgnoreCase(eventType.name()))
if (name.equalsIgnoreCase(eventType.getName()))
{
caller.sendMessage(F.main(Plugin.getName(), "Starting the " + F.elem(eventType.name()) + " world event."));
caller.sendMessage(F.main(Plugin.getName(), "Starting the " + F.elem(eventType.getName()) + " world event."));
Plugin.startEvent(eventType);
return;
}
@ -41,7 +50,7 @@ public class StartCommand extends CommandBase<WorldEventModule>
for (WorldEventType eventType : WorldEventType.values())
{
caller.sendMessage(C.cGray + "- " + F.elem(eventType.name()));
caller.sendMessage(C.cGray + "- " + F.elem(eventType.getName()));
}
}

View File

@ -13,6 +13,7 @@ import org.bukkit.entity.Monster;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.util.Vector;
@ -27,18 +28,22 @@ import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.gemhunters.safezone.SafezoneModule;
import mineplex.gemhunters.spawn.SpawnModule;
import mineplex.minecraft.game.core.damage.DamageManager;
public class CustomGiant implements Listener
{
private static final int GIANT_HEALTH = 100;
private static final int GIANT_HEALTH = 500;
private static final int GIANT_WIDTH = 5;
private static final int GIANT_HEIGHT = 13;
private static final float DESTORY_FALLING_BLOCK_CHANCE = 0.04F;
private static final float MOVE_FACTOR = 0.3F;
private static final int MAX_SEARCH_DISTANCE_SQUARED = 2500;
private static final int TOO_CLOSE_DISTANCE_SQUARED = 625;
private static final int DAMAGE_RADIUS = 4;
private static final int DAMAGE = 4;
private final DamageManager _damage;
private final SafezoneModule _safezone;
private final Monster _giant;
@ -48,8 +53,10 @@ public class CustomGiant implements Listener
public CustomGiant(Location spawn)
{
_safezone = Managers.get(SafezoneModule.class);
_damage = Managers.require(DamageManager.class);
_safezone = Managers.require(SafezoneModule.class);
spawn.getChunk().load();
_giant = spawn.getWorld().spawn(spawn, Giant.class);
_giant.setMaxHealth(GIANT_HEALTH);
@ -101,7 +108,7 @@ public class CustomGiant implements Listener
}
@EventHandler
public void updateBlockDestrory(UpdateEvent event)
public void updateBlockDestroy(UpdateEvent event)
{
if (event.getType() != UpdateType.FASTER)
{
@ -128,6 +135,20 @@ public class CustomGiant implements Listener
}
}
@EventHandler
public void updateDamage(UpdateEvent event)
{
if (event.getType() != UpdateType.FASTER)
{
return;
}
for (Player player : UtilPlayer.getInRadius(_giant.getLocation(), DAMAGE_RADIUS).keySet())
{
_damage.NewDamageEvent(player, _giant, null, DamageCause.ENTITY_ATTACK, DAMAGE, true, true, false, UtilEnt.getName(_giant), "Zombie Awakening");
}
}
@EventHandler
public void playerQuit(PlayerQuitEvent event)
{

View File

@ -3,17 +3,25 @@ package mineplex.gemhunters.worldevent.giant;
import java.util.concurrent.TimeUnit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Zombie;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityCombustEvent;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.gemhunters.loot.rewards.LootChestReward;
import mineplex.gemhunters.worldevent.WorldEvent;
import mineplex.gemhunters.worldevent.WorldEventState;
import mineplex.gemhunters.worldevent.WorldEventType;
@ -21,15 +29,26 @@ import mineplex.gemhunters.worldevent.WorldEventType;
public class GiantWorldEvent extends WorldEvent
{
private static final float START_CHANCE = 0.01F;
private static final int MINI_ZOMBIES = 10;
private static final int MINI_ZOMBIES_MAX_DISTANCE_SQUARED = 2500;
private static final long MAX_TIME = TimeUnit.MINUTES.toMillis(5);
private static final long CASH_OUT_DELAY = TimeUnit.MINUTES.toMillis(10);
private CustomGiant _giant;
public GiantWorldEvent(WorldEventType eventType)
public GiantWorldEvent()
{
super(eventType);
super(WorldEventType.GIANT);
}
@EventHandler
public void trigger(PlayerDeathEvent event)
{
if (Math.random() < START_CHANCE)
{
setEventState(WorldEventState.WARMUP);
}
}
@Override
@ -52,12 +71,22 @@ public class GiantWorldEvent extends WorldEvent
@Override
public void onEnd()
{
ItemStack itemStack = new ItemBuilder(Material.SEA_LANTERN).setTitle(C.cAqua + "Omega Chest").build();
LootChestReward reward = new LootChestReward(CASH_OUT_DELAY, itemStack, "Omega", 1);
_worldData.World.dropItemNaturally(getEventLocations()[0], itemStack);
_loot.addItemReward(reward);
UtilServer.broadcast(F.main(_worldEvent.getName(), "The Giant has been killed! And has dropped loot!"));
UtilServer.Unregister(_giant);
_giant = null;
}
@Override
public Location getCurrentLocation()
public Location[] getEventLocations()
{
return _giant.getGiant().getLocation();
return new Location[] { _giant.getGiant().getLocation() };
}
@EventHandler

View File

@ -0,0 +1,134 @@
package mineplex.gemhunters.worldevent.gwenmart;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import mineplex.core.Managers;
import mineplex.core.blockrestore.BlockRestore;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTextBottom;
import mineplex.core.common.util.UtilTime;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.gemhunters.worldevent.WorldEvent;
import mineplex.gemhunters.worldevent.WorldEventState;
import mineplex.gemhunters.worldevent.WorldEventType;
public class GwenMartWorldEvent extends WorldEvent
{
private static final long WARMUP_TIME = TimeUnit.MINUTES.toMillis(3);
private static final long MAX_TIME = TimeUnit.MINUTES.toMillis(8);
private final BlockRestore _restore;
private final Location _average;
private List<Location> _door;
private boolean _colour;
public GwenMartWorldEvent()
{
super(WorldEventType.GWEN_MART);
_restore = Managers.require(BlockRestore.class);
_average = UtilAlg.getAverageLocation(_worldData.getCustomLocation("GWEN_MART"));
_door = _worldData.getCustomLocation(String.valueOf(Material.EMERALD_BLOCK.getId()));
_worldEvent.runSyncLater(() -> {
for (Location location : _door)
{
location.getBlock().setType(Material.WOOD);
}
}, 20);
}
@EventHandler
public void updateOpening(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC)
{
return;
}
_colour = !_colour;
if (UtilTime.elapsed(_start, WARMUP_TIME) && isWarmup())
{
for (Location location : _door)
{
_restore.add(location.getBlock(), 0, (byte) 0, Long.MAX_VALUE);
}
for (Location location : _worldData.getCustomLocation("GWEN_MART_CHEST"))
{
location.getBlock().setType(Material.CHEST);
_loot.addSpawnedChest(location, UtilMath.random.nextBoolean() ? "ORANGE" : "PINK");
}
setEventState(WorldEventState.LIVE);
}
else if (isLive())
{
UtilTextBottom.display((_colour ? C.cDAquaB : C.cWhiteB) + "GWEN MART IS CLOSING IN " + UtilTime.MakeStr(_start + MAX_TIME - System.currentTimeMillis()), UtilServer.getPlayers());
}
else if (isWarmup())
{
UtilTextBottom.display((_colour ? C.cDAquaB : C.cWhiteB) + "GWEN MART IS OPENING IN " + UtilTime.MakeStr(_start + WARMUP_TIME - System.currentTimeMillis()), UtilServer.getPlayers());
}
}
@Override
public void onStart()
{
}
@Override
public boolean checkToEnd()
{
return UtilTime.elapsed(_start, MAX_TIME);
}
@Override
public void onEnd()
{
Location teleportTo = _worldData.getCustomLocation("GWEN_MART_TP").get(0);
for (Player player : Bukkit.getOnlinePlayers())
{
if (isInGwenMart(player.getLocation()))
{
player.teleport(teleportTo);
}
}
for (Location location : _door)
{
_restore.restore(location.getBlock());
}
}
@Override
public Location[] getEventLocations()
{
return new Location[] { _average };
}
private boolean isInGwenMart(Location location)
{
List<Location> locations = _worldData.getCustomLocation("GWEN_MART");
return UtilAlg.inBoundingBox(location, locations.get(0), locations.get(1));
}
}

View File

@ -0,0 +1,212 @@
package mineplex.gemhunters.worldevent.nether;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.entity.Skeleton;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityTargetEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.ItemStack;
import mineplex.core.Managers;
import mineplex.core.blockrestore.BlockRestore;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEvent;
import mineplex.core.common.util.UtilInv;
import mineplex.core.common.util.UtilEvent.ActionType;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.utils.UtilVariant;
import mineplex.gemhunters.loot.rewards.LootChestReward;
import mineplex.gemhunters.worldevent.WorldEvent;
import mineplex.gemhunters.worldevent.WorldEventState;
import mineplex.gemhunters.worldevent.WorldEventType;
public class NetherPortalWorldEvent extends WorldEvent
{
private static final int PORTALS = 5;
private static final long MAX_TIME = TimeUnit.MINUTES.toMillis(20);
private static final int SKELETONS_PER_PORTAL = 10;
private static final long CASH_OUT_DELAY = TimeUnit.MINUTES.toMillis(10);
private final BlockRestore _restore;
private Player _player;
private List<Location> _portalLocations;
private List<Block> _portalBlocks;
private long _portalLit;
public NetherPortalWorldEvent()
{
super(WorldEventType.NETHER);
_restore = Managers.require(BlockRestore.class);
_portalLocations = new ArrayList<>();
_portalBlocks = new ArrayList<>(50);
_portalLit = 0;
}
@EventHandler
public void lightPortal(PlayerInteractEvent event)
{
if (!UtilEvent.isAction(event, ActionType.R_BLOCK))
{
return;
}
Player player = event.getPlayer();
Block block = event.getClickedBlock();
if (player.getItemInHand() == null)
{
return;
}
if (player.getItemInHand().getType() != Material.FLINT_AND_STEEL)
{
return;
}
if (!_portalBlocks.contains(block))
{
return;
}
if (_portalLit == 0)
{
_portalLit = System.currentTimeMillis();
for (Location location : _portalLocations)
{
lightPortal(location);
}
_player = player;
UtilServer.broadcast(F.main(_worldEvent.getName(), F.name(player.getName()) + " has lit a nether portal and become the " + F.color("Pumpkin King", C.cGold) + "! They now have 5 Omega Chests!"));
ItemStack itemStack = new ItemBuilder(Material.ENDER_CHEST).setTitle(C.cAqua + "5 Omega Chests").build();
LootChestReward reward = new LootChestReward(CASH_OUT_DELAY, itemStack, "Omega", 5);
_loot.addItemReward(reward);
if (UtilInv.hasSpace(player, 1))
{
reward.collectItem(player);
player.getInventory().addItem(itemStack);
}
else
{
_worldData.World.dropItemNaturally(player.getLocation(), itemStack);
}
for (Location location : _portalLocations)
{
for (int i = 0; i < SKELETONS_PER_PORTAL; i++)
{
Skeleton skeleton = UtilVariant.spawnWitherSkeleton(location);
skeleton.setCustomName(C.cGold + "Pumpkin Minions");
skeleton.setCustomNameVisible(true);
addEntity(skeleton);
}
}
setEventState(WorldEventState.LIVE);
}
}
@EventHandler
public void playerQuit(PlayerQuitEvent event)
{
if (_player != null && event.getPlayer().equals(_player))
{
setEventState(WorldEventState.COMPLETE);
}
}
@EventHandler
public void entityTarget(EntityTargetEvent event)
{
if (_player != null && _entities.contains(event) && _player.equals(event.getTarget()))
{
event.setCancelled(true);
}
}
@Override
public void onStart()
{
List<Location> storedLocations = _worldData.getCustomLocation("NETHER_PORTAL");
for (int i = 0; i < PORTALS; i++)
{
Location location = UtilAlg.Random(storedLocations);
if (_portalLocations.contains(location))
{
continue;
}
_portalLocations.add(location);
buildPortal(location);
}
UtilServer.broadcast(F.main(_worldEvent.getName(), "Portals have spawned around the map!"));
}
@Override
public boolean checkToEnd()
{
return UtilTime.elapsed(_start, MAX_TIME);
}
@Override
public void onEnd()
{
_portalLocations.clear();
for (Block block : _portalBlocks)
{
_restore.restore(block);
}
_portalLit = 0;
}
@Override
public Location[] getEventLocations()
{
return _portalLocations.toArray(new Location[0]);
}
private void buildPortal(Location location)
{
for (Block block : UtilBlock.getInBoundingBox(location.clone().add(2, 4, 0), location.clone().add(-2, 0, 0), false, true, false, false))
{
_restore.add(block, Material.OBSIDIAN.getId(), (byte) 0, Integer.MAX_VALUE);
_portalBlocks.add(block);
}
}
private void lightPortal(Location location)
{
for (Block block : UtilBlock.getInBoundingBox(location.clone().add(1, 3, 0), location.clone().add(-1, 1, 0), false, true, false, false))
{
_restore.add(block, Material.PORTAL.getId(), (byte) 0, Integer.MAX_VALUE);
_portalBlocks.add(block);
}
}
}

View File

@ -0,0 +1,137 @@
package mineplex.gemhunters.worldevent.wither;
import java.util.concurrent.TimeUnit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.entity.Skeleton;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilTime;
import mineplex.core.utils.UtilVariant;
import mineplex.gemhunters.worldevent.WorldEvent;
import mineplex.gemhunters.worldevent.WorldEventState;
import mineplex.gemhunters.worldevent.WorldEventType;
public class WitherWorldEvent extends WorldEvent
{
private static final long MAX_TIME = TimeUnit.MINUTES.toMillis(5);
private static final int SKELETONS = 5;
private static final ItemStack IN_HAND = new ItemStack(Material.STONE_SWORD);
private static final int HEALTH = 40;
private static final int RADIUS = 5;
private Location[] _skulls;
public WitherWorldEvent()
{
super(WorldEventType.WITHER);
_worldEvent.runSyncLater(() -> buildAlter(), 20);
}
@EventHandler(priority = EventPriority.HIGHEST)
public void trigger(BlockPlaceEvent event)
{
if (_skulls == null)
{
return;
}
Player player = event.getPlayer();
Block block = event.getBlock();
boolean start = true;
// Check for allowed placement
for (Location location : _skulls)
{
if (block.getLocation().equals(location))
{
event.setCancelled(false);
player.sendMessage(F.main(_worldEvent.getName(), "grrrrr...."));
break;
}
}
// Check for all skulls
for (Location location : _skulls)
{
if (location.getBlock().getType() != Material.SKULL)
{
start = false;
}
}
// Start Event
if (start)
{
setEventState(WorldEventState.WARMUP);
}
}
@Override
public void onStart()
{
Location location = _worldData.getCustomLocation("WITHER_ALTER").get(0).clone().add(0, 1, 0);
location.getBlock().setType(Material.ENDER_CHEST);
_loot.addSpawnedChest(location, "PURPLE");
for (int i = 0; i < SKELETONS; i++)
{
Skeleton skeleton = UtilVariant.spawnWitherSkeleton(UtilAlg.getRandomLocation(location, RADIUS));
skeleton.getEquipment().setItemInHand(IN_HAND);
skeleton.setMaxHealth(HEALTH);
skeleton.setHealth(HEALTH);
}
setEventState(WorldEventState.LIVE);
}
@Override
public boolean checkToEnd()
{
return UtilTime.elapsed(_start, MAX_TIME);
}
@Override
public void onEnd()
{
for (Location location : _skulls)
{
location.getBlock().setType(Material.AIR);
}
}
@Override
public Location[] getEventLocations()
{
return new Location[] { _skulls[1] };
}
private void buildAlter()
{
Location point = _worldData.getCustomLocation("WITHER_ALTER").get(0).clone();
point.getBlock().setType(Material.SOUL_SAND);
point.add(0, 1, 0).getBlock().setType(Material.SOUL_SAND);
point.add(0, 0, -1).getBlock().setType(Material.SOUL_SAND);
point.add(0, 0, 2).getBlock().setType(Material.SOUL_SAND);
_skulls = new Location[] {
point.add(0, 1, 0),
point.add(0, 0, -1),
point.add(0, 0, -1)
};
}
}