Pumpkin's Revenge (#237)

* Initial Commit

* Update

* Bunch of new stuff

* Fixed fletcher arrow typo

* Added reward pet, fixed typo, tweaked lose cinematic

* Lots of tweaks and fixes with QA

* Cleaning up a little code

* Removed debug message on prince death

* Added nighttime to halloween game lobby maps

* Tweaked spawn rates and mob caps

* Typo

* Tweaked texts, cleaned import and cleared all mobs from boss cinematic

* Fixed creepers not getting properly removed during boss cinematic

* Reward typo

* Fixed rare NPE

* Typos

* Tweaked mini zombie

* Typo

* Prevent zombie from spawning minis after being removed

* Tweaked wave announcements + formated WaveVictory

* Changed color of prince tag + formated ZombieSpawner

* Fixed (another) rare NPE

* Tweaked boss wave cinematic
This commit is contained in:
xADudex 2016-10-13 04:40:05 +02:00 committed by Shaun Bennett
parent 66dfe06b34
commit 311751cc39
49 changed files with 4290 additions and 123 deletions

View File

@ -33,6 +33,12 @@ public class AnimationPoint
return _tick; return _tick;
} }
@Override
public String toString()
{
return "AnimationPoint[tick" + _tick + ", motion:[" + _move + "], dir:[" + _dir + "]]";
}
@Override @Override
public boolean equals(Object obj) public boolean equals(Object obj)
{ {

View File

@ -1,5 +1,6 @@
package mineplex.core.common.animation; package mineplex.core.common.animation;
import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.PriorityQueue; import java.util.PriorityQueue;
import java.util.Set; import java.util.Set;
@ -36,6 +37,11 @@ public abstract class Animator
_plugin = plugin; _plugin = plugin;
} }
public void addPoints(Collection<AnimationPoint> points)
{
for(AnimationPoint p : points) _points.add(p);
}
public void addPoint(AnimationPoint point) { public void addPoint(AnimationPoint point) {
_points.add(point); _points.add(point);
} }
@ -48,7 +54,9 @@ public abstract class Animator
* @return Returns a cloned list of the animator points for this instance. * @return Returns a cloned list of the animator points for this instance.
*/ */
public Set<AnimationPoint> getSet() { public Set<AnimationPoint> getSet() {
return new HashSet<AnimationPoint>(_points); Set<AnimationPoint> set = new HashSet<>();
set.addAll(_points);
return set;
} }
/** /**
@ -110,6 +118,7 @@ public abstract class Animator
prev.setDirection(_prev.getDirection()); prev.setDirection(_prev.getDirection());
double diff = ((double)_tick-_prev.getTick())/(_next.getTick()-_prev.getTick()); double diff = ((double)_tick-_prev.getTick())/(_next.getTick()-_prev.getTick());
if(!Double.isFinite(diff)) diff = 0;
prev.add(next.clone().subtract(prev).toVector().multiply(diff)); prev.add(next.clone().subtract(prev).toVector().multiply(diff));
Vector dirDiff = _next.getDirection().subtract(prev.getDirection()); Vector dirDiff = _next.getDirection().subtract(prev.getDirection());

View File

@ -35,5 +35,10 @@ public class AnimatorEntity extends Animator
@Override @Override
protected void finish(Location loc) {} protected void finish(Location loc) {}
public Entity getEntity()
{
return _ent;
}
} }

View File

@ -0,0 +1,48 @@
package mineplex.core.common.animation;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.bukkit.Location;
import org.bukkit.util.Vector;
/**
* A small factory class to build animations using location inputs with embedded directions. It then calculates the vector difference
* between the locations in an ordered fashion when building the list.
*/
public class AnimatorFactory
{
private Map<Integer, Location> _locations = new HashMap<>();
public void addLocation(Location loc, int tick)
{
_locations.put(tick, loc.clone());
}
public List<AnimationPoint> getBuildList(Location base)
{
List<AnimationPoint> list = new ArrayList<>();
Iterator<Entry<Integer, Location>> it = _locations.entrySet().stream()
.sorted((e1, e2)
-> Integer.compare(e1.getKey(), e2.getKey())
)
.iterator();
while(it.hasNext())
{
Entry<Integer, Location> e = it.next();
Vector diff = e.getValue().clone().subtract(base).toVector();
list.add(new AnimationPoint(e.getKey(), diff, e.getValue().getDirection()));
}
return list;
}
}

View File

@ -1,6 +1,7 @@
package mineplex.core.common.util; package mineplex.core.common.util;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@ -132,6 +133,53 @@ public class UtilEnt
} }
/**
* See {@link #getEntitiesInsideEntity(Entity, List)}
* Uses all players in the same world as the entity as input
*/
public static List<Player> getPlayersInsideEntity(Entity ent)
{
return getEntitiesInsideEntity(ent, ent.getWorld().getPlayers());
}
/**
* See {@link #getEntitiesInsideEntity(Entity, List)}
* Uses all entities in the same world as the entity as input
*/
public static List<Entity> getEntitiesInsideEntity(Entity ent)
{
return getEntitiesInsideEntity(ent, ent.getWorld().getEntities());
}
/**
* See {@link #getEntitiesInsideEntity(Entity, List)}
* Auto cast to list of players
*/
public static List<Player> getPlayersInsideEntity(Entity ent, List<Player> players)
{
return getEntitiesInsideEntity(ent, players);
}
/**
* Returns entities which are inside the provided entity's boundingbox
* @param ent The entity to check inside
* @param entities List of entities to check
* @return Returns a sublist of entities which are inside the entity's boundingbox
*/
public static <T extends Entity> List<T> getEntitiesInsideEntity(Entity ent, List<T> entities)
{
AxisAlignedBB box = ((CraftEntity)ent).getHandle().getBoundingBox();
List<T> list = new ArrayList<>();
for(T e : entities)
{
AxisAlignedBB box2 = ((CraftEntity)e).getHandle().getBoundingBox();
if(box2.b(box)) list.add(e);
}
return list;
}
public static void Vegetate(Entity entity) public static void Vegetate(Entity entity)
{ {
Vegetate(entity, false); Vegetate(entity, false);
@ -345,6 +393,35 @@ public class UtilEnt
} }
} }
/**
* Set whether this entity should be ticked normally when far away. By default entities are only ticked once every 20 ticks
* when they are outside the activation range.
*
* Default ranges are calculated in a AABB fashion from their closest player:
* animalActivationRange = 32
* monsterActivationRange = 32
* miscActivationRange = 16
*
* Entities that are unaffected by range (always active):
* Players, Projectiles, Enderdragon, Wither, Fireballs, Lightning strikes, TNT, Ender Crystals and Fireworks.
*
* You can make entities which are by default active (Projectiles etc) not load when far away
* or make entities that are not active by default (mobs, animals etc) load when far away
*/
public static void setTickWhenFarAway(Entity ent, boolean loadWhenFar)
{
try
{
Field state = net.minecraft.server.v1_8_R3.Entity.class.getDeclaredField("defaultActivationState");
state.setAccessible(true);
state.setBoolean(((CraftEntity)ent).getHandle(), loadWhenFar);
}
catch(Exception e)
{
e.printStackTrace();
}
}
public static String getName(Entity ent) public static String getName(Entity ent)
{ {
if (ent == null) if (ent == null)
@ -578,6 +655,16 @@ public class UtilEnt
return false; return false;
} }
public static float getStepHeight(Entity ent)
{
return ((CraftEntity)ent).getHandle().S;
}
public static void setStepHeight(Entity ent, float stepHeight)
{
((CraftEntity)ent).getHandle().S = stepHeight;
}
public static boolean isGrounded(Entity ent) public static boolean isGrounded(Entity ent)
{ {
@ -813,6 +900,18 @@ public class UtilEnt
return true; return true;
} }
/**
* Returns true if the entity got a path that will lead it closer to the current navigation path finding target.
* It will return false, it it is as close as it can get. Using this got an advantage compared to distance checking, as the target
* might be inside blocks, leaving the entity unable to get any closer.
* @param ent The entity to check
* @return Returns whether the entity can walk any closer to the current navigation target.
*/
public static boolean canEntityWalkCloserToNavigationTarget(Creature ent)
{
return ((CraftCreature)ent).getHandle().getNavigation().m();
}
public static int getNewEntityId() public static int getNewEntityId()
{ {
@ -887,7 +986,17 @@ public class UtilEnt
{ {
((CraftEntity)ent).getHandle().setSize((float) width, (float)height); ((CraftEntity)ent).getHandle().setSize((float) width, (float)height);
} }
public static double getHeight(Entity ent)
{
return ((CraftEntity)ent).getHandle().length;
}
public static double getWidth(Entity ent)
{
return ((CraftEntity)ent).getHandle().width;
}
public static void SetMetadata(Entity entity, String key, Object value) public static void SetMetadata(Entity entity, String key, Object value)
{ {
entity.setMetadata(key, new FixedMetadataValue(UtilServer.getPlugin(), value)); entity.setMetadata(key, new FixedMetadataValue(UtilServer.getPlugin(), value));

View File

@ -86,7 +86,7 @@ public class UtilFuture
CompletableFuture.allOf(values.toArray(new CompletableFuture[values.size()])); CompletableFuture.allOf(values.toArray(new CompletableFuture[values.size()]));
return futuresCompleted.thenApply(v -> return futuresCompleted.thenApply(v ->
seqValues.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().join()))); (Map<K, Collection<V>>) seqValues.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> (Collection<V>) entry.getValue().join())));
} }
/** /**

View File

@ -1,16 +1,17 @@
package mineplex.core.common.util; package mineplex.core.common.util;
import mineplex.core.common.MinecraftVersion; import java.util.ArrayList;
import mineplex.core.common.events.PlayerMessageEvent; import java.util.Arrays;
import net.md_5.bungee.api.chat.ClickEvent; import java.util.Collection;
import net.md_5.bungee.api.chat.ClickEvent.Action; import java.util.HashMap;
import net.md_5.bungee.api.chat.HoverEvent; import java.util.HashSet;
import net.md_5.bungee.api.chat.TextComponent; import java.util.Iterator;
import net.minecraft.server.v1_8_R3.EntityPlayer; import java.util.LinkedList;
import net.minecraft.server.v1_8_R3.Packet; import java.util.List;
import net.minecraft.server.v1_8_R3.PacketPlayOutWorldBorder; import java.util.Map;
import net.minecraft.server.v1_8_R3.PlayerConnection; import java.util.Random;
import net.minecraft.server.v1_8_R3.WorldBorder; import java.util.UUID;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Location; import org.bukkit.Location;
@ -26,9 +27,23 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView; import org.bukkit.inventory.InventoryView;
import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffect;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.BlockIterator; import org.bukkit.util.BlockIterator;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import mineplex.core.common.MinecraftVersion;
import mineplex.core.common.events.PlayerMessageEvent;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ClickEvent.Action;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
import net.minecraft.server.v1_8_R3.EntityPlayer;
import net.minecraft.server.v1_8_R3.EntityTracker;
import net.minecraft.server.v1_8_R3.EntityTrackerEntry;
import net.minecraft.server.v1_8_R3.Packet;
import net.minecraft.server.v1_8_R3.PacketPlayOutWorldBorder;
import net.minecraft.server.v1_8_R3.PlayerConnection;
import net.minecraft.server.v1_8_R3.WorldBorder;
import java.util.*; import java.util.*;
public class UtilPlayer public class UtilPlayer
@ -73,6 +88,49 @@ public class UtilPlayer
return true; return true;
} }
public static void setSpectating(Player player, Entity ent)
{
if(!ent.isValid()) return;
player.setGameMode(GameMode.SPECTATOR);
if(player.getSpectatorTarget() != null)
{
player.setSpectatorTarget(null);
}
player.teleport(ent);
if(isTracked(player, ent))
{
player.setSpectatorTarget(ent);
}
else
{
new BukkitRunnable()
{
public void run()
{
setSpectating(player, ent);
}
}.runTaskLater(UtilServer.getPlugin(), 1);
}
}
/**
* Returns true if the given player is tracking the given target, meaning that the player
* got the entity loaded and knows about the entity.
*/
public static boolean isTracked(Player player, Entity target)
{
EntityPlayer ep = ((CraftPlayer) player).getHandle();
EntityTracker tracker = ep.u().getTracker();
EntityTrackerEntry entry = tracker.trackedEntities.get(target.getEntityId());
return entry.trackedPlayers.contains(ep);
}
public static void hideFrom(Player player, Collection<Player> players) { public static void hideFrom(Player player, Collection<Player> players) {
players.stream().forEach(p->p.hidePlayer(player)); players.stream().forEach(p->p.hidePlayer(player));
} }

View File

@ -0,0 +1,33 @@
package mineplex.core.common.util;
import java.lang.reflect.Field;
public class UtilReflection
{
/**
* Returns the value of the field from the given object instance
*/
public static Object getValueOfField(Object object, String fieldName)
{
return getValueOfField(object.getClass(), object, fieldName);
}
/**
* Returns the value of the field from the given object instance
*/
public static Object getValueOfField(Class<?> className, Object object, String fieldName)
{
try
{
Field f = className.getDeclaredField(fieldName);
f.setAccessible(true);
return f.get(object);
}
catch (Exception e)
{
e.printStackTrace();
return null;
}
}
}

View File

@ -25,6 +25,7 @@ public enum GameDisplay
Evolution("Evolution", Material.EMERALD, (byte)0, GameCategory.ARCADE, 16), Evolution("Evolution", Material.EMERALD, (byte)0, GameCategory.ARCADE, 16),
Gravity("Gravity", Material.ENDER_PORTAL_FRAME, (byte)0, GameCategory.EXTRA, 18), Gravity("Gravity", Material.ENDER_PORTAL_FRAME, (byte)0, GameCategory.EXTRA, 18),
Halloween("Halloween Horror", Material.PUMPKIN, (byte)0, GameCategory.CLASSICS, 19), Halloween("Halloween Horror", Material.PUMPKIN, (byte)0, GameCategory.CLASSICS, 19),
Halloween2016("Pumpkin's Revenge", Material.PUMPKIN, (byte)0, GameCategory.CLASSICS, 63),
HideSeek("Block Hunt", Material.GRASS, (byte)0, GameCategory.CLASSICS, 20), HideSeek("Block Hunt", Material.GRASS, (byte)0, GameCategory.CLASSICS, 20),
HoleInTheWall("Hole in the Wall", Material.STAINED_GLASS, (byte) 2, GameCategory.ARCADE, 52), HoleInTheWall("Hole in the Wall", Material.STAINED_GLASS, (byte) 2, GameCategory.ARCADE, 52),
Horse("Horseback", Material.IRON_BARDING, (byte)0, GameCategory.ARCADE, 21), Horse("Horseback", Material.IRON_BARDING, (byte)0, GameCategory.ARCADE, 21),

View File

@ -31,6 +31,7 @@ public enum GameType
Gladiators("Gladiators"), Gladiators("Gladiators"),
Gravity("Gravity"), Gravity("Gravity"),
Halloween("Halloween Horror"), Halloween("Halloween Horror"),
Halloween2016("Halloween Horror 2016"),
HideSeek("Block Hunt"), HideSeek("Block Hunt"),
Horse("Horseback"), Horse("Horseback"),
Lobbers("Bomb Lobbers"), Lobbers("Bomb Lobbers"),

View File

@ -40,6 +40,7 @@ import nautilus.game.arcade.game.games.gladiators.modes.OverpoweredGladiators;
import nautilus.game.arcade.game.games.gladiators.modes.SmashGladiators; import nautilus.game.arcade.game.games.gladiators.modes.SmashGladiators;
import nautilus.game.arcade.game.games.gravity.Gravity; import nautilus.game.arcade.game.games.gravity.Gravity;
import nautilus.game.arcade.game.games.halloween.Halloween; import nautilus.game.arcade.game.games.halloween.Halloween;
import nautilus.game.arcade.game.games.halloween2016.Halloween2016;
import nautilus.game.arcade.game.games.hideseek.HideSeek; import nautilus.game.arcade.game.games.hideseek.HideSeek;
import nautilus.game.arcade.game.games.hideseek.modes.Countdown; import nautilus.game.arcade.game.games.hideseek.modes.Countdown;
import nautilus.game.arcade.game.games.holeinwall.HoleInTheWall; import nautilus.game.arcade.game.games.holeinwall.HoleInTheWall;
@ -143,6 +144,7 @@ public enum GameType
{ {
Pair.create(MinecraftVersion.ALL, "http://file.mineplex.com/ResHalloween.zip") Pair.create(MinecraftVersion.ALL, "http://file.mineplex.com/ResHalloween.zip")
}, true), }, true),
Halloween2016(Halloween2016.class, GameDisplay.Halloween2016),
HideSeek(HideSeek.class, GameDisplay.HideSeek), HideSeek(HideSeek.class, GameDisplay.HideSeek),
HoleInTheWall(HoleInTheWall.class, GameDisplay.HoleInTheWall), HoleInTheWall(HoleInTheWall.class, GameDisplay.HoleInTheWall),
Horse(Horse.class, GameDisplay.Horse), Horse(Horse.class, GameDisplay.Horse),

View File

@ -1,7 +1,37 @@
package nautilus.game.arcade.game.games.halloween; package nautilus.game.arcade.game.games.halloween;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import org.bukkit.ChatColor;
import org.bukkit.Difficulty;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.entity.Fireball;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.EntityTargetEvent;
import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import mineplex.core.common.currency.GlobalCurrency; import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.*; import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.common.util.UtilTime.TimeUnit; import mineplex.core.common.util.UtilTime.TimeUnit;
import mineplex.core.recharge.Recharge; import mineplex.core.recharge.Recharge;
import mineplex.core.updater.UpdateType; import mineplex.core.updater.UpdateType;
@ -17,36 +47,38 @@ import nautilus.game.arcade.game.games.halloween.creatures.InterfaceMove;
import nautilus.game.arcade.game.games.halloween.kits.KitFinn; import nautilus.game.arcade.game.games.halloween.kits.KitFinn;
import nautilus.game.arcade.game.games.halloween.kits.KitRobinHood; import nautilus.game.arcade.game.games.halloween.kits.KitRobinHood;
import nautilus.game.arcade.game.games.halloween.kits.KitThor; import nautilus.game.arcade.game.games.halloween.kits.KitThor;
import nautilus.game.arcade.game.games.halloween.waves.*; import nautilus.game.arcade.game.games.halloween.waves.Wave1;
import nautilus.game.arcade.game.games.halloween.waves.Wave2;
import nautilus.game.arcade.game.games.halloween.waves.Wave3;
import nautilus.game.arcade.game.games.halloween.waves.Wave4;
import nautilus.game.arcade.game.games.halloween.waves.Wave5;
import nautilus.game.arcade.game.games.halloween.waves.WaveBase;
import nautilus.game.arcade.game.games.halloween.waves.WaveBoss;
import nautilus.game.arcade.game.games.halloween.waves.WaveVictory;
import nautilus.game.arcade.kit.Kit; import nautilus.game.arcade.kit.Kit;
import nautilus.game.arcade.managers.chat.ChatStatData; import nautilus.game.arcade.managers.chat.ChatStatData;
import net.minecraft.server.v1_8_R3.PacketPlayOutNamedSoundEffect; import net.minecraft.server.v1_8_R3.PacketPlayOutNamedSoundEffect;
import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.entity.Fireball;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.*;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import java.util.*;
public class Halloween extends SoloGame public class Halloween extends SoloGame
{ {
//Wave Data //Wave Data
private ArrayList<ArrayList<Location>> _spawns; protected ArrayList<ArrayList<Location>> _spawns;
private ArrayList<WaveBase> _waves; protected ArrayList<WaveBase> _waves;
private int _wave = 0; protected int _wave = 0;
private int _maxMobs = 80; protected int _maxMobs = 80;
private ArrayList<CreatureBase> _mobs = new ArrayList<CreatureBase>(); protected ArrayList<CreatureBase<?>> _mobs = new ArrayList<>();
private HashMap<Player, Long> _damageTime = new HashMap<Player, Long>(); protected HashMap<Player, Long> _damageTime = new HashMap<Player, Long>();
private HashSet<Player> _soundOff = new HashSet<Player>(); protected HashSet<Player> _soundOff = new HashSet<Player>();
protected UpdateType _updateCreatureMoveRate = UpdateType.FASTEST;
protected boolean doVoices = true;
public String Objective = null;
public long total = 0; public long total = 0;
public long move = 0; public long move = 0;
@ -78,7 +110,7 @@ public class Halloween extends SoloGame
public Halloween(ArcadeManager manager) public Halloween(ArcadeManager manager)
{ {
super(manager, GameType.Halloween, this(manager, GameType.Halloween,
new Kit[] new Kit[]
{ {
@ -94,6 +126,12 @@ public class Halloween extends SoloGame
"Defeat the waves of monsters", "Defeat the waves of monsters",
"Kill the Pumpkin King" "Kill the Pumpkin King"
}); });
}
protected Halloween(ArcadeManager manager, GameType gameType, Kit[] kits, String[] gameDesc)
{
super(manager, gameType, kits, gameDesc);
this.DamagePvP = false; this.DamagePvP = false;
@ -116,6 +154,19 @@ public class Halloween extends SoloGame
BlankLine, BlankLine,
new ChatStatData("kit", "Kit", true) new ChatStatData("kit", "Kit", true)
); );
_help = new String[]
{
C.cGreen + "Giants one hit kill you! Stay away!!!",
C.cAqua + "Work together with your team mates.",
C.cGreen + "Each kit gives a buff to nearby allies.",
C.cAqua + "Kill monsters to keep their numbers down.",
C.cGreen + "Kill giants quickly.",
C.cAqua + "Defend your team mates from monsters.",
C.cGreen + "Zombies, Giants and Spiders get faster over time.",
C.cAqua + "Stick together to survive.",
C.cGreen + "The Pumpkin King gets harder over time!",
};
} }
@Override @Override
@ -134,7 +185,7 @@ public class Halloween extends SoloGame
_waves.add(new Wave4(this)); _waves.add(new Wave4(this));
_waves.add(new Wave5(this)); _waves.add(new Wave5(this));
_waves.add(new WaveBoss(this)); _waves.add(new WaveBoss(this));
_waves.add(new WaveVictory(this)); _waves.add(new WaveVictory(this, GetSpawnSet(3)));
//Make zombies break doors //Make zombies break doors
WorldData.World.setDifficulty(Difficulty.HARD); WorldData.World.setDifficulty(Difficulty.HARD);
@ -146,13 +197,20 @@ public class Halloween extends SoloGame
if (event.GetState() != GameState.End) if (event.GetState() != GameState.End)
return; return;
for (CreatureBase ent : _mobs) for (CreatureBase<?> ent : _mobs)
ent.GetEntity().remove(); {
ent.remove();
}
_mobs.clear(); _mobs.clear();
_spawns.clear(); _spawns.clear();
} }
public ArrayList<CreatureBase<?>> getMobs()
{
return _mobs;
}
@EventHandler(priority = EventPriority.MONITOR) @EventHandler(priority = EventPriority.MONITOR)
public void TeamGen(GameStateChangeEvent event) public void TeamGen(GameStateChangeEvent event)
{ {
@ -168,6 +226,8 @@ public class Halloween extends SoloGame
if (event.GetState() != GameState.Live) if (event.GetState() != GameState.Live)
return; return;
if(!doVoices) return;
Announce(C.Bold + "Type " + C.cGreen + C.Bold + "/voice" + C.cWhite + C.Bold + " to disable voice audio."); Announce(C.Bold + "Type " + C.cGreen + C.Bold + "/voice" + C.cWhite + C.Bold + " to disable voice audio.");
} }
@ -253,8 +313,12 @@ public class Halloween extends SoloGame
if (!IsLive()) if (!IsLive())
return; return;
if(_waves.get(_wave) instanceof WaveVictory ||
_waves.get(_wave) instanceof nautilus.game.arcade.game.games.halloween2016.wave.WaveVictory)
return;
if (Math.random() > 0.6) if (Math.random() > 0.2)
return; return;
for (Player player : UtilServer.getPlayers()) for (Player player : UtilServer.getPlayers())
@ -297,12 +361,12 @@ public class Halloween extends SoloGame
return locSet.get(UtilMath.r(locSet.size())); return locSet.get(UtilMath.r(locSet.size()));
} }
public void AddCreature(CreatureBase mob) public void AddCreature(CreatureBase<?> mob)
{ {
_mobs.add(0, mob); _mobs.add(0, mob);
} }
public ArrayList<CreatureBase> GetCreatures() public ArrayList<CreatureBase<?>> GetCreatures()
{ {
return _mobs; return _mobs;
} }
@ -310,7 +374,7 @@ public class Halloween extends SoloGame
@EventHandler @EventHandler
public void CreatureMoveUpdate(UpdateEvent event) public void CreatureMoveUpdate(UpdateEvent event)
{ {
if (event.getType() != UpdateType.FASTEST) if (event.getType() != _updateCreatureMoveRate)
return; return;
if (_mobs.isEmpty()) if (_mobs.isEmpty())
@ -318,7 +382,7 @@ public class Halloween extends SoloGame
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
CreatureBase base = _mobs.remove(0); CreatureBase<?> base = _mobs.remove(0);
if (base instanceof InterfaceMove) if (base instanceof InterfaceMove)
{ {
@ -342,25 +406,33 @@ public class Halloween extends SoloGame
return; return;
//Clean //Clean
Iterator<CreatureBase> mobIterator = _mobs.iterator(); Iterator<CreatureBase<?>> mobIterator = _mobs.iterator();
while (mobIterator.hasNext()) while (mobIterator.hasNext())
{ {
CreatureBase base = mobIterator.next(); CreatureBase<?> base = mobIterator.next();
if (base.Updater(event)) if (base.Updater(event))
{
onRemove(base);
base.remove();
mobIterator.remove(); mobIterator.remove();
}
} }
total += System.currentTimeMillis() - start; total += System.currentTimeMillis() - start;
update += System.currentTimeMillis() - start; update += System.currentTimeMillis() - start;
} }
public void onRemove(CreatureBase<?> mob)
{
}
@EventHandler @EventHandler
public void CreatureDamage(CustomDamageEvent event) public void CreatureDamage(CustomDamageEvent event)
{ {
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
for (CreatureBase base : _mobs) for (CreatureBase<?> base : _mobs)
base.Damage(event); base.Damage(event);
total += System.currentTimeMillis() - start; total += System.currentTimeMillis() - start;
@ -372,7 +444,7 @@ public class Halloween extends SoloGame
{ {
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
for (CreatureBase base : _mobs) for (CreatureBase<?> base : _mobs)
base.Target(event); base.Target(event);
total += System.currentTimeMillis() - start; total += System.currentTimeMillis() - start;
@ -451,7 +523,7 @@ public class Halloween extends SoloGame
{ {
Block block = blockIterator.next(); Block block = blockIterator.next();
if (block.getY() < 4) if (block.getY() < 4 || block.getY() <= WorldData.MinY)
blockIterator.remove(); blockIterator.remove();
} }
@ -494,40 +566,6 @@ public class Halloween extends SoloGame
{ {
return _maxMobs; return _maxMobs;
} }
private long _helpTimer = 0;
private int _helpIndex = 0;
private String[] _help = new String[]
{
C.cGreen + "Giants one hit kill you! Stay away!!!",
C.cAqua + "Work together with your team mates.",
C.cGreen + "Each kit gives a buff to nearby allies.",
C.cAqua + "Kill monsters to keep their numbers down.",
C.cGreen + "Kill giants quickly.",
C.cAqua + "Defend your team mates from monsters.",
C.cGreen + "Zombies, Giants and Spiders get faster over time.",
C.cAqua + "Stick together to survive.",
C.cGreen + "The Pumpkin King gets harder over time!",
};
@EventHandler
public void StateUpdate(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC)
return;
if (this.GetState() != GameState.Recruit)
return;
if (!UtilTime.elapsed(_helpTimer, 8000))
return;
_helpTimer = System.currentTimeMillis();
Announce(C.cWhite + C.Bold + "TIP " + ChatColor.RESET + _help[_helpIndex]);
_helpIndex = (_helpIndex + 1)%_help.length;
}
@Override @Override
@EventHandler @EventHandler
@ -552,7 +590,7 @@ public class Halloween extends SoloGame
Scoreboard.writeNewLine(); Scoreboard.writeNewLine();
Scoreboard.write(C.cYellow + C.Bold + "Players"); Scoreboard.write(C.cYellow + C.Bold + "Players");
if (GetPlayers(true).size() < 8) if (GetPlayers(true).size() < 5)
{ {
for (Player player : GetPlayers(true)) for (Player player : GetPlayers(true))
{ {
@ -564,12 +602,21 @@ public class Halloween extends SoloGame
Scoreboard.write(GetPlayers(true).size() + " Alive"); Scoreboard.write(GetPlayers(true).size() + " Alive");
} }
if(Objective != null)
{
Scoreboard.writeNewLine();
Scoreboard.write(C.cYellow + C.Bold + "Objective");
Scoreboard.write(Objective);
}
Scoreboard.draw(); Scoreboard.draw();
} }
@EventHandler @EventHandler
public void soundOff(PlayerCommandPreprocessEvent event) public void soundOff(PlayerCommandPreprocessEvent event)
{ {
if(!doVoices) return;
if (event.getMessage().equalsIgnoreCase("/voice")) if (event.getMessage().equalsIgnoreCase("/voice"))
{ {
if (_soundOff.remove(event.getPlayer())) if (_soundOff.remove(event.getPlayer()))
@ -587,12 +634,12 @@ public class Halloween extends SoloGame
} }
} }
public void playSound(HalloweenAudio audio) public void playSound(NamedAudio audio)
{ {
for (Player player : UtilServer.getPlayers()) for (Player player : UtilServer.getPlayers())
if (!_soundOff.contains(player)) if (!_soundOff.contains(player))
{ {
PacketPlayOutNamedSoundEffect packet = new PacketPlayOutNamedSoundEffect(audio.getName(), PacketPlayOutNamedSoundEffect packet = new PacketPlayOutNamedSoundEffect(audio.getAudioPath(),
player.getLocation().getBlockX(), player.getLocation().getBlockY(), player.getLocation().getBlockZ(), player.getLocation().getBlockX(), player.getLocation().getBlockY(), player.getLocation().getBlockZ(),
20f, 1F); 20f, 1F);

View File

@ -1,6 +1,6 @@
package nautilus.game.arcade.game.games.halloween; package nautilus.game.arcade.game.games.halloween;
public enum HalloweenAudio public enum HalloweenAudio implements NamedAudio
{ {
WAVE_1("halloween.wave1"), WAVE_1("halloween.wave1"),
WAVE_2("halloween.wave2"), WAVE_2("halloween.wave2"),
@ -25,7 +25,7 @@ public enum HalloweenAudio
_name = name; _name = name;
} }
public String getName() public String getAudioPath()
{ {
return _name; return _name;
} }

View File

@ -0,0 +1,8 @@
package nautilus.game.arcade.game.games.halloween;
public interface NamedAudio
{
public String getAudioPath();
}

View File

@ -1,18 +1,22 @@
package nautilus.game.arcade.game.games.halloween.creatures; package nautilus.game.arcade.game.games.halloween.creatures;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.entity.Creature;
import org.bukkit.entity.Damageable;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityTargetEvent;
import mineplex.core.common.util.UtilEnt; import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath; import mineplex.core.common.util.UtilMath;
import mineplex.core.updater.event.UpdateEvent; import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.damage.CustomDamageEvent; import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import nautilus.game.arcade.game.games.halloween.Halloween; import nautilus.game.arcade.game.games.halloween.Halloween;
import org.bukkit.Location;
import org.bukkit.entity.Creature;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityTargetEvent;
import org.bukkit.util.Vector;
public abstract class CreatureBase<T extends LivingEntity> public abstract class CreatureBase<T extends LivingEntity>
{ {
public Halloween Host; public Halloween Host;
@ -22,6 +26,8 @@ public abstract class CreatureBase<T extends LivingEntity>
private Location _target; private Location _target;
private long _targetTime; private long _targetTime;
private List<Entity> _parts = new ArrayList<>();
public CreatureBase(Halloween game, String name, Class<T> mobClass, Location loc) public CreatureBase(Halloween game, String name, Class<T> mobClass, Location loc)
{ {
@ -37,11 +43,39 @@ public abstract class CreatureBase<T extends LivingEntity>
_ent.setCustomName(name); _ent.setCustomName(name);
_ent.setCustomNameVisible(true); _ent.setCustomNameVisible(true);
} }
addEntityPart(_ent);
SpawnCustom(_ent); SpawnCustom(_ent);
game.CreatureAllowOverride = false; game.CreatureAllowOverride = false;
} }
protected void addEntityPart(Entity ent)
{
if(_parts.contains(ent)) return;
_parts.add(ent);
}
public List<Entity> getEntityParts()
{
return new ArrayList<>(_parts);
}
public List<Player> getInsideBoundingBox()
{
List<Player> players = Host.GetPlayers(true);
List<Player> list = UtilEnt.getPlayersInsideEntity(_ent, players);
for(Entity ent : _parts)
{
players.removeAll(list);
if(players.isEmpty()) break;
list.addAll(UtilEnt.getPlayersInsideEntity(ent, players));
}
return list;
}
public abstract void SpawnCustom(T ent); public abstract void SpawnCustom(T ent);
@ -114,8 +148,13 @@ public abstract class CreatureBase<T extends LivingEntity>
public abstract void Damage(CustomDamageEvent event); public abstract void Damage(CustomDamageEvent event);
public abstract void Target(EntityTargetEvent event); public abstract void Target(EntityTargetEvent event);
public void CreatureMove(Creature creature) public void CreatureMove(Creature creature)
{
CreatureMove(creature, 1);
}
public void CreatureMove(Creature creature, float speed)
{ {
//New Target //New Target
SetTarget(GetRoamTarget()); SetTarget(GetRoamTarget());
@ -131,8 +170,23 @@ public abstract class CreatureBase<T extends LivingEntity>
//Move //Move
else else
{ {
UtilEnt.CreatureMove(creature, GetTarget(), 1f); UtilEnt.CreatureMove(creature, GetTarget(), speed);
Host.moves++; Host.moves++;
} }
} }
public void remove()
{
for(Entity ent : _parts)
{
if(ent instanceof Damageable)
{
((Damageable) ent).damage(((Damageable) ent).getHealth());
}
else
{
ent.remove();
}
}
}
} }

View File

@ -31,8 +31,8 @@ public class KitRobinHood extends ProgressingKit
}; };
private static final Perk[] PERKS = { private static final Perk[] PERKS = {
new PerkFletcher(1, 8, true), new PerkFletcher(3, 6, true),
new PerkBarrage(8, 125, true, true), new PerkBarrage(8, 125, true, false),
new PerkQuickshotRobinHood() new PerkQuickshotRobinHood()
}; };

View File

@ -32,7 +32,7 @@ public class KitThor extends ProgressingKit
private static final Perk[] PERKS = { private static final Perk[] PERKS = {
new PerkKnockbackAttack(2), new PerkKnockbackAttack(2),
new PerkFletcher(2, 2, true, 9), new PerkFletcher(2, 2, true, 8),
new PerkSeismicHammer(), new PerkSeismicHammer(),
new PerkHammerThrow(), new PerkHammerThrow(),
}; };

View File

@ -1,6 +1,6 @@
package nautilus.game.arcade.game.games.halloween.waves; package nautilus.game.arcade.game.games.halloween.waves;
import java.util.ArrayList; import java.util.List;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
@ -9,29 +9,40 @@ import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import nautilus.game.arcade.game.games.halloween.Halloween;
import nautilus.game.arcade.game.games.halloween.HalloweenAudio;
import mineplex.core.common.util.C; import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilMath; import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.common.util.UtilTextMiddle; import mineplex.core.common.util.UtilTextMiddle;
import mineplex.core.common.util.UtilTime;
import nautilus.game.arcade.game.games.halloween.Halloween;
import nautilus.game.arcade.game.games.halloween.NamedAudio;
public abstract class WaveBase public abstract class WaveBase
{ {
protected Halloween Host; protected Halloween Host;
protected String _name; protected String _name;
protected HalloweenAudio _audio; protected boolean _displayWaveNumber = true;
protected boolean _announceWaveChat = true;
protected boolean _announceWaveTitle = true;
protected NamedAudio _audio;
protected long _start; protected long _start;
protected long _duration; protected long _duration;
private int _tick = 0; private int _tick = 0;
protected ArrayList<Location> _spawns; protected List<Location> _spawns;
public WaveBase(Halloween host, String name, long duration, ArrayList<Location> spawns, HalloweenAudio audio) private boolean _spawnBeacons = true;
private boolean _announceStart = true;
private boolean _displayProgress = true;
protected String _titleColor = C.cYellow;
protected String[] _desc = null;
public WaveBase(Halloween host, String name, long duration, List<Location> spawns, NamedAudio audio)
{ {
Host = host; Host = host;
@ -66,22 +77,57 @@ public abstract class WaveBase
if (_tick == 0) if (_tick == 0)
{ {
System.out.println("Wave " + wave + " has started."); System.out.println("Wave " + wave + " has started.");
Host.Announce(C.cRed + C.Bold + "Wave " + wave + ": " + C.cYellow + _name); if(_announceStart)
{
UtilTextMiddle.display(C.cYellow + "Wave " + wave, _name, 10, 100, 20); if(_announceWaveChat)
{
if (_audio != null) String number = C.cRed + C.Bold + "Wave " + wave;
{ String name = C.cYellow + _name;
Host.playSound(_audio); if(name != null)
{
number += ": ";
}
if(_name == null) name = "";
if(!_displayWaveNumber) number = "";
String waveName = number + name;
Host.Announce(waveName);
}
if(_desc != null)
{
for(String l : _desc)
{
Host.Announce(C.cGray + "" + C.cYellow + l);
}
}
if(_announceWaveTitle)
{
String waveTitle = _displayWaveNumber ? _titleColor + "Wave " + wave : _name;
String waveSub = _displayWaveNumber ? _name : "";
UtilTextMiddle.display(waveTitle, waveSub, 10, 100, 20);
}
if (_audio != null)
{
Host.playSound(_audio);
}
} }
} }
//Display //Display
for (Player player : UtilServer.getPlayers()) if(_displayProgress)
player.setExp(Math.min(0.999f, (float)(_duration - (System.currentTimeMillis() - _start)) / (float)_duration)); {
for (Player player : UtilServer.getPlayers())
{
player.setExp(Math.min(0.999f, (float)(_duration - (System.currentTimeMillis() - _start)) / (float)_duration));
}
}
//Spawn Beacons //Spawn Beacons
if (_tick == 0) if (_tick == 0 && _spawnBeacons)
SpawnBeacons(_spawns); SpawnBeacons(_spawns);
//Spawn //Spawn
@ -92,7 +138,7 @@ public abstract class WaveBase
return false; return false;
} }
public void SpawnBeacons(ArrayList<Location> locs) public void SpawnBeacons(List<Location> locs)
{ {
//Average Location //Average Location
Vector total = new Vector(0,0,0); Vector total = new Vector(0,0,0);
@ -121,6 +167,36 @@ public abstract class WaveBase
{ {
return true; return true;
} }
public void setAnnounceStart(boolean announceStart)
{
_announceStart = announceStart;
}
public void setDisplayProgress(boolean displayProgress)
{
_displayProgress = displayProgress;
}
public void setSpawnBeacons(boolean spawnBeacons)
{
_spawnBeacons = spawnBeacons;
}
public boolean getAnnounceStart()
{
return _announceStart;
}
public boolean getDisplayProgress()
{
return _displayProgress;
}
public boolean getSpawnBeacons()
{
return _spawnBeacons;
}
public abstract void Spawn(int tick); public abstract void Spawn(int tick);
} }

View File

@ -1,6 +1,9 @@
package nautilus.game.arcade.game.games.halloween.waves; package nautilus.game.arcade.game.games.halloween.waves;
import java.util.List;
import org.bukkit.Effect; import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -11,9 +14,9 @@ import nautilus.game.arcade.game.games.halloween.creatures.CreatureBase;
public class WaveVictory extends WaveBase public class WaveVictory extends WaveBase
{ {
public WaveVictory(Halloween host) public WaveVictory(Halloween host, List<Location> beaconSpawn)
{ {
super(host, "Celebration!", 15000, host.GetSpawnSet(3), null); super(host, "Celebration!", 15000, beaconSpawn, null);
} }
@Override @Override
@ -28,7 +31,7 @@ public class WaveVictory extends WaveBase
player.playEffect(Host.WorldData.GetDataLocs("BLACK").get(0), Effect.RECORD_PLAY, 2259); player.playEffect(Host.WorldData.GetDataLocs("BLACK").get(0), Effect.RECORD_PLAY, 2259);
//Mobs //Mobs
for (CreatureBase<LivingEntity> mob : Host.GetCreatures()) for (CreatureBase<? extends LivingEntity> mob : Host.GetCreatures())
mob.GetEntity().damage(5); mob.GetEntity().damage(5);
//Time //Time

View File

@ -0,0 +1,139 @@
package nautilus.game.arcade.game.games.halloween2016;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import mineplex.core.common.block.schematic.Schematic;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTextTop;
import mineplex.core.common.util.UtilTime;
public class Crypt
{
private int _maxHealth = 2000;
private int _health = _maxHealth;
private List<Schematic> _states;
private int _stateIndex = 0;
private Location _schematicBase;
private Map<Entity, Integer> _damageCooldown = new HashMap<>();
private Halloween2016 _host;
public Crypt(Halloween2016 host, Location base, List<Schematic> states)
{
_host = host;
_states = new ArrayList<>();
_states.addAll(states);
_schematicBase = base.clone();
}
public boolean tryDamage(Entity mob, int damage, int cooldown)
{
if(isDestroyed()) return false;
Integer lastTime = _damageCooldown.get(mob);
if(lastTime != null && lastTime > UtilTime.getServerTick()) return false;
_health -= damage;
_damageCooldown.put(mob, UtilTime.getServerTick() + cooldown);
updateState(damage);
return true;
}
public void setHealth(int health)
{
int diff = _health-health;
_health = health;
updateState(diff);
}
public void updateHealthDisplay()
{
UtilTextTop.displayProgress(C.cRed + C.Bold + "Crypt", getHealthProgress(), UtilServer.getPlayers());
}
public float getHealthProgress()
{
return Math.max(0, _health/ (float) _maxHealth);
}
public int getMaxHealth()
{
return _maxHealth;
}
public int getHealth()
{
return _health;
}
public int getStateIndex()
{
return _stateIndex;
}
public Location getSchematicBase()
{
return _schematicBase.clone();
}
public void updateState(int damage)
{
float prevProg = (damage + _health) / (float) _maxHealth;
float progress = getHealthProgress();
int state = (int) (_states.size() * (1-progress));
if(state != _stateIndex && state < _states.size())
{
_stateIndex = state;
_states.get(state).paste(_schematicBase, false, true);
}
int iprog = (int) Math.ceil(progress*100);
int iprevProg = (int) Math.ceil(prevProg*100);
if((iprog%10 == 0 || iprog <= 5) && iprevProg > iprog)
{
String color = C.cGreen;
if(iprog <= 60) color = C.cYellow;
if(iprog <= 30) color = C.cGold;
if(iprog <= 10) color = C.cRed;
if(iprog == 0)
{
_host.Announce(F.main("Crypt", "The crypt has been destroyed!"), true);
}
else
{
_host.Announce(F.main("Crypt", "The crypt only has " + color + C.Bold + iprog + "%" + C.mBody + " left!"), true);
}
if(iprog == 0)
{
for(Location loc : _host.getInfrontOfDoorTargets())
{
loc.getWorld().playEffect(loc, Effect.EXPLOSION_HUGE, 0);
loc.getWorld().strikeLightningEffect(loc);
}
}
}
}
public boolean isDestroyed()
{
return _health <= 0;
}
}

View File

@ -0,0 +1,715 @@
package nautilus.game.arcade.game.games.halloween2016;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.Action;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import mineplex.core.common.animation.AnimationPoint;
import mineplex.core.common.animation.Animator;
import mineplex.core.common.animation.AnimatorFactory;
import mineplex.core.common.block.schematic.Schematic;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.reward.RewardRarity;
import mineplex.core.reward.rewards.PetReward;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import javafx.util.Pair;
import nautilus.game.arcade.ArcadeManager;
import nautilus.game.arcade.GameType;
import nautilus.game.arcade.events.GameStateChangeEvent;
import nautilus.game.arcade.game.GameTeam;
import nautilus.game.arcade.game.games.halloween.Halloween;
import nautilus.game.arcade.game.games.halloween.creatures.CreatureBase;
import nautilus.game.arcade.game.games.halloween.kits.KitFinn;
import nautilus.game.arcade.game.games.halloween.kits.KitRobinHood;
import nautilus.game.arcade.game.games.halloween.kits.KitThor;
import nautilus.game.arcade.game.games.halloween2016.creatures.MobPumpling;
import nautilus.game.arcade.game.games.halloween2016.tutorial.TutorialHalloween2016;
import nautilus.game.arcade.game.games.halloween2016.wave.Wave1;
import nautilus.game.arcade.game.games.halloween2016.wave.Wave2;
import nautilus.game.arcade.game.games.halloween2016.wave.Wave3;
import nautilus.game.arcade.game.games.halloween2016.wave.Wave4;
import nautilus.game.arcade.game.games.halloween2016.wave.Wave5;
import nautilus.game.arcade.game.games.halloween2016.wave.WaveBoss;
import nautilus.game.arcade.game.games.halloween2016.wave.WaveVictory;
import nautilus.game.arcade.kit.Kit;
public class Halloween2016 extends Halloween
{
private List<PumpkinPlant> _pumpkins = new ArrayList<>();
private Crypt _crypt;
private Animator _introAnimator;
private int _maxPumplings = 30;
private int _maxNonPumplings = 65;
private double _mobCapMultiplier = 1;
private int _defaultMaxPlayerCount = 16;
private List<MobPumpling> _pumplings = new ArrayList<>();
private List<CreatureBase<?>> _nonPumplings = new ArrayList<>();
private List<List<Location>> _lanes = new ArrayList<>();
private Location _cryptView;
private Location _lockAllPlayers = null;
private Map<Player, Pair<Location, GameMode>> _playerPreLockData = new HashMap<>();
private static boolean DO_TUTORIALS = true;
public Halloween2016(ArcadeManager manager)
{
super(manager, GameType.Halloween2016,
new Kit[]
{
new KitFinn(manager),
new KitRobinHood(manager),
new KitThor(manager)
},
new String[]
{
"Do not die.",
"Work as a team!",
"Defeat the waves of monsters",
"Kill the Pumpkin Prince",
"Destroy pumpkins by hitting them 3 times",
"Protect the crypt!"
}
);
_help = new String[]
{
C.cGreen + "Giants one hit kill you! Stay away!!!",
C.cAqua + "Work together with your teammates.",
C.cGreen + "Each kit gives a buff to nearby allies.",
C.cAqua + "Kill monsters to keep their numbers down.",
C.cGreen + "Giants instantly destroy the crypt! Kill them quickly!",
C.cAqua + "Defend your teammates from monsters.",
C.cGreen + "Zombies, Giants and Spiders get faster over time.",
C.cAqua + "Stick together to survive.",
C.cGreen + "The Pumpkin Prince gets harder over time!",
C.cAqua + "Protect the crypt to not lose the game!",
C.cGreen + "Pumplings spawn from pumpkins. Hit the pumpkins 3 times to prevent it from spawning.",
};
_updateCreatureMoveRate = UpdateType.TICK;
EnableTutorials = DO_TUTORIALS;
doVoices = false;
}
public void setObjective(String objective)
{
Objective = objective;
Announce(F.main("Objective", C.cYellow + C.Bold + objective));
}
public void unlockAllPlayers()
{
if(_lockAllPlayers == null) return;
_lockAllPlayers = null;
for(Entry<Player, Pair<Location, GameMode>> e : _playerPreLockData.entrySet())
{
e.getKey().teleport(e.getValue().getKey());
e.getKey().setGameMode(e.getValue().getValue());
if(IsAlive(e.getKey()))
{
UtilPlayer.showForAll(e.getKey());
}
}
_playerPreLockData.clear();
Manager.getCosmeticManager().setHideParticles(false);
}
public void lockAllPlayers(Location loc)
{
unlockAllPlayers();
_lockAllPlayers = loc;
Manager.getCosmeticManager().setHideParticles(true);
}
@EventHandler
public void lockPlayerTask(UpdateEvent event)
{
if(event.getType() != UpdateType.TICK) return;
if(_lockAllPlayers != null)
{
for(Player p : Bukkit.getOnlinePlayers())
{
if(!_playerPreLockData.containsKey(p))
{
_playerPreLockData.put(p, new Pair<Location, GameMode>(p.getLocation(), p.getGameMode()));
p.setGameMode(GameMode.SPECTATOR);
}
p.teleport(_lockAllPlayers);
if(IsAlive(p))
{
UtilPlayer.hideFromAll(p);
}
}
}
}
@EventHandler
@Override
public void onGameStart(GameStateChangeEvent event)
{
super.onGameStart(event);
if(event.GetState() != GameState.Live) return;
_mobCapMultiplier = (double) GetPlayers(true).size() / (double) _defaultMaxPlayerCount;
if(_mobCapMultiplier < 0.5)
{
_mobCapMultiplier = 0.5;
}
_maxNonPumplings *= _mobCapMultiplier;
_maxPumplings *= _mobCapMultiplier;
_maxMobs *= _mobCapMultiplier;
}
public int getMaxPumplings()
{
return _maxPumplings;
}
public void setMaxPumplings(int maxPumplings)
{
_maxPumplings = maxPumplings;
}
@Override
public void ParseData()
{
List<Schematic> schematics = new ArrayList<>();
Location doorSchematicLocation = getDoorSchematicLocation();
_crypt = new Crypt(this, getDoorSchematicLocation(), schematics);
for(Location loc : getPumkinSpawns())
{
_pumpkins.add(new PumpkinPlant(this, loc));
}
_lanes.add(getBackLane());
_lanes.add(getLeftLane());
_lanes.add(getRightLane());
_lanes.add(getMainLane());
_lanes.add(getGraveLane());
_waves = new ArrayList<>();
_waves.add(new Wave1(this));
_waves.add(new Wave2(this));
_waves.add(new Wave3(this));
_waves.add(new Wave4(this));
_waves.add(new Wave5(this));
_waves.add(new WaveBoss(this));
_waves.add(new WaveVictory(this, getMobSpawns()));
_spawns = new ArrayList<>();
CreatureAllowOverride = true;
ArmorStand bat = doorSchematicLocation.getWorld().spawn(doorSchematicLocation, ArmorStand.class);
CreatureAllowOverride = false;
UtilEnt.Vegetate(bat, true);
UtilEnt.setAI(bat, false);
UtilEnt.setTickWhenFarAway(bat, true);
bat.setRemoveWhenFarAway(false);
bat.setVisible(false);
_introAnimator = new Animator(Manager.getPlugin())
{
private int _tick = 0;
@Override
protected void tick(Location loc)
{
if(loc == null) return;
for(Player p : Halloween2016.this.GetPlayers(false))
{
if(p.getGameMode() != GameMode.SPECTATOR) p.setGameMode(GameMode.SPECTATOR);
if(!p.getAllowFlight()) p.setAllowFlight(true);
if(!p.isFlying()) p.setFlying(true);
if(_tick%3 == 0) p.teleport(loc);
}
_tick++;
}
@Override
protected void finish(Location loc)
{}
};
_cryptView = WorldData.GetCustomLocs("CryptView").get(0);
_cryptView.setDirection(getClosest(_cryptView, "PINK").subtract(_cryptView).toVector());
AnimatorFactory factory = new AnimatorFactory();
double lastEntry = 0;
double firstEntry = Double.MAX_VALUE;
Location first = null;
for(Entry<String, ArrayList<Location>> point : WorldData.GetAllCustomLocs().entrySet())
{
String[] args = point.getKey().split(" ");
if(args.length < 2) continue;
if(args[0].equals("Intro"))
{
try
{
double sec = Double.parseDouble(args[1]);
double delay = 0;
try
{
delay = Double.parseDouble(args[2]);
}
catch(Exception e1) {}
int tick = (int) (sec*20);
int tickdelay = (int) (delay*20);
Location loc = point.getValue().get(0);
Location lookingAt = getClosest(loc, "PINK");
loc.setDirection(lookingAt.subtract(loc).toVector());
factory.addLocation(loc, tick);
if(tickdelay > 0) factory.addLocation(loc, tickdelay);
if(sec > lastEntry) lastEntry = sec;
if(delay > lastEntry) lastEntry = delay;
if(sec < firstEntry)
{
firstEntry = sec;
first = loc.clone();
}
}
catch(Exception e2) {}
}
}
System.out.print("Scanned " + WorldData.GetAllCustomLocs().entrySet().size() + " data points");
List<AnimationPoint> animation = factory.getBuildList(first);
_introAnimator.addPoints(animation);
System.out.println("Loaded intro animation with " + _introAnimator.getSet().size() + " | " + animation.size() + " points and duration of " + lastEntry + "s");
GameTeam team = GetTeamList().get(0);
team.setTutorial(new TutorialHalloween2016(this, _introAnimator, team, first, (int) (lastEntry * 20)));
}
public Location getInfrontOfCrypt()
{
return WorldData.GetCustomLocs("PumpkinKing Win").get(0).clone();
}
public Location getPrinceTargetInfrontOfCrypt()
{
return WorldData.GetCustomLocs("PrinceTarget").get(0).clone();
}
public Location getPrinceSpawn()
{
return WorldData.GetCustomLocs("PrinceSpawn").get(0).clone();
}
public Location getClosest(Location loc, String dataSet)
{
Location c = null;
double dist = 0;
for(Location l : WorldData.GetDataLocs(dataSet))
{
double ldist = loc.distanceSquared(l);
if(c == null || ldist <= dist)
{
c = l;
dist = ldist;
}
}
if(c == null) return null;
return c.clone();
}
public Crypt getCrypt()
{
return _crypt;
}
public Location getGiantSpawn()
{
return getMainLane().get(UtilMath.r(getMainLane().size()));
}
public List<Location> getMainLane()
{
return WorldData.GetDataLocs("RED");
}
public List<Location> getLeftLane()
{
return WorldData.GetDataLocs("MAGENTA");
}
public List<Location> getBackLane()
{
return WorldData.GetDataLocs("LIGHT_BLUE");
}
public List<Location> getRightLane()
{
return WorldData.GetDataLocs("YELLOW");
}
public List<Location> getGraveLane()
{
return WorldData.GetDataLocs("MAGENTA");
}
public List<Location> getRandomLane()
{
List<Location> lane = new ArrayList<>();
lane.addAll(_lanes.get(UtilMath.r(_lanes.size())));
return lane;
}
public List<Location> getMobSpawns()
{
List<Location> list = new ArrayList<>();
for(List<Location> lane : _lanes)
{
list.addAll(lane);
}
return list;
}
public List<Location> getPumkinSpawns()
{
return new ArrayList<>(WorldData.GetDataLocs("ORANGE"));
}
public List<Location> getInfrontOfDoorTargets()
{
return new ArrayList<>(WorldData.GetDataLocs("BLUE"));
}
public Location getDoorSchematicLocation()
{
return WorldData.GetCustomLocs("Door Schematic Paste").get(0).clone();
}
@EventHandler
public void updatePumpkinPlants(UpdateEvent event)
{
if(!IsLive()) return;
if(event.getType() != UpdateType.TICK) return;
List<PumpkinPlant> notGrowing = new ArrayList<>();
int growing = 0;
for(PumpkinPlant plant : _pumpkins)
{
if(plant.isGrowing())
{
growing++;
}
else
{
notGrowing.add(plant);
}
plant.tick();
}
if(!notGrowing.isEmpty() && growing + getPumplings().size() < getMaxPumplings())
{
notGrowing.get(UtilMath.r(notGrowing.size())).startGrow();
}
}
public Location getCryptView()
{
return _cryptView.clone();
}
@Override
@EventHandler
public void WaveUpdate(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
return;
if (!IsLive())
return;
if(_crypt.isDestroyed() && !(_waves.get(_wave) instanceof WaveBoss) && !(_waves.get(_wave) instanceof WaveVictory))
{
for(CreatureBase<?> c : _mobs)
{
c.remove();
}
Announce(F.main("Objective", C.cRed + C.Bold + "Objective failed!"));
endGame(GetTeam(ChatColor.RED));
return;
}
super.WaveUpdate(event);
}
@EventHandler
public void onUpdateCrypt(UpdateEvent event)
{
if(event.getType() != UpdateType.TICK) return;
if(!IsLive()) return;
if(_crypt.isDestroyed()) return;
_crypt.updateHealthDisplay();
}
@EventHandler
public void onInteract(PlayerInteractEvent event)
{
if(event.getAction() != Action.LEFT_CLICK_BLOCK) return;
if(event.getClickedBlock() == null) return;
Block block = event.getClickedBlock();
for(PumpkinPlant plant : _pumpkins)
{
plant.hit(block);
}
}
@Override
public void AddCreature(CreatureBase<?> mob)
{
AddCreature(mob, true);
}
public void AddCreature(CreatureBase<?> mob, boolean cap)
{
super.AddCreature(mob);
if(!cap) return;
if(mob instanceof MobPumpling)
{
_pumplings.add((MobPumpling) mob);
}
else
{
_nonPumplings.add(mob);
}
}
public List<MobPumpling> getPumplings()
{
return _pumplings;
}
public List<CreatureBase<?>> getNonPumplings()
{
return _nonPumplings;
}
public int getMaxNonPumplings()
{
return _maxNonPumplings;
}
@Override
public void onRemove(CreatureBase<?> mob)
{
_pumplings.remove(mob);
_nonPumplings.remove(mob);
}
@EventHandler
public void onCommand(PlayerCommandPreprocessEvent event)
{
if(!UtilServer.isTestServer()) return;
String[] args = event.getMessage().split(" ");
boolean orig = event.isCancelled();
event.setCancelled(true);
if(args[0].equalsIgnoreCase("/setwave"))
{
if(event.getMessage().matches("/setwave [0-9]+"))
{
Announce(event.getPlayer().getName() + " set wave to " + args[1], true);
_wave = Integer.parseInt(args[1]);
}
else
{
event.getPlayer().sendMessage("Use /setwave #Wave");
}
}
else if(args[0].equalsIgnoreCase("/god"))
{
Announce(event.getPlayer().getName() + " made everyone 'gods'", true);
for(Player p : GetPlayers(false))
{
p.addPotionEffect(new PotionEffect(PotionEffectType.REGENERATION, 99999, 200, true, false), true);
p.addPotionEffect(new PotionEffect(PotionEffectType.SATURATION, 99999, 200, true, false), true);
p.addPotionEffect(new PotionEffect(PotionEffectType.NIGHT_VISION, 99999, 200, true, false), true);
}
}
else if(args[0].equalsIgnoreCase("/degod"))
{
Announce(event.getPlayer().getName() + " made everyone no longer 'gods'", true);
for(Player p : GetPlayers(false))
{
p.removePotionEffect(PotionEffectType.REGENERATION);
p.removePotionEffect(PotionEffectType.SATURATION);
p.removePotionEffect(PotionEffectType.NIGHT_VISION);
}
}
else if(args[0].equals("/tutorial"))
{
if(args.length != 2)
{
event.getPlayer().sendMessage("Use /tutorial <true/false> - true = tutorial enabled before game");
return;
}
if(args[1].equalsIgnoreCase("true") || args[1].equalsIgnoreCase("on"))
{
DO_TUTORIALS = true;
Announce(event.getPlayer().getName() + " enabled tutorials before games starts");
}
else if(args[1].equalsIgnoreCase("false") || args[1].equalsIgnoreCase("off"))
{
DO_TUTORIALS = false;
Announce(event.getPlayer().getName() + " disabled tutorials before games starts");
}
else
{
event.getPlayer().sendMessage("Use /tutorial <true/false> - true = tutorial enabled before game");
}
EnableTutorials = DO_TUTORIALS;
}
else
{
event.setCancelled(orig);
}
}
@EventHandler
public void onDeath(EntityDeathEvent event)
{
if(event.getEntity().getKiller() != null)
{
AddGems(event.getEntity().getKiller(), 0.2, "Mobs Killed", true, true);
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void Clean(GameStateChangeEvent event)
{}
@Override
@EventHandler(priority = EventPriority.MONITOR)
public void TeamGen(GameStateChangeEvent event)
{
if (event.GetState() != GameState.Live)
return;
GetTeamList().add(new GameTeam(this, "Pumpkin Prince", ChatColor.RED, WorldData.GetDataLocs("RED")));
}
@Override
public void EndCheck()
{
if (!IsLive())
return;
if (_wave >= _waves.size())
{
for (Player player : GetPlayers(false))
{
Manager.GetGame().AddGems(player, 30, "Killing the Pumpkin Prince", false, false);
Manager.GetGame().AddGems(player, 10, "Participation", false, false);
}
if (Manager.IsRewardItems())
{
SetCustomWinLine("You earned the Grim Reaper Pet!");
for (Player player : GetPlayers(false))
{
//Prevent game hopping
if (!player.isOnline())
continue;
PetReward pr = new PetReward(Manager.getCosmeticManager().getPetManager(), Manager.getInventoryManager(), Manager.GetDonation(), "Grim Reaper", "Grim Reaper", EntityType.BLAZE, RewardRarity.OTHER, 0, 0);
if (pr.canGiveReward(player))
{
pr.giveReward(null, player, data -> {});
}
}
}
AnnounceEnd(this.GetTeamList().get(0));
SetState(GameState.End);
}
else if (GetPlayers(true).size() == 0)
{
for (Player player : GetPlayers(false))
{
Manager.GetGame().AddGems(player, 10, "Participation", false, false);
}
AnnounceEnd(this.GetTeamList().get(1));
SetState(GameState.End);
}
}
}

View File

@ -0,0 +1,107 @@
package nautilus.game.arcade.game.games.halloween2016;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.material.MaterialData;
import nautilus.game.arcade.game.games.halloween2016.creatures.MobPumpling;
public class PumpkinPlant
{
/**
* Defines how fast the pumpkin is going to blink. the closer to 1, the faster the blinking.
*/
private static final double BLINK_SPEED = 0.95;
private Halloween2016 _game;
private int _growTicksTotal = 30 * 20;
private int _growTick;
private int _sleep;
private Block _growing = null;
private int _health;
public PumpkinPlant(Halloween2016 game, Location loc)
{
_growing = loc.getBlock();
_game = game;
}
public void startGrow()
{
if(isGrowing()) return;
_growing.setType(Material.PUMPKIN);
_growTick = _growTicksTotal;
_sleep = _growTick;
_health = 3;
}
public boolean isGrowing()
{
return _growing != null &&_growing.getType() != Material.AIR;
}
public void tick()
{
if(!isGrowing()) return;
if(_sleep > _growTick)
{
_sleep *= BLINK_SPEED;
Material old = _growing.getType();
_growing.setType(old == Material.PUMPKIN ? Material.JACK_O_LANTERN : Material.PUMPKIN);
}
_growTick--;
if(_growTick == 0)
{
spawn();
}
}
public void spawn()
{
_growing.setType(Material.AIR);
_growTick = 0;
_sleep = 0;
Location loc = _growing.getLocation().add(0.5, 0, 0.5);
_game.AddCreature(new MobPumpling(_game, loc));
loc.getWorld().playEffect(loc, Effect.LARGE_SMOKE, 4);
}
public void hit(Block block)
{
if(block.equals(_growing))
{
_health--;
Location loc = _growing.getLocation().add(0.5, 0, 0.5);
if(_health <= 0)
{
_growing.setType(Material.AIR);
_growTick = 0;
_sleep = 0;
loc.getWorld().playEffect(loc, Effect.TILE_BREAK, new MaterialData(Material.PUMPKIN));
_growing = null;
}
else
{
loc.getWorld().playSound(loc, Sound.DIG_WOOL, 1, 1);
}
}
}
}

View File

@ -0,0 +1,256 @@
package nautilus.game.arcade.game.games.halloween2016.creatures;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.entity.Creature;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityTargetEvent;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import nautilus.game.arcade.game.games.halloween.creatures.CreatureBase;
import nautilus.game.arcade.game.games.halloween.creatures.InterfaceMove;
import nautilus.game.arcade.game.games.halloween2016.Crypt;
import nautilus.game.arcade.game.games.halloween2016.Halloween2016;
import net.minecraft.server.v1_8_R3.PacketPlayOutAnimation;
public abstract class CryptBreaker<T extends Creature> extends CreatureBase<T> implements InterfaceMove
{
protected final Crypt _crypt;
protected final List<Location> _doorLocations = new ArrayList<>();
protected final int _cryptDamage;
protected final int _cryptDamageRate;
protected double _playerTargetForwardRange = 4;
protected double _playerTargetBackRange = 1;
protected double _playerFollowRange = 5;
protected double _customCryptRange = -1;
protected double _extraDamage;
protected float _speed;
protected boolean _targetPlayers = true;
protected Halloween2016 Host16;
public CryptBreaker(Halloween2016 game, String name, Class<T> mobClass, Location loc, int cryptDamage, int cryptDamageRate, float speed)
{
super(game, name, mobClass, loc);
_crypt = game.getCrypt();
_doorLocations.addAll(game.getInfrontOfDoorTargets());
_cryptDamage = cryptDamage;
_cryptDamageRate = cryptDamageRate;
_speed = speed;
Host16 = game;
Creature ent = GetEntity();
UtilEnt.setTickWhenFarAway(ent, true);
ent.setRemoveWhenFarAway(false);
}
@Override
public void SpawnCustom(T ent)
{}
@Override
public void Update(UpdateEvent event)
{
if(event.getType() != UpdateType.TICK) return;
if(inCryptRange())
{
attackCrypt();
}
}
public boolean inCryptRange()
{
double width = UtilEnt.getWidth(GetEntity());
if(_customCryptRange != -1)
{
width = _customCryptRange;
}
if(getClosestDoor().distanceSquared(GetEntity().getLocation()) <= width*width)
{
return true;
}
return false;
}
public void attackCrypt()
{
if(!_crypt.tryDamage(GetEntity(), _cryptDamage, _cryptDamageRate)) return;
GetEntity().getWorld().playSound(GetEntity().getLocation(), Sound.ZOMBIE_WOODBREAK, 1, 0.7f + UtilMath.random.nextFloat() * 0.5f);
swingArms();
}
public void swingArms()
{
PacketPlayOutAnimation packet = new PacketPlayOutAnimation();
packet.a = GetEntity().getEntityId();
packet.b = 0;
for(Player p : Host.GetPlayers(false))
{
UtilPlayer.sendPacket(p, packet);
}
}
@Override
public void Damage(CustomDamageEvent event)
{
if(_extraDamage > 0)
{
if(GetEntity().equals(event.GetDamagerEntity(true)))
{
event.AddMod("Mod", _extraDamage);
}
}
}
@Override
public void Target(EntityTargetEvent event)
{
if(_crypt.isDestroyed()) return;
if(!event.getEntity().equals(GetEntity())) return;
if(event.getTarget() == null) return;
if(!_targetPlayers)
{
event.setCancelled(true);
return;
}
if(!(event.getTarget() instanceof Player))
{
event.setCancelled(true);
return;
}
if(inCryptRange())
{
event.setCancelled(true);
return;
}
Location door = getClosestDoor();
Location target = event.getTarget().getLocation();
if(target.distanceSquared(door) - _playerTargetBackRange*_playerTargetBackRange > door.distanceSquared(GetEntity().getLocation()))
{
event.setCancelled(true);
return;
}
if(target.distanceSquared(GetEntity().getLocation()) <= _playerTargetForwardRange*_playerTargetForwardRange)
{
event.setCancelled(true);
return;
}
}
@Override
public Location GetRoamTarget()
{
if(_crypt.isDestroyed()) return GetPlayerTarget();
Location door = getClosestDoor();
double distDoor = door.distanceSquared(GetEntity().getLocation());
if(!_targetPlayers) return door;
Player player = null;
double distance = -1;
for(Player p : Host.GetPlayers(true))
{
if(p.getLocation().distanceSquared(door) - _playerTargetBackRange*_playerTargetBackRange > distDoor) continue;
double dist = GetEntity().getLocation().distanceSquared(p.getLocation());
if(player == null || dist < distance)
{
player = p;
distance = dist;
}
}
if(player != null && distance <= _playerTargetForwardRange*_playerTargetForwardRange)
{
GetEntity().setTarget(player);
return player.getLocation();
}
return door;
}
@Override
public void Move()
{
if(_crypt.isDestroyed())
{
CreatureMove(GetEntity());
return;
}
Location door = getClosestDoor();
double distDoor = door.distanceSquared(GetEntity().getLocation());
if(GetEntity().getTarget() != null)
{
Location target = GetEntity().getTarget().getLocation();
if(target.distanceSquared(door) - _playerFollowRange*_playerFollowRange > distDoor)
{
GetEntity().setTarget(null);
SetTarget(GetRoamTarget());
}
}
if(GetEntity().getTarget() == null)
{
SetTarget(GetRoamTarget());
}
if(_customCryptRange > 0)
{
if(distDoor <= _customCryptRange*_customCryptRange)
{
SetTarget(GetEntity().getLocation());
}
}
if(GetTarget() != null)
{
UtilEnt.CreatureMove(GetEntity(), GetTarget(), _speed);
Host.moves++;
}
}
public Location getClosestDoor()
{
Location loc = GetEntity().getLocation();
Location door = null;
double dist = -1;
for(Location d : _doorLocations)
{
double testDist = d.distanceSquared(loc);
if(door == null || testDist < dist)
{
door = d;
dist = testDist;
}
}
return door.clone();
}
}

View File

@ -0,0 +1,23 @@
package nautilus.game.arcade.game.games.halloween2016.creatures;
import org.bukkit.Location;
import org.bukkit.entity.Blaze;
import mineplex.core.common.util.C;
import nautilus.game.arcade.game.games.halloween2016.Halloween2016;
public class MobBlaze extends CryptBreaker<Blaze>
{
private static int CRYPT_DAMAGE = 10;
private static int CRYPT_RATE = 30;
private static float SPEED = 1;
public MobBlaze(Halloween2016 game, Location loc)
{
super(game, C.cYellow + "Blaze", Blaze.class, loc, CRYPT_DAMAGE, CRYPT_RATE, SPEED);
}
}

View File

@ -0,0 +1,83 @@
package nautilus.game.arcade.game.games.halloween2016.creatures;
import java.lang.reflect.Method;
import net.minecraft.server.v1_8_R3.EntityCreeper;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftCreeper;
import org.bukkit.entity.Creeper;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilReflection;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import nautilus.game.arcade.game.games.halloween2016.Halloween2016;
public class MobCreeper extends CryptBreaker<Creeper>
{
public static final int CRYPT_DAMAGE = 200;
public static float SPEED = 0.8f;
private boolean exploded = false;
public MobCreeper(Halloween2016 game, Location loc)
{
super(game, C.cYellow + "Creeper", Creeper.class, loc, 0, 0, SPEED);
_extraDamage = 5;
_targetPlayers = false;
}
@Override
public void Update(UpdateEvent event)
{
if(event.getType() != UpdateType.TICK) return;
if(_crypt.isDestroyed()) return;
double width = UtilEnt.getWidth(GetEntity());
EntityCreeper c = ((CraftCreeper)GetEntity()).getHandle();
if(getClosestDoor().distanceSquared(GetEntity().getLocation()) <= width*width)
{
c.co();
}
int fuse = (int) UtilReflection.getValueOfField(c, "fuseTicks");
int max = (int) UtilReflection.getValueOfField(c, "maxFuseTicks");
if(fuse >= max-1)
{
_crypt.tryDamage(GetEntity(), CRYPT_DAMAGE, 0);
exploded = true;
}
}
@Override
public void remove()
{
if(!exploded && GetEntity().isDead())
{
//Make creeper explode, even if dead using NMS code
try
{
EntityCreeper nms = ((CraftCreeper)GetEntity()).getHandle();
Method explodeMethod = nms.getClass().getDeclaredMethod("cr");
explodeMethod.setAccessible(true);
explodeMethod.invoke(nms);
}
catch(Exception e)
{
e.printStackTrace();
}
}
super.remove();
}
}

View File

@ -0,0 +1,190 @@
package nautilus.game.arcade.game.games.halloween2016.creatures;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.entity.Giant;
import org.bukkit.entity.Player;
import org.bukkit.entity.Zombie;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilText;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import nautilus.game.arcade.game.games.halloween2016.Halloween2016;
public class MobGiant extends CryptBreaker<Giant>
{
//Instant destroy crypt
public static final int CRYPT_DAMAGE = 100000;
public static final int CRYPT_DAMAGE_COOLDOWN = 1;
public static final float SPEED = 0.5f;
private static double DAMAGE = 9000;
private static double KNOCKBACK = 8;
private static double HEALTH = 200;
private static float EXTRA_EXPLOSION_DAMAGE = 10;
private boolean _cryptDestroyed = false;
private Zombie _pathDummy;
private Player _target;
public MobGiant(Halloween2016 game, Location loc)
{
super(game, null, Giant.class, loc, CRYPT_DAMAGE, CRYPT_DAMAGE_COOLDOWN, SPEED);
_customCryptRange = 3;
}
@Override
public void SpawnCustom(Giant ent)
{
_pathDummy = ent.getWorld().spawn(ent.getLocation(), Zombie.class);
super.Host.Manager.GetCondition().Factory().Invisible("Cloak", _pathDummy, _pathDummy, 999999, 0, false, false, false);
_pathDummy.setCustomNameVisible(true);
ent.setMaxHealth(HEALTH);
ent.setHealth(ent.getMaxHealth());
UtilEnt.setBoundingBox(_pathDummy, 0, 0);
UtilEnt.Vegetate(_pathDummy, true);
UtilEnt.setStepHeight(_pathDummy, 1);
//Prevent other mobs from pushing the giant
UtilEnt.ghost(_pathDummy, true, true);
_pathDummy.setRemoveWhenFarAway(false);
UtilEnt.setTickWhenFarAway(_pathDummy, true);
addEntityPart(_pathDummy);
}
@Override
public void Update(UpdateEvent event)
{
if(event.getType() == UpdateType.TICK)
{
move();
updateHealthBar();
}
if(!_cryptDestroyed && _crypt.isDestroyed())
{
SetTarget(null);
_cryptDestroyed = true;
}
}
private Player getRandomPlayer()
{
List<Player> players = Host.GetPlayers(true);
return players.get(UtilMath.r(players.size()));
}
private void move()
{
if(_target != null)
{
if(!_target.isOnline() || !_target.isValid() || !Host.GetPlayers(true).contains(_target))
{
_target = null;
}
}
Location target = GetTarget();
if(target == null && _target == null)
{
if(_crypt.isDestroyed())
{
_target = getRandomPlayer();
}
else
{
target = getClosestDoor();
}
SetTarget(target);
}
if(_target != null)
{
target = _target.getLocation();
}
UtilEnt.CreatureMove(_pathDummy, target, SPEED);
GetEntity().teleport(_pathDummy);
if(!_crypt.isDestroyed())
{
if(getClosestDoor().distanceSquared(GetEntity().getLocation()) <= _customCryptRange*_customCryptRange)
{
if(!_crypt.tryDamage(GetEntity(), _cryptDamage, _cryptDamageRate)) return;
GetEntity().getWorld().playSound(GetEntity().getLocation(), Sound.ZOMBIE_WOODBREAK, 1, 0.7f + UtilMath.random.nextFloat() * 0.5f);
swingArms();
}
}
boolean hit = false;
for(Player p : getInsideBoundingBox())
{
Host.getArcadeManager().GetDamage().NewDamageEvent(p, GetEntity(), null, GetEntity().getLocation(), DamageCause.ENTITY_ATTACK, DAMAGE, true, false, false, "Giant", "Giant Damage", false);
hit = true;
}
if(hit)
{
swingArms();
GetEntity().getWorld().playSound(GetEntity().getLocation(), Sound.ZOMBIE_IDLE, 2, 0.5f);
}
}
@Override
public void Move()
{}
@Override
public void Damage(CustomDamageEvent event)
{
if(_pathDummy.equals(event.GetDamageeEntity()))
{
event.SetCancelled("Invalid Entity");
return;
}
if(event.GetDamageeEntity().equals(GetEntity()))
{
event.SetKnockback(false);
if(event.GetCause() == DamageCause.SUFFOCATION)
{
event.SetCancelled("Invalid Giant Damage");
return;
}
else if(event.GetCause() == DamageCause.ENTITY_EXPLOSION)
{
event.AddMod("Explosion", EXTRA_EXPLOSION_DAMAGE);
}
}
if(!GetEntity().equals(event.GetDamagerEntity(false))) return;
event.SetKnockback(true);
event.AddKnockback("Giant Knockback", KNOCKBACK);
}
public void updateHealthBar()
{
_pathDummy.setCustomName(UtilText.getProgress(C.cGreen, GetEntity().getHealth()/GetEntity().getMaxHealth(), C.cGray, false));
}
}

View File

@ -0,0 +1,70 @@
package nautilus.game.arcade.game.games.halloween2016.creatures;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.entity.Zombie;
import org.bukkit.event.entity.EntityTargetEvent;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilParticle.ViewDist;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import nautilus.game.arcade.game.games.halloween.Halloween;
import nautilus.game.arcade.game.games.halloween.creatures.CreatureBase;
import nautilus.game.arcade.game.games.halloween.creatures.InterfaceMove;
public class MobMiniZombie extends CreatureBase<Zombie> implements InterfaceMove
{
private static final double HEALTH = 5;
public MobMiniZombie(Halloween game, Location loc)
{
super(game, C.cYellow + "Baby Zombie", Zombie.class, loc);
}
@Override
public void SpawnCustom(Zombie ent)
{
ent.setBaby(true);
ent.setMaxHealth(HEALTH);
ent.setHealth(HEALTH);
}
@Override
public void Update(UpdateEvent event)
{
}
@Override
public void Damage(CustomDamageEvent event)
{
}
@Override
public void Target(EntityTargetEvent event)
{
}
@Override
public void Move()
{
CreatureMove(GetEntity(), 1f);
}
@Override
public void remove()
{
super.remove();
UtilParticle.PlayParticleToAll(ParticleType.LARGE_SMOKE, GetEntity().getLocation(), null, 0.1f, 10, ViewDist.NORMAL);
GetEntity().getWorld().playSound(GetEntity().getLocation(), Sound.FIZZ, 0.8f, 0.3f);
}
}

View File

@ -0,0 +1,72 @@
package nautilus.game.arcade.game.games.halloween2016.creatures;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.entity.Zombie;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.util.C;
import mineplex.core.disguise.disguises.DisguisePigZombie;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import nautilus.game.arcade.game.games.halloween2016.Halloween2016;
public class MobPigZombie extends CryptBreaker<Zombie>
{
private static float SPEED = 1;
private static int CRYPT_DAMAGE = 3;
private static int CRYPT_RATE = 20;
private static int FIRE_TICKS = 60;
public MobPigZombie(Halloween2016 game, Location loc)
{
super(game, C.cYellow + "Pigman Warrior", Zombie.class, loc, CRYPT_DAMAGE, CRYPT_RATE, SPEED);
_extraDamage = 5;
}
@Override
public void SpawnCustom(Zombie ent)
{
ent.getEquipment().setItemInHand(new ItemStack(Material.GOLD_SWORD));
DisguisePigZombie disg = new DisguisePigZombie(ent);
Host.getArcadeManager().GetDisguise().disguise(disg);
}
@Override
public void Update(UpdateEvent event)
{
super.Update(event);
if(event.getType() == UpdateType.TICK)
{
GetEntity().setFireTicks(5);
}
}
@Override
public void Damage(CustomDamageEvent event)
{
if(event.GetDamageeEntity() instanceof Player)
{
if(GetEntity().equals(event.GetDamagerEntity(false)))
{
event.GetDamageeEntity().setFireTicks(FIRE_TICKS);
}
}
else if(GetEntity().equals(event.GetDamageeEntity()))
{
if(event.GetCause() == DamageCause.FIRE || event.GetCause() == DamageCause.FIRE_TICK)
{
event.SetCancelled("Cancel Fire");
}
}
}
}

View File

@ -0,0 +1,236 @@
package nautilus.game.arcade.game.games.halloween2016.creatures;
import java.util.List;
import net.minecraft.server.v1_8_R3.PacketPlayOutAnimation;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Horse.Variant;
import org.bukkit.entity.Player;
import org.bukkit.entity.Skeleton;
import org.bukkit.entity.Zombie;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.EntityTargetEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import org.spigotmc.event.entity.EntityDismountEvent;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilParticle.ViewDist;
import mineplex.core.disguise.disguises.DisguiseHorse;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import nautilus.game.arcade.game.games.halloween.Halloween;
import nautilus.game.arcade.game.games.halloween.creatures.CreatureBase;
public class MobPrinceGuard extends CreatureBase<Skeleton>
{
private Zombie _horse;
private DisguiseHorse _horseDisguise;
private MobPumpkinPrince _prince;
private Entity _target;
private Location _strikeTarget;
private long _strikeStamp;
private boolean _AI = true;
private final static float HORSE_SPEED = 1.8f;
private final static float HORSE_SPEED_CHARGE = 2.3f;
private final static double STRIKE_RANGE = 10;
private final static long MAX_STRIKE_TIME = 10_000;
private final static long STRIKE_COOLDOWN = 15_000;
private final static double DAMAGE = 5;
private final static double KNOCKBACK = 3;
private final static double HEALTH = 50;
public MobPrinceGuard(Halloween game, Location loc, MobPumpkinPrince prince)
{
super(game, C.cYellow + C.Bold + "Prince Guard", Skeleton.class, loc);
_prince = prince;
}
public Zombie getHorse()
{
return _horse;
}
@Override
public void SpawnCustom(Skeleton ent)
{
ent.getEquipment().setItemInHand(new ItemStack(Material.IRON_SWORD));
ent.getEquipment().setHelmet(new ItemStack(Material.PUMPKIN));
_horse = ent.getWorld().spawn(ent.getLocation(), Zombie.class);
_horseDisguise = new DisguiseHorse(_horse);
_horseDisguise.setType(Variant.SKELETON_HORSE);
Host.getArcadeManager().GetDisguise().disguise(_horseDisguise);
_horse.setRemoveWhenFarAway(false);
UtilEnt.setTickWhenFarAway(_horse, true);
UtilEnt.setStepHeight(_horse, 1);
UtilEnt.setBoundingBox(_horse, 0, 0);
UtilEnt.setTickWhenFarAway(ent, true);
ent.setRemoveWhenFarAway(true);
ent.setMaxHealth(HEALTH);
ent.setHealth(ent.getMaxHealth());
_horse.setPassenger(ent);
_horse.setVegetated(true);
//UtilEnt#silence doesn't seem to work. Using native silence instead
((CraftEntity)_horse).getHandle().b(true);
addEntityPart(_horse);
}
public void setAI(boolean aI)
{
_AI = aI;
}
public boolean getAI()
{
return _AI;
}
@Override
public void Update(UpdateEvent event)
{
if(event.getType() != UpdateType.TICK) return;
if(!_AI) return;
if(_strikeTarget != null)
{
if(_strikeStamp < System.currentTimeMillis())
{
_strikeTarget = null;
}
else if(UtilEnt.canEntityWalkCloserToNavigationTarget(_horse))
{
_strikeTarget = null;
return;
}
else
{
_horse.getWorld().playSound(_horse.getLocation(), Sound.FIZZ, 0.2f, 1f);
_horse.getWorld().playSound(_horse.getLocation(), Sound.SKELETON_WALK, 0.2f, 0.5f);
UtilParticle.PlayParticleToAll(ParticleType.SMOKE, _horse.getLocation(), null, 0.1f, 5, ViewDist.NORMAL);
UtilParticle.PlayParticleToAll(ParticleType.FLAME, _horse.getLocation(), null, 0.1f, 5, ViewDist.NORMAL);
}
}
List<Player> inGame = Host.GetPlayers(true);
if(_target == null || !inGame.contains(_target))
{
double dist = 0;
for(Player p : inGame)
{
double d = p.getLocation().distanceSquared(_prince.getHorse().getLocation());
if(_target == null || dist > d)
{
dist = d;
_target = p;
}
}
}
Location target = _target.getLocation();
Vector diff = target.clone().subtract(_horse.getLocation()).toVector();
if(_strikeStamp + STRIKE_COOLDOWN > System.currentTimeMillis() || diff.lengthSquared() >= STRIKE_RANGE*STRIKE_RANGE)
{
diff.normalize().multiply(STRIKE_RANGE*2);
target.add(diff);
SetTarget(target);
UtilEnt.CreatureMove(_horse, GetTarget(), HORSE_SPEED);
}
else
{
_target = null;
_strikeTarget = target;
_strikeStamp = System.currentTimeMillis() + MAX_STRIKE_TIME;
UtilEnt.CreatureMove(_horse, GetTarget(), HORSE_SPEED_CHARGE);
}
for(Player p : getInsideBoundingBox())
{
Host.getArcadeManager().GetDamage().NewDamageEvent(p, _horse, null, _horse.getLocation(), DamageCause.ENTITY_ATTACK, DAMAGE, true, false, false, "Prince Guard", "Horse Kick", false);
}
}
@Override
public void Damage(CustomDamageEvent event)
{
if(_horse.equals(event.GetDamageeEntity()))
{
event.setDamagee(GetEntity());
}
if(GetEntity().equals(event.GetDamageeEntity()))
{
if(_prince.equals(event.GetDamagerEntity(true)))
{
if(event.GetProjectile() != null)
{
event.GetProjectile().setFireTicks(0);
}
event.SetCancelled("Cancel");
return;
}
if(!_AI)
{
event.SetCancelled("No AI");
return;
}
if(!event.isCancelled() && _horse != null && _horse.isValid())
{
PacketPlayOutAnimation hurt = new PacketPlayOutAnimation();
hurt.a = _horseDisguise.getEntityId();
hurt.b = 1;
_horseDisguise.sendPacket(hurt);
}
}
else if(event.GetDamageeEntity() instanceof Player)
{
if(_horse.equals(event.GetDamagerEntity(false)))
{
event.AddKnockback("Horse Knockback", KNOCKBACK);
}
}
}
@Override
public void Target(EntityTargetEvent event)
{}
@EventHandler
public void onDismount(EntityDismountEvent event)
{
if(event.getDismounted().equals(GetEntity())) event.setCancelled(true);
}
}

View File

@ -0,0 +1,478 @@
package nautilus.game.arcade.game.games.halloween2016.creatures;
import net.minecraft.server.v1_8_R3.PacketPlayOutAnimation;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftZombie;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Fireball;
import org.bukkit.entity.Horse.Variant;
import org.bukkit.entity.Player;
import org.bukkit.entity.Skeleton;
import org.bukkit.entity.Skeleton.SkeletonType;
import org.bukkit.entity.Snowball;
import org.bukkit.entity.Zombie;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.EntityShootBowEvent;
import org.bukkit.event.entity.EntityTargetEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.util.Vector;
import org.spigotmc.event.entity.EntityDismountEvent;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilItem;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilParticle.ViewDist;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTextTop;
import mineplex.core.disguise.disguises.DisguiseHorse;
import mineplex.core.recharge.Recharge;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import nautilus.game.arcade.game.games.halloween.creatures.CreatureBase;
import nautilus.game.arcade.game.games.halloween2016.Halloween2016;
public class MobPumpkinPrince extends CreatureBase<Skeleton> implements Listener
{
private Halloween2016 Host;
private Zombie _horse;
private DisguiseHorse _horseDisguise;
private boolean _AI = false;
private boolean _invulnerable = false;
private long _horseKick = 0;
private static final long HORSE_KICK_DURATION = 1000;
private static final double HORSE_KICK_DAMAGE = 5;
private static final float HORSE_SPEED = 1.5f;
private static final double STAGE_3_KNOCKBACK = 3;
private static final double HORSE_KNOCKBACK = 3;
private static final double HEALTH = 1000;
public MobPumpkinPrince(Halloween2016 game, Location loc)
{
super(game, C.cRed + C.Bold + "Pumpkin Prince", Skeleton.class, loc);
Host = game;
}
@Override
public void SpawnCustom(Skeleton ent)
{
ent.getEquipment().setHelmet(new ItemStack(Material.PUMPKIN));
ent.getEquipment().setItemInHand(new ItemStack(Material.BOW));
ent.setMaxHealth(HEALTH);
ent.setHealth(ent.getMaxHealth());
ent.setSkeletonType(SkeletonType.WITHER);
super.Host.CreatureAllowOverride = true;
_horse = ent.getWorld().spawn(ent.getLocation(), Zombie.class);
super.Host.CreatureAllowOverride = false;
_horseDisguise = new DisguiseHorse(_horse);
_horseDisguise.setType(Variant.SKELETON_HORSE);
super.Host.getArcadeManager().GetDisguise().disguise(_horseDisguise);
UtilEnt.setStepHeight(ent, 1);
UtilEnt.setStepHeight(_horse, 1);
UtilEnt.setBoundingBox(_horse, 0, 0);
//For some reason 'UtilEnt.silence' doesn't work, so using native silence instead
//UtilEnt.silence(_horse, true);
((CraftZombie)_horse).getHandle().b(true);
_horse.setPassenger(ent);
UtilEnt.Vegetate(_horse);
UtilServer.RegisterEvents(this);
UtilEnt.setTickWhenFarAway(ent, true);
ent.setRemoveWhenFarAway(false);
UtilEnt.setTickWhenFarAway(_horse, true);
_horse.setRemoveWhenFarAway(false);
addEntityPart(_horse);
}
public void setInvulnerable(boolean invulnerable)
{
_invulnerable = invulnerable;
}
public boolean isInvulnerable()
{
return _invulnerable;
}
public void setAI(boolean AI)
{
_AI = AI;
}
public boolean getAI()
{
return _AI;
}
@Override
public void Update(UpdateEvent event)
{
if(!_AI) return;
if(event.getType() != UpdateType.TICK) return;
UtilTextTop.displayProgress(C.cYellow + C.Bold + "Pumpkin Prince", getHealthProgress(), UtilServer.getPlayers());
int state = getState();
if(_horse.isValid() && state > 1)
{
_horse.getWorld().playSound(_horse.getLocation(), Sound.BLAZE_DEATH, 3, 1);
UtilParticle.PlayParticleToAll(ParticleType.LARGE_SMOKE, _horse.getLocation(), null, 0.5f, 20, ViewDist.NORMAL);
_horse.setHealth(0);
}
if(state == 1)
{
Entity target = GetEntity().getTarget();
if(target != null)
{
UtilEnt.CreatureMove(_horse, GetEntity().getTarget().getLocation(), HORSE_SPEED);
boolean hit = false;
for(Player p : getInsideBoundingBox())
{
CustomDamageEvent dmgEvent = Host.getArcadeManager().GetDamage().NewDamageEvent(p, _horse, null, GetEntity().getLocation(), DamageCause.ENTITY_ATTACK, HORSE_KICK_DAMAGE, true, false, false, "Pumpkin Prince", "Horse Kick", false);
if(dmgEvent.isCancelled()) continue;
hit = true;
}
if(hit)
{
_horseKick = System.currentTimeMillis();
_horseDisguise.kick();
Host.getArcadeManager().GetDisguise().updateDisguise(_horseDisguise);
_horse.getWorld().playSound(_horse.getLocation(), Sound.SKELETON_HURT, 4f, 0.6f);
_horse.getWorld().playSound(_horse.getLocation(), Sound.SKELETON_HURT, 4f, 0.6f);
}
if(_horseKick + HORSE_KICK_DURATION < System.currentTimeMillis())
{
_horseDisguise.stopKick();
Host.getArcadeManager().GetDisguise().updateDisguise(_horseDisguise);
}
if(GetEntity().getTicksLived() % 15 == 0)
{
if(target.getLocation().distanceSquared(GetEntity().getLocation()) > 40*40) return;
Arrow a = GetEntity().launchProjectile(Arrow.class);
Vector force = UtilAlg.getTrajectory(GetEntity(), target).add(new Vector(0, 0.2, 0));
a.setVelocity(force);
a.setFireTicks(99999);
}
}
else
{
GetEntity().setTarget(getRandomPlayer());
}
}
else if(state == 2)
{
if(GetEntity().getTicksLived() % (20*5) == 0)
{
for(int i = 0; i < 64; i++)
{
if(tryRandomTeleport()) break;
}
}
if(GetEntity().getTicksLived() % 25 == 0)
{
Vector v = GetPlayerTarget().subtract(GetEntity().getLocation()).toVector().multiply(0.01);
Location loc = GetEntity().getLocation();
loc.setDirection(v);
GetEntity().teleport(loc);
GetEntity().launchProjectile(Fireball.class, v);
}
}
else if(state == 3)
{
if(GetEntity().getTicksLived() % 20*10 == 0)
{
GetEntity().setTarget(getRandomPlayer());
}
}
}
public Player getRandomPlayer()
{
return Host.GetPlayers(true).get(UtilMath.r(Host.GetPlayers(true).size()));
}
private boolean tryRandomTeleport()
{
Location loc = GetPlayerTarget();
loc.add((UtilMath.random.nextDouble() - 0.5) * 64, UtilMath.r(64)-32, (UtilMath.random.nextDouble() - 0.5) * 64);
for(int y = loc.getBlockY(); y > 0; y--)
{
if(!loc.getBlock().getRelative(BlockFace.DOWN).getType().isSolid()) continue;
Material m1 = loc.getBlock().getType();
Material m2 = loc.getBlock().getRelative(BlockFace.UP).getType();
if(m1.isSolid()) continue;
if(m2.isSolid()) continue;
if(UtilItem.isLiquid(m1)) continue;
if(UtilItem.isLiquid(m2)) continue;
loc.getWorld().playEffect(GetEntity().getLocation(), Effect.ENDER_SIGNAL, 0);
loc.getWorld().playSound(GetEntity().getLocation(), Sound.ENDERMAN_TELEPORT, 2, 0);
GetEntity().teleport(loc.getBlock().getLocation().add(0.5, 0, 0.5));
loc.getWorld().playEffect(GetEntity().getLocation(), Effect.ENDER_SIGNAL, 0);
loc.getWorld().playSound(GetEntity().getLocation(), Sound.ENDERMAN_TELEPORT, 2, 0);
return true;
}
return false;
}
@EventHandler
public void onShoot(EntityShootBowEvent event)
{
if(!event.getEntity().equals(GetEntity())) return;
event.setCancelled(true);
}
@EventHandler
public void onDismount(EntityDismountEvent event)
{
if(event.getDismounted().equals(GetEntity())) event.setCancelled(true);
}
public Zombie getHorse()
{
return _horse;
}
@Override
public void Damage(CustomDamageEvent event)
{
if(event.GetDamageeEntity().equals(_horse))
{
event.setDamagee(GetEntity());
_horse.setFireTicks(0);
}
if(event.GetDamageeEntity() instanceof Player)
{
if(GetEntity().equals(event.GetDamagerEntity(true)))
{
onPrinceDamagePlayer(event);
}
else
{
onOtherDamagePlayer(event);
}
}
if(GetEntity().equals(event.GetDamageeEntity()))
{
onPrinceTakeDamage(event);
if(!event.isCancelled() && _horse != null && _horse.isValid())
{
PacketPlayOutAnimation hurt = new PacketPlayOutAnimation();
hurt.a = _horseDisguise.getEntityId();
hurt.b = 1;
_horseDisguise.sendPacket(hurt);
}
}
}
public void onPrinceTakeDamage(CustomDamageEvent event)
{
if(event.GetCause() == DamageCause.SUFFOCATION || event.GetCause() == DamageCause.FALL)
{
event.SetCancelled("Boss Invalid Damage");
return;
}
if(GetEntity().equals(event.GetDamagerEntity(true)))
{
event.SetCancelled("Boss Invalid Damage");
return;
}
if(!_AI)
{
event.SetCancelled("AI Disabled");
return;
}
if(_invulnerable)
{
event.SetCancelled("Invulnerable");
Player p = event.GetDamagerPlayer(true);
if(p != null)
{
if(Recharge.Instance.use(p, "Boss Inulnerable Info", 5000, false, false))
{
p.sendMessage(F.main("Game", "Kill the " + F.item("Guards") + " before you can damage the " + F.color("Pumpkin Prince", C.cYellow + C.Bold)));
}
}
return;
}
if(event.GetProjectile() instanceof Snowball)
{
event.SetKnockback(false);
}
updateHealth(GetEntity().getHealth(), GetEntity().getHealth()-event.GetDamage());
}
public void onPrinceDamagePlayer(CustomDamageEvent event)
{
int state = getState();
if(state == 3)
{
event.AddKnockback("Boss Knockback", STAGE_3_KNOCKBACK);
}
}
public void onOtherDamagePlayer(CustomDamageEvent event)
{
if(_horse.equals(event.GetDamagerEntity(false)))
{
event.AddKnockback("Horse Kick", HORSE_KNOCKBACK);
}
}
public void updateHealth(double oldH, double newH)
{
int oldState = getState(getHealthProgress(oldH));
int newState = getState(getHealthProgress(newH));
if(oldState != newState)
{
updateState(newState);
}
}
public void updateState(int state)
{
if(state == 1)
{
}
if(state == 2)
{
GetEntity().getEquipment().setItemInHand(new ItemStack(Material.DIAMOND_SWORD));
GetEntity().addPotionEffect(new PotionEffect(PotionEffectType.SPEED, Integer.MAX_VALUE, 1));
GetEntity().addPotionEffect(new PotionEffect(PotionEffectType.JUMP, Integer.MAX_VALUE, 1));
}
if(state == 3)
{
Host.setMaxPumplings(0);
GetEntity().addPotionEffect(new PotionEffect(PotionEffectType.SPEED, Integer.MAX_VALUE, 2), true);
GetEntity().addPotionEffect(new PotionEffect(PotionEffectType.JUMP, Integer.MAX_VALUE, 2), true);
}
}
@Override
public void remove()
{
die();
super.remove();
}
public void die()
{
UtilServer.Unregister(this);
}
@Override
public void Target(EntityTargetEvent event)
{
if(!event.getEntity().equals(GetEntity())) return;
if(!_AI)
{
event.setCancelled(true);
return;
}
if(event.getTarget() == null)
{
event.setCancelled(true);
return;
}
if(event.getTarget().getType() != EntityType.PLAYER) event.setCancelled(true);
}
public int getState()
{
return getState(getHealthProgress());
}
public int getState(double healthProgress)
{
if(healthProgress > 0.6) return 1;
if(healthProgress > 0.4) return 2;
return 3;
}
public double getHealthProgress(double health)
{
return health / GetEntity().getMaxHealth();
}
public double getHealthProgress()
{
return getHealthProgress(GetEntity().getHealth());
}
public boolean isDead()
{
return getHealthProgress() <= 0;
}
}

View File

@ -0,0 +1,97 @@
package nautilus.game.arcade.game.games.halloween2016.creatures;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.entity.Skeleton;
import org.bukkit.event.entity.EntityTargetEvent;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilParticle.ViewDist;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import nautilus.game.arcade.game.games.halloween.creatures.CreatureBase;
import nautilus.game.arcade.game.games.halloween.creatures.InterfaceMove;
import nautilus.game.arcade.game.games.halloween2016.Halloween2016;
public class MobPumpling extends CreatureBase<Skeleton> implements InterfaceMove
{
private static double EXTRA_DAMAGE = 5;
private static float SPEED = 1;
public MobPumpling(Halloween2016 game, Location loc)
{
super(game, C.cYellow + "Pumpling", Skeleton.class, loc);
}
@Override
public void SpawnCustom(Skeleton ent)
{
Host.Manager.GetCondition().Factory().Invisible("Cloak", ent, ent, 999999, 0, false, false, false);
ent.getEquipment().setHelmet(new ItemStack(Material.PUMPKIN));
ent.setMaxHealth(15);
ent.setHealth(ent.getMaxHealth());
UtilEnt.setTickWhenFarAway(ent, true);
}
@Override
public void Damage(CustomDamageEvent event)
{
if(GetEntity().equals(event.GetDamagerEntity(false)))
{
event.AddMod("Damage", EXTRA_DAMAGE);
}
}
@Override
public void Target(EntityTargetEvent event)
{
}
@Override
public void Update(UpdateEvent event)
{
}
@Override
public void Move()
{
UtilEnt.CreatureMove(GetEntity(), getClosestPlayer(), SPEED);
}
public Location getClosestPlayer()
{
Player p = null;
double d = 0;
for(Player pp : Host.GetPlayers(true))
{
double dd = pp.getLocation().distanceSquared(GetEntity().getLocation());
if(p == null || dd < d)
{
d = dd;
p = pp;
}
}
return p.getLocation();
}
@Override
public void remove()
{
UtilParticle.PlayParticleToAll(ParticleType.LARGE_SMOKE, GetEntity().getLocation(), null, 0.3f, 20, ViewDist.NORMAL);
GetEntity().getWorld().playSound(GetEntity().getLocation(), Sound.SKELETON_DEATH, 1, 1);
GetEntity().getWorld().playSound(GetEntity().getLocation(), Sound.FIZZ, 1, 1);
super.remove();
}
}

View File

@ -0,0 +1,53 @@
package nautilus.game.arcade.game.games.halloween2016.creatures;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftArrow;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Skeleton;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import mineplex.core.common.util.C;
import nautilus.game.arcade.game.games.halloween2016.Halloween2016;
public class MobSkeletonArcher extends CryptBreaker<Skeleton>
{
private static final int CRYPT_DAMAGE = 3;
private static final int CRYPT_DAMAGE_RATE = 20;
private static final float SPEED = 1;
private static final double HEALTH = 15;
public MobSkeletonArcher(Halloween2016 game, Location loc)
{
super(game, C.cYellow + "Skeleton Archer", Skeleton.class, loc, CRYPT_DAMAGE, CRYPT_DAMAGE_RATE, SPEED);
_extraDamage = 1;
_customCryptRange = 3;
_playerTargetBackRange = 2;
}
@Override
public void SpawnCustom(Skeleton ent)
{
ent.getEquipment().setItemInHand(new ItemStack(Material.BOW));
ent.setMaxHealth(HEALTH);
ent.setHealth(HEALTH);
}
@Override
public void attackCrypt()
{
if(!_crypt.tryDamage(GetEntity(), _cryptDamage, _cryptDamageRate)) return;
Location door = getClosestDoor();
Vector diff = door.toVector().subtract(GetEntity().getLocation().toVector());
diff.setY(diff.getY() + 0.5);
Arrow a = GetEntity().launchProjectile(Arrow.class, diff);
((CraftArrow)a).getHandle().noclip = true;
}
}

View File

@ -0,0 +1,295 @@
package nautilus.game.arcade.game.games.halloween2016.creatures;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftCreature;
import org.bukkit.entity.Bat;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Zombie;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.EntityTargetEvent;
import org.bukkit.util.Vector;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilParticle.ViewDist;
import mineplex.core.common.util.UtilServer;
import mineplex.core.disguise.disguises.DisguiseWitch;
import mineplex.core.recharge.Recharge;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import nautilus.game.arcade.game.games.halloween.creatures.CreatureBase;
import nautilus.game.arcade.game.games.halloween2016.Halloween2016;
import net.minecraft.server.v1_8_R3.RandomPositionGenerator;
import net.minecraft.server.v1_8_R3.Vec3D;
public class MobWitch extends CreatureBase<Zombie>
{
private static int HEALTH = 20;
private static int PANIC_TIME = 100;
private float SPEED_IDLE = 1f;
private float SPEED_PANIC = 2f;
private static int BATS_BURST = 10;
private static int BATS_TICKS = 80;
private static double BAT_KNOCKBACK = 1.75;
private static int BAT_FIRE_TICKS = 10;
private static double BAT_DAMAGE = 3;
private static double HEAL_DISTANCE = 7;
private static double HEAL_AMOUNT = 10;
private static double HEAL_RAY_SPEED = 0.2;
private CreatureBase<?> _healTarget = null;
public Location _healRay = null;
private int _panicTicks = 0;
private List<Bat> _bats = new ArrayList<>();
private Location _panicTarget = null;
private Halloween2016 _host;
public MobWitch(Halloween2016 game, Location loc)
{
super(game, C.cYellow + "Witch", Zombie.class, loc);
_host = game;
}
@Override
public void SpawnCustom(Zombie ent)
{
ent.setMaxHealth(HEALTH);
ent.setHealth(ent.getMaxHealth());
UtilEnt.setTickWhenFarAway(ent, true);
ent.setRemoveWhenFarAway(false);
DisguiseWitch disg = new DisguiseWitch(ent);
Host.getArcadeManager().GetDisguise().disguise(disg);
}
@Override
public void Update(UpdateEvent event)
{
if(event.getType() == UpdateType.TICK)
{
updateBats();
move();
}
}
@Override
public void Damage(CustomDamageEvent event)
{
if(event.isCancelled()) return;
if(_bats.contains(event.GetDamageeEntity()))
{
if(event.GetCause() == DamageCause.FIRE_TICK)
{
event.SetCancelled("Fire Imunity");
return;
}
}
if(event.GetDamageeEntity() instanceof Player)
{
if (event.GetReason() != null && event.GetReason().contains(GetName()))
{
event.AddKnockback(GetName(), BAT_KNOCKBACK);
return;
}
}
if(!GetEntity().equals(event.GetDamageeEntity())) return;
LivingEntity damager = event.GetDamagerEntity(false);
if(damager != null && _panicTicks <= 0)
{
shootBats(damager.getEyeLocation().subtract(GetEntity().getEyeLocation()).toVector());
}
_panicTicks = PANIC_TIME;
}
public void shootBats(Vector direction)
{
Location loc = GetEntity().getLocation();
loc.setDirection(direction);
GetEntity().teleport(loc);
Host.CreatureAllowOverride = true;
for(int i = 0; i < BATS_BURST; i++)
{
Bat bat = GetEntity().getWorld().spawn(GetEntity().getEyeLocation(), Bat.class);
UtilEnt.Vegetate(bat);
_bats.add(bat);
addEntityPart(bat);
}
Host.CreatureAllowOverride = false;
}
@Override
public void Target(EntityTargetEvent event)
{}
public void move()
{
if(_panicTicks > 0)
{
movePanic();
_panicTicks--;
}
else
{
_panicTarget = null;
moveIdle();
}
}
public void updateBats()
{
for (Iterator<Bat> it = _bats.iterator(); it.hasNext();)
{
Bat bat = it.next();
if (!bat.isValid())
{
it.remove();
continue;
}
if(bat.getTicksLived() > BATS_TICKS)
{
bat.remove();
it.remove();
UtilParticle.PlayParticle(ParticleType.LARGE_SMOKE, bat.getLocation(), 0, 0, 0, 0, 3,
ViewDist.LONG, UtilServer.getPlayers());
continue;
}
bat.setFireTicks(10);
Vector rand = new Vector((Math.random() - 0.5)/2, (Math.random() - 0.5)/2, (Math.random() - 0.5)/2);
bat.setVelocity(bat.getLocation().getDirection().multiply(0.5).add(rand));
for(Player p : UtilEnt.getPlayersInsideEntity(bat, Host.GetPlayers(true)))
{
if (!Recharge.Instance.usable(p, "Hit by Bat"))
continue;
//Damage Event
Host.getArcadeManager().GetDamage().NewDamageEvent(p, GetEntity(), null,
DamageCause.CUSTOM, BAT_DAMAGE, true, true, false,
GetEntity().getName(), GetName());
p.setFireTicks(p.getFireTicks() + BAT_FIRE_TICKS);
//Effect
bat.getWorld().playSound(bat.getLocation(), Sound.BAT_HURT, 1f, 1f);
UtilParticle.PlayParticle(ParticleType.LARGE_SMOKE, bat.getLocation(), 0, 0, 0, 0, 3,
ViewDist.LONG, UtilServer.getPlayers());
bat.remove();
it.remove();
//Recharge on hit
Recharge.Instance.useForce(p, "Hit by Bat", 200);
}
}
}
public void getNewHealTarget()
{
CreatureBase<?> close = null;
double dist = -1;
for(CreatureBase<?> c : _host.getNonPumplings())
{
if(c.equals(this)) continue;
if(!c.GetEntity().isValid()) continue;
if(c.GetEntity().getHealth() < c.GetEntity().getMaxHealth())
{
double d = GetEntity().getLocation().distanceSquared(c.GetEntity().getLocation());
if(close == null || d < dist)
{
close = c;
dist = d;
}
}
}
_healTarget = close;
}
public void moveIdle()
{
if(_healTarget != null && !_healTarget.GetEntity().isValid())
{
_healTarget = null;
}
if(_healTarget == null)
{
getNewHealTarget();
}
if(_healTarget == null)
{
UtilEnt.CreatureMove(GetEntity(), _host.getInfrontOfDoorTargets().get(0), SPEED_IDLE);
return;
}
if(_healRay != null)
{
Vector diff = _healTarget.GetEntity().getEyeLocation().subtract(_healRay).toVector();
double length = diff.lengthSquared();
if(length <= HEAL_RAY_SPEED * HEAL_RAY_SPEED)
{
LivingEntity ent = _healTarget.GetEntity();
ent.setHealth(Math.min(ent.getMaxHealth(), ent.getHealth()+HEAL_AMOUNT));
UtilParticle.PlayParticleToAll(ParticleType.HEART, ent.getEyeLocation(), 1, 1, 1, 0, 20, ViewDist.NORMAL);
_healTarget = null;
_healRay = null;
return;
}
diff.normalize().multiply(HEAL_RAY_SPEED);
_healRay.add(diff);
UtilParticle.PlayParticleToAll(ParticleType.HEART, _healRay, 0, 0, 0, 0, 1, ViewDist.NORMAL);
return;
}
double dist = _healTarget.GetEntity().getLocation().distanceSquared(GetEntity().getLocation());
if(dist < HEAL_DISTANCE * HEAL_DISTANCE)
{
_healRay = GetEntity().getEyeLocation();
return;
}
UtilEnt.CreatureMove(GetEntity(), _healTarget.GetEntity().getLocation(), SPEED_IDLE);
}
public void movePanic()
{
if(_panicTarget == null || UtilEnt.canEntityWalkCloserToNavigationTarget(GetEntity()))
{
Vec3D v = RandomPositionGenerator.a(((CraftCreature)GetEntity()).getHandle(), 5, 4);
_panicTarget = new Location(GetEntity().getWorld(), v.a, v.b, v.c);
}
UtilEnt.CreatureMove(GetEntity(), _panicTarget, SPEED_PANIC);
}
}

View File

@ -0,0 +1,32 @@
package nautilus.game.arcade.game.games.halloween2016.creatures;
import org.bukkit.Location;
import org.bukkit.entity.Zombie;
import mineplex.core.common.util.C;
import nautilus.game.arcade.game.games.halloween2016.Halloween2016;
public class MobZombie extends CryptBreaker<Zombie>
{
private static float SPEED = 1;
private static int CRYPT_DAMAGE = 3;
private static int CRYPT_DAMAGE_COOLDOWN = 20;
private static double HEALTH = 15;
public MobZombie(Halloween2016 game, Location loc)
{
super(game, C.cYellow + "Zombie", Zombie.class, loc, CRYPT_DAMAGE, CRYPT_DAMAGE_COOLDOWN, SPEED);
_extraDamage = 5;
}
@Override
public void SpawnCustom(Zombie ent)
{
ent.setMaxHealth(HEALTH);
ent.setHealth(HEALTH);
}
}

View File

@ -0,0 +1,75 @@
package nautilus.game.arcade.game.games.halloween2016.creatures;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Zombie;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilParticle.ViewDist;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import nautilus.game.arcade.game.games.halloween2016.Halloween2016;
public class MobZombieSpawner extends CryptBreaker<Zombie>
{
private static final int CRYPT_DAMAGE = 20;
private static final int CRYPT_RATE = 20;
private static final float SPEED = 0.5f;
private static final int MAX_MINI_ZOMBIES = 4;
private List<MobMiniZombie> _miniZombies = new ArrayList<>();
public MobZombieSpawner(Halloween2016 game, Location loc)
{
super(game, C.cYellow + "Zombie Spawner", Zombie.class, loc, CRYPT_DAMAGE, CRYPT_RATE, SPEED);
}
@Override
public void SpawnCustom(Zombie ent)
{
ent.setVillager(true);
ent.getEquipment().setHelmet(new ItemStack(Material.MOB_SPAWNER));
}
@Override
public void Update(UpdateEvent event)
{
super.Update(event);
if(event.getType() == UpdateType.SEC_05)
{
for(Iterator<MobMiniZombie> it = _miniZombies.iterator(); it.hasNext();)
{
if(!it.next().GetEntity().isValid()) it.remove();
}
if(_miniZombies.size() >= MAX_MINI_ZOMBIES) return;
//Combat concurrency issues (can't add mobs while in the "tick" loop of mobs)
Host.Manager.runSync(() ->
{
if(GetEntity().isValid())
{
Location loc = GetEntity().getLocation().add(GetEntity().getLocation().getDirection().normalize());
UtilParticle.PlayParticleToAll(ParticleType.SMOKE, loc, null, 0.1f, 20, ViewDist.NORMAL);
loc.getWorld().playSound(loc, Sound.ZOMBIE_INFECT, 1, 0.6f);
MobMiniZombie mini = new MobMiniZombie(Host, loc);
_miniZombies.add(mini);
Host16.AddCreature(mini, false);
}
});
}
}
}

View File

@ -0,0 +1,44 @@
package nautilus.game.arcade.game.games.halloween2016.tutorial;
import org.bukkit.Location;
import mineplex.core.common.animation.Animator;
import nautilus.game.arcade.game.GameTeam;
import nautilus.game.arcade.game.games.halloween2016.Halloween2016;
import nautilus.game.arcade.gametutorial.GameTutorial;
import nautilus.game.arcade.gametutorial.TutorialPhase;
public class TutorialHalloween2016 extends GameTutorial
{
private Halloween2016 _host;
public TutorialHalloween2016(Halloween2016 host, Animator animator, GameTeam team, Location start, int duration)
{
super(host.Manager, new TutorialPhase[]{
new TutorialPhaseHalloween(duration, animator, team, start)
});
_host = host;
SetTutorialPositions = false;
}
@Override
public void onStart()
{
super.onStart();
_host.Manager.getCosmeticManager().setHideParticles(true);
}
@Override
public void onEnd()
{
super.onEnd();
_host.AllowParticles = true;
_host.Manager.getCosmeticManager().setHideParticles(false);
}
}

View File

@ -0,0 +1,67 @@
package nautilus.game.arcade.game.games.halloween2016.tutorial;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import mineplex.core.common.animation.Animator;
import mineplex.core.common.util.C;
import nautilus.game.arcade.game.GameTeam;
import nautilus.game.arcade.gametutorial.TutorialPhase;
import nautilus.game.arcade.gametutorial.TutorialText;
public class TutorialPhaseHalloween extends TutorialPhase
{
private Animator _animator;
private GameTeam _team;
private Location _start;
public TutorialPhaseHalloween(int duration, Animator animator, GameTeam team, Location start)
{
super(new TutorialText[]
{
new TutorialText(C.cGold + "Legend says that many years ago", 5 * 20, 1),
new TutorialText(C.cGold + "A group of heroes defeated the Pumpkin King", 4 * 20, 2),
new TutorialText(C.cGold + "Since then the world has known peace.", 3 * 20, 3),
new TutorialText("", 2 * 20, 4),
new TutorialText(C.cGold + "My family has guarded this tomb for generations.", 4 * 20, 5),
new TutorialText(C.cGold + "All I know is we must not let it fall.", 4 * 20, 6),
new TutorialText("", 2 * 20, 7),
new TutorialText("", Math.max((duration-(24*20)), 8))
});
_animator = animator;
_team = team;
_start = start;
}
@Override
public void onStart()
{
_animator.start(_start);
}
@Override
public void onEnd()
{
for(Player p : _team.GetPlayers(false))
{
p.setGameMode(GameMode.SURVIVAL);
}
_animator.stop();
}
@Override
public int ID()
{
return 1;
}
}

View File

@ -0,0 +1,46 @@
package nautilus.game.arcade.game.games.halloween2016.wave;
import mineplex.core.common.util.UtilTime;
import nautilus.game.arcade.game.games.halloween2016.Halloween2016;
import nautilus.game.arcade.game.games.halloween2016.creatures.MobSkeletonArcher;
import nautilus.game.arcade.game.games.halloween2016.creatures.MobZombie;
public class Wave1 extends WaveBase
{
public Wave1(Halloween2016 host)
{
super(host, null, 80000, host.getMobSpawns(), null);
_desc = new String[]
{
"Zombies",
"Skeletons"
};
}
@Override
public void Spawn(int tick)
{
if(tick == 0)
{
Host.setObjective("Protect the Crypt");
}
if (UtilTime.elapsed(_start, 50000))
return;
if (Host.getNonPumplings().size() > Host.getMaxNonPumplings()) return;
if(tick%10 == 0)
{
Host.AddCreature(new MobZombie(Host, GetSpawn()));
}
if(tick%15 == 0)
{
Host.AddCreature(new MobSkeletonArcher(Host, GetSpawn()));
}
}
}

View File

@ -0,0 +1,56 @@
package nautilus.game.arcade.game.games.halloween2016.wave;
import mineplex.core.common.util.UtilTime;
import nautilus.game.arcade.game.games.halloween.creatures.MobSpiderLeaper;
import nautilus.game.arcade.game.games.halloween.creatures.MobSpiderSmasher;
import nautilus.game.arcade.game.games.halloween2016.Halloween2016;
import nautilus.game.arcade.game.games.halloween2016.creatures.MobGiant;
import nautilus.game.arcade.game.games.halloween2016.creatures.MobZombie;
public class Wave2 extends WaveBase
{
public Wave2(Halloween2016 host)
{
super(host, null, 90000, host.getMobSpawns(), null);
_desc = new String[]
{
"Giants",
"Creepers",
"Zombies",
"Spiders"
};
}
@Override
public void Spawn(int tick)
{
if(tick == 0)
{
Host.AddCreature(new MobGiant(Host, getSpawn(Host.getMainLane())));
}
if (UtilTime.elapsed(_start, 60000))
return;
if(tick%200 == 0)
{
spawnCreepers();
}
if (Host.getNonPumplings().size() > Host.getMaxNonPumplings()) return;
if(tick%7 == 0)
{
Host.AddCreature(new MobZombie(Host, GetSpawn()));
}
if(tick%20 == 0)
{
Host.AddCreature(new MobSpiderLeaper(Host, GetSpawn()));
Host.AddCreature(new MobSpiderSmasher(Host, GetSpawn()));
}
}
}

View File

@ -0,0 +1,68 @@
package nautilus.game.arcade.game.games.halloween2016.wave;
import mineplex.core.common.util.UtilTime;
import nautilus.game.arcade.game.games.halloween2016.Halloween2016;
import nautilus.game.arcade.game.games.halloween2016.creatures.MobBlaze;
import nautilus.game.arcade.game.games.halloween2016.creatures.MobGiant;
import nautilus.game.arcade.game.games.halloween2016.creatures.MobWitch;
import nautilus.game.arcade.game.games.halloween2016.creatures.MobZombie;
import nautilus.game.arcade.game.games.halloween2016.creatures.MobZombieSpawner;
public class Wave3 extends WaveBase
{
public Wave3(Halloween2016 host)
{
super(host, null, 90000, host.getMobSpawns(), null);
_desc = new String[]
{
"Giants",
"Creepers",
"Zombies",
"Zombie Spawners",
"Blazes"
};
}
@Override
public void Spawn(int tick)
{
if (UtilTime.elapsed(_start, 60000))
return;
if(tick%200 == 0)
{
spawnCreepers();
}
if(tick%(20*7) == 0)
{
Host.AddCreature(new MobWitch(Host, GetSpawn()));
}
if(tick%(20 * 10) == 0)
{
Host.AddCreature(new MobGiant(Host, getSpawn(Host.getMainLane())));
}
if (Host.getNonPumplings().size() > Host.getMaxNonPumplings()) return;
if(tick%15 == 0)
{
Host.AddCreature(new MobZombie(Host, GetSpawn()));
}
if(tick%60 == 0)
{
Host.AddCreature(new MobZombieSpawner(Host, GetSpawn()));
}
if(tick%30 == 0)
{
Host.AddCreature(new MobBlaze(Host, GetSpawn()));
}
}
}

View File

@ -0,0 +1,56 @@
package nautilus.game.arcade.game.games.halloween2016.wave;
import mineplex.core.common.util.UtilTime;
import nautilus.game.arcade.game.games.halloween2016.Halloween2016;
import nautilus.game.arcade.game.games.halloween2016.creatures.MobBlaze;
import nautilus.game.arcade.game.games.halloween2016.creatures.MobGiant;
import nautilus.game.arcade.game.games.halloween2016.creatures.MobPigZombie;
import nautilus.game.arcade.game.games.halloween2016.creatures.MobWitch;
public class Wave4 extends WaveBase
{
public Wave4(Halloween2016 host)
{
super(host, null, 100000, host.getMobSpawns(), null);
_desc = new String[]
{
"Giants",
"Creepers",
"Zombie Pigmen",
"Blazes",
"Witches",
};
}
@Override
public void Spawn(int tick)
{
if(tick%(20 * 30) == 0)
{
Host.AddCreature(new MobGiant(Host, getSpawn(Host.getMainLane())));
}
if (Host.getNonPumplings().size() > Host.getMaxNonPumplings()) return;
if (UtilTime.elapsed(_start, 70000))
return;
if(tick%15 == 0)
{
Host.AddCreature(new MobPigZombie(Host, GetSpawn()));
}
if(tick%60 == 0)
{
Host.AddCreature(new MobBlaze(Host, GetSpawn()));
}
if(tick%100 == 0)
{
Host.AddCreature(new MobWitch(Host, GetSpawn()));
}
}
}

View File

@ -0,0 +1,84 @@
package nautilus.game.arcade.game.games.halloween2016.wave;
import mineplex.core.common.util.UtilTime;
import nautilus.game.arcade.game.games.halloween.creatures.MobSpiderLeaper;
import nautilus.game.arcade.game.games.halloween.creatures.MobSpiderSmasher;
import nautilus.game.arcade.game.games.halloween2016.Halloween2016;
import nautilus.game.arcade.game.games.halloween2016.creatures.MobBlaze;
import nautilus.game.arcade.game.games.halloween2016.creatures.MobGiant;
import nautilus.game.arcade.game.games.halloween2016.creatures.MobSkeletonArcher;
import nautilus.game.arcade.game.games.halloween2016.creatures.MobWitch;
import nautilus.game.arcade.game.games.halloween2016.creatures.MobZombie;
import nautilus.game.arcade.game.games.halloween2016.creatures.MobZombieSpawner;
public class Wave5 extends WaveBase
{
public Wave5(Halloween2016 host)
{
super(host, null, 120000, host.getMobSpawns(), null);
_desc = new String[]
{
"Giants",
"Creepers",
"Zombies",
"Zombie Spawners",
"Skeletons",
"Witches",
"Blazes",
"Spiders"
};
}
@Override
public void Spawn(int tick)
{
if(tick%(20*30) == 0)
{
Host.AddCreature(new MobGiant(Host, getSpawn(Host.getMainLane())));
}
if (UtilTime.elapsed(_start, 100000))
return;
if(tick%300 == 0)
{
spawnCreepers();
}
if (Host.getNonPumplings().size() > Host.getMaxNonPumplings()) return;
if(tick%40 == 0)
{
Host.AddCreature(new MobZombie(Host, GetSpawn()));
}
if(tick%40 == 0)
{
Host.AddCreature(new MobSkeletonArcher(Host, GetSpawn()));
}
if(tick%50 == 0)
{
Host.AddCreature(new MobZombieSpawner(Host, GetSpawn()));
}
if(tick%50 == 0)
{
Host.AddCreature(new MobWitch(Host, GetSpawn()));
}
if(tick%50 == 0)
{
Host.AddCreature(new MobBlaze(Host, GetSpawn()));
}
if(tick%40 == 0)
{
Host.AddCreature(new MobSpiderLeaper(Host, GetSpawn()));
Host.AddCreature(new MobSpiderSmasher(Host, GetSpawn()));
}
}
}

View File

@ -0,0 +1,46 @@
package nautilus.game.arcade.game.games.halloween2016.wave;
import java.util.List;
import org.bukkit.Location;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilMath;
import nautilus.game.arcade.game.games.halloween.NamedAudio;
import nautilus.game.arcade.game.games.halloween2016.Halloween2016;
import nautilus.game.arcade.game.games.halloween2016.creatures.MobCreeper;
public abstract class WaveBase extends nautilus.game.arcade.game.games.halloween.waves.WaveBase
{
protected Halloween2016 Host;
protected static final int CREEPER_SPAWN_PACK_SIZE = 5;
public WaveBase(Halloween2016 host, String name, long duration, List<Location> spawns, NamedAudio audio)
{
super(host, name, duration, spawns, audio);
Host = host;
_titleColor = C.cRed;
}
public Location getSpawn(List<Location> lane)
{
return lane.get(UtilMath.r(lane.size()));
}
public void spawnCreepers()
{
Location loc = GetSpawn();
for(int i = 0; i < CREEPER_SPAWN_PACK_SIZE; i++)
{
double x = UtilMath.random(-3, 3);
double z = UtilMath.random(-3, 3);
Host.AddCreature(new MobCreeper(Host, loc.clone().add(x, 0, z)), false);
}
}
}

View File

@ -0,0 +1,253 @@
package nautilus.game.arcade.game.games.halloween2016.wave;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Fireball;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Skeleton;
import org.bukkit.entity.Skeleton.SkeletonType;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTextMiddle;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
import nautilus.game.arcade.game.games.halloween.creatures.CreatureBase;
import nautilus.game.arcade.game.games.halloween2016.Halloween2016;
import nautilus.game.arcade.game.games.halloween2016.creatures.MobPrinceGuard;
import nautilus.game.arcade.game.games.halloween2016.creatures.MobPumpkinPrince;
public class WaveBoss extends WaveBase implements Listener
{
private MobPumpkinPrince _prince;
private Halloween2016 Host;
private Skeleton _pumpkinKing;
private List<MobPrinceGuard> _guards = new ArrayList<>();
private int _guardsCount = 4;
private int _guardsCountQueue = _guardsCount;
private double _nextPrinceHealthStageForNewGuards;
private int _tick = 0;
private Fireball _fireball;
private final static float KING_SPEED = 1.7f;
private final static float PRINCE_SPEED = 1.3f;
private Location _princeTarget;
public WaveBoss(Halloween2016 host)
{
super(host, "Boss Fight", 0, host.getMobSpawns(), null);
Host = host;
}
@Override
public void Spawn(int tick)
{
tick = _tick;
_tick++;
if(tick == 0)
{
UtilServer.RegisterEvents(this);
for(Player p : Host.GetPlayers(true))
{
p.teleport(Host.getCryptView());
}
Host.lockAllPlayers(Host.getCryptView());
for(CreatureBase<?> c : Host.getMobs())
{
c.remove();
}
}
else if(tick == 4)
{
for(CreatureBase<?> c : Host.getMobs())
{
c.remove();
}
for(Entity e : Host.WorldData.World.getEntities())
{
if((e instanceof LivingEntity) && !(e instanceof Player))
{
e.remove();
}
}
}
else if(tick == 5)
{
_princeTarget = Host.getPrinceTargetInfrontOfCrypt();
_prince = new MobPumpkinPrince(Host, Host.getPrinceSpawn());
_prince.setAI(false);
Host.AddCreature(_prince);
_nextPrinceHealthStageForNewGuards = _prince.GetEntity().getHealth()-200;
}
else if(tick < 20 * 5)
{
UtilEnt.CreatureMove(_prince.getHorse(), _princeTarget, PRINCE_SPEED);
}
else if(tick == 20 * 6)
{
Vector diff = Host.getInfrontOfDoorTargets().get(1).clone().add(0, 1, 0).subtract(_prince.GetEntity().getEyeLocation()).toVector();
UtilEnt.CreatureLook(_prince.GetEntity(), UtilAlg.GetPitch(diff), UtilAlg.GetYaw(diff));
_fireball = _prince.GetEntity().launchProjectile(Fireball.class);
}
else if(tick == 20 * 11)
{
Host.Announce("", false);
Host.Announce("", false);
say("Pumpkin King", "I am free! Free at last!");
}
if(tick == 20 * 12)
{
say("Pumpkin King", "Protect me my son!");
}
if(tick > 20 * 13 && tick < 20 * 18)
{
UtilEnt.CreatureMove(_pumpkinKing, Host.getGiantSpawn(), KING_SPEED);
}
else if(tick == 20 * 18)
{
_pumpkinKing.remove();
Host.unlockAllPlayers();
_prince.setAI(true);
for(MobPrinceGuard guard : _guards)
{
guard.setAI(true);
}
Host.Objective = "Eliminate the Guards";
Host.Announce(C.cGreen + C.Bold + "Kill the Prince's Guards first!", false);
}
if(tick > 20 * 18){
boolean empt = _guards.isEmpty();
for(Iterator<MobPrinceGuard> it = _guards.iterator(); it.hasNext();)
{
MobPrinceGuard g = it.next();
if(!g.GetEntity().isValid()) it.remove();
}
if(empt != _guards.isEmpty() && !empt)
{
Host.Objective = "Defeat the Pumpkin Prince";
Host.Announce(C.cGreen + C.Bold + "All the Pumpking Prince's guards are dead!", false);
Host.Announce(C.cGreen + C.Bold + "Kill him while he is unprotected!", true);
}
_prince.setInvulnerable(!_guards.isEmpty());
if(_prince.GetEntity().getHealth() < _nextPrinceHealthStageForNewGuards)
{
Host.Objective = "Eliminate the Guards";
Host.Announce(C.cGreen + C.Bold + "The Pumpkin Prince's guards are back to protect him", false);
Host.Announce(C.cGreen + C.Bold + "Kill them first before attacking the Prince!", true);
_prince.setInvulnerable(true);
_nextPrinceHealthStageForNewGuards -= 200;
_guardsCountQueue = _guardsCount;
}
if(tick % 20 * 20 == 0)
{
if(_guardsCountQueue > 0)
{
MobPrinceGuard guard = new MobPrinceGuard(Host, Host.getGiantSpawn(), _prince);
_guards.add(guard);
Host.AddCreature(guard);
_guardsCountQueue--;
}
}
}
}
public void say(String role, String msg)
{
Host.Announce("\n" + C.cGold + C.Bold + role + ": " + C.cGray + msg + "\n");
UtilTextMiddle.display(C.cGold + msg, null, 0, 40, 0);
}
@Override
public boolean CanEnd()
{
boolean r = _prince != null && _prince.isDead();
if(r)
{
end();
}
return r;
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onExplode(EntityExplodeEvent event)
{
if(event.getEntity().equals(_fireball))
{
event.setCancelled(true);
event.blockList().clear();
Host.getCrypt().setHealth(0);
Host.CreatureAllowOverride = true;
_pumpkinKing = GetSpawn().getWorld().spawn(Host.getInfrontOfCrypt(), Skeleton.class);
Host.CreatureAllowOverride = false;
_pumpkinKing.setSkeletonType(SkeletonType.WITHER);
_pumpkinKing.getEquipment().setHelmet(new ItemStack(Material.PUMPKIN));
_pumpkinKing.setCustomName(C.cYellow + C.Bold + "Pumpking King");
_pumpkinKing.setCustomNameVisible(true);
UtilEnt.Vegetate(_pumpkinKing);
_pumpkinKing.getWorld().strikeLightningEffect(_pumpkinKing.getLocation());
}
}
public void end()
{
UtilServer.Unregister(this);
Host.Announce("\n" + C.cYellow + C.Bold + "The Pumpkin Prince has been defeated!\nThe World is safe... for tonight.\n");
}
@EventHandler
public void onDamage(CustomDamageEvent event)
{
if(event.GetDamageeEntity().equals(_pumpkinKing))
{
event.SetCancelled("Invincible Statue");
}
}
}

View File

@ -0,0 +1,52 @@
package nautilus.game.arcade.game.games.halloween2016.wave;
import java.util.List;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import nautilus.game.arcade.game.games.halloween.creatures.CreatureBase;
import nautilus.game.arcade.game.games.halloween2016.Halloween2016;
public class WaveVictory extends WaveBase
{
public WaveVictory(Halloween2016 host, List<Location> beaconSpawn)
{
super(host, "Celebration!", 15000, beaconSpawn, null);
_displayWaveNumber = false;
_announceWaveChat = false;
}
@Override
public void Spawn(int tick)
{
if (UtilTime.elapsed(_start, 20000)) return;
// Play
if (tick == 0)
{
for (Player player : UtilServer.getPlayers())
{
player.playEffect(Host.getDoorSchematicLocation(), Effect.RECORD_PLAY, 2259);
}
}
// Mobs
for (CreatureBase<? extends LivingEntity> mob : Host.GetCreatures())
{
mob.GetEntity().damage(5);
}
// Time
if (Host.WorldTimeSet != 6000)
{
Host.WorldTimeSet = (Host.WorldTimeSet + 50) % 24000;
Host.WorldData.World.setTime(Host.WorldTimeSet);
}
}
}

View File

@ -57,7 +57,7 @@ public class PerkFletcher extends Perk
public PerkFletcher(int time, int max, boolean remove, int slot, boolean instant) public PerkFletcher(int time, int max, boolean remove, int slot, boolean instant)
{ {
this(time, max, remove, slot, instant, "Fletcted Arrow"); this(time, max, remove, slot, instant, "Fletched Arrow");
} }
public PerkFletcher(int time, int max, boolean remove, int slot, boolean instant, String name) public PerkFletcher(int time, int max, boolean remove, int slot, boolean instant, String name)
@ -162,7 +162,13 @@ public class PerkFletcher extends Perk
} }
else else
{ {
cur.getInventory().setItem(_slot, ItemStackFactory.Instance.CreateStack(262, (byte)0, 1, F.item(_name))); int amount = 1;
ItemStack old = cur.getInventory().getItem(_slot);
if(old != null && old.getType() == Material.ARROW)
{
amount += old.getAmount();
}
cur.getInventory().setItem(_slot, ItemStackFactory.Instance.CreateStack(262, (byte)0, amount, F.item(_name)));
} }
cur.playSound(cur.getLocation(), Sound.ITEM_PICKUP, 2f, 1f); cur.playSound(cur.getLocation(), Sound.ITEM_PICKUP, 2f, 1f);

View File

@ -87,7 +87,7 @@ public class PerkHammerThrow extends Perk implements IThrown
@EventHandler @EventHandler
public void Pickup(PlayerPickupItemEvent event) public void Pickup(PlayerPickupItemEvent event)
{ {
if (!_thrown.containsKey(event.getItem())) if (!event.getPlayer().equals(_thrown.get(event.getItem())))
return; return;
event.setCancelled(true); event.setCancelled(true);

View File

@ -20,6 +20,7 @@ import nautilus.game.arcade.events.PlayerStateChangeEvent;
import nautilus.game.arcade.game.Game; import nautilus.game.arcade.game.Game;
import nautilus.game.arcade.game.Game.GameState; import nautilus.game.arcade.game.Game.GameState;
import nautilus.game.arcade.game.GameTeam.PlayerState; import nautilus.game.arcade.game.GameTeam.PlayerState;
import nautilus.game.arcade.game.games.halloween2016.Halloween2016;
import nautilus.game.arcade.game.games.minestrike.Minestrike; import nautilus.game.arcade.game.games.minestrike.Minestrike;
import nautilus.game.arcade.game.games.paintball.Paintball; import nautilus.game.arcade.game.games.paintball.Paintball;
import nautilus.game.arcade.game.games.wither.WitherGame; import nautilus.game.arcade.game.games.wither.WitherGame;
@ -245,6 +246,7 @@ public class NextBestGameManager implements Listener
if(event.GetGame() instanceof Minestrike if(event.GetGame() instanceof Minestrike
|| event.GetGame() instanceof WitherGame || event.GetGame() instanceof WitherGame
|| event.GetGame() instanceof Paintball || event.GetGame() instanceof Paintball
|| event.GetGame() instanceof Halloween2016
|| event.GetGame().Manager.GetHost() != null) || event.GetGame().Manager.GetHost() != null)
{ {
return; return;

View File

@ -528,6 +528,12 @@ public class NewGameLobbyManager extends LobbyManager
{ {
_multipleLocs.put(lastName, locations); _multipleLocs.put(lastName, locations);
} }
} else if(name.equalsIgnoreCase("MAP_NAME"))
{
if(tokens[1].toLowerCase().contains("halloween"))
{
WORLD.setTime(13850);
}
} else } else
{ {
lastName = tokens[1]; lastName = tokens[1];