Final season 3 world event tweaks (adds skeleton king)
This commit is contained in:
parent
5829b720a8
commit
1cdf9d2bba
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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,7 +146,10 @@ public class GolemCreature extends EventCreature<IronGolem>
|
|||||||
_lastAbility = 20;
|
_lastAbility = 20;
|
||||||
|
|
||||||
HandlerList.unregisterAll(ability);
|
HandlerList.unregisterAll(ability);
|
||||||
System.out.print("Unregistered golem ability " + ability.getClass().getSimpleName());
|
if (DEBUG_MODE)
|
||||||
|
{
|
||||||
|
System.out.print("Unregistered golem ability " + ability.getClass().getSimpleName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (!ability.inProgress())
|
else if (!ability.inProgress())
|
||||||
{
|
{
|
||||||
|
@ -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() {}
|
||||||
|
}
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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));
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,10 @@ public class HeatingUp extends Cataclysm
|
|||||||
_center.getBlock().getRelative(x, -1, z).setType(Material.STONE);
|
_center.getBlock().getRelative(x, -1, z).setType(Material.STONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
((MagmusMeteor)Magmus.Abilities.get(2)).Disabled = false;
|
if (Magmus.Abilities.size() > 1 && Magmus.Abilities.get(2) instanceof MagmusMeteor)
|
||||||
|
{
|
||||||
|
((MagmusMeteor)Magmus.Abilities.get(2)).Disabled = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -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()
|
||||||
|
@ -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,13 +43,16 @@ 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();
|
||||||
try
|
if (!_cataclysms.isEmpty())
|
||||||
{
|
{
|
||||||
UtilMath.randomElement(_cataclysms).getConstructor(ChallengeSix.class, Magmus.class).newInstance(getBoss().getChallenge(), getBoss());
|
try
|
||||||
}
|
{
|
||||||
catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e)
|
UtilMath.randomElement(_cataclysms).getConstructor(ChallengeSix.class, Magmus.class).newInstance(getBoss().getChallenge(), getBoss());
|
||||||
{
|
}
|
||||||
e.printStackTrace();
|
catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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");
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user