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:
parent
66dfe06b34
commit
311751cc39
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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());
|
||||||
|
@ -36,4 +36,9 @@ public class AnimatorEntity extends Animator
|
|||||||
@Override
|
@Override
|
||||||
protected void finish(Location loc) {}
|
protected void finish(Location loc) {}
|
||||||
|
|
||||||
|
public Entity getEntity()
|
||||||
|
{
|
||||||
|
return _ent;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -814,6 +901,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()
|
||||||
{
|
{
|
||||||
return getNewEntityId(true);
|
return getNewEntityId(true);
|
||||||
@ -888,6 +987,16 @@ 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));
|
||||||
|
@ -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())));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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),
|
||||||
|
@ -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"),
|
||||||
|
@ -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),
|
||||||
|
@ -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.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,7 +314,11 @@ public class Halloween extends SoloGame
|
|||||||
if (!IsLive())
|
if (!IsLive())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (Math.random() > 0.6)
|
if(_waves.get(_wave) instanceof WaveVictory ||
|
||||||
|
_waves.get(_wave) instanceof nautilus.game.arcade.game.games.halloween2016.wave.WaveVictory)
|
||||||
|
return;
|
||||||
|
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -495,40 +567,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
|
||||||
public void ScoreboardUpdate(UpdateEvent event)
|
public void ScoreboardUpdate(UpdateEvent event)
|
||||||
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
package nautilus.game.arcade.game.games.halloween;
|
||||||
|
|
||||||
|
public interface NamedAudio
|
||||||
|
{
|
||||||
|
|
||||||
|
public String getAudioPath();
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
@ -23,6 +27,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)
|
||||||
{
|
{
|
||||||
Host = game;
|
Host = game;
|
||||||
@ -38,11 +44,39 @@ public abstract class CreatureBase<T extends LivingEntity>
|
|||||||
_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);
|
||||||
|
|
||||||
public String GetName()
|
public String GetName()
|
||||||
@ -116,6 +150,11 @@ public abstract class CreatureBase<T extends LivingEntity>
|
|||||||
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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(),
|
||||||
};
|
};
|
||||||
|
@ -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 (_audio != null)
|
|
||||||
{
|
{
|
||||||
Host.playSound(_audio);
|
if(_announceWaveChat)
|
||||||
|
{
|
||||||
|
String number = C.cRed + C.Bold + "Wave " + wave;
|
||||||
|
String name = C.cYellow + _name;
|
||||||
|
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);
|
||||||
@ -122,5 +168,35 @@ 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);
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -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()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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];
|
||||||
|
Loading…
Reference in New Issue
Block a user