Pumpkin's Revenge (#237)

* Initial Commit

* Update

* Bunch of new stuff

* Fixed fletcher arrow typo

* Added reward pet, fixed typo, tweaked lose cinematic

* Lots of tweaks and fixes with QA

* Cleaning up a little code

* Removed debug message on prince death

* Added nighttime to halloween game lobby maps

* Tweaked spawn rates and mob caps

* Typo

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

* Fixed creepers not getting properly removed during boss cinematic

* Reward typo

* Fixed rare NPE

* Typos

* Tweaked mini zombie

* Typo

* Prevent zombie from spawning minis after being removed

* Tweaked wave announcements + formated WaveVictory

* Changed color of prince tag + formated ZombieSpawner

* Fixed (another) rare NPE

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

View File

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

View File

@ -1,5 +1,6 @@
package mineplex.core.common.animation;
import java.util.Collection;
import java.util.HashSet;
import java.util.PriorityQueue;
import java.util.Set;
@ -36,6 +37,11 @@ public abstract class Animator
_plugin = plugin;
}
public void addPoints(Collection<AnimationPoint> points)
{
for(AnimationPoint p : points) _points.add(p);
}
public void addPoint(AnimationPoint point) {
_points.add(point);
}
@ -48,7 +54,9 @@ public abstract class Animator
* @return Returns a cloned list of the animator points for this instance.
*/
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());
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));
Vector dirDiff = _next.getDirection().subtract(prev.getDirection());

View File

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

View File

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

View File

@ -1,6 +1,7 @@
package mineplex.core.common.util;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
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)
{
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)
{
if (ent == null)
@ -578,6 +655,16 @@ public class UtilEnt
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)
{
@ -813,6 +900,18 @@ public class UtilEnt
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()
{
@ -887,7 +986,17 @@ public class UtilEnt
{
((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)
{
entity.setMetadata(key, new FixedMetadataValue(UtilServer.getPlugin(), value));

View File

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

View File

@ -1,16 +1,17 @@
package mineplex.core.common.util;
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.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.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.Location;
@ -26,9 +27,23 @@ import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
import org.bukkit.potion.PotionEffect;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.BlockIterator;
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.*;
public class UtilPlayer
@ -73,6 +88,49 @@ public class UtilPlayer
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) {
players.stream().forEach(p->p.hidePlayer(player));
}

View File

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

View File

@ -25,6 +25,7 @@ public enum GameDisplay
Evolution("Evolution", Material.EMERALD, (byte)0, GameCategory.ARCADE, 16),
Gravity("Gravity", Material.ENDER_PORTAL_FRAME, (byte)0, GameCategory.EXTRA, 18),
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),
HoleInTheWall("Hole in the Wall", Material.STAINED_GLASS, (byte) 2, GameCategory.ARCADE, 52),
Horse("Horseback", Material.IRON_BARDING, (byte)0, GameCategory.ARCADE, 21),

View File

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

View File

@ -40,6 +40,7 @@ import nautilus.game.arcade.game.games.gladiators.modes.OverpoweredGladiators;
import nautilus.game.arcade.game.games.gladiators.modes.SmashGladiators;
import nautilus.game.arcade.game.games.gravity.Gravity;
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.modes.Countdown;
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")
}, true),
Halloween2016(Halloween2016.class, GameDisplay.Halloween2016),
HideSeek(HideSeek.class, GameDisplay.HideSeek),
HoleInTheWall(HoleInTheWall.class, GameDisplay.HoleInTheWall),
Horse(Horse.class, GameDisplay.Horse),

View File

@ -1,7 +1,37 @@
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.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.recharge.Recharge;
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.KitRobinHood;
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.managers.chat.ChatStatData;
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
{
//Wave Data
private ArrayList<ArrayList<Location>> _spawns;
protected ArrayList<ArrayList<Location>> _spawns;
private ArrayList<WaveBase> _waves;
private int _wave = 0;
protected ArrayList<WaveBase> _waves;
protected int _wave = 0;
private int _maxMobs = 80;
private ArrayList<CreatureBase> _mobs = new ArrayList<CreatureBase>();
protected int _maxMobs = 80;
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 move = 0;
@ -78,7 +110,7 @@ public class Halloween extends SoloGame
public Halloween(ArcadeManager manager)
{
super(manager, GameType.Halloween,
this(manager, GameType.Halloween,
new Kit[]
{
@ -94,6 +126,12 @@ public class Halloween extends SoloGame
"Defeat the waves of monsters",
"Kill the Pumpkin King"
});
}
protected Halloween(ArcadeManager manager, GameType gameType, Kit[] kits, String[] gameDesc)
{
super(manager, gameType, kits, gameDesc);
this.DamagePvP = false;
@ -116,6 +154,19 @@ public class Halloween extends SoloGame
BlankLine,
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
@ -134,7 +185,7 @@ public class Halloween extends SoloGame
_waves.add(new Wave4(this));
_waves.add(new Wave5(this));
_waves.add(new WaveBoss(this));
_waves.add(new WaveVictory(this));
_waves.add(new WaveVictory(this, GetSpawnSet(3)));
//Make zombies break doors
WorldData.World.setDifficulty(Difficulty.HARD);
@ -146,13 +197,20 @@ public class Halloween extends SoloGame
if (event.GetState() != GameState.End)
return;
for (CreatureBase ent : _mobs)
ent.GetEntity().remove();
for (CreatureBase<?> ent : _mobs)
{
ent.remove();
}
_mobs.clear();
_spawns.clear();
}
public ArrayList<CreatureBase<?>> getMobs()
{
return _mobs;
}
@EventHandler(priority = EventPriority.MONITOR)
public void TeamGen(GameStateChangeEvent event)
{
@ -168,6 +226,8 @@ public class Halloween extends SoloGame
if (event.GetState() != GameState.Live)
return;
if(!doVoices) return;
Announce(C.Bold + "Type " + C.cGreen + C.Bold + "/voice" + C.cWhite + C.Bold + " to disable voice audio.");
}
@ -253,8 +313,12 @@ public class Halloween extends SoloGame
if (!IsLive())
return;
if(_waves.get(_wave) instanceof WaveVictory ||
_waves.get(_wave) instanceof nautilus.game.arcade.game.games.halloween2016.wave.WaveVictory)
return;
if (Math.random() > 0.6)
if (Math.random() > 0.2)
return;
for (Player player : UtilServer.getPlayers())
@ -297,12 +361,12 @@ public class Halloween extends SoloGame
return locSet.get(UtilMath.r(locSet.size()));
}
public void AddCreature(CreatureBase mob)
public void AddCreature(CreatureBase<?> mob)
{
_mobs.add(0, mob);
}
public ArrayList<CreatureBase> GetCreatures()
public ArrayList<CreatureBase<?>> GetCreatures()
{
return _mobs;
}
@ -310,7 +374,7 @@ public class Halloween extends SoloGame
@EventHandler
public void CreatureMoveUpdate(UpdateEvent event)
{
if (event.getType() != UpdateType.FASTEST)
if (event.getType() != _updateCreatureMoveRate)
return;
if (_mobs.isEmpty())
@ -318,7 +382,7 @@ public class Halloween extends SoloGame
long start = System.currentTimeMillis();
CreatureBase base = _mobs.remove(0);
CreatureBase<?> base = _mobs.remove(0);
if (base instanceof InterfaceMove)
{
@ -342,25 +406,33 @@ public class Halloween extends SoloGame
return;
//Clean
Iterator<CreatureBase> mobIterator = _mobs.iterator();
Iterator<CreatureBase<?>> mobIterator = _mobs.iterator();
while (mobIterator.hasNext())
{
CreatureBase base = mobIterator.next();
CreatureBase<?> base = mobIterator.next();
if (base.Updater(event))
{
onRemove(base);
base.remove();
mobIterator.remove();
}
}
total += System.currentTimeMillis() - start;
update += System.currentTimeMillis() - start;
}
public void onRemove(CreatureBase<?> mob)
{
}
@EventHandler
public void CreatureDamage(CustomDamageEvent event)
{
long start = System.currentTimeMillis();
for (CreatureBase base : _mobs)
for (CreatureBase<?> base : _mobs)
base.Damage(event);
total += System.currentTimeMillis() - start;
@ -372,7 +444,7 @@ public class Halloween extends SoloGame
{
long start = System.currentTimeMillis();
for (CreatureBase base : _mobs)
for (CreatureBase<?> base : _mobs)
base.Target(event);
total += System.currentTimeMillis() - start;
@ -451,7 +523,7 @@ public class Halloween extends SoloGame
{
Block block = blockIterator.next();
if (block.getY() < 4)
if (block.getY() < 4 || block.getY() <= WorldData.MinY)
blockIterator.remove();
}
@ -494,40 +566,6 @@ public class Halloween extends SoloGame
{
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
@EventHandler
@ -552,7 +590,7 @@ public class Halloween extends SoloGame
Scoreboard.writeNewLine();
Scoreboard.write(C.cYellow + C.Bold + "Players");
if (GetPlayers(true).size() < 8)
if (GetPlayers(true).size() < 5)
{
for (Player player : GetPlayers(true))
{
@ -564,12 +602,21 @@ public class Halloween extends SoloGame
Scoreboard.write(GetPlayers(true).size() + " Alive");
}
if(Objective != null)
{
Scoreboard.writeNewLine();
Scoreboard.write(C.cYellow + C.Bold + "Objective");
Scoreboard.write(Objective);
}
Scoreboard.draw();
}
@EventHandler
public void soundOff(PlayerCommandPreprocessEvent event)
{
if(!doVoices) return;
if (event.getMessage().equalsIgnoreCase("/voice"))
{
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())
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(),
20f, 1F);

View File

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

View File

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

View File

@ -1,18 +1,22 @@
package nautilus.game.arcade.game.games.halloween.creatures;
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.UtilMath;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
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 Halloween Host;
@ -22,6 +26,8 @@ public abstract class CreatureBase<T extends LivingEntity>
private Location _target;
private long _targetTime;
private List<Entity> _parts = new ArrayList<>();
public CreatureBase(Halloween game, String name, Class<T> mobClass, Location loc)
{
@ -37,11 +43,39 @@ public abstract class CreatureBase<T extends LivingEntity>
_ent.setCustomName(name);
_ent.setCustomNameVisible(true);
}
addEntityPart(_ent);
SpawnCustom(_ent);
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);
@ -114,8 +148,13 @@ public abstract class CreatureBase<T extends LivingEntity>
public abstract void Damage(CustomDamageEvent event);
public abstract void Target(EntityTargetEvent event);
public void CreatureMove(Creature creature)
{
CreatureMove(creature, 1);
}
public void CreatureMove(Creature creature, float speed)
{
//New Target
SetTarget(GetRoamTarget());
@ -131,8 +170,23 @@ public abstract class CreatureBase<T extends LivingEntity>
//Move
else
{
UtilEnt.CreatureMove(creature, GetTarget(), 1f);
UtilEnt.CreatureMove(creature, GetTarget(), speed);
Host.moves++;
}
}
public void remove()
{
for(Entity ent : _parts)
{
if(ent instanceof Damageable)
{
((Damageable) ent).damage(((Damageable) ent).getHealth());
}
else
{
ent.remove();
}
}
}
}

View File

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

View File

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

View File

@ -1,6 +1,6 @@
package nautilus.game.arcade.game.games.halloween.waves;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.Material;
@ -9,29 +9,40 @@ import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
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.UtilMath;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
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
{
protected Halloween Host;
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 _duration;
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;
@ -66,22 +77,57 @@ public abstract class WaveBase
if (_tick == 0)
{
System.out.println("Wave " + wave + " has started.");
Host.Announce(C.cRed + C.Bold + "Wave " + wave + ": " + C.cYellow + _name);
UtilTextMiddle.display(C.cYellow + "Wave " + wave, _name, 10, 100, 20);
if (_audio != null)
{
Host.playSound(_audio);
if(_announceStart)
{
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
for (Player player : UtilServer.getPlayers())
player.setExp(Math.min(0.999f, (float)(_duration - (System.currentTimeMillis() - _start)) / (float)_duration));
if(_displayProgress)
{
for (Player player : UtilServer.getPlayers())
{
player.setExp(Math.min(0.999f, (float)(_duration - (System.currentTimeMillis() - _start)) / (float)_duration));
}
}
//Spawn Beacons
if (_tick == 0)
if (_tick == 0 && _spawnBeacons)
SpawnBeacons(_spawns);
//Spawn
@ -92,7 +138,7 @@ public abstract class WaveBase
return false;
}
public void SpawnBeacons(ArrayList<Location> locs)
public void SpawnBeacons(List<Location> locs)
{
//Average Location
Vector total = new Vector(0,0,0);
@ -121,6 +167,36 @@ public abstract class WaveBase
{
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);
}

View File

@ -1,6 +1,9 @@
package nautilus.game.arcade.game.games.halloween.waves;
import java.util.List;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
@ -11,9 +14,9 @@ import nautilus.game.arcade.game.games.halloween.creatures.CreatureBase;
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
@ -28,7 +31,7 @@ public class WaveVictory extends WaveBase
player.playEffect(Host.WorldData.GetDataLocs("BLACK").get(0), Effect.RECORD_PLAY, 2259);
//Mobs
for (CreatureBase<LivingEntity> mob : Host.GetCreatures())
for (CreatureBase<? extends LivingEntity> mob : Host.GetCreatures())
mob.GetEntity().damage(5);
//Time

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -57,7 +57,7 @@ public class PerkFletcher extends Perk
public PerkFletcher(int time, int max, boolean remove, int slot, boolean instant)
{
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)
@ -162,7 +162,13 @@ public class PerkFletcher extends Perk
}
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);

View File

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

View File

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

View File

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