Lots of world events!
This commit is contained in:
parent
d4bdc3e5d1
commit
7760404b4e
@ -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);
|
||||
}
|
||||
|
@ -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,38 +43,50 @@ 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);
|
||||
}
|
||||
|
||||
|
||||
public abstract void onStart();
|
||||
|
||||
public abstract boolean checkToEnd();
|
||||
|
||||
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()
|
||||
|
@ -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,66 +16,77 @@ 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;
|
||||
private long _lastEventComplete;
|
||||
|
||||
|
||||
private WorldEventModule()
|
||||
{
|
||||
super("World Event");
|
||||
|
||||
_events = new ArrayList<>();
|
||||
|
||||
_events = Arrays.asList(
|
||||
|
||||
new GiantWorldEvent(),
|
||||
new BlizzardWorldEvent(),
|
||||
new NetherPortalWorldEvent(),
|
||||
new WitherWorldEvent(),
|
||||
new GwenMartWorldEvent()
|
||||
|
||||
);
|
||||
|
||||
_lastEventComplete = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addCommands()
|
||||
{
|
||||
addCommand(new WorldEventCommand(this));
|
||||
}
|
||||
|
||||
|
||||
public void startEvent(WorldEventType eventType)
|
||||
{
|
||||
WorldEvent event = eventType.createInstance();
|
||||
WorldEvent event = getEvent(eventType);
|
||||
|
||||
_events.add(event);
|
||||
|
||||
event.setEventState(WorldEventState.WARMUP);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
possibleWorldEvents.add(eventType);
|
||||
}
|
||||
|
||||
|
||||
if (possibleWorldEvents.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
startEvent(UtilAlg.Random(possibleWorldEvents));
|
||||
|
||||
startEvent(UtilAlg.Random(possibleWorldEvents));
|
||||
}
|
||||
|
||||
|
||||
@EventHandler
|
||||
public void checkNextEvent(UpdateEvent event)
|
||||
{
|
||||
@ -82,59 +94,68 @@ public class WorldEventModule extends MiniPlugin
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Iterator<WorldEvent> iterator = _events.iterator();
|
||||
|
||||
|
||||
while (iterator.hasNext())
|
||||
{
|
||||
WorldEvent worldEvent = iterator.next();
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!isEventActive() && UtilTime.elapsed(_lastEventComplete, EVENT_TIMER))
|
||||
{
|
||||
startRandomEvent();
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
return _lastEventComplete;
|
||||
}
|
||||
|
||||
|
||||
public long getEventTimer()
|
||||
{
|
||||
return EVENT_TIMER;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
@ -127,6 +134,20 @@ public class CustomGiant implements Listener
|
||||
block.setType(Material.AIR);
|
||||
}
|
||||
}
|
||||
|
||||
@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)
|
||||
|
@ -3,63 +3,92 @@ 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;
|
||||
|
||||
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
|
||||
public void onStart()
|
||||
{
|
||||
_giant = new CustomGiant(_worldData.getCustomLocation("GIANT_SPAWN").get(0));
|
||||
addEntity(_giant.getGiant());
|
||||
|
||||
|
||||
_worldEvent.registerEvents(_giant);
|
||||
|
||||
|
||||
setEventState(WorldEventState.LIVE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkToEnd()
|
||||
{
|
||||
return UtilTime.elapsed(_start, MAX_TIME) || _giant.getGiant().isDead() || !_giant.getGiant().isValid();
|
||||
return UtilTime.elapsed(_start, MAX_TIME) || _giant.getGiant().isDead() || !_giant.getGiant().isValid();
|
||||
}
|
||||
|
||||
|
||||
@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
|
||||
public void zombieCombust(EntityCombustEvent event)
|
||||
{
|
||||
@ -68,7 +97,7 @@ public class GiantWorldEvent extends WorldEvent
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@EventHandler
|
||||
public void update(UpdateEvent event)
|
||||
{
|
||||
@ -76,7 +105,7 @@ public class GiantWorldEvent extends WorldEvent
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for (Entity entity : _entities)
|
||||
{
|
||||
if (UtilMath.offsetSquared(entity, _giant.getGiant()) > MINI_ZOMBIES_MAX_DISTANCE_SQUARED)
|
||||
@ -84,15 +113,15 @@ public class GiantWorldEvent extends WorldEvent
|
||||
entity.teleport(_giant.getGiant());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -1 for the giant
|
||||
if (_entities.size() - 1 < MINI_ZOMBIES)
|
||||
{
|
||||
Zombie zombie = _worldData.World.spawn(_giant.getGiant().getLocation(), Zombie.class);
|
||||
|
||||
|
||||
zombie.setRemoveWhenFarAway(false);
|
||||
zombie.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, Integer.MAX_VALUE, 1));
|
||||
|
||||
|
||||
addEntity(zombie);
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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)
|
||||
};
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user