Final season 3 world event tweaks (adds skeleton king)

This commit is contained in:
AlexTheCoder 2017-06-15 23:10:16 -04:00
parent 5829b720a8
commit 1cdf9d2bba
31 changed files with 2375 additions and 84 deletions

View File

@ -156,19 +156,25 @@ public class WorldEventManager extends MiniPlugin implements ScoreboardElement
private WorldEventType tryStartEvent() private WorldEventType tryStartEvent()
{ {
WorldEventType[] types = WorldEventType.values(); WorldEventType[] types = WorldEventType.values();
WorldEventType type = types[_random.nextInt(types.length)]; if (types.length == 0)
Location location = _terrainFinder.findAreaInBorderlands(false);
if (location != null)
{ {
initializeEvent(type.createInstance(this, location, _skillFactory)); return null;
return type;
} }
else else
{ {
// Try again in 5 minutes WorldEventType type = types[_random.nextInt(types.length)];
_nextEventStart = System.currentTimeMillis() + (5 * 60 * 1000); //Location location = _terrainFinder.findAreaInBorderlands(false);
//if (location != null)
{
initializeEvent(type.createInstance(this));
return type;
}
//else
//{
// Try again in 5 minutes
//_nextEventStart = System.currentTimeMillis() + (5 * 60 * 1000);
//}
} }
return null;
} }
private void initializeEvent(WorldEvent event) private void initializeEvent(WorldEvent event)
@ -182,12 +188,16 @@ public class WorldEventManager extends MiniPlugin implements ScoreboardElement
_runningEvents.add(event); _runningEvents.add(event);
} }
public WorldEvent startEventFromName(Location location, String name) public WorldEvent startEventFromName(String name)
{ {
WorldEventType eventType = WorldEventType.valueOf(name); WorldEventType eventType = WorldEventType.valueOf(name);
if (eventType != null) if (eventType != null)
{ {
WorldEvent event = eventType.createInstance(this, location, _skillFactory); WorldEvent event = eventType.createInstance(this);
if (event == null)
{
return null;
}
initializeEvent(event); initializeEvent(event);
return event; return event;
} }
@ -199,8 +209,8 @@ public class WorldEventManager extends MiniPlugin implements ScoreboardElement
{ {
if (eventType != null) if (eventType != null)
{ {
Location location = _terrainFinder.findAreaInBorderlands(true); //Location location = _terrainFinder.findAreaInBorderlands(true);
WorldEvent event = eventType.createInstance(this, location, _skillFactory); WorldEvent event = eventType.createInstance(this);
if (event != null) if (event != null)
{ {
initializeEvent(event); initializeEvent(event);

View File

@ -1,11 +1,8 @@
package mineplex.game.clans.clans.worldevent; package mineplex.game.clans.clans.worldevent;
import java.lang.reflect.Constructor;
import org.bukkit.Location;
import mineplex.game.clans.clans.worldevent.api.WorldEvent; import mineplex.game.clans.clans.worldevent.api.WorldEvent;
import mineplex.minecraft.game.classcombat.Skill.SkillFactory; import mineplex.game.clans.clans.worldevent.boss.ironwizard.GolemBoss;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.SkeletonBoss;
public enum WorldEventType public enum WorldEventType
{ {
@ -15,58 +12,34 @@ public enum WorldEventType
//IRON_WIZARD("Iron Wizard", GolemBoss.class, 30), //IRON_WIZARD("Iron Wizard", GolemBoss.class, 30),
//BROOD_MOTHER("Brood Mother", SpiderBoss.class, 30), //BROOD_MOTHER("Brood Mother", SpiderBoss.class, 30),
//SKELETON_KING("Skeleton King", SkeletonBoss.class, 30) //SKELETON_KING("Skeleton King", SkeletonBoss.class, 30)
IRON_WIZARD("Iron Wizard", GolemBoss.class, (man) ->
{
return new GolemBoss(man);
}),
SKELETON_KING("Skeleton King", SkeletonBoss.class, (man) ->
{
return new SkeletonBoss(man);
})
; ;
private String _name; private String _name;
private Class<? extends WorldEvent> _clazz; private Class<? extends WorldEvent> _clazz;
private int _areaNeeded; private EventCreator _creator;
WorldEventType(String name, Class<? extends WorldEvent> clazz, int areaNeeded) WorldEventType(String name, Class<? extends WorldEvent> clazz, EventCreator creator)
{ {
_name = name; _name = name;
_clazz = clazz; _clazz = clazz;
_areaNeeded = areaNeeded; _creator = creator;
} }
public int getAreaNeeded() public WorldEvent createInstance(WorldEventManager eventManager)
{
return _areaNeeded;
}
public WorldEvent createInstance(WorldEventManager eventManager, Location centerLocation, SkillFactory skillFactory)
{ {
WorldEvent worldEvent = null; WorldEvent worldEvent = null;
try if (_creator != null)
{ {
for (Constructor<?> con : _clazz.getConstructors()) worldEvent = _creator.createEvent(eventManager);
{
Class<?>[] classes = con.getParameterTypes();
if (classes[0] == WorldEventManager.class)
{
if (classes.length == 3)
{
worldEvent = (WorldEvent) con.newInstance(eventManager, centerLocation, skillFactory);
}
else
{
worldEvent = (WorldEvent) con.newInstance(eventManager, centerLocation);
}
}
else if (classes.length == 4)
{
worldEvent = (WorldEvent) con.newInstance(eventManager.getDamage(), eventManager.getBlockRestore(), eventManager.getClans().getCondition(), centerLocation);
}
else
{
worldEvent = (WorldEvent) con.newInstance(eventManager.getDisguiseManager(), eventManager.getDamage(), eventManager.getBlockRestore(), eventManager.getClans().getCondition(), eventManager.getClans().getProjectile(), centerLocation);
}
}
}
catch (Exception e)
{
e.printStackTrace();
} }
return worldEvent; return worldEvent;
@ -74,6 +47,11 @@ public enum WorldEventType
public String getName() public String getName()
{ {
return this._name; return _name;
}
private static interface EventCreator
{
WorldEvent createEvent(WorldEventManager manager);
} }
} }

View File

@ -20,7 +20,7 @@ public class BossArenaLocationFinder
public Location getIronWizardCenter() public Location getIronWizardCenter()
{ {
return new Location(_world, 0, 0, 0); return new Location(_world, 1057, 63, -77);
} }
public Pair<List<Vector>, List<Vector>> getIronWizardPads() public Pair<List<Vector>, List<Vector>> getIronWizardPads()
@ -28,12 +28,22 @@ public class BossArenaLocationFinder
List<Vector> in = new ArrayList<>(); List<Vector> in = new ArrayList<>();
List<Vector> out = new ArrayList<>(); List<Vector> out = new ArrayList<>();
in.add(new Vector(1006, 62, -77));
in.add(new Vector(1057, 62, -26));
in.add(new Vector(1108, 62, -77));
in.add(new Vector(1057, 62, -128));
out.add(new Vector(1035, 63, -77));
out.add(new Vector(1057, 63, -99));
out.add(new Vector(1079, 63, -77));
out.add(new Vector(1057, 63, -55));
return Pair.create(in, out); return Pair.create(in, out);
} }
public Location getSkeletonKingCenter() public Location getSkeletonKingCenter()
{ {
return new Location(_world, 0, 0, 0); return new Location(_world, -1043, 58, 159);
} }
public Pair<List<Vector>, List<Vector>> getSkeletonKingPads() public Pair<List<Vector>, List<Vector>> getSkeletonKingPads()
@ -41,6 +51,16 @@ public class BossArenaLocationFinder
List<Vector> in = new ArrayList<>(); List<Vector> in = new ArrayList<>();
List<Vector> out = new ArrayList<>(); List<Vector> out = new ArrayList<>();
in.add(new Vector(-1094, 57, 159));
in.add(new Vector(-1043, 57, 210));
in.add(new Vector(-992, 57, 159));
in.add(new Vector(-1043, 57, 108));
out.add(new Vector(-1021, 58, 159));
out.add(new Vector(-1043, 58, 137));
out.add(new Vector(-1065, 58, 159));
out.add(new Vector(-1043, 58, 181));
return Pair.create(in, out); return Pair.create(in, out);
} }
} }

View File

@ -5,14 +5,18 @@ import java.util.stream.Collectors;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import mineplex.core.blockrestore.BlockRestore; import mineplex.core.blockrestore.BlockRestore;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilServer;
import mineplex.core.disguise.DisguiseManager; import mineplex.core.disguise.DisguiseManager;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.projectile.ProjectileManager; import mineplex.core.projectile.ProjectileManager;
import mineplex.core.updater.UpdateType; import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent; import mineplex.core.updater.event.UpdateEvent;
@ -21,6 +25,8 @@ import mineplex.game.clans.clans.worldevent.api.EventCreature;
import mineplex.game.clans.clans.worldevent.api.EventCreatureDeathEvent; import mineplex.game.clans.clans.worldevent.api.EventCreatureDeathEvent;
import mineplex.game.clans.clans.worldevent.api.EventState; import mineplex.game.clans.clans.worldevent.api.EventState;
import mineplex.game.clans.clans.worldevent.api.WorldEvent; import mineplex.game.clans.clans.worldevent.api.WorldEvent;
import mineplex.minecraft.game.classcombat.Skill.ISkill;
import mineplex.minecraft.game.classcombat.Skill.Assassin.Recall;
import mineplex.minecraft.game.core.condition.ConditionManager; import mineplex.minecraft.game.core.condition.ConditionManager;
import mineplex.minecraft.game.core.damage.DamageManager; import mineplex.minecraft.game.core.damage.DamageManager;
@ -38,7 +44,7 @@ public abstract class BossWorldEvent<T extends EventCreature<?>> extends WorldEv
super(name, centerLocation, radius, true, disguiseManager, projectileManager, damageManager, blockRestore, conditionManager); super(name, centerLocation, radius, true, disguiseManager, projectileManager, damageManager, blockRestore, conditionManager);
_teleportFrom = teleportFrom.stream().map(vec -> vec.toLocation(centerLocation.getWorld())).collect(Collectors.toList()); _teleportFrom = teleportFrom.stream().map(vec -> vec.toLocation(centerLocation.getWorld())).collect(Collectors.toList());
_teleportTo = teleportFrom.stream().map(vec -> vec.toLocation(centerLocation.getWorld())).collect(Collectors.toList()); _teleportTo = teleportTo.stream().map(vec -> vec.toLocation(centerLocation.getWorld())).collect(Collectors.toList());
} }
public abstract String getDeathMessage(); public abstract String getDeathMessage();
@ -72,7 +78,14 @@ public abstract class BossWorldEvent<T extends EventCreature<?>> extends WorldEv
{ {
for (Player player : UtilPlayer.getInRadius(from, TELEPORT_PAD_RANGE).keySet()) for (Player player : UtilPlayer.getInRadius(from, TELEPORT_PAD_RANGE).keySet())
{ {
player.teleport(_teleportTo.get(getRandom().nextInt(_teleportTo.size()))); player.teleport(UtilMath.randomElement(_teleportTo));
for (ISkill skill : ClansManager.getInstance().getClassManager().Get(player).GetSkills())
{
if (skill instanceof Recall)
{
((Recall)skill).Reset(player);
}
}
sendMessage(player, "You have teleported inside the arena!"); sendMessage(player, "You have teleported inside the arena!");
} }
} }
@ -89,7 +102,11 @@ public abstract class BossWorldEvent<T extends EventCreature<?>> extends WorldEv
{ {
Location drop = event.getCreature().getLastKnownLocation(); Location drop = event.getCreature().getLastKnownLocation();
UtilServer.CallEvent(new BossDeathEvent(this, drop)); UtilServer.CallEvent(new BossDeathEvent(this, drop));
ClansManager.getInstance().runSyncLater(() -> ClansManager.getInstance().getLootManager().dropRare(drop), DELAY_TILL_DROP_REWARD); ClansManager.getInstance().runSyncLater(() ->
{
ClansManager.getInstance().getLootManager().dropRare(drop);
drop.getWorld().dropItem(drop, new ItemBuilder(Material.IRON_INGOT).setTitle(C.cDRedB + "Old Silver Token").setLore(C.cRed + "This token pulses with an evil aura.").setGlow(true).build());
}, DELAY_TILL_DROP_REWARD);
Bukkit.broadcastMessage(getDeathMessage()); Bukkit.broadcastMessage(getDeathMessage());
} }
} }

View File

@ -11,7 +11,7 @@ public class GolemBoss extends BossWorldEvent<GolemCreature>
{ {
public GolemBoss(WorldEventManager manager) public GolemBoss(WorldEventManager manager)
{ {
super("Iron Wizard", manager.getBossArenaLocationFinder().getIronWizardCenter(), 30, manager.getBossArenaLocationFinder().getIronWizardPads().getLeft(), manager.getBossArenaLocationFinder().getIronWizardPads().getRight(), manager.getDisguiseManager(), manager.getClans().getProjectile(), manager.getClans().getDamageManager(), manager.getBlockRestore(), manager.getClans().getCondition()); super("Iron Wizard", manager.getBossArenaLocationFinder().getIronWizardCenter(), 50, manager.getBossArenaLocationFinder().getIronWizardPads().getLeft(), manager.getBossArenaLocationFinder().getIronWizardPads().getRight(), manager.getDisguiseManager(), manager.getClans().getProjectile(), manager.getClans().getDamageManager(), manager.getBlockRestore(), manager.getClans().getCondition());
} }
@Override @Override
@ -19,7 +19,6 @@ public class GolemBoss extends BossWorldEvent<GolemCreature>
{ {
Bukkit.broadcastMessage(F.main(getName(), "The mighty " + getName() + " challenges you to face him!")); Bukkit.broadcastMessage(F.main(getName(), "The mighty " + getName() + " challenges you to face him!"));
spawnGolem(getCenterLocation()); spawnGolem(getCenterLocation());
announceStart();
} }
@Override @Override
@ -30,7 +29,7 @@ public class GolemBoss extends BossWorldEvent<GolemCreature>
private GolemCreature spawnGolem(Location location) private GolemCreature spawnGolem(Location location)
{ {
GolemCreature golemCreature = new GolemCreature(this, location, 3000); GolemCreature golemCreature = new GolemCreature(this, location);
registerCreature(golemCreature); registerCreature(golemCreature);
setBossCreature(golemCreature); setBossCreature(golemCreature);
return golemCreature; return golemCreature;

View File

@ -59,7 +59,7 @@ public class GolemCreature extends EventCreature<IronGolem>
private Vector _afkWalk = new Vector(); private Vector _afkWalk = new Vector();
private long _lastSlam; private long _lastSlam;
public GolemCreature(GolemBoss boss, Location location, double maxHealth) public GolemCreature(GolemBoss boss, Location location)
{ {
super(boss, location, "Iron Wizard", true, 3000, 30, true, IronGolem.class); super(boss, location, "Iron Wizard", true, 3000, 30, true, IronGolem.class);
@ -146,8 +146,11 @@ public class GolemCreature extends EventCreature<IronGolem>
_lastAbility = 20; _lastAbility = 20;
HandlerList.unregisterAll(ability); HandlerList.unregisterAll(ability);
if (DEBUG_MODE)
{
System.out.print("Unregistered golem ability " + ability.getClass().getSimpleName()); System.out.print("Unregistered golem ability " + ability.getClass().getSimpleName());
} }
}
else if (!ability.inProgress()) else if (!ability.inProgress())
{ {
canDoNew = false; canDoNew = false;

View File

@ -0,0 +1,64 @@
package mineplex.game.clans.clans.worldevent.boss.skeletonking;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilServer;
import mineplex.game.clans.clans.worldevent.WorldEventManager;
import mineplex.game.clans.clans.worldevent.api.EventCreature;
import mineplex.game.clans.clans.worldevent.boss.BossWorldEvent;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.minion.MinionType;
public class SkeletonBoss extends BossWorldEvent<SkeletonCreature>
{
protected boolean canMove = false;
public SkeletonBoss(WorldEventManager manager)
{
super("Skeleton King", manager.getBossArenaLocationFinder().getIronWizardCenter(), 50, manager.getBossArenaLocationFinder().getIronWizardPads().getLeft(), manager.getBossArenaLocationFinder().getIronWizardPads().getRight(), manager.getDisguiseManager(), manager.getClans().getProjectile(), manager.getClans().getDamageManager(), manager.getBlockRestore(), manager.getClans().getCondition());
}
@Override
protected void customStart()
{
Bukkit.broadcastMessage(F.main(getName(), "The evils of the world have manifested in the form of the " + getName() + "! Become the champion of Light and destroy him!"));
spawnNecromancer(getCenterLocation());
Bukkit.getScheduler().runTaskLater(UtilServer.getPlugin(), () ->
{
canMove = true;
}, 20 * 3);
}
public EventCreature<?> spawnMinion(MinionType type, Location location)
{
EventCreature<?> minionCreature = type.getNewInstance(this, location);
if (minionCreature != null)
{
registerCreature(minionCreature);
}
return minionCreature;
}
private SkeletonCreature spawnNecromancer(Location location)
{
SkeletonCreature necromancerCreature = new SkeletonCreature(this, location);
registerCreature(necromancerCreature);
return necromancerCreature;
}
@Override
public String getDeathMessage()
{
return F.main(getName(), "The demonic " + getName() + " has been slain!");
}
@Override
protected void customTick() {}
@Override
public void customCleanup(boolean onDisable) {}
@Override
protected void customStop() {}
}

View File

@ -0,0 +1,482 @@
package mineplex.game.clans.clans.worldevent.boss.skeletonking;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
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.HandlerList;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
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.common.util.UtilTime;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.clans.clans.worldevent.api.BossAbility;
import mineplex.game.clans.clans.worldevent.api.EventCreature;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities.SkeletonArcherShield;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities.SkeletonPassive;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities.SkeletonPulse;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities.SkeletonSmite;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities.SkeletonStrike;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities.SkeletonWraithSummon;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.minion.UndeadArcherCreature;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.minion.UndeadWarriorCreature;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
public class SkeletonCreature extends EventCreature<Skeleton>
{
private List<BossAbility<SkeletonCreature, Skeleton>> _currentAbilities = new ArrayList<>();
private SkeletonPassive _passive;
private int _lastAbility;
private Map<Class<?>, Long> _cooldowns = new HashMap<>();
private LinkedList<Double> _wraithTriggers = new LinkedList<>();
private List<Location> _movePoints = new ArrayList<>();
private Location _movingTo;
private boolean _moving;
private long _lastMoved;
private long _lastUsedPassive;
public List<UndeadArcherCreature> Archers = new ArrayList<>();
public List<UndeadWarriorCreature> Warriors = new ArrayList<>();
public SkeletonCreature(SkeletonBoss boss, Location location)
{
super(boss, location, "Skeleton King", true, 2500, 30, true, Skeleton.class);
spawnEntity();
_passive = new SkeletonPassive(this);
_wraithTriggers.add(1500D);
_wraithTriggers.add(1000D);
_wraithTriggers.add(500D);
_wraithTriggers.add(100D);
getEntity().getWorld().setThunderDuration(10000000);
getEntity().getWorld().setThundering(true);
}
@Override
protected void spawnCustom()
{
UtilEnt.vegetate(getEntity());
getEntity().setSkeletonType(SkeletonType.WITHER);
getEntity().getEquipment().setItemInHand(new ItemStack(Material.RECORD_6)); //Meridian Scepter
getEntity().getEquipment().setItemInHandDropChance(0.f);
}
@Override
public void dieCustom()
{
HandlerList.unregisterAll(_passive);
_passive = null;
endAbility();
getEntity().getWorld().setThunderDuration(0);
getEntity().getWorld().setThundering(false);
}
private void endAbility()
{
for (BossAbility<SkeletonCreature, Skeleton> ability : _currentAbilities)
{
ability.setFinished();
HandlerList.unregisterAll(ability);
}
_currentAbilities.clear();
}
@EventHandler
public void onTick(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
if (_passive != null && ((SkeletonBoss)getEvent()).canMove)
{
if (UtilTime.elapsed(_lastUsedPassive, _passive.getCooldown() * 20) || _passive.isProgressing())
{
_lastUsedPassive = System.currentTimeMillis();
_passive.tick();
}
}
Iterator<BossAbility<SkeletonCreature, Skeleton>> itel = _currentAbilities.iterator();
boolean canDoNew = _currentAbilities.size() < 3;
while (itel.hasNext())
{
BossAbility<SkeletonCreature, Skeleton> ability = itel.next();
if (ability.hasFinished())
{
itel.remove();
ability.setFinished();
_lastAbility = 20;// _currentAbility.getCooldown();
HandlerList.unregisterAll(ability);
if (DEBUG_MODE)
{
System.out.print("Unregistered necromancer ability " + ability.getClass().getSimpleName());
}
_cooldowns.put(ability.getClass(), System.currentTimeMillis() + (ability.getCooldown() * 1000));
}
else if (ability.inProgress())
{
canDoNew = false;
_lastAbility = 20;// _currentAbility.getCooldown();
}
}
if (_lastAbility-- <= 0 && canDoNew && UtilBlock.solid(getEntity().getLocation().getBlock().getRelative(BlockFace.DOWN)))
{
Map<Class<? extends BossAbility<SkeletonCreature, Skeleton>>, Integer> weight = new HashMap<>();
Map<Player, Double> dist = new HashMap<>();
for (Player player : UtilPlayer.getNearby(getEntity().getLocation(), 50, true))
{
if (player.hasLineOfSight(getEntity()))
{
dist.put(player, player.getLocation().distance(getEntity().getLocation()));
}
}
if (!dist.isEmpty())
{
{// Pulse & Strike
List<Player> players = getPlayers(dist, UtilMath.r(10) == 0 ? 25 : 20);
List<Player> near = getPlayers(dist, 5);
if (!players.isEmpty())
{
if (!near.isEmpty() && near.size() >= 4 && new Random().nextDouble() <= .45)
{
weight.put(SkeletonPulse.class, 999);
}
else
{
weight.put(SkeletonStrike.class, 6);
}
}
}
{// Smite
List<Player> players = getPlayers(dist, 15);
if (!players.isEmpty())
{
weight.put(SkeletonSmite.class, 6);
}
}
{//Archer Shield
List<Player> players = getPlayers(dist, 20);
double score = 0;
for (Player player : players)
{
score += (18 - dist.get(player)) / 2;
}
if (players.size() >= 4)
{
score += 17;
}
if (score > 0)
{
weight.put(SkeletonArcherShield.class, (int) Math.ceil(score));
}
}
Double wraithUse = null;
for (Double test : _wraithTriggers)
{
if (wraithUse == null)
{
if (getHealth() <= test)
{
wraithUse = test;
break;
}
}
}
if (wraithUse != null)
{// Wraith Summon
_wraithTriggers.remove(wraithUse);
weight.clear();
weight.put(SkeletonWraithSummon.class, 999);
}
}
for (BossAbility<SkeletonCreature, Skeleton> ability : _currentAbilities)
{
weight.remove(ability.getClass());
}
for (Class<?> c : _cooldowns.keySet())
{
if (_cooldowns.get(c) > System.currentTimeMillis())
{
weight.remove(c);
}
}
if (_moving)
{
Iterator<Class<? extends BossAbility<SkeletonCreature, Skeleton>>> trying = weight.keySet().iterator();
while (trying.hasNext())
{
Class<? extends BossAbility<SkeletonCreature, Skeleton>> abilityClass = trying.next();
try
{
BossAbility<SkeletonCreature, Skeleton> ability = abilityClass.newInstance();
if (!ability.canMove())
{
trying.remove();
}
}
catch (Exception e) {}
}
}
BossAbility<SkeletonCreature, Skeleton> ability = null;
if (!weight.isEmpty())
{
int i = 0;
for (Integer entry : weight.values())
{
i += entry;
}
loop: for (int a = 0; a < 10; a++)
{
int luckyNumber = UtilMath.r(i);
for (Entry<Class<? extends BossAbility<SkeletonCreature, Skeleton>>, Integer> entry : weight.entrySet())
{
luckyNumber -= entry.getValue();
if (luckyNumber <= 0)
{
try
{
ability = entry.getKey().getConstructor(SkeletonCreature.class).newInstance(this);
if (ability.getTarget() == null || ability.hasFinished())
{
ability = null;
}
else
{
break loop;
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
break;
}
}
}
}
if (ability != null && ability.getTarget() != null)
{
Bukkit.getPluginManager().registerEvents(ability, UtilServer.getPlugin());
if (DEBUG_MODE)
{
System.out.print("Necromancer is using " + ability.getClass().getSimpleName());
}
_currentAbilities.add(ability);
}
_lastAbility = 10;
}
for (BossAbility<SkeletonCreature, Skeleton> ability : _currentAbilities)
{
try
{
ability.tick();
}
catch (Exception e)
{
e.printStackTrace();
}
}
boolean canMove = true;
for (BossAbility<SkeletonCreature, Skeleton> ability : _currentAbilities)
{
if (!ability.canMove())
{
canMove = false;
}
}
if (!((SkeletonBoss)getEvent()).canMove)
{
return;
}
if (_moving)
{
if (_movingTo == null)
{
_movingTo = selectWalkTarget();
}
if (UtilMath.offset(getEntity().getLocation(), _movingTo) <= 1.3)
{
_lastMoved = System.currentTimeMillis();
_movingTo = null;
_moving = false;
return;
}
UtilEnt.LookAt(getEntity(), _movingTo);
Vector walk = UtilAlg.getTrajectory(getEntity().getLocation(), _movingTo);
walk.multiply(walk.length());
walk.multiply(.2);
getEntity().setVelocity(walk);
}
else
{
if (!UtilTime.elapsed(_lastMoved, 7000) || !canMove)
{
return;
}
_movingTo = selectWalkTarget();
_moving = true;
}
}
private Location selectWalkTarget()
{
if (_movePoints.isEmpty())
{
Location base = getSpawnLocation().clone();
base.setY(getEntity().getLocation().getY());
generateWalkPoints(base);
}
Location selected = _movePoints.get(new Random().nextInt(_movePoints.size()));
_movePoints.remove(selected);
return selected;
}
private void generateWalkPoints(Location base)
{
_movePoints.add(base.clone().add(5 + UtilMath.random(1, 3), 0, 5 + UtilMath.random(1, 3)));
_movePoints.add(base.clone().add(-5 + UtilMath.random(1, 3), 0, 5 + UtilMath.random(1, 3)));
_movePoints.add(base.clone().add(5 + UtilMath.random(1, 3), 0, -5 + UtilMath.random(1, 3)));
_movePoints.add(base.clone().add(-5 + UtilMath.random(1, 3), 0, -5 + UtilMath.random(1, 3)));
}
private List<Player> getPlayers(Map<Player, Double> map, double maxDist)
{
return getPlayers(map, 0, maxDist);
}
private List<Player> getPlayers(final Map<Player, Double> map, double minDist, double maxDist)
{
List<Player> list = new ArrayList<>();
for (Player p : map.keySet())
{
if (map.get(p) >= minDist && map.get(p) <= maxDist)
{
list.add(p);
}
}
Collections.sort(list, (o1, o2) ->
{
return Double.compare(map.get(o2), map.get(o1));
});
return list;
}
@EventHandler
public void onSkeletonDamage(CustomDamageEvent event)
{
if (event.GetDamageeEntity().getEntityId() == getEntity().getEntityId())
{
event.SetKnockback(false);
}
}
@EventHandler
public void noFallDamage(CustomDamageEvent event)
{
if (getEntity() == null)
{
return;
}
if (event.GetDamageeEntity().getEntityId() != getEntity().getEntityId())
{
return;
}
DamageCause cause = event.GetCause();
if (cause == DamageCause.FALL)
{
event.SetCancelled("Boss Invulnerability");
}
}
@EventHandler(priority = EventPriority.HIGH)
public void protect(CustomDamageEvent event)
{
if (event.IsCancelled())
{
return;
}
LivingEntity damagee = event.GetDamageeEntity();
LivingEntity damager = event.GetDamagerEntity(event.GetCause() == DamageCause.PROJECTILE);
if (damagee == null)
{
return;
}
if (damager == null)
{
return;
}
if (getEntity().equals(damagee))
{
if (!(damager instanceof Player))
{
event.SetCancelled("Allied Attacker");
}
}
}
}

View File

@ -0,0 +1,187 @@
package mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftSkeleton;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Player;
import org.bukkit.entity.Skeleton;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
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.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.game.clans.clans.worldevent.api.BossAbility;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.SkeletonCreature;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.minion.UndeadArcherCreature;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
public class SkeletonArcherShield extends BossAbility<SkeletonCreature, Skeleton>
{
private static long ATTACK_DURATION = 10000;
private static long ARROW_DELAY = 100;
private static long ARROW_WARMUP = 2000;
private static double PULL_RANGE = 12;
private long _start;
private long _lastShoot;
private boolean _teleported;
public SkeletonArcherShield(SkeletonCreature creature)
{
super(creature);
_start = System.currentTimeMillis();
}
@Override
public int getCooldown()
{
return 20;
}
@Override
public boolean canMove()
{
return false;
}
@Override
public boolean inProgress()
{
return false;
}
@Override
public boolean hasFinished()
{
return UtilTime.elapsed(_start, ATTACK_DURATION);
}
@Override
public void setFinished()
{
_start = System.currentTimeMillis() - ATTACK_DURATION;
for (UndeadArcherCreature creature : getBoss().Archers)
{
creature.getEntity().remove();
}
}
private void run(boolean initial)
{
for (int i = 0; i < getBoss().Archers.size(); i++)
{
Skeleton archer = getBoss().Archers.get(i).getEntity();
UtilEnt.vegetate(archer);
((CraftSkeleton)archer).setVegetated(false);
double lead = i * ((2d * Math.PI)/getBoss().Archers.size());
double sizeMod = 2;
//Orbit
double speed = 10d;
double oX = -Math.sin(getEntity().getTicksLived()/speed + lead) * 2 * sizeMod;
double oY = 0;
double oZ = Math.cos(getEntity().getTicksLived()/speed + lead) * 2 * sizeMod;
if (initial)
{
archer.teleport(getEntity().getLocation().add(oX, oY, oZ));
UtilEnt.vegetate(archer);
}
else
{
Location to = getEntity().getLocation().add(oX, oY, oZ);
UtilEnt.LookAt(archer, to);
UtilAction.velocity(archer, UtilAlg.getTrajectory(archer.getLocation(), to), 0.4, false, 0, 0.1, 1, true);
}
}
}
private void shoot()
{
if (UtilTime.elapsed(_start, ARROW_WARMUP) && UtilTime.elapsed(_lastShoot, ARROW_DELAY))
{
_lastShoot = System.currentTimeMillis();
for (UndeadArcherCreature archer : getBoss().Archers)
{
Location spawn = archer.getEntity().getEyeLocation().add(UtilAlg.getTrajectory(getEntity().getEyeLocation(), archer.getEntity().getEyeLocation()).normalize());
Vector vector = UtilAlg.getTrajectory(getEntity().getEyeLocation(), spawn);
Arrow arrow = archer.getEntity().getWorld().spawnArrow(spawn, vector, 0.6f, 12f);
arrow.setMetadata("SHIELD_SHOT", new FixedMetadataValue(UtilServer.getPlugin(), true));
arrow.setMetadata("BARBED_ARROW", new FixedMetadataValue(UtilServer.getPlugin(), 10));
arrow.setShooter(archer.getEntity());
}
}
}
@Override
public void tick()
{
if (!_teleported)
{
run(true);
_teleported = true;
for (Player near : UtilPlayer.getInRadius(getEntity().getLocation(), PULL_RANGE).keySet())
{
Vector velocity = UtilAlg.getTrajectory(near, getEntity());
UtilAction.velocity(near, velocity, 2, false, 0, 0, 1, true);
near.addPotionEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, 5 * 20, -2));
for (int i = 0; i < 6; i++)
{
Vector random = new Vector(Math.random() * 4 - 2, Math.random() * 4 - 2, Math.random() * 4 - 2);
Location origin = getEntity().getLocation().add(0, 1.3, 0);
origin.add(velocity.clone().multiply(10));
origin.add(random);
Vector vel = UtilAlg.getTrajectory(origin, getEntity().getLocation().add(0, 1.3, 0));
vel.multiply(7);
UtilParticle.PlayParticleToAll(ParticleType.MAGIC_CRIT, origin, (float)vel.getX(), (float)vel.getY(), (float)vel.getZ(), 1, 0, ViewDist.LONG);
}
}
}
else
{
run(false);
shoot();
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onDamage(CustomDamageEvent event)
{
if (event.GetDamageeEntity().equals(getBoss().getEntity()))
{
if (!hasFinished())
{
event.SetCancelled("Wraiths Alive");
}
}
}
@EventHandler
public void onArrowHit(ProjectileHitEvent event)
{
if (event.getEntity().hasMetadata("SHIELD_SHOT"))
{
Bukkit.getScheduler().runTaskLater(UtilServer.getPlugin(), () ->
{
event.getEntity().remove();
}, 20L);
}
}
}

View File

@ -0,0 +1,119 @@
package mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import org.bukkit.Location;
import org.bukkit.entity.Skeleton;
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.UtilTime;
import mineplex.game.clans.clans.worldevent.api.BossAbility;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.SkeletonBoss;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.SkeletonCreature;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.minion.MinionType;
public class SkeletonHellishFlood extends BossAbility<SkeletonCreature, Skeleton>
{
private static final int WAVE_COUNT = 3;
private static final int WAVE_SIZE = 5;
private static final MinionType[] POSSIBLE_MINIONS = new MinionType[] {MinionType.WARRIOR, MinionType.ARCHER};
private static final long WAVE_DELAY = 1000;
private Map<String, MinionType[]> _waves = new HashMap<>();
private long _lastSpawned;
private int _current;
private int _ticks;
public SkeletonHellishFlood(SkeletonCreature creature)
{
super(creature);
if (WAVE_COUNT > 0)
{
for (int i = 1; i <= WAVE_COUNT; i++)
{
createWave(i);
}
}
_lastSpawned = System.currentTimeMillis();
_current = 1;
}
private void createWave(int number)
{
int length = POSSIBLE_MINIONS.length;
if (length <= 0 || WAVE_SIZE <= 0)
{
return;
}
MinionType[] wave = new MinionType[WAVE_SIZE];
for (int i = 0; i < WAVE_SIZE; i++)
{
wave[i] = POSSIBLE_MINIONS[new Random().nextInt(length)];
}
_waves.put("Wave " + number, wave);
}
@Override
public int getCooldown()
{
return 30;
}
@Override
public boolean canMove()
{
return false;
}
@Override
public boolean inProgress()
{
return true;
}
@Override
public boolean hasFinished()
{
return _waves.isEmpty() && _ticks > ((WAVE_DELAY / 1000) * 20 * (WAVE_COUNT - 1));
}
@Override
public void setFinished()
{
_waves.clear();
_ticks = 60;
}
@Override
public void tick()
{
_ticks++;
if (UtilTime.elapsed(_lastSpawned, WAVE_DELAY))
{
if (_current <= WAVE_COUNT)
{
for (MinionType type : _waves.get("Wave " + _current))
{
Location toSpawn = getLocation().clone();
toSpawn.add(UtilMath.random(3, 6), 0, UtilMath.random(3, 6));
((SkeletonBoss)getBoss().getEvent()).spawnMinion(type, toSpawn);
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, toSpawn, null, 0, 2, ViewDist.MAX);
UtilParticle.PlayParticleToAll(ParticleType.SMOKE, toSpawn, null, 0, 2, ViewDist.MAX);
}
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, getEntity().getLocation(), null, 0, 2, ViewDist.MAX);
UtilParticle.PlayParticleToAll(ParticleType.SMOKE, getEntity().getLocation(), null, 0, 2, ViewDist.MAX);
_waves.remove("Wave " + _current);
_current++;
_lastSpawned = System.currentTimeMillis();
}
}
}
}

View File

@ -0,0 +1,120 @@
package mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Skeleton;
import org.bukkit.event.EventHandler;
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.UtilTime;
import mineplex.game.clans.clans.worldevent.api.BossPassive;
import mineplex.game.clans.clans.worldevent.api.EventCreatureDeathEvent;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.SkeletonBoss;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.SkeletonCreature;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.minion.MinionType;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.minion.UndeadArcherCreature;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.minion.UndeadWarriorCreature;
public class SkeletonPassive extends BossPassive<SkeletonCreature, Skeleton>
{
private static final int MAX_ARCHERS = 10;
private static final int MAX_WARRIORS = 8;
private static final long SPAWN_RATE = 5000;
private List<Location> _queuedArchers = new ArrayList<>();
private List<Location> _queuedWarriors = new ArrayList<>();
private long _lastASpawned;
private long _lastWSpawned;
public SkeletonPassive(SkeletonCreature creature)
{
super(creature);
}
@Override
public int getCooldown()
{
return 20;
}
@Override
public boolean isProgressing()
{
return !_queuedArchers.isEmpty() || !_queuedWarriors.isEmpty();
}
@Override
public void tick()
{
if (getBoss().Archers.size() < MAX_ARCHERS && _queuedArchers.isEmpty())
{
for (int i = 0; i < (MAX_ARCHERS - getBoss().Archers.size()); i++)
{
Location spawn = getLocation().clone();
spawn.add(UtilMath.random(3, 6), 0, UtilMath.random(3, 6));
_queuedArchers.add(spawn);
}
}
if (getBoss().Warriors.size() < MAX_WARRIORS && _queuedWarriors.isEmpty())
{
for (int i = 0; i < (MAX_WARRIORS - getBoss().Warriors.size()); i++)
{
Location spawn = getLocation().clone();
spawn.add(UtilMath.random(3, 6), 0, UtilMath.random(3, 6));
_queuedWarriors.add(spawn);
}
}
for (Location animate : _queuedArchers)
{
UtilParticle.PlayParticleToAll(ParticleType.BLOCK_DUST.getParticle(Material.DIRT, 0),
animate.clone().add(0, 0.2, 0), null, 0, 4, ViewDist.NORMAL);
}
for (Location animate : _queuedWarriors)
{
UtilParticle.PlayParticleToAll(ParticleType.BLOCK_DUST.getParticle(Material.DIRT, 0),
animate.clone().add(0, 0.2, 0), null, 0, 4, ViewDist.NORMAL);
}
if (!_queuedArchers.isEmpty() && UtilTime.elapsed(_lastASpawned, SPAWN_RATE))
{
_lastASpawned = System.currentTimeMillis();
Location spawn = _queuedArchers.remove(0);
getBoss().Archers.add((UndeadArcherCreature) ((SkeletonBoss)getBoss().getEvent()).spawnMinion(MinionType.ARCHER, spawn));
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, spawn, null, 0, 2, ViewDist.MAX);
UtilParticle.PlayParticleToAll(ParticleType.SMOKE, spawn, null, 0, 2, ViewDist.MAX);
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, getEntity().getLocation(), null, 0, 2, ViewDist.MAX);
UtilParticle.PlayParticleToAll(ParticleType.SMOKE, getEntity().getLocation(), null, 0, 2, ViewDist.MAX);
}
if (!_queuedWarriors.isEmpty() && UtilTime.elapsed(_lastWSpawned, SPAWN_RATE))
{
_lastWSpawned = System.currentTimeMillis();
Location spawn = _queuedWarriors.remove(0);
getBoss().Warriors.add((UndeadWarriorCreature) ((SkeletonBoss)getBoss().getEvent()).spawnMinion(MinionType.WARRIOR, spawn));
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, spawn, null, 0, 2, ViewDist.MAX);
UtilParticle.PlayParticleToAll(ParticleType.SMOKE, spawn, null, 0, 2, ViewDist.MAX);
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, getEntity().getLocation(), null, 0, 2, ViewDist.MAX);
UtilParticle.PlayParticleToAll(ParticleType.SMOKE, getEntity().getLocation(), null, 0, 2, ViewDist.MAX);
}
}
@EventHandler
public void onArcherDeath(EventCreatureDeathEvent event)
{
if (event.getCreature() instanceof UndeadArcherCreature)
{
getBoss().Archers.remove(event.getCreature());
}
if (event.getCreature() instanceof UndeadWarriorCreature)
{
getBoss().Warriors.remove(event.getCreature());
}
}
}

View File

@ -0,0 +1,108 @@
package mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.entity.Skeleton;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
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.UtilPlayer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.recharge.Recharge;
import mineplex.game.clans.clans.worldevent.api.BossAbility;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.SkeletonCreature;
public class SkeletonPulse extends BossAbility<SkeletonCreature, Skeleton>
{
private static final long TOTAL_ATTACK_DURATION = 8000;
private static final long TOTAL_ATTACK_PROGRESS = 3000;
private long _start, _lastIncrement;
private int _radius;
private Location _center;
public SkeletonPulse(SkeletonCreature creature)
{
super(creature);
_start = System.currentTimeMillis();
_radius = 2;
_lastIncrement = System.currentTimeMillis();
_center = creature.getEntity().getLocation();
}
private int getRadius()
{
return Math.min(8, _radius);
}
@Override
public int getCooldown()
{
return 7;
}
@Override
public boolean canMove()
{
return UtilTime.elapsed(_start, TOTAL_ATTACK_PROGRESS);
}
@Override
public boolean inProgress()
{
return UtilTime.elapsed(_start, TOTAL_ATTACK_PROGRESS);
}
@Override
public boolean hasFinished()
{
return UtilTime.elapsed(_start, TOTAL_ATTACK_DURATION);
}
@Override
public void setFinished()
{
_start = System.currentTimeMillis() - TOTAL_ATTACK_DURATION;
}
@Override
public void tick()
{
if (UtilTime.elapsed(_lastIncrement, 500))
{
_lastIncrement = System.currentTimeMillis();
_radius++;
}
for (double token = 0; token <= (2 * Math.PI); token += .2)
{
double x = getRadius() * Math.cos(token);
double z = getRadius() * Math.sin(token);
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, _center.clone().add(x, 1.5, z), null, 0, 1, ViewDist.MAX);
}
for (Player player : UtilPlayer.getInRadius(getEntity().getLocation(), getRadius()).keySet())
{
if (player.isDead() || !player.isValid() || !player.isOnline())
{
continue;
}
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR)
{
continue;
}
if (!Recharge.Instance.use(player, "Pulse Knockback", 400, false, false, false))
{
continue;
}
player.playSound(player.getLocation(), Sound.AMBIENCE_THUNDER, 1f, 1f);
UtilAction.velocity(player, UtilAlg.getTrajectory2d(getEntity(), player), 2, false, 0.6, 0, 1.4, true);
}
}
}

View File

@ -0,0 +1,104 @@
package mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities;
import java.math.BigDecimal;
import org.bukkit.GameMode;
import org.bukkit.entity.Player;
import org.bukkit.entity.Skeleton;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
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.UtilPlayer;
import mineplex.core.common.util.UtilTime;
import mineplex.game.clans.clans.worldevent.api.BossAbility;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.SkeletonCreature;
public class SkeletonSmite extends BossAbility<SkeletonCreature, Skeleton>
{
private static final long TOTAL_ATTACK_DURATION = 8000;
private long _start;
private int _ticks;
private boolean _shot;
public SkeletonSmite(SkeletonCreature creature)
{
super(creature);
_start = System.currentTimeMillis();
_ticks = 0;
_shot = false;
}
@Override
public int getCooldown()
{
return 15;
}
@Override
public boolean canMove()
{
return false;
}
@Override
public boolean inProgress()
{
return true;
}
@Override
public boolean hasFinished()
{
return UtilTime.elapsed(_start, TOTAL_ATTACK_DURATION) && _shot;
}
@Override
public void setFinished()
{
_start = System.currentTimeMillis() - TOTAL_ATTACK_DURATION;
_shot = true;
}
@Override
public void tick()
{
if (_shot)
return;
if (_ticks < (6 * 20))
{
_ticks++;
double maxHeight = Math.min(_ticks / 20, 6);
int radius = Math.max(6 - (new BigDecimal(_ticks).divide(new BigDecimal(20)).intValue()), 0);
for (double y = 0; y < maxHeight; y += 0.5)
{
double cos = radius * Math.cos(y);
double sin = radius * Math.sin(y);
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, getEntity().getLocation().add(cos, y, sin), null, 0, 1, ViewDist.MAX);
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, getEntity().getLocation().add(sin, y, cos), null, 0, 1, ViewDist.MAX);
}
}
else
{
_shot = true;
for (Player player : UtilPlayer.getInRadius(getEntity().getLocation(), 15).keySet())
{
if (player.isDead() || !player.isValid() || !player.isOnline())
{
continue;
}
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR)
{
continue;
}
player.getWorld().strikeLightningEffect(player.getLocation());
getBoss().getEvent().getDamageManager().NewDamageEvent(player, getEntity(), null, DamageCause.LIGHTNING, 15 * getBoss().getDifficulty(), false, true, false, getEntity().getName(), "Lightning Strike");
}
}
}
}

View File

@ -0,0 +1,167 @@
package mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.entity.Skeleton;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
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.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.game.clans.clans.worldevent.api.BossAbility;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.SkeletonCreature;
public class SkeletonStrike extends BossAbility<SkeletonCreature, Skeleton>
{
private static final double MAX_RANGE = 25;
private static final Integer MAX_TARGETS = 1;
private boolean _shot;
public SkeletonStrike(SkeletonCreature creature)
{
super(creature);
_shot = false;
}
private int getPosition(Player toAdd, LinkedList<Player> ordered)
{
int position = ordered.size();
int index = 0;
for (Player player : ordered)
{
if (player.getHealth() < toAdd.getHealth())
{
position = index;
return position;
}
index++;
}
return position;
}
private List<Player> getTargets()
{
Skeleton necromancer = getBoss().getEntity();
LinkedList<Player> selections = new LinkedList<>();
List<Player> targeted = new ArrayList<>();
Map<Player, Double> near = UtilPlayer.getInRadius(necromancer.getLocation(), MAX_RANGE);
for (Player nearby : near.keySet())
{
if (nearby.getGameMode() == GameMode.CREATIVE || nearby.getGameMode() == GameMode.SPECTATOR)
{
continue;
}
if (selections.isEmpty())
{
selections.addFirst(nearby);
}
else
{
selections.add(getPosition(nearby, selections), nearby);
}
}
for (int i = 0; i < MAX_TARGETS; i++)
{
if (i < selections.size())
{
targeted.add(selections.get(i));
}
}
return targeted;
}
private void shootAt(Player target)
{
double curRange = 0;
boolean canHit = false;
while (curRange <= MAX_RANGE)
{
Location newTarget = getEntity().getEyeLocation().add(UtilAlg.getTrajectory(getEntity(), target).multiply(curRange));
if (!UtilBlock.airFoliage(newTarget.getBlock()))
{
canHit = false;
break;
}
if (UtilMath.offset(newTarget, target.getLocation()) <= 0.9)
{
canHit = true;
break;
}
curRange += 0.2;
UtilParticle.PlayParticle(ParticleType.WITCH_MAGIC, newTarget, 0, 0, 0, 0, 1,
ViewDist.MAX, UtilServer.getPlayers());
canHit = true;
}
if (canHit)
{
getBoss().getEvent().getDamageManager().NewDamageEvent(target, getEntity(), null, DamageCause.CUSTOM, 12 * getBoss().getDifficulty(), true, true, false, getEntity().getName(), "Mystical Energy");
}
}
@Override
public int getCooldown()
{
return 15;
}
@Override
public boolean canMove()
{
return true;
}
@Override
public boolean inProgress()
{
return false;
}
@Override
public boolean hasFinished()
{
return _shot;
}
@Override
public void setFinished()
{
_shot = true;
}
@Override
public void tick()
{
if (_shot)
return;
_shot = true;
for (Player target : getTargets())
{
shootAt(target);
}
}
}

View File

@ -0,0 +1,231 @@
package mineplex.game.clans.clans.worldevent.boss.skeletonking.abilities;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.entity.Skeleton;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.util.Vector;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
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.UtilPlayer;
import mineplex.game.clans.clans.worldevent.api.BossAbility;
import mineplex.game.clans.clans.worldevent.api.EventCreatureDeathEvent;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.SkeletonBoss;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.SkeletonCreature;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.minion.MinionType;
import mineplex.game.clans.clans.worldevent.boss.skeletonking.minion.WraithCreature;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
public class SkeletonWraithSummon extends BossAbility<SkeletonCreature, Skeleton>
{
private static final int WRAITH_AMOUNT = 4;
private static final double DISTANCE_FROM_KING = 4;
private static final double FINAL_SKELETON_HEALTH = 100;
private static final double FINAL_WRAITH_MULTIPLIER = 2;
private final int WRAITH_AMOUNT_THIS_USE;
private Map<WraithCreature, String> _wraiths = new HashMap<>();
private Location[] _spawns;
private int _ticks;
public SkeletonWraithSummon(SkeletonCreature creature)
{
super(creature);
_spawns = new Location[]
{
getEntity().getLocation().add(DISTANCE_FROM_KING, 0, DISTANCE_FROM_KING),
getEntity().getLocation().add(DISTANCE_FROM_KING * -1, 0, DISTANCE_FROM_KING),
getEntity().getLocation().add(DISTANCE_FROM_KING, 0, DISTANCE_FROM_KING * -1),
getEntity().getLocation().add(DISTANCE_FROM_KING * -1, 0, DISTANCE_FROM_KING * -1),
getEntity().getLocation().add(DISTANCE_FROM_KING / 2, 0, DISTANCE_FROM_KING / 2),
getEntity().getLocation().add((DISTANCE_FROM_KING / 2) * -1, 0, DISTANCE_FROM_KING / 2),
getEntity().getLocation().add(DISTANCE_FROM_KING / 2, 0, (DISTANCE_FROM_KING / 2) * -1),
getEntity().getLocation().add((DISTANCE_FROM_KING / 2) * -1, 0, (DISTANCE_FROM_KING / 2) * -1)
};
if (creature.getHealth() <= FINAL_SKELETON_HEALTH)
{
WRAITH_AMOUNT_THIS_USE = (int)(WRAITH_AMOUNT * FINAL_WRAITH_MULTIPLIER);
}
else
{
WRAITH_AMOUNT_THIS_USE = WRAITH_AMOUNT;
}
}
private String getNumberString(Integer number)
{
String num = number.toString();
char last = num.toCharArray()[num.length() - 1];
String formatted = number.toString();
String ending = "";
if (last == '1' && !num.equals("1" + last))
{
ending = "st";
}
if (last == '2' && !num.equals("1" + last))
{
ending = "nd";
}
if (last == '3' && !num.equals("1" + last))
{
ending = "rd";
}
if (ending.equals(""))
{
ending = "th";
}
return formatted + ending;
}
private void spawnWraith(Location loc, int number)
{
WraithCreature wraith = (WraithCreature)((SkeletonBoss)getBoss().getEvent()).spawnMinion(MinionType.WRAITH, loc);
_wraiths.put(wraith, getNumberString(number));
}
@Override
public int getCooldown()
{
return 0;
}
@Override
public boolean canMove()
{
return false;
}
@Override
public boolean inProgress()
{
return true;
}
@Override
public boolean hasFinished()
{
return _wraiths.isEmpty() && _ticks > 40;
}
@Override
public void setFinished()
{
for (WraithCreature wraith : _wraiths.keySet())
{
wraith.remove();
}
_wraiths.clear();
_ticks = 41;
}
@Override
public void tick()
{
if (_ticks == 0)
{
if (WRAITH_AMOUNT > 0)
{
for (int i = 0; i < WRAITH_AMOUNT_THIS_USE; i++)
{
int spawnIndex = i;
if (spawnIndex >= _spawns.length)
{
spawnIndex = spawnIndex % _spawns.length;
}
spawnWraith(_spawns[spawnIndex], i + 1);
}
for (Player player : UtilPlayer.getInRadius(getEntity().getLocation(), 80).keySet())
{
if (player.isDead() || !player.isValid() || !player.isOnline())
{
continue;
}
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR)
{
continue;
}
player.sendMessage(F.main(getBoss().getEvent().getName(), "You must slay all " + WRAITH_AMOUNT_THIS_USE + " wraiths before continuing to fight the " + getBoss().getEvent().getName() + "!"));
}
}
}
_ticks++;
if (!hasFinished())
{
int ticks = 10;
int hticks = 40;
boolean up = getEntity().getTicksLived() % (hticks * 2) < hticks;
int tick = getEntity().getTicksLived() % ticks;
double htick = getEntity().getTicksLived() % hticks;
int splits = 4;
Location loc = getEntity().getLocation().add(0, 2, 0);
for (double d = tick * (Math.PI * 2 / splits) / ticks; d < Math.PI * 2; d += Math.PI * 2 / splits)
{
Vector v = new Vector(Math.sin(d), 0, Math.cos(d));
v.normalize().multiply(Math.max(0.2, Math.sin((htick / hticks) * Math.PI) * 1.0));
v.setY((htick / hticks) * -2);
if (up) v.setY(-2 + 2 * (htick / hticks));
Location lloc = loc.clone().add(v);
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, lloc, null, 0f, 2, ViewDist.MAX);
}
}
}
@EventHandler
public void onWraithDie(EventCreatureDeathEvent event)
{
if (event.getCreature() instanceof WraithCreature)
{
String number = _wraiths.remove(event.getCreature());
if (number != null)
{
double remainPercent = new BigDecimal(_wraiths.size()).divide(new BigDecimal(WRAITH_AMOUNT_THIS_USE)).doubleValue();
ChatColor remainColor = ChatColor.GREEN;
if (remainPercent < .66)
{
remainColor = ChatColor.YELLOW;
}
if (remainPercent < .33)
{
remainColor = ChatColor.RED;
}
Bukkit.broadcastMessage(F.main(getBoss().getEvent().getName(), "A wraith has been slain!" + " (" + remainColor + _wraiths.size() + "/" + WRAITH_AMOUNT_THIS_USE + C.cGray + ") wraiths remaining!"));
System.out.println(F.main(getBoss().getEvent().getName(), "The " + number + " wraith has been slain!"));
}
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onDamage(CustomDamageEvent event)
{
if (event.GetDamageeEntity().equals(getBoss().getEntity()))
{
if (!hasFinished())
{
event.SetCancelled("Wraiths Alive");
}
}
}
}

View File

@ -0,0 +1,34 @@
package mineplex.game.clans.clans.worldevent.boss.skeletonking.minion;
import org.bukkit.Location;
import mineplex.game.clans.clans.worldevent.api.EventCreature;
import mineplex.game.clans.clans.worldevent.api.WorldEvent;
public enum MinionType
{
WARRIOR(UndeadWarriorCreature.class),
ARCHER(UndeadArcherCreature.class),
WRAITH(WraithCreature.class);
private Class<? extends EventCreature<?>> _code;
private MinionType(Class<? extends EventCreature<?>> code)
{
_code = code;
}
public EventCreature<?> getNewInstance(WorldEvent event, Location spawn)
{
try
{
return _code.getConstructor(WorldEvent.class, Location.class).newInstance(event, spawn);
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
}

View File

@ -0,0 +1,234 @@
package mineplex.game.clans.clans.worldevent.boss.skeletonking.minion;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.Skeleton;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.EntityShootBowEvent;
import org.bukkit.event.entity.EntityTargetLivingEntityEvent;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilServer;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.clans.clans.worldevent.api.EventCreature;
import mineplex.game.clans.clans.worldevent.api.WorldEvent;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
public class UndeadArcherCreature extends EventCreature<Skeleton>
{
private static final int BARBED_LEVEL = 1;
private static final int LIFETIME = -1;
public UndeadArcherCreature(WorldEvent event, Location spawnLocation)
{
super(event, spawnLocation, "Undead Archer", true, 25, 30, true, Skeleton.class);
spawnEntity();
}
@Override
protected void spawnCustom()
{
Skeleton entity = getEntity();
EntityEquipment eq = entity.getEquipment();
eq.setItemInHand(new ItemStack(Material.BOW));
eq.setHelmet(new ItemStack(Material.CHAINMAIL_HELMET));
eq.setChestplate(new ItemStack(Material.CHAINMAIL_CHESTPLATE));
eq.setLeggings(new ItemStack(Material.CHAINMAIL_LEGGINGS));
eq.setBoots(new ItemStack(Material.CHAINMAIL_BOOTS));
eq.setItemInHandDropChance(0.f);
eq.setHelmetDropChance(0.f);
eq.setChestplateDropChance(0.f);
eq.setLeggingsDropChance(0.f);
eq.setBootsDropChance(0.f);
entity.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 999999, 0));
}
@Override
public void dieCustom()
{
if (LIFETIME >= 0 && getEntity().getTicksLived() >= (20 * LIFETIME))
{
return;
}
if (Math.random() > 0.97)
{
getEntity().getWorld().dropItem(getEntity().getLocation(), new org.bukkit.inventory.ItemStack(Material.CHAINMAIL_HELMET));
}
if (Math.random() > 0.97)
{
getEntity().getWorld().dropItem(getEntity().getLocation(), new org.bukkit.inventory.ItemStack(Material.CHAINMAIL_CHESTPLATE));
}
if (Math.random() > 0.97)
{
getEntity().getWorld().dropItem(getEntity().getLocation(), new org.bukkit.inventory.ItemStack(Material.CHAINMAIL_LEGGINGS));
}
if (Math.random() > 0.97)
{
getEntity().getWorld().dropItem(getEntity().getLocation(), new org.bukkit.inventory.ItemStack(Material.CHAINMAIL_BOOTS));
}
if (Math.random() > 0.90)
{
getEntity().getWorld().dropItem(getEntity().getLocation(), new org.bukkit.inventory.ItemStack(Material.BOW));
}
getEntity().getWorld().dropItem(getEntity().getLocation(), new org.bukkit.inventory.ItemStack(Material.ARROW, UtilMath.r(12) + 1));
}
@EventHandler(priority = EventPriority.MONITOR)
public void bowShoot(EntityShootBowEvent event)
{
if (BARBED_LEVEL == 0)
{
return;
}
if (!(event.getProjectile() instanceof Arrow))
{
return;
}
if (event.getEntity().getEntityId() != getEntity().getEntityId())
{
return;
}
event.getProjectile().setMetadata("BARBED_ARROW", new FixedMetadataValue(UtilServer.getPlugin(), 2));
}
@EventHandler(priority = EventPriority.HIGH)
public void damage(CustomDamageEvent event)
{
if (event.IsCancelled())
{
return;
}
if (event.GetCause() != DamageCause.PROJECTILE)
{
return;
}
Projectile projectile = event.GetProjectile();
LivingEntity damagee = event.GetDamageeEntity();
LivingEntity damager = event.GetDamagerEntity(true);
if (projectile == null)
{
return;
}
if (!projectile.hasMetadata("BARBED_ARROW"))
{
return;
}
if (damagee == null)
{
return;
}
if (damager == null)
{
return;
}
if (!getEntity().equals(damager))
{
return;
}
// Level
if (BARBED_LEVEL == 0)
{
return;
}
Player damageePlayer = event.GetDamageePlayer();
if (damageePlayer != null)
{
damageePlayer.setSprinting(false);
}
// Damage
event.AddMod(damager.getName(), "Barbed Arrows", projectile.getMetadata("BARBED_ARROW").get(0).asDouble(), false);
// Condition
getEvent().getCondition().Factory().Slow("Barbed Arrows", damagee, damager, (projectile.getVelocity().length() / 3) * (2 + BARBED_LEVEL), 0, false, true, true, true);
}
@EventHandler
public void clean(UpdateEvent event)
{
if (event.getType() != UpdateType.FAST)
{
return;
}
if (LIFETIME >= 0 && getEntity().getTicksLived() >= (20 * LIFETIME))
{
remove();
return;
}
}
@EventHandler
public void onTarget(EntityTargetLivingEntityEvent event)
{
if (getEntity().equals(event.getEntity()))
{
if (!(event.getTarget() instanceof Player))
{
event.setCancelled(true);
}
}
}
@EventHandler(priority = EventPriority.HIGH)
public void protect(CustomDamageEvent event)
{
if (event.IsCancelled())
{
return;
}
LivingEntity damagee = event.GetDamageeEntity();
LivingEntity damager = event.GetDamagerEntity(event.GetCause() == DamageCause.PROJECTILE);
if (damagee == null)
{
return;
}
if (damager == null)
{
return;
}
if (getEntity().equals(damagee))
{
if (!(damager instanceof Player))
{
event.SetCancelled("Allied Attacker");
}
}
}
}

View File

@ -0,0 +1,186 @@
package mineplex.game.clans.clans.worldevent.boss.skeletonking.minion;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Zombie;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.EntityTargetLivingEntityEvent;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilMath;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.clans.clans.worldevent.api.EventCreature;
import mineplex.game.clans.clans.worldevent.api.WorldEvent;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
public class UndeadWarriorCreature extends EventCreature<Zombie>
{
private static final int LIFETIME = -1;
public UndeadWarriorCreature(WorldEvent event, Location spawnLocation)
{
super(event, spawnLocation, "Undead Warrior", true, 30, 30, true, Zombie.class);
spawnEntity();
}
@Override
protected void spawnCustom()
{
Zombie entity = getEntity();
EntityEquipment eq = entity.getEquipment();
eq.setHelmet(new ItemStack(Material.IRON_HELMET));
eq.setChestplate(new ItemStack(Material.IRON_CHESTPLATE));
eq.setLeggings(new ItemStack(Material.IRON_LEGGINGS));
eq.setBoots(new ItemStack(Material.IRON_BOOTS));
eq.setItemInHand(new ItemStack(Material.STONE_SWORD));
eq.setHelmetDropChance(0.f);
eq.setChestplateDropChance(0.f);
eq.setLeggingsDropChance(0.f);
eq.setBootsDropChance(0.f);
eq.setItemInHandDropChance(0.f);
entity.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 999999, 0));
}
@Override
public void dieCustom()
{
if (LIFETIME >= 0 && getEntity().getTicksLived() >= (20 * LIFETIME))
{
return;
}
if (Math.random() > 0.97)
getEntity().getWorld().dropItem(getEntity().getLocation(), new ItemStack(Material.IRON_HELMET));
if (Math.random() > 0.97)
getEntity().getWorld().dropItem(getEntity().getLocation(), new ItemStack(Material.IRON_CHESTPLATE));
if (Math.random() > 0.97)
getEntity().getWorld().dropItem(getEntity().getLocation(), new ItemStack(Material.IRON_LEGGINGS));
if (Math.random() > 0.97)
getEntity().getWorld().dropItem(getEntity().getLocation(), new ItemStack(Material.IRON_BOOTS));
}
@EventHandler
public void leap(UpdateEvent event)
{
if (getEntity() == null)
return;
if (event.getType() != UpdateType.FAST)
return;
if (LIFETIME >= 0 && getEntity().getTicksLived() >= (20 * LIFETIME))
{
remove();
return;
}
if (Math.random() < 0.9)
return;
Zombie zombie = getEntity();
if (zombie.getTarget() == null)
return;
double dist = UtilMath.offset(zombie.getTarget(), zombie);
if (dist <= 3 || dist > 16)
return;
double power = 0.8 + (1.2 * ((dist-3)/13d));
//Leap
UtilAction.velocity(zombie, UtilAlg.getTrajectory(zombie, zombie.getTarget()),
power, false, 0, 0.2, 1, true);
//Effect
zombie.getWorld().playSound(zombie.getLocation(), Sound.ZOMBIE_HURT, 1f, 2f);
}
@EventHandler
public void onTarget(EntityTargetLivingEntityEvent event)
{
if (getEntity().equals(event.getEntity()))
{
if (!(event.getTarget() instanceof Player))
{
event.setCancelled(true);
}
}
}
@EventHandler(priority = EventPriority.HIGH)
public void attack(CustomDamageEvent event)
{
if (event.IsCancelled())
{
return;
}
LivingEntity damagee = event.GetDamageeEntity();
LivingEntity damager = event.GetDamagerEntity(false);
if (damagee == null)
{
return;
}
if (damager == null)
{
return;
}
if (getEntity().equals(damager))
{
if (damagee instanceof Player)
{
((Player)damagee).setFoodLevel(((Player)damagee).getFoodLevel() - 1);
}
}
}
@EventHandler(priority = EventPriority.HIGH)
public void protect(CustomDamageEvent event)
{
if (event.IsCancelled())
{
return;
}
LivingEntity damagee = event.GetDamageeEntity();
LivingEntity damager = event.GetDamagerEntity(event.GetCause() == DamageCause.PROJECTILE);
if (damagee == null)
{
return;
}
if (damager == null)
{
return;
}
if (getEntity().equals(damagee))
{
if (!(damager instanceof Player))
{
event.SetCancelled("Allied Attacker");
}
}
}
}

View File

@ -0,0 +1,190 @@
package mineplex.game.clans.clans.worldevent.boss.skeletonking.minion;
import org.bukkit.Color;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Zombie;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.EntityTargetLivingEntityEvent;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
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.itemstack.ItemBuilder;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.game.clans.clans.worldevent.api.EventCreature;
import mineplex.game.clans.clans.worldevent.api.WorldEvent;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
public class WraithCreature extends EventCreature<Zombie>
{
private static final int LIFETIME = -1;
public WraithCreature(WorldEvent event, Location spawnLocation)
{
super(event, spawnLocation, "Wraith", true, 200, 30, true, Zombie.class);
spawnEntity();
}
@Override
protected void spawnCustom()
{
Zombie entity = getEntity();
EntityEquipment eq = entity.getEquipment();
eq.setHelmet(new ItemStack(Material.SKULL_ITEM, 1, (short)1));
eq.setChestplate(new ItemBuilder(Material.LEATHER_CHESTPLATE).setColor(Color.BLACK).build());
eq.setLeggings(new ItemBuilder(Material.LEATHER_LEGGINGS).setColor(Color.BLACK).build());
eq.setBoots(new ItemBuilder(Material.LEATHER_BOOTS).setColor(Color.BLACK).build());
eq.setItemInHand(new ItemStack(Material.IRON_SWORD));
eq.setHelmetDropChance(0.f);
eq.setChestplateDropChance(0.f);
eq.setLeggingsDropChance(0.f);
eq.setBootsDropChance(0.f);
eq.setItemInHandDropChance(0.f);
entity.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, 999999, 0));
entity.addPotionEffect(new PotionEffect(PotionEffectType.FIRE_RESISTANCE, 999999, 0));
entity.addPotionEffect(new PotionEffect(PotionEffectType.WATER_BREATHING, 999999, 0));
entity.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 999999, 1));
}
@Override
public void dieCustom()
{
if (LIFETIME >= 0 && getEntity().getTicksLived() >= (20 * LIFETIME))
{
return;
}
if (Math.random() > 0.97)
getEntity().getWorld().dropItem(getEntity().getLocation(), new ItemStack(Material.DIAMOND_HELMET));
if (Math.random() > 0.97)
getEntity().getWorld().dropItem(getEntity().getLocation(), new ItemStack(Material.DIAMOND_CHESTPLATE));
if (Math.random() > 0.97)
getEntity().getWorld().dropItem(getEntity().getLocation(), new ItemStack(Material.DIAMOND_LEGGINGS));
if (Math.random() > 0.97)
getEntity().getWorld().dropItem(getEntity().getLocation(), new ItemStack(Material.DIAMOND_BOOTS));
}
@EventHandler(priority = EventPriority.HIGH)
public void damage(CustomDamageEvent event)
{
if (event.IsCancelled())
{
return;
}
LivingEntity damagee = event.GetDamageeEntity();
LivingEntity damager = event.GetDamagerEntity(false);
if (damagee == null)
{
return;
}
if (damager == null)
{
return;
}
if (getEntity().equals(damager))
{
event.AddMult(damager.getName(), "Mystical Darkness", 2, false);
}
}
@EventHandler
public void blink(UpdateEvent event)
{
if (getEntity() == null)
return;
if (event.getType() != UpdateType.FAST)
return;
if (LIFETIME >= 0 && getEntity().getTicksLived() >= (20 * LIFETIME))
{
remove();
return;
}
if (Math.random() < 0.6)
return;
Zombie zombie = getEntity();
if (zombie.getTarget() == null)
return;
double dist = UtilMath.offset(zombie.getTarget(), zombie);
if (dist <= 10 || dist > 25)
return;
Location teleport = zombie.getTarget().getLocation().add(Math.random() + 1, 0, Math.random() + 1);
if (UtilMath.offset(getSpawnLocation(), teleport) > 30)
{
return;
}
UtilParticle.PlayParticleToAll(ParticleType.SMOKE, zombie.getLocation(), 0, 0, 0, 0, 5, ViewDist.MAX);
zombie.getWorld().playSound(zombie.getLocation(), Sound.ENDERMAN_TELEPORT, 1f, 2f);
zombie.teleport(teleport);
UtilParticle.PlayParticleToAll(ParticleType.SMOKE, zombie.getLocation(), 0, 0, 0, 0, 5, ViewDist.MAX);
zombie.getWorld().playSound(zombie.getLocation(), Sound.ENDERMAN_TELEPORT, 1f, 2f);
}
@EventHandler
public void onTarget(EntityTargetLivingEntityEvent event)
{
if (getEntity().equals(event.getEntity()))
{
if (!(event.getTarget() instanceof Player))
{
event.setCancelled(true);
}
}
}
@EventHandler(priority = EventPriority.HIGH)
public void protect(CustomDamageEvent event)
{
if (event.IsCancelled())
{
return;
}
LivingEntity damagee = event.GetDamageeEntity();
LivingEntity damager = event.GetDamagerEntity(event.GetCause() == DamageCause.PROJECTILE);
if (damagee == null)
{
return;
}
if (damager == null)
{
return;
}
if (getEntity().equals(damagee))
{
if (!(damager instanceof Player))
{
event.SetCancelled("Allied Attacker");
}
}
}
}

View File

@ -22,7 +22,7 @@ public class WorldEventCommand extends MultiCommandBase<WorldEventManager>
@Override @Override
protected void Help(Player caller, String[] args) protected void Help(Player caller, String[] args)
{ {
UtilPlayer.message(caller, F.help("/" + _aliasUsed + " start <type>", "Start a World Event where you're standing", Rank.ADMIN)); UtilPlayer.message(caller, F.help("/" + _aliasUsed + " start <type>", "Start a World Event", Rank.ADMIN));
UtilPlayer.message(caller, F.help("/" + _aliasUsed + " clear", "Clears all World Events", Rank.ADMIN)); UtilPlayer.message(caller, F.help("/" + _aliasUsed + " clear", "Clears all World Events", Rank.ADMIN));
UtilPlayer.message(caller, F.help("/" + _aliasUsed + " random", "Starts a random World Event", Rank.ADMIN)); UtilPlayer.message(caller, F.help("/" + _aliasUsed + " random", "Starts a random World Event", Rank.ADMIN));
} }

View File

@ -78,7 +78,7 @@ public class RaidAltar
if (!rejected) if (!rejected)
{ {
count++; count += item.getAmount();
} }
} }
@ -153,10 +153,12 @@ public class RaidAltar
{ {
if (item.getAmount() > (amount - removed)) if (item.getAmount() > (amount - removed))
{ {
removed += (amount - removed);
item.setAmount(item.getAmount() - (amount - removed)); item.setAmount(item.getAmount() - (amount - removed));
} }
else else
{ {
removed += item.getAmount();
player.getInventory().setItem(i, null); player.getInventory().setItem(i, null);
} }
} }

View File

@ -7,19 +7,24 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitTask; import org.bukkit.scheduler.BukkitTask;
import mineplex.core.MiniPlugin; import mineplex.core.MiniPlugin;
import mineplex.core.blockrestore.BlockRestore; import mineplex.core.blockrestore.BlockRestore;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F; import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilServer;
import mineplex.core.disguise.DisguiseManager; import mineplex.core.disguise.DisguiseManager;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.projectile.ProjectileManager; import mineplex.core.projectile.ProjectileManager;
import mineplex.core.updater.UpdateType; import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent; import mineplex.core.updater.event.UpdateEvent;
@ -42,6 +47,13 @@ public class RaidManager extends MiniPlugin
super("Raid Manager", plugin); super("Raid Manager", plugin);
addCommand(new StartRaidCommand(this)); addCommand(new StartRaidCommand(this));
{
List<ItemStack> items = new ArrayList<>();
items.add(new ItemStack(Material.BONE, 20));
items.add(new ItemBuilder(Material.IRON_INGOT).setAmount(2).setTitle(C.cDRedB + "Old Silver Token").setLore(C.cRed + "This token pulses with an evil aura.").setGlow(true).build());
_altars.add(new RaidAltar(new Location(Bukkit.getWorld("world"), 361, 57, -990).getBlock(), RaidType.CHARLES_WITHERTON, items));
}
} }
@Override @Override

View File

@ -269,6 +269,7 @@ public abstract class RaidWorldEvent extends WorldEvent
event.getEntity().getActivePotionEffects().forEach(pe -> event.getEntity().removePotionEffect(pe.getType())); event.getEntity().getActivePotionEffects().forEach(pe -> event.getEntity().removePotionEffect(pe.getType()));
event.getEntity().setExp(0); event.getEntity().setExp(0);
event.getEntity().setLevel(0); event.getEntity().setLevel(0);
event.getEntity().setFireTicks(-1);
event.getEntity().teleport(Spawn.getNorthSpawn()); event.getEntity().teleport(Spawn.getNorthSpawn());
} }
} }

View File

@ -85,7 +85,7 @@ public class WitherRaid extends RaidWorldEvent
{ {
if (_currentChallenge.isComplete()) if (_currentChallenge.isComplete())
{ {
if (_challenges.size() < 6) if (_challenges.size() < 5)
{ {
teleportToAltar(); teleportToAltar();
} }

View File

@ -25,6 +25,12 @@ import mineplex.game.clans.clans.worldevent.raid.RaidChallenge;
import mineplex.game.clans.clans.worldevent.raid.wither.WitherRaid; import mineplex.game.clans.clans.worldevent.raid.wither.WitherRaid;
import mineplex.game.clans.clans.worldevent.raid.wither.creature.mage.UndeadKnight; import mineplex.game.clans.clans.worldevent.raid.wither.creature.mage.UndeadKnight;
import mineplex.game.clans.clans.worldevent.raid.wither.creature.wither.CharlesWitherton; import mineplex.game.clans.clans.worldevent.raid.wither.creature.wither.CharlesWitherton;
import mineplex.game.clans.items.ItemType;
import mineplex.game.clans.items.RareItemFactory;
import mineplex.game.clans.items.attributes.weapon.ConqueringAttribute;
import mineplex.game.clans.items.attributes.weapon.FlamingAttribute;
import mineplex.game.clans.items.attributes.weapon.SharpAttribute;
import mineplex.game.clans.items.legendaries.DemonicScythe;
public class ChallengeSeven extends RaidChallenge<WitherRaid> public class ChallengeSeven extends RaidChallenge<WitherRaid>
{ {
@ -91,6 +97,14 @@ public class ChallengeSeven extends RaidChallenge<WitherRaid>
ClansManager.getInstance().getLootManager().dropRare(drop); ClansManager.getInstance().getLootManager().dropRare(drop);
drop.getWorld().dropItem(drop, new ItemStack(Material.EMERALD, emeralds)); drop.getWorld().dropItem(drop, new ItemStack(Material.EMERALD, emeralds));
} }
RareItemFactory mainFactory = RareItemFactory.begin(ItemType.LEGENDARY).setLegendary(DemonicScythe.class);
if (Math.random() < 0.1)
{
mainFactory.setSuperPrefix(FlamingAttribute.class);
mainFactory.setPrefix(SharpAttribute.class);
mainFactory.setSuffix(ConqueringAttribute.class);
}
_altar.getWorld().dropItem(_altar.clone().add(0, 2, 0), mainFactory.fabricate());
getRaid().getWorldData().getCustomLocs("GATE_FIVE").get(0).getBlock().getRelative(BlockFace.DOWN).setType(Material.OBSIDIAN); getRaid().getWorldData().getCustomLocs("GATE_FIVE").get(0).getBlock().getRelative(BlockFace.DOWN).setType(Material.OBSIDIAN);
getRaid().setForceEnd(System.currentTimeMillis() + UtilTime.convert(2, TimeUnit.MINUTES, TimeUnit.MILLISECONDS)); getRaid().setForceEnd(System.currentTimeMillis() + UtilTime.convert(2, TimeUnit.MINUTES, TimeUnit.MILLISECONDS));
} }

View File

@ -50,8 +50,11 @@ public class HeatingUp extends Cataclysm
_center.getBlock().getRelative(x, -1, z).setType(Material.STONE); _center.getBlock().getRelative(x, -1, z).setType(Material.STONE);
} }
} }
if (Magmus.Abilities.size() > 1 && Magmus.Abilities.get(2) instanceof MagmusMeteor)
{
((MagmusMeteor)Magmus.Abilities.get(2)).Disabled = false; ((MagmusMeteor)Magmus.Abilities.get(2)).Disabled = false;
} }
}
@Override @Override
protected void tick() protected void tick()

View File

@ -36,6 +36,7 @@ public class Magmus extends RaidCreature<MagmaCube>
Abilities.add(new MagmusCataclysm(this)); Abilities.add(new MagmusCataclysm(this));
Abilities.add(new MagmusSmash(this)); Abilities.add(new MagmusSmash(this));
Abilities.add(new MagmusMeteor(this)); Abilities.add(new MagmusMeteor(this));
Abilities.add(new MagmusEat(this));
} }
protected ChallengeSix getChallenge() protected ChallengeSix getChallenge()

View File

@ -28,7 +28,7 @@ public class MagmusCataclysm extends BossPassive<Magmus, MagmaCube>
@Override @Override
public int getCooldown() public int getCooldown()
{ {
return 15; return 23;
} }
@Override @Override
@ -43,6 +43,8 @@ public class MagmusCataclysm extends BossPassive<Magmus, MagmaCube>
if (UtilTime.elapsed(_lastUse, getCooldown() * 1000)) if (UtilTime.elapsed(_lastUse, getCooldown() * 1000))
{ {
_lastUse = System.currentTimeMillis(); _lastUse = System.currentTimeMillis();
if (!_cataclysms.isEmpty())
{
try try
{ {
UtilMath.randomElement(_cataclysms).getConstructor(ChallengeSix.class, Magmus.class).newInstance(getBoss().getChallenge(), getBoss()); UtilMath.randomElement(_cataclysms).getConstructor(ChallengeSix.class, Magmus.class).newInstance(getBoss().getChallenge(), getBoss());
@ -54,3 +56,4 @@ public class MagmusCataclysm extends BossPassive<Magmus, MagmaCube>
} }
} }
} }
}

View File

@ -48,6 +48,7 @@ public class MagmusEat extends BossPassive<Magmus, MagmaCube>
{ {
spit(); spit();
} }
_ticks++;
} }
private void initialEat(Player target) private void initialEat(Player target)
@ -79,7 +80,7 @@ public class MagmusEat extends BossPassive<Magmus, MagmaCube>
} }
if (UtilTime.elapsed(_lastUse, getCooldown() * 1000)) if (UtilTime.elapsed(_lastUse, getCooldown() * 1000))
{ {
Player target = UtilPlayer.getClosest(getLocation(), 3); Player target = UtilPlayer.getClosest(getLocation(), 7);
if (target != null) if (target != null)
{ {
initialEat(target); initialEat(target);

View File

@ -43,7 +43,7 @@ public class MagmusMeteor extends BossPassive<Magmus, MagmaCube>
return; return;
} }
Player target = UtilMath.randomElement(getBoss().getChallenge().getRaid().getPlayers()); Player target = UtilMath.randomElement(getBoss().getChallenge().getRaid().getPlayers());
LargeFireball ball = target.getWorld().spawn(target.getLocation().add(Math.random() * 24 - 12, 32 + Math.random() * 16, Math.random() * 24 - 12), LargeFireball.class); LargeFireball ball = target.getWorld().spawn(target.getLocation().add(2 * Math.random(), 10 + Math.random() * 16, 2 * Math.random()), LargeFireball.class);
EntityLargeFireball eFireball = ((CraftLargeFireball) ball).getHandle(); EntityLargeFireball eFireball = ((CraftLargeFireball) ball).getHandle();
eFireball.dirX = (Math.random()-0.5)*0.02; eFireball.dirX = (Math.random()-0.5)*0.02;
@ -51,8 +51,9 @@ public class MagmusMeteor extends BossPassive<Magmus, MagmaCube>
eFireball.dirZ = (Math.random()-0.5)*0.02; eFireball.dirZ = (Math.random()-0.5)*0.02;
ball.setShooter(getEntity()); ball.setShooter(getEntity());
ball.setYield(2.2f); ball.setYield(0f);
ball.setBounce(false); ball.setBounce(false);
ball.setIsIncendiary(false);
_shot.add(ball); _shot.add(ball);
} }
@ -105,12 +106,12 @@ public class MagmusMeteor extends BossPassive<Magmus, MagmaCube>
if (event.getEntity() instanceof LargeFireball) if (event.getEntity() instanceof LargeFireball)
{ {
LargeFireball ball = (LargeFireball) event.getEntity(); LargeFireball ball = (LargeFireball) event.getEntity();
if (ball.getShooter() instanceof MagmaCube && ((MagmaCube)ball.getShooter()).getEntityId() == getEntity().getEntityId()) if (_shot.contains(ball))
{ {
_shot.remove(ball); _shot.remove(ball);
UtilParticle.PlayParticle(ParticleType.EXPLODE, ball.getLocation(), null, 0, 2, ViewDist.MAX, UtilServer.getPlayers()); UtilParticle.PlayParticle(ParticleType.EXPLODE, ball.getLocation(), null, 0, 2, ViewDist.MAX, UtilServer.getPlayers());
ball.getWorld().playSound(ball.getLocation(), Sound.EXPLODE, 10, 0); ball.getWorld().playSound(ball.getLocation(), Sound.EXPLODE, 10, 0);
Player hit = UtilPlayer.getClosest(ball.getLocation(), 0.5); Player hit = UtilPlayer.getClosest(ball.getLocation(), 3);
if (hit != null) if (hit != null)
{ {
getBoss().getEvent().getDamageManager().NewDamageEvent(hit, getEntity(), ball, DamageCause.PROJECTILE, 4, true, true, false, getEntity().getName(), "Meteor Shower"); getBoss().getEvent().getDamageManager().NewDamageEvent(hit, getEntity(), ball, DamageCause.PROJECTILE, 4, true, true, false, getEntity().getName(), "Meteor Shower");

View File

@ -30,7 +30,7 @@ public class MagmusSmash extends BossPassive<Magmus, MagmaCube>
Map<Player, Double> targets = UtilPlayer.getInRadius(getLocation(), 5.5d + 0.5 * 5); Map<Player, Double> targets = UtilPlayer.getInRadius(getLocation(), 5.5d + 0.5 * 5);
getBoss().TeleportBackASAP = false; getBoss().TeleportBackASAP = false;
getEntity().setVelocity(new Vector(0, 5, 0)); getEntity().setVelocity(new Vector(0, 5, 0));
UtilServer.runSyncLater(() -> getBoss().TeleportBackASAP = false, 3 * 20); UtilServer.runSyncLater(() -> getBoss().TeleportBackASAP = true, 3 * 20);
for (Player player : targets.keySet()) for (Player player : targets.keySet())
{ {
getBoss().getEvent().getDamageManager().NewDamageEvent(player, getEntity(), null, getBoss().getEvent().getDamageManager().NewDamageEvent(player, getEntity(), null,