Ability cleanup.
- All the core abilities have been moved into the project folders such that they no longer require any extraction. As such, all servers should have the abilities already installed and ready to use, regardless of setup-retardation. - An attempt at fixing the "invisible bosses" issue; a call to removeBoss was replaced with getBoss - hopefully this fixes all the issues.
This commit is contained in:
@@ -469,7 +469,7 @@ public class ArenaListener
|
||||
ap.getStats().inc("kills");
|
||||
arena.getScoreboard().addKill(p);
|
||||
}
|
||||
MABoss boss = monsters.removeBoss(event.getEntity());
|
||||
MABoss boss = monsters.getBoss(event.getEntity());
|
||||
if (boss != null) {
|
||||
ItemStack reward = boss.getReward();
|
||||
if (reward != null) {
|
||||
|
||||
@@ -202,8 +202,9 @@ public class MobArena extends JavaPlugin
|
||||
private void loadAbilities() {
|
||||
File dir = new File(this.getDataFolder(), "abilities");
|
||||
if (!dir.exists()) dir.mkdir();
|
||||
|
||||
AbilityManager.loadAbilities(dir, getClass());
|
||||
|
||||
AbilityManager.loadCoreAbilities();
|
||||
AbilityManager.loadAbilities(dir);
|
||||
}
|
||||
|
||||
private void startMetrics() {
|
||||
|
||||
@@ -279,7 +279,7 @@ public class WaveParser
|
||||
if (ablts != null) {
|
||||
String[] parts = ablts.split(",");
|
||||
for (String ability : parts) {
|
||||
Ability a = AbilityManager.fromString(ability.trim());
|
||||
Ability a = AbilityManager.getAbility(ability.trim());
|
||||
if (a == null) {
|
||||
Messenger.warning(WaveError.BOSS_ABILITY.format(ability.trim(), name, arena.configName()));
|
||||
continue;
|
||||
|
||||
@@ -16,6 +16,7 @@ import javax.tools.ToolProvider;
|
||||
|
||||
import com.garbagemule.MobArena.Messenger;
|
||||
import com.garbagemule.MobArena.util.FileUtils;
|
||||
import com.garbagemule.MobArena.waves.ability.core.*;
|
||||
|
||||
public class AbilityManager
|
||||
{
|
||||
@@ -23,22 +24,58 @@ public class AbilityManager
|
||||
private static final String classpath = jarpath + ";" + System.getProperty("java.class.path");
|
||||
|
||||
private static Map<String,Ability> abilities;
|
||||
|
||||
private static Map<String,Class<? extends Ability>> abs;
|
||||
|
||||
/**
|
||||
* Get an Ability by one of its aliases.
|
||||
* @param name an Ability alias
|
||||
* @return an Ability, if one exists with the given alias, false otherwise
|
||||
* Get an instance of an ability by alias
|
||||
* @param alias the alias of an ability
|
||||
* @return a new Ability object, or null
|
||||
*/
|
||||
public static Ability fromString(String name) {
|
||||
return abilities.get(name.toLowerCase().replaceAll("[-_.]", ""));
|
||||
public static Ability getAbility(String alias) {
|
||||
try {
|
||||
Class<? extends Ability> cls = abs.get(alias.toLowerCase().replaceAll("[-_.]", ""));
|
||||
return cls.newInstance();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all the core abilities included in MobArena
|
||||
*/
|
||||
public static void loadCoreAbilities() {
|
||||
if (abs == null) abs = new HashMap<String,Class<? extends Ability>>();
|
||||
|
||||
register(ChainLightning.class);
|
||||
register(DisorientDistant.class);
|
||||
register(DisorientNearby.class);
|
||||
register(DisorientTarget.class);
|
||||
register(FetchDistant.class);
|
||||
register(FetchNearby.class);
|
||||
register(FetchTarget.class);
|
||||
register(FireAura.class);
|
||||
register(Flood.class);
|
||||
register(LightningAura.class);
|
||||
register(LivingBomb.class);
|
||||
register(ObsidianBomb.class);
|
||||
register(PullDistant.class);
|
||||
register(PullNearby.class);
|
||||
register(PullTarget.class);
|
||||
register(RootTarget.class);
|
||||
register(ShootArrow.class);
|
||||
register(ShootFireball.class);
|
||||
register(ShufflePositions.class);
|
||||
register(ThrowDistant.class);
|
||||
register(ThrowNearby.class);
|
||||
register(ThrowTarget.class);
|
||||
register(WarpToPlayer.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the known abilities as well as all custom abilities from
|
||||
* the specified directory.
|
||||
* @param dir a directory of .class (and/or .java) files
|
||||
* Load the custom abilities from the specified directory.
|
||||
* @param classDir a directory of .class (and/or .java) files
|
||||
*/
|
||||
public static void loadAbilities(File classDir, Class<?> cls) {
|
||||
public static void loadAbilities(File classDir) {
|
||||
abilities = new HashMap<String,Ability>();
|
||||
|
||||
// Grab the source directory.
|
||||
@@ -56,32 +93,21 @@ public class AbilityManager
|
||||
}
|
||||
}
|
||||
|
||||
/* If there is only one file in the directory, make sure it isn't the
|
||||
* src/ folder, in which case there will be no .class files to load.
|
||||
* In the case of no .class files, extract the defaults. */
|
||||
String[] files = classDir.list();
|
||||
if (files.length == 0 || (files.length == 1 && files[0].equals("src"))) {
|
||||
Messenger.info("No boss abilities found. Extracting defaults...");
|
||||
extractDefaultAbilities(classDir, cls);
|
||||
}
|
||||
|
||||
// Load all the custom abilities.
|
||||
loadClasses(classDir);
|
||||
}
|
||||
|
||||
private static void extractDefaultAbilities(File classDir, Class<?> cls) {
|
||||
// Grab a list of all the class files.
|
||||
List<String> resources = FileUtils.listFilesOnPath("res/abilities/", ".class");
|
||||
|
||||
// Check that there is stuff to extract.
|
||||
if (resources == null || resources.isEmpty()) {
|
||||
Messenger.severe("Couldn't extract the default boss abilities!");
|
||||
return;
|
||||
|
||||
/**
|
||||
* Register an ability by its class object
|
||||
* @param cls the ability class
|
||||
*/
|
||||
private static void register(Class<? extends Ability> cls) {
|
||||
AbilityInfo info = cls.getAnnotation(AbilityInfo.class);
|
||||
if (info == null) return;
|
||||
|
||||
for (String alias : info.aliases()) {
|
||||
abs.put(alias, cls);
|
||||
}
|
||||
|
||||
// Extract everything.
|
||||
List<File> files = FileUtils.extractResources(classDir, "abilities/", resources, cls);
|
||||
Messenger.info("Extracted abilities: " + fileListToString(files, "$"));
|
||||
}
|
||||
|
||||
private static void compileAbilities(File javaDir, File classDir) {
|
||||
@@ -175,7 +201,7 @@ public class AbilityManager
|
||||
|
||||
/**
|
||||
* (Compiles and) loads all custom abilities in the given directory.
|
||||
* @param dir a directory
|
||||
* @param classDir a directory
|
||||
*/
|
||||
private static void loadClasses(File classDir) {
|
||||
// Grab the class loader
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.garbagemule.MobArena.waves.ability.core;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.waves.MABoss;
|
||||
import com.garbagemule.MobArena.waves.ability.Ability;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityInfo;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityUtils;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@AbilityInfo(
|
||||
name = "Chain Lightning",
|
||||
aliases = {"chainlightning"}
|
||||
)
|
||||
public class ChainLightning implements Ability
|
||||
{
|
||||
/**
|
||||
* How many blocks the chain lightning can spread over.
|
||||
* Must be greater than 0.
|
||||
*/
|
||||
private final int RADIUS = 4;
|
||||
|
||||
/**
|
||||
* How many server ticks between each lightning strike.
|
||||
* Must be greater than 0.
|
||||
*/
|
||||
private final int TICKS = 10;
|
||||
|
||||
@Override
|
||||
public void execute(Arena arena, MABoss boss) {
|
||||
final LivingEntity target = AbilityUtils.getTarget(arena, boss.getEntity(), true);
|
||||
if (target == null || !(target instanceof Player))
|
||||
return;
|
||||
|
||||
strikeLightning(arena, (Player) target, new ArrayList<Player>());
|
||||
}
|
||||
|
||||
private void strikeLightning(final Arena arena, final Player p, final List<Player> done) {
|
||||
arena.scheduleTask(new Runnable() {
|
||||
public void run() {
|
||||
if (!arena.isRunning() || !arena.inArena(p))
|
||||
return;
|
||||
|
||||
// Smite the target
|
||||
arena.getWorld().strikeLightning(p.getLocation());
|
||||
done.add(p);
|
||||
|
||||
// Grab all nearby players
|
||||
List<Player> nearby = AbilityUtils.getNearbyPlayers(arena, p, RADIUS);
|
||||
|
||||
// Remove all that are "done", and return if empty
|
||||
nearby.removeAll(done);
|
||||
if (nearby.isEmpty()) return;
|
||||
|
||||
// Otherwise, smite the next target!
|
||||
strikeLightning(arena, nearby.get(0), done);
|
||||
}
|
||||
}, TICKS);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.garbagemule.MobArena.waves.ability.core;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.waves.MABoss;
|
||||
import com.garbagemule.MobArena.waves.ability.Ability;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityInfo;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@AbilityInfo(
|
||||
name = "Disorient Distant",
|
||||
aliases = {"disorientdistant"}
|
||||
)
|
||||
public class DisorientDistant implements Ability
|
||||
{
|
||||
/**
|
||||
* How far away players must be to be affected by the ability.
|
||||
*/
|
||||
private final int RADIUS = 8;
|
||||
|
||||
@Override
|
||||
public void execute(Arena arena, MABoss boss) {
|
||||
for (Player p : AbilityUtils.getDistantPlayers(arena, boss.getEntity(), RADIUS)) {
|
||||
Location loc = p.getLocation();
|
||||
loc.setYaw(loc.getYaw() + 45 + AbilityUtils.random.nextInt(270));
|
||||
p.teleport(loc);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.garbagemule.MobArena.waves.ability.core;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.waves.MABoss;
|
||||
import com.garbagemule.MobArena.waves.ability.Ability;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityInfo;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@AbilityInfo(
|
||||
name = "Disorient Nearby",
|
||||
aliases = {"disorientnearby"}
|
||||
)
|
||||
public class DisorientNearby implements Ability
|
||||
{
|
||||
/**
|
||||
* How close players must be to be affected by the ability.
|
||||
*/
|
||||
private final int RADIUS = 5;
|
||||
|
||||
@Override
|
||||
public void execute(Arena arena, MABoss boss) {
|
||||
LivingEntity target = AbilityUtils.getTarget(arena, boss.getEntity(), false);
|
||||
if (target == null) return;
|
||||
|
||||
for (Player p : AbilityUtils.getNearbyPlayers(arena, boss.getEntity(), RADIUS)) {
|
||||
Location loc = p.getLocation();
|
||||
loc.setYaw(loc.getYaw() + 45 + AbilityUtils.random.nextInt(270));
|
||||
p.teleport(loc);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.garbagemule.MobArena.waves.ability.core;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.waves.MABoss;
|
||||
import com.garbagemule.MobArena.waves.ability.Ability;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityInfo;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
||||
@AbilityInfo(
|
||||
name = "Disorient Target",
|
||||
aliases = {"disorienttarget"}
|
||||
)
|
||||
public class DisorientTarget implements Ability
|
||||
{
|
||||
/**
|
||||
* If the boss has no target, should a random player be selected?
|
||||
*/
|
||||
private final boolean RANDOM = false;
|
||||
|
||||
@Override
|
||||
public void execute(Arena arena, MABoss boss) {
|
||||
LivingEntity target = AbilityUtils.getTarget(arena, boss.getEntity(), RANDOM);
|
||||
if (target == null) return;
|
||||
|
||||
Location loc = target.getLocation();
|
||||
loc.setYaw(loc.getYaw() + 45 + AbilityUtils.random.nextInt(270));
|
||||
target.teleport(loc);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.garbagemule.MobArena.waves.ability.core;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.waves.MABoss;
|
||||
import com.garbagemule.MobArena.waves.ability.Ability;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityInfo;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@AbilityInfo(
|
||||
name = "Fetch Distant",
|
||||
aliases = {"fetchdistant"}
|
||||
)
|
||||
public class FetchDistant implements Ability
|
||||
{
|
||||
/**
|
||||
* How far away players must be to be affected by the ability.
|
||||
*/
|
||||
private final int RADIUS = 8;
|
||||
|
||||
@Override
|
||||
public void execute(Arena arena, MABoss boss) {
|
||||
Location bLoc = boss.getEntity().getLocation();
|
||||
|
||||
for (Player p : AbilityUtils.getDistantPlayers(arena, boss.getEntity(), RADIUS)) {
|
||||
p.teleport(bLoc);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.garbagemule.MobArena.waves.ability.core;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.waves.MABoss;
|
||||
import com.garbagemule.MobArena.waves.ability.Ability;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityInfo;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@AbilityInfo(
|
||||
name = "Fetch Nearby",
|
||||
aliases = {"fetchnearby"}
|
||||
)
|
||||
public class FetchNearby implements Ability
|
||||
{
|
||||
/**
|
||||
* How close players must be to be affected by the ability.
|
||||
*/
|
||||
private final int RADIUS = 5;
|
||||
|
||||
@Override
|
||||
public void execute(Arena arena, MABoss boss) {
|
||||
Location bLoc = boss.getEntity().getLocation();
|
||||
|
||||
for (Player p : AbilityUtils.getNearbyPlayers(arena, boss.getEntity(), RADIUS)) {
|
||||
p.teleport(bLoc);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.garbagemule.MobArena.waves.ability.core;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.waves.MABoss;
|
||||
import com.garbagemule.MobArena.waves.ability.Ability;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityInfo;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityUtils;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
||||
@AbilityInfo(
|
||||
name = "Fetch Target",
|
||||
aliases = {"fetchtarget"}
|
||||
)
|
||||
public class FetchTarget implements Ability
|
||||
{
|
||||
/**
|
||||
* If the boss has no target, should a random player be selected?
|
||||
*/
|
||||
private final boolean RANDOM = true;
|
||||
|
||||
@Override
|
||||
public void execute(Arena arena, MABoss boss) {
|
||||
LivingEntity target = AbilityUtils.getTarget(arena, boss.getEntity(), RANDOM);
|
||||
if (target == null) return;
|
||||
|
||||
target.teleport(boss.getEntity());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.garbagemule.MobArena.waves.ability.core;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.waves.MABoss;
|
||||
import com.garbagemule.MobArena.waves.ability.Ability;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityInfo;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@AbilityInfo(
|
||||
name = "Fire Aura",
|
||||
aliases = {"fireaura","auraoffire"}
|
||||
)
|
||||
public class FireAura implements Ability
|
||||
{
|
||||
/**
|
||||
* How close players must be to be affected by the ability.
|
||||
*/
|
||||
private final int RADIUS = 5;
|
||||
|
||||
/**
|
||||
* How many ticks the players should be on fire for.
|
||||
*/
|
||||
private final int TICKS = 20;
|
||||
|
||||
@Override
|
||||
public void execute(Arena arena, MABoss boss) {
|
||||
for (Player p : AbilityUtils.getNearbyPlayers(arena, boss.getEntity(), RADIUS))
|
||||
p.setFireTicks(TICKS);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.garbagemule.MobArena.waves.ability.core;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.waves.MABoss;
|
||||
import com.garbagemule.MobArena.waves.ability.Ability;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityInfo;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityUtils;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@AbilityInfo(
|
||||
name = "Flood",
|
||||
aliases = {"flood"}
|
||||
)
|
||||
public class Flood implements Ability
|
||||
{
|
||||
@Override
|
||||
public void execute(Arena arena, MABoss boss) {
|
||||
Player p = AbilityUtils.getRandomPlayer(arena);
|
||||
Block block = p.getLocation().getBlock();
|
||||
|
||||
if (block.getTypeId() == 0) {
|
||||
block.setTypeId(8);
|
||||
arena.addBlock(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.garbagemule.MobArena.waves.ability.core;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.waves.MABoss;
|
||||
import com.garbagemule.MobArena.waves.ability.Ability;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityInfo;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityUtils;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@AbilityInfo(
|
||||
name = "Lightning Aura",
|
||||
aliases = {"lightningaura","auraoflightning"}
|
||||
)
|
||||
public class LightningAura implements Ability
|
||||
{
|
||||
/**
|
||||
* How close players must be to be affected by the ability.
|
||||
*/
|
||||
private final int RADIUS = 5;
|
||||
|
||||
@Override
|
||||
public void execute(Arena arena, MABoss boss) {
|
||||
World world = arena.getWorld();
|
||||
for (Player p : AbilityUtils.getNearbyPlayers(arena, boss.getEntity(), RADIUS)) {
|
||||
world.strikeLightning(p.getLocation());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package com.garbagemule.MobArena.waves.ability.core;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.waves.MABoss;
|
||||
import com.garbagemule.MobArena.waves.ability.Ability;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityInfo;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityUtils;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@AbilityInfo(
|
||||
name = "Living Bomb",
|
||||
aliases = {"livingbomb"}
|
||||
)
|
||||
public class LivingBomb implements Ability
|
||||
{
|
||||
/**
|
||||
* How many ticks before the bomb goes off.
|
||||
*/
|
||||
private final int FUSE = 60;
|
||||
|
||||
/**
|
||||
* How close players must be to be affected by the bomb.
|
||||
*/
|
||||
private final int RADIUS = 3;
|
||||
|
||||
/**
|
||||
* How many ticks players affected by the bomb should burn.
|
||||
*/
|
||||
private final int AFTERBURN = 40;
|
||||
|
||||
@Override
|
||||
public void execute(final Arena arena, MABoss boss) {
|
||||
// Grab the target, or a random player.
|
||||
LivingEntity target = AbilityUtils.getTarget(arena, boss.getEntity(), true);
|
||||
|
||||
// We only want players.
|
||||
if (target == null || !(target instanceof Player))
|
||||
return;
|
||||
|
||||
final Player p = (Player) target;
|
||||
p.setFireTicks(FUSE + 5);
|
||||
|
||||
// Create an explosion after 4 seconds
|
||||
arena.scheduleTask(new Runnable() {
|
||||
public void run() {
|
||||
// If the player died, or if they put out the fire.
|
||||
if (!arena.isRunning() || !arena.inArena(p) || p.getFireTicks() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Explode!
|
||||
arena.getWorld().createExplosion(p.getLocation(), 1F);
|
||||
|
||||
// And set every nearby player on fire!
|
||||
for (Player nearby : AbilityUtils.getNearbyPlayers(arena, p, RADIUS)) {
|
||||
nearby.setFireTicks(AFTERBURN);
|
||||
}
|
||||
}
|
||||
}, FUSE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.garbagemule.MobArena.waves.ability.core;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.waves.MABoss;
|
||||
import com.garbagemule.MobArena.waves.ability.Ability;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityInfo;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
||||
@AbilityInfo(
|
||||
name = "Obsidian Bomb",
|
||||
aliases = {"obsidianbomb"}
|
||||
)
|
||||
public class ObsidianBomb implements Ability
|
||||
{
|
||||
/**
|
||||
* How many ticks before the bomb goes off.
|
||||
*/
|
||||
private final int FUSE = 80;
|
||||
|
||||
@Override
|
||||
public void execute(final Arena arena, MABoss boss) {
|
||||
// Grab the target, or a random player.
|
||||
LivingEntity target = AbilityUtils.getTarget(arena, boss.getEntity(), true);
|
||||
|
||||
final World world = arena.getWorld();
|
||||
final Location loc = target.getLocation();
|
||||
|
||||
Block b = world.getBlockAt(loc);
|
||||
b.setType(Material.OBSIDIAN);
|
||||
arena.addBlock(b);
|
||||
|
||||
arena.scheduleTask(new Runnable() {
|
||||
public void run() {
|
||||
if (!arena.isRunning())
|
||||
return;
|
||||
|
||||
world.getBlockAt(loc).breakNaturally();
|
||||
world.createExplosion(loc, 3F);
|
||||
}
|
||||
}, FUSE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.garbagemule.MobArena.waves.ability.core;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.waves.MABoss;
|
||||
import com.garbagemule.MobArena.waves.ability.Ability;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityInfo;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
@AbilityInfo(
|
||||
name = "Pull Distant",
|
||||
aliases = {"pulldistant"}
|
||||
)
|
||||
public class PullDistant implements Ability
|
||||
{
|
||||
/**
|
||||
* How far away players must be to be affected by the ability.
|
||||
*/
|
||||
private final int RADIUS = 8;
|
||||
|
||||
@Override
|
||||
public void execute(Arena arena, MABoss boss) {
|
||||
Location bLoc = boss.getEntity().getLocation();
|
||||
|
||||
for (Player p : AbilityUtils.getDistantPlayers(arena, boss.getEntity(), RADIUS)) {
|
||||
Location loc = p.getLocation();
|
||||
Vector v = new Vector(bLoc.getX() - loc.getX(), 0, bLoc.getZ() - loc.getZ());
|
||||
|
||||
double a = Math.abs(bLoc.getX() - loc.getX());
|
||||
double b = Math.abs(bLoc.getZ() - loc.getZ());
|
||||
double c = Math.sqrt((a*a + b*b));
|
||||
|
||||
p.setVelocity(v.normalize().multiply(c*0.3).setY(0.8));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.garbagemule.MobArena.waves.ability.core;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.waves.MABoss;
|
||||
import com.garbagemule.MobArena.waves.ability.Ability;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityInfo;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
@AbilityInfo(
|
||||
name = "Pull Nearby",
|
||||
aliases = {"pullnearby"}
|
||||
)
|
||||
public class PullNearby implements Ability
|
||||
{
|
||||
/**
|
||||
* How close players must be to be affected by the ability.
|
||||
*/
|
||||
private final int RADIUS = 5;
|
||||
|
||||
@Override
|
||||
public void execute(Arena arena, MABoss boss) {
|
||||
Location bLoc = boss.getEntity().getLocation();
|
||||
|
||||
for (Player p : AbilityUtils.getNearbyPlayers(arena, boss.getEntity(), RADIUS)) {
|
||||
Location loc = p.getLocation();
|
||||
Vector v = new Vector(bLoc.getX() - loc.getX(), 0, bLoc.getZ() - loc.getZ());
|
||||
|
||||
double a = Math.abs(bLoc.getX() - loc.getX());
|
||||
double b = Math.abs(bLoc.getZ() - loc.getZ());
|
||||
double c = Math.sqrt((a*a + b*b));
|
||||
|
||||
p.setVelocity(v.normalize().multiply(c*0.3).setY(0.8));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.garbagemule.MobArena.waves.ability.core;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.waves.MABoss;
|
||||
import com.garbagemule.MobArena.waves.ability.Ability;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityInfo;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
@AbilityInfo(
|
||||
name = "Pull Target",
|
||||
aliases = {"pulltarget"}
|
||||
)
|
||||
public class PullTarget implements Ability
|
||||
{
|
||||
/**
|
||||
* If the boss has no target, should a random player be selected?
|
||||
*/
|
||||
private final boolean RANDOM = false;
|
||||
|
||||
@Override
|
||||
public void execute(Arena arena, MABoss boss) {
|
||||
LivingEntity target = AbilityUtils.getTarget(arena, boss.getEntity(), RANDOM);
|
||||
if (target == null) return;
|
||||
|
||||
Location loc = target.getLocation();
|
||||
Location bLoc = boss.getEntity().getLocation();
|
||||
Vector v = new Vector(bLoc.getX() - loc.getX(), 0, bLoc.getZ() - loc.getZ());
|
||||
|
||||
double a = Math.abs(bLoc.getX() - loc.getX());
|
||||
double b = Math.abs(bLoc.getZ() - loc.getZ());
|
||||
double c = Math.sqrt((a*a + b*b));
|
||||
|
||||
target.setVelocity(v.normalize().multiply(c*0.3).setY(0.8));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.garbagemule.MobArena.waves.ability.core;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.waves.MABoss;
|
||||
import com.garbagemule.MobArena.waves.ability.Ability;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityInfo;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* DISCLAIMER: The Ability source code is provided as-is, and the creator(s) of
|
||||
* MobArena WILL NOT be held responsible for any damage that may
|
||||
* result from altering the files.
|
||||
*
|
||||
* WARNING: Unless you know exactly what you are doing, i.e. you have a lot
|
||||
* of experience with Java and Bukkit, you should never change any
|
||||
* other values than those of the variables in CAPITAL LETTERS.
|
||||
*
|
||||
*
|
||||
* Root Target
|
||||
* Freezes the boss' target in place for ~3 seconds (default), by warping the
|
||||
* player to the same spot [ITERATIONS] times, with [TICKS] server ticks
|
||||
* between each iteration.
|
||||
*
|
||||
* @author garbagemule
|
||||
*/
|
||||
@AbilityInfo(
|
||||
name = "Root Target",
|
||||
aliases = {"roottarget", "freezetarget"}
|
||||
)
|
||||
public class RootTarget implements Ability
|
||||
{
|
||||
/**
|
||||
* How many times the player will be warped back to his original position.
|
||||
* Must be greater than 0.
|
||||
*/
|
||||
private final int ITERATIONS = 5;
|
||||
|
||||
/**
|
||||
* How many server ticks between each iteration of
|
||||
* Must be greater than 0.
|
||||
*/
|
||||
private final int TICKS = 5;
|
||||
|
||||
@Override
|
||||
public void execute(Arena arena, MABoss boss) {
|
||||
final LivingEntity target = AbilityUtils.getTarget(arena, boss.getEntity(), true);
|
||||
if (target == null || !(target instanceof Player))
|
||||
return;
|
||||
|
||||
Player p = (Player) target;
|
||||
Location loc = p.getLocation();
|
||||
|
||||
rootTarget(arena, p, loc, ITERATIONS);
|
||||
}
|
||||
|
||||
private void rootTarget(final Arena arena, final Player p, final Location loc, final int counter) {
|
||||
// If the counter is 0, we're done.
|
||||
if (counter <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
arena.scheduleTask(new Runnable() {
|
||||
public void run() {
|
||||
if (!arena.isRunning() || !arena.inArena(p)) {
|
||||
return;
|
||||
}
|
||||
|
||||
p.teleport(loc);
|
||||
rootTarget(arena, p, loc, counter - 1);
|
||||
}
|
||||
}, TICKS);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.garbagemule.MobArena.waves.ability.core;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.waves.MABoss;
|
||||
import com.garbagemule.MobArena.waves.ability.Ability;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityInfo;
|
||||
import org.bukkit.entity.Arrow;
|
||||
|
||||
@AbilityInfo(
|
||||
name = "Shoot Arrow",
|
||||
aliases = {"arrow","arrows"}
|
||||
)
|
||||
public class ShootArrow implements Ability
|
||||
{
|
||||
@Override
|
||||
public void execute(Arena arena, MABoss boss) {
|
||||
boss.getEntity().launchProjectile(Arrow.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.garbagemule.MobArena.waves.ability.core;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.waves.MABoss;
|
||||
import com.garbagemule.MobArena.waves.ability.Ability;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityInfo;
|
||||
import org.bukkit.entity.Fireball;
|
||||
|
||||
@AbilityInfo(
|
||||
name = "Shoot Fireball",
|
||||
aliases = {"fireball","fireballs"}
|
||||
)
|
||||
public class ShootFireball implements Ability
|
||||
{
|
||||
@Override
|
||||
public void execute(Arena arena, MABoss boss) {
|
||||
boss.getEntity().launchProjectile(Fireball.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.garbagemule.MobArena.waves.ability.core;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.waves.MABoss;
|
||||
import com.garbagemule.MobArena.waves.ability.Ability;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityInfo;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
@AbilityInfo(
|
||||
name = "Shuffle Positions",
|
||||
aliases = {"shuffle","shufflepositions"}
|
||||
)
|
||||
public class ShufflePositions implements Ability
|
||||
{
|
||||
@Override
|
||||
public void execute(Arena arena, MABoss boss) {
|
||||
// Grab the players and add the boss
|
||||
List<LivingEntity> entities = new ArrayList<LivingEntity>(arena.getPlayersInArena());
|
||||
entities.add(boss.getEntity());
|
||||
|
||||
// Grab the locations
|
||||
List<Location> locations = new LinkedList<Location>();
|
||||
for (LivingEntity e : entities) {
|
||||
locations.add(e.getLocation());
|
||||
}
|
||||
|
||||
// Shuffle the entities list.
|
||||
Collections.shuffle(entities);
|
||||
|
||||
/* The entities are shuffled, but the locations are not, so if
|
||||
* we remove the first element of each list, chances are they
|
||||
* will not match, i.e. shuffle achieved! */
|
||||
while (!entities.isEmpty() && !locations.isEmpty()) {
|
||||
entities.remove(0).teleport(locations.remove(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.garbagemule.MobArena.waves.ability.core;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.waves.MABoss;
|
||||
import com.garbagemule.MobArena.waves.ability.Ability;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityInfo;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
@AbilityInfo(
|
||||
name = "Throw Distant",
|
||||
aliases = {"throwdistant"}
|
||||
)
|
||||
public class ThrowDistant implements Ability
|
||||
{
|
||||
/**
|
||||
* How far away players must be to be affected by the ability.
|
||||
*/
|
||||
private final int RADIUS = 8;
|
||||
|
||||
@Override
|
||||
public void execute(Arena arena, MABoss boss) {
|
||||
Location bLoc = boss.getEntity().getLocation();
|
||||
|
||||
for (Player p : AbilityUtils.getDistantPlayers(arena, boss.getEntity(), RADIUS)) {
|
||||
Location loc = p.getLocation();
|
||||
Vector v = new Vector(loc.getX() - bLoc.getX(), 0, loc.getZ() - bLoc.getZ());
|
||||
p.setVelocity(v.normalize().setY(0.8));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.garbagemule.MobArena.waves.ability.core;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.waves.MABoss;
|
||||
import com.garbagemule.MobArena.waves.ability.Ability;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityInfo;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
@AbilityInfo(
|
||||
name = "Throw Nearby",
|
||||
aliases = {"thrownearby"}
|
||||
)
|
||||
public class ThrowNearby implements Ability
|
||||
{
|
||||
/**
|
||||
* How close players must be to be affected by the ability.
|
||||
*/
|
||||
private final int RADIUS = 5;
|
||||
|
||||
@Override
|
||||
public void execute(Arena arena, MABoss boss) {
|
||||
Location bLoc = boss.getEntity().getLocation();
|
||||
|
||||
for (Player p : AbilityUtils.getNearbyPlayers(arena, boss.getEntity(), RADIUS)) {
|
||||
Location loc = p.getLocation();
|
||||
Vector v = new Vector(loc.getX() - bLoc.getX(), 0, loc.getZ() - bLoc.getZ());
|
||||
p.setVelocity(v.normalize().setY(0.8));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.garbagemule.MobArena.waves.ability.core;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.waves.MABoss;
|
||||
import com.garbagemule.MobArena.waves.ability.Ability;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityInfo;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityUtils;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
@AbilityInfo(
|
||||
name = "Throw Target",
|
||||
aliases = {"throwtarget"}
|
||||
)
|
||||
public class ThrowTarget implements Ability
|
||||
{
|
||||
/**
|
||||
* If the boss has no target, should a random player be selected?
|
||||
*/
|
||||
private final boolean RANDOM = false;
|
||||
|
||||
@Override
|
||||
public void execute(Arena arena, MABoss boss) {
|
||||
LivingEntity target = AbilityUtils.getTarget(arena, boss.getEntity(), RANDOM);
|
||||
if (target == null) return;
|
||||
|
||||
Location bLoc = boss.getEntity().getLocation();
|
||||
Location loc = target.getLocation();
|
||||
Vector v = new Vector(loc.getX() - bLoc.getX(), 0, loc.getZ() - bLoc.getZ());
|
||||
|
||||
target.setVelocity(v.normalize().setY(0.8));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.garbagemule.MobArena.waves.ability.core;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.waves.MABoss;
|
||||
import com.garbagemule.MobArena.waves.ability.Ability;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityInfo;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@AbilityInfo(
|
||||
name = "Warp",
|
||||
aliases = {"warp","warptoplayer"}
|
||||
)
|
||||
public class WarpToPlayer implements Ability
|
||||
{
|
||||
@Override
|
||||
public void execute(Arena arena, MABoss boss) {
|
||||
Player p = AbilityUtils.getRandomPlayer(arena);
|
||||
boss.getEntity().teleport(p);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user