mirror of
https://github.com/garbagemule/MobArena.git
synced 2024-11-22 18:46:45 +01:00
Revamped valid spawnpoint algorithm.
This commit is contained in:
parent
32f722d733
commit
4ffee1630b
BIN
MobArena.jar
BIN
MobArena.jar
Binary file not shown.
116
src/com/garbagemule/ArenaPlugin/Arena.java
Normal file
116
src/com/garbagemule/ArenaPlugin/Arena.java
Normal file
@ -0,0 +1,116 @@
|
||||
package com.garbagemule.ArenaPlugin;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public interface Arena
|
||||
{
|
||||
/**
|
||||
* Start the arena session.
|
||||
* This method should warp all players to their respective warp points, start all
|
||||
* needed timers, clear/populate all sets and lists, and flag all booleans.
|
||||
*/
|
||||
public void startArena();
|
||||
|
||||
/**
|
||||
* Stop the arena session.
|
||||
* Distribute rewards, clean up arena floor and reset everything to how it was before
|
||||
* the arena session was started.
|
||||
*/
|
||||
public void endArena();
|
||||
|
||||
/**
|
||||
* Force the arena to start.
|
||||
* If some players are ready, this method will force all non-ready players to leave,
|
||||
* and the arena will start with only the currently ready players.
|
||||
* @return true, if the arena was successfully started, false otherwise
|
||||
*/
|
||||
public boolean forceStart();
|
||||
|
||||
/**
|
||||
* Force the arena to end.
|
||||
* Returns all players to their entry locations, distributes rewards, cleans the arena
|
||||
* floor, as well as all lists, sets and maps. Calling this method will return the
|
||||
* arena to the state it would be in right after MobArena has loaded.
|
||||
* @return true, if the session was successfully ended.
|
||||
*/
|
||||
public boolean forceEnd();
|
||||
|
||||
/**
|
||||
* Player joins the arena/lobby.
|
||||
* The player should either enter with an empty inventory, or have their inventory
|
||||
* stored upon entering, such that the classes in the lobby/arena will be the only
|
||||
* means of equipment. The player's previous location and health is also stored.
|
||||
* @param p A player
|
||||
* @precondition Calling canJoin(p) for the given player must return true.
|
||||
*/
|
||||
public void playerJoin(Player p);
|
||||
|
||||
/**
|
||||
* Player leaves the arena or lobby.
|
||||
* Upon leaving, the player will have their inventory restored (if it was stored
|
||||
* on join), as well as their health. They will be completely discarded/cleared from
|
||||
* the arena, such that they no longer reside in any collections.
|
||||
* @param p A player
|
||||
* @precondition Calling canLeave(p) for the given player must return true.
|
||||
*/
|
||||
public void playerLeave(Player p);
|
||||
|
||||
/**
|
||||
* Player joins the spectator area.
|
||||
* The player takes a spectator role, meaning they cannot participate in the arena
|
||||
* in any way. The player's location and health is stored upon spectating, and of
|
||||
* course restored upon leaving.
|
||||
* @param p A player
|
||||
* @precondition Calling canSpec(p) for the given player must return true.
|
||||
*/
|
||||
public void playerSpec(Player p);
|
||||
|
||||
/**
|
||||
* Player dies in the arena.
|
||||
*/
|
||||
public void playerDeath(Player p);
|
||||
|
||||
/**
|
||||
* Player signals that they are ready.
|
||||
*/
|
||||
public void playerReady(Player p);
|
||||
|
||||
/**
|
||||
* Check if a player can join the arena.
|
||||
* @param p A player
|
||||
* @return true, if the player is eligible to join the arena.
|
||||
*/
|
||||
public boolean canJoin(Player p);
|
||||
|
||||
/**
|
||||
* Check if a player can leave the arena.
|
||||
* @param p A player
|
||||
* @return true, if the player is eligible to leave the arena.
|
||||
*/
|
||||
public boolean canLeave(Player p);
|
||||
|
||||
/**
|
||||
* Check if a player can spectate the arena.
|
||||
* @param p A player
|
||||
* @return true, if the player is eligible for spectating.
|
||||
*/
|
||||
public boolean canSpec(Player p);
|
||||
|
||||
/**
|
||||
* Check if the arena is enabled.
|
||||
* @return true, if the arena is enabled.
|
||||
*/
|
||||
public boolean isEnabled();
|
||||
|
||||
/**
|
||||
* Check if the arena is set up and ready for use.
|
||||
* @return true, if the arena is ready for use.
|
||||
*/
|
||||
public boolean isSetup();
|
||||
|
||||
/**
|
||||
* Check if the arena is running.
|
||||
* @return true, if the arena is running.
|
||||
*/
|
||||
public boolean isRunning();
|
||||
}
|
6
src/com/garbagemule/ArenaPlugin/ArenaPlugin.java
Normal file
6
src/com/garbagemule/ArenaPlugin/ArenaPlugin.java
Normal file
@ -0,0 +1,6 @@
|
||||
package com.garbagemule.ArenaPlugin;
|
||||
|
||||
public interface ArenaPlugin
|
||||
{
|
||||
public Master getMaster();
|
||||
}
|
16
src/com/garbagemule/ArenaPlugin/Master.java
Normal file
16
src/com/garbagemule/ArenaPlugin/Master.java
Normal file
@ -0,0 +1,16 @@
|
||||
package com.garbagemule.ArenaPlugin;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public interface Master
|
||||
{
|
||||
//public List<Arena> getArenas();
|
||||
|
||||
//public List<Arena> getEnabledArenas();
|
||||
|
||||
//public List<Arena> getPermittedArenas(Player p);
|
||||
|
||||
|
||||
}
|
@ -1,65 +1,44 @@
|
||||
package com.garbagemule.MobArena;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public abstract class AbstractArena implements Arenaz
|
||||
import com.garbagemule.ArenaPlugin.ArenaPlugin;
|
||||
|
||||
public abstract class AbstractArena implements ArenaInterface
|
||||
{
|
||||
|
||||
private String name;
|
||||
private World world;
|
||||
private MobArena plugin;
|
||||
private String name;
|
||||
private World world;
|
||||
private ArenaPlugin plugin;
|
||||
|
||||
private boolean enabled, setup, running;
|
||||
private Set<Player> arenaPlayers, lobbyPlayers, readyPlayers, specPlayers;
|
||||
private Map<Player,String> playerClassMap;
|
||||
private Map<Player,Location> locations;
|
||||
private Map<Player,Integer> healthMap;
|
||||
private Map<Player,Integer> healths;
|
||||
|
||||
/**
|
||||
* Start the arena session.
|
||||
* This method should warp all players to their respective warp points, start all
|
||||
* needed timers, clear/populate all sets and lists, and flag all booleans.
|
||||
*/
|
||||
public AbstractArena(String name, World world, ArenaPlugin plugin)
|
||||
{
|
||||
if (world == null)
|
||||
throw new NullPointerException("[" + plugin.getClass().getSimpleName() + "] ERROR! World for arena '" + name + "' does not exist!");
|
||||
|
||||
this.name = name;
|
||||
this.world = world;
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public abstract void startArena();
|
||||
|
||||
/**
|
||||
* Stop the arena session.
|
||||
* Distribute rewards, clean up arena floor and reset everything to how it was before
|
||||
* the arena session was started, false otherwise
|
||||
*/
|
||||
public abstract void endArena();
|
||||
|
||||
/**
|
||||
* Force the arena to start.
|
||||
* If some players are ready, this method will force all non-ready players to leave,
|
||||
* and the arena will start with only the currently ready players.
|
||||
* @return true, if the arena was successfully started, false otherwise
|
||||
*/
|
||||
|
||||
public abstract boolean forceStart();
|
||||
|
||||
/**
|
||||
* Force the arena to end.
|
||||
* Returns all players to their entry locations, distributes rewards, cleans the arena
|
||||
* floor, as well as all lists, sets and maps. Calling this method will return the
|
||||
* arena to the state it would be in right after MobArena has loaded.
|
||||
* @return true, if the session was successfully ended.
|
||||
*/
|
||||
|
||||
public abstract boolean forceEnd();
|
||||
|
||||
/**
|
||||
* Player joins the arena/lobby.
|
||||
* @param p A player
|
||||
* @precondition Calling canJoin(p) for the given player must return true.
|
||||
*/
|
||||
/*
|
||||
public void playerJoin(Player p)
|
||||
{
|
||||
storePlayerData(p, p.getLocation());
|
||||
@ -67,12 +46,7 @@ public abstract class AbstractArena implements Arenaz
|
||||
p.setHealth(20);
|
||||
movePlayerToLobby(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Player leaves the arena or lobby.
|
||||
* @param p A player
|
||||
* @precondition Calling canLeave(p) for the given player must return true.
|
||||
*/
|
||||
*/
|
||||
/*
|
||||
public void playerLeave(Player p)
|
||||
{
|
||||
@ -86,66 +60,29 @@ public abstract class AbstractArena implements Arenaz
|
||||
endArena();
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Player joins the spectator area.
|
||||
* @param p A player
|
||||
* @precondition Calling canSpec(p) for the given player must return true.
|
||||
*/
|
||||
|
||||
public abstract void playerSpec(Player p);
|
||||
|
||||
/**
|
||||
* Player dies in the arena.
|
||||
*/
|
||||
|
||||
public abstract void playerDeath(Player p);
|
||||
|
||||
/**
|
||||
* Player signals that they are ready.
|
||||
*/
|
||||
|
||||
public abstract void playerReady(Player p);
|
||||
|
||||
/**
|
||||
* Check if a player can join the arena.
|
||||
* @param p A player
|
||||
* @return true, if the player is eligible to join the arena.
|
||||
*/
|
||||
|
||||
public abstract boolean canJoin(Player p);
|
||||
|
||||
/**
|
||||
* Check if a player can leave the arena.
|
||||
* @param p A player
|
||||
* @return true, if the player is eligible to leave the arena.
|
||||
*/
|
||||
|
||||
public abstract boolean canLeave(Player p);
|
||||
|
||||
/**
|
||||
* Check if a player can spectate the arena.
|
||||
* @param p A player
|
||||
* @return true, if the player is eligible for spectating.
|
||||
*/
|
||||
|
||||
public abstract boolean canSpec(Player p);
|
||||
|
||||
/**
|
||||
* Check if the arena is enabled.
|
||||
* @return true, if the arena is enabled.
|
||||
*/
|
||||
|
||||
public boolean isEnabled()
|
||||
{
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the arena is set up and ready for use.
|
||||
* @return true, if the arena is ready for use.
|
||||
*/
|
||||
|
||||
public boolean isSetup()
|
||||
{
|
||||
return setup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the arena is running.
|
||||
* @return true, if the arena is running.
|
||||
*/
|
||||
|
||||
public boolean isRunning()
|
||||
{
|
||||
return running;
|
||||
@ -159,15 +96,21 @@ public abstract class AbstractArena implements Arenaz
|
||||
if (!locations.containsKey(p))
|
||||
locations.put(p, loc);
|
||||
|
||||
if (!healthMap.containsKey(p))
|
||||
healthMap.put(p, p.getHealth());
|
||||
if (!healths.containsKey(p))
|
||||
healths.put(p, p.getHealth());
|
||||
}
|
||||
|
||||
public abstract void movePlayerToLobby(Player p);
|
||||
|
||||
public abstract void movePlayerToSpec(Player p);
|
||||
|
||||
public abstract void movePlayerToEntry(Player p);
|
||||
public void movePlayerToEntry(Player p)
|
||||
{
|
||||
Location entry = locations.get(p);
|
||||
if (entry == null) return;
|
||||
|
||||
p.teleport(entry);
|
||||
}
|
||||
|
||||
public abstract void restoreInvAndGiveRewards(final Player p);
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ import com.garbagemule.MobArena.MAMessages.Msg;
|
||||
import com.garbagemule.MobArena.repairable.Repairable;
|
||||
import com.garbagemule.MobArena.repairable.RepairableComparator;
|
||||
import com.garbagemule.MobArena.repairable.RepairableContainer;
|
||||
import com.garbagemule.MobArena.util.InventoryItem;
|
||||
import com.garbagemule.MobArena.util.WaveUtils;
|
||||
import com.garbagemule.MobArena.waves.BossWave;
|
||||
import com.garbagemule.MobArena.waves.Wave;
|
||||
@ -63,7 +64,7 @@ public class Arena
|
||||
|
||||
protected boolean edit, waveClear, detCreepers, detDamage, lightning, hellhounds, specOnDeath, shareInArena;
|
||||
protected Location p1, p2, l1, l2, arenaLoc, lobbyLoc, spectatorLoc;
|
||||
protected Map<String,Location> spawnpoints;
|
||||
protected Map<String,Location> spawnpoints, containers;
|
||||
protected String logging;
|
||||
|
||||
// Wave/reward/entryfee fields
|
||||
@ -89,7 +90,7 @@ public class Arena
|
||||
protected Set<Block> blocks;
|
||||
protected Set<Wolf> pets;
|
||||
protected Map<Player,Integer> petMap;
|
||||
protected LinkedList<Repairable> repairables, containers;
|
||||
protected LinkedList<Repairable> repairables, containables;
|
||||
|
||||
// Spawn overriding
|
||||
protected int spawnMonsters;
|
||||
@ -137,7 +138,7 @@ public class Arena
|
||||
classMap = new HashMap<Player,String>();
|
||||
randoms = new HashSet<Player>();
|
||||
repairables = new LinkedList<Repairable>();
|
||||
containers = new LinkedList<Repairable>();
|
||||
containables = new LinkedList<Repairable>();
|
||||
|
||||
running = false;
|
||||
edit = false;
|
||||
@ -179,7 +180,10 @@ public class Arena
|
||||
p.setHealth(20);
|
||||
}
|
||||
|
||||
// Spawn pets.
|
||||
// Set the boolean.
|
||||
running = true;
|
||||
|
||||
// Spawn pets (must happen after 'running = true;')
|
||||
spawnPets();
|
||||
|
||||
// Copy the singleWaves Set.
|
||||
@ -193,9 +197,6 @@ public class Arena
|
||||
log = new ArenaLog(plugin, this);
|
||||
log.start();
|
||||
|
||||
// Set the boolean.
|
||||
running = true;
|
||||
|
||||
// Announce and notify.
|
||||
MAUtils.tellAll(this, Msg.ARENA_START.get());
|
||||
for (MobArenaListener listener : plugin.getAM().listeners)
|
||||
@ -339,7 +340,6 @@ public class Arena
|
||||
|
||||
if (specOnDeath)
|
||||
{
|
||||
//resetPlayer(p);
|
||||
clearPlayer(p);
|
||||
movePlayerToSpec(p);
|
||||
}
|
||||
@ -353,13 +353,14 @@ public class Arena
|
||||
spawnThread.updateTargets();
|
||||
|
||||
MAUtils.tellAll(this, Msg.PLAYER_DIED.get(p.getName()));
|
||||
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable()
|
||||
{
|
||||
public void run()
|
||||
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin,
|
||||
new Runnable()
|
||||
{
|
||||
endArena();
|
||||
}
|
||||
});
|
||||
public void run()
|
||||
{
|
||||
endArena();
|
||||
}
|
||||
});
|
||||
|
||||
// Notify listeners.
|
||||
for (MobArenaListener listener : plugin.getAM().listeners)
|
||||
@ -520,14 +521,12 @@ public class Arena
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
for (int x = p1.getBlockX(); x <= p2.getBlockX(); x++)
|
||||
for (int y = p1.getBlockY(); y <= p2.getBlockY(); y++)
|
||||
for (int z = p1.getBlockZ(); z <= p2.getBlockZ(); z++)
|
||||
{
|
||||
BlockState state = world.getBlockAt(x,y,z).getState();
|
||||
if (state instanceof ContainerBlock)
|
||||
containers.add(new RepairableContainer(state, false));
|
||||
}
|
||||
for (Location loc : containers.values())
|
||||
{
|
||||
BlockState state = world.getBlockAt(loc).getState();
|
||||
if (state instanceof ContainerBlock)
|
||||
containables.add(new RepairableContainer(state, false));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -539,7 +538,7 @@ public class Arena
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
for (Repairable r : containers)
|
||||
for (Repairable r : containables)
|
||||
r.repair();
|
||||
}
|
||||
});
|
||||
@ -807,6 +806,7 @@ public class Arena
|
||||
lobbyLoc = MAUtils.getArenaCoord(config, world, configName, "lobby");
|
||||
spectatorLoc = MAUtils.getArenaCoord(config, world, configName, "spectator");
|
||||
spawnpoints = MAUtils.getArenaSpawnpoints(config, world, configName);
|
||||
containers = MAUtils.getArenaContainers(config, world, configName);
|
||||
|
||||
// NEW WAVES
|
||||
singleWaves = WaveUtils.getWaves(this, config, WaveBranch.SINGLE);
|
||||
@ -1025,12 +1025,12 @@ public class Arena
|
||||
return classes;
|
||||
}
|
||||
|
||||
public Collection<Location> getAllSpawnpoints()
|
||||
public List<Location> getAllSpawnpoints()
|
||||
{
|
||||
return spawnpoints.values();
|
||||
return new ArrayList<Location>(spawnpoints.values());
|
||||
}
|
||||
|
||||
public Collection<Location> getSpawnpoints()
|
||||
public List<Location> getSpawnpoints()
|
||||
{
|
||||
List<Location> result = new ArrayList<Location>(spawnpoints.size());
|
||||
|
||||
@ -1040,7 +1040,7 @@ public class Arena
|
||||
result.add(entry.getValue());
|
||||
}
|
||||
|
||||
return !result.isEmpty() ? result : spawnpoints.values();
|
||||
return !result.isEmpty() ? result : new ArrayList<Location>(spawnpoints.values());
|
||||
}
|
||||
|
||||
public Location getBossSpawnpoint()
|
||||
@ -1200,54 +1200,25 @@ public class Arena
|
||||
return true;
|
||||
|
||||
PlayerInventory inv = p.getInventory();
|
||||
for (ItemStack stack : entryFee)
|
||||
{
|
||||
// Economy money
|
||||
if (stack.getTypeId() == MobArena.ECONOMY_MONEY_ID)
|
||||
{
|
||||
if (plugin.Methods.hasMethod() && !plugin.Method.getAccount(p.getName()).subtract(stack.getAmount()))
|
||||
return false;
|
||||
}
|
||||
InventoryItem[] items = InventoryItem.parseItemStacks(inv.getContents());
|
||||
InventoryItem[] fee = InventoryItem.parseItemStacks(entryFee);
|
||||
|
||||
// Normal stack
|
||||
else
|
||||
{
|
||||
int id = stack.getTypeId();
|
||||
int amount = stack.getAmount();
|
||||
|
||||
while (amount > 0)
|
||||
{
|
||||
int pos = inv.first(id);
|
||||
if (pos == -1) return false;
|
||||
|
||||
ItemStack is = inv.getItem(pos);
|
||||
if (is.getAmount() > amount)
|
||||
{
|
||||
is.setAmount(is.getAmount() - amount);
|
||||
amount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
amount -= is.getAmount();
|
||||
inv.setItem(pos, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Take some economy money
|
||||
for (InventoryItem item : InventoryItem.extractAllFromArray(MobArena.ECONOMY_MONEY_ID, fee))
|
||||
if (plugin.Methods.hasMethod())
|
||||
plugin.Method.getAccount(p.getName()).subtract(item.getAmount());
|
||||
|
||||
// Take any other items
|
||||
for (InventoryItem item : fee)
|
||||
InventoryItem.removeItemFromArray(item, items);
|
||||
|
||||
hasPaid.add(p);
|
||||
// Turn everything back into ItemStacks
|
||||
for (int i = 0; i < items.length; i++)
|
||||
inv.setItem(i, items[i].toItemStack());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void refund(Player p)
|
||||
{
|
||||
if (!hasPaid.contains(p))
|
||||
return;
|
||||
|
||||
MAUtils.giveItems(p, entryFee, false, plugin);
|
||||
hasPaid.remove(p);
|
||||
}
|
||||
|
||||
public boolean canJoin(Player p)
|
||||
{
|
||||
if (!enabled)
|
||||
@ -1266,12 +1237,14 @@ public class Arena
|
||||
MAUtils.tellPlayer(p, Msg.JOIN_PLAYER_LIMIT_REACHED);
|
||||
else if (joinDistance > 0 && !inRegionRadius(p.getLocation(), joinDistance))
|
||||
MAUtils.tellPlayer(p, Msg.JOIN_TOO_FAR);
|
||||
else if (!canAfford(p) || !takeFee(p))
|
||||
else if (emptyInvJoin && !MAUtils.hasEmptyInventory(p))
|
||||
MAUtils.tellPlayer(p, Msg.JOIN_EMPTY_INV);
|
||||
/*else if (!canAfford(p) || !takeFee(p))
|
||||
MAUtils.tellPlayer(p, Msg.JOIN_FEE_REQUIRED, MAUtils.listToString(entryFee, plugin));
|
||||
else if (emptyInvJoin && !MAUtils.hasEmptyInventory(p))
|
||||
MAUtils.tellPlayer(p, Msg.JOIN_EMPTY_INV);
|
||||
else if (!emptyInvJoin && !MAUtils.storeInventory(p))
|
||||
MAUtils.tellPlayer(p, Msg.JOIN_STORE_INV_FAIL);
|
||||
MAUtils.tellPlayer(p, Msg.JOIN_STORE_INV_FAIL);*/
|
||||
else return true;
|
||||
|
||||
return false;
|
||||
|
116
src/com/garbagemule/MobArena/ArenaInterface.java
Normal file
116
src/com/garbagemule/MobArena/ArenaInterface.java
Normal file
@ -0,0 +1,116 @@
|
||||
package com.garbagemule.MobArena;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public interface ArenaInterface
|
||||
{
|
||||
/**
|
||||
* Start the arena session.
|
||||
* This method should warp all players to their respective warp points, start all
|
||||
* needed timers, clear/populate all sets and lists, and flag all booleans.
|
||||
*/
|
||||
public void startArena();
|
||||
|
||||
/**
|
||||
* Stop the arena session.
|
||||
* Distribute rewards, clean up arena floor and reset everything to how it was before
|
||||
* the arena session was started.
|
||||
*/
|
||||
public void endArena();
|
||||
|
||||
/**
|
||||
* Force the arena to start.
|
||||
* If some players are ready, this method will force all non-ready players to leave,
|
||||
* and the arena will start with only the currently ready players.
|
||||
* @return true, if the arena was successfully started, false otherwise
|
||||
*/
|
||||
public boolean forceStart();
|
||||
|
||||
/**
|
||||
* Force the arena to end.
|
||||
* Returns all players to their entry locations, distributes rewards, cleans the arena
|
||||
* floor, as well as all lists, sets and maps. Calling this method will return the
|
||||
* arena to the state it would be in right after MobArena has loaded.
|
||||
* @return true, if the session was successfully ended.
|
||||
*/
|
||||
public boolean forceEnd();
|
||||
|
||||
/**
|
||||
* Player joins the arena/lobby.
|
||||
* The player should either enter with an empty inventory, or have their inventory
|
||||
* stored upon entering, such that the classes in the lobby/arena will be the only
|
||||
* means of equipment. The player's previous location and health is also stored.
|
||||
* @param p A player
|
||||
* @precondition Calling canJoin(p) for the given player must return true.
|
||||
*/
|
||||
public void playerJoin(Player p);
|
||||
|
||||
/**
|
||||
* Player leaves the arena or lobby.
|
||||
* Upon leaving, the player will have their inventory restored (if it was stored
|
||||
* on join), as well as their health. They will be completely discarded/cleared from
|
||||
* the arena, such that they no longer reside in any collections.
|
||||
* @param p A player
|
||||
* @precondition Calling canLeave(p) for the given player must return true.
|
||||
*/
|
||||
public void playerLeave(Player p);
|
||||
|
||||
/**
|
||||
* Player joins the spectator area.
|
||||
* The player takes a spectator role, meaning they cannot participate in the arena
|
||||
* in any way. The player's location and health is stored upon spectating, and of
|
||||
* course restored upon leaving.
|
||||
* @param p A player
|
||||
* @precondition Calling canSpec(p) for the given player must return true.
|
||||
*/
|
||||
public void playerSpec(Player p);
|
||||
|
||||
/**
|
||||
* Player dies in the arena.
|
||||
*/
|
||||
public void playerDeath(Player p);
|
||||
|
||||
/**
|
||||
* Player signals that they are ready.
|
||||
*/
|
||||
public void playerReady(Player p);
|
||||
|
||||
/**
|
||||
* Check if a player can join the arena.
|
||||
* @param p A player
|
||||
* @return true, if the player is eligible to join the arena.
|
||||
*/
|
||||
public boolean canJoin(Player p);
|
||||
|
||||
/**
|
||||
* Check if a player can leave the arena.
|
||||
* @param p A player
|
||||
* @return true, if the player is eligible to leave the arena.
|
||||
*/
|
||||
public boolean canLeave(Player p);
|
||||
|
||||
/**
|
||||
* Check if a player can spectate the arena.
|
||||
* @param p A player
|
||||
* @return true, if the player is eligible for spectating.
|
||||
*/
|
||||
public boolean canSpec(Player p);
|
||||
|
||||
/**
|
||||
* Check if the arena is enabled.
|
||||
* @return true, if the arena is enabled.
|
||||
*/
|
||||
public boolean isEnabled();
|
||||
|
||||
/**
|
||||
* Check if the arena is set up and ready for use.
|
||||
* @return true, if the arena is ready for use.
|
||||
*/
|
||||
public boolean isSetup();
|
||||
|
||||
/**
|
||||
* Check if the arena is running.
|
||||
* @return true, if the arena is running.
|
||||
*/
|
||||
public boolean isRunning();
|
||||
}
|
@ -15,7 +15,9 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.config.Configuration;
|
||||
|
||||
public class ArenaMaster
|
||||
import com.garbagemule.ArenaPlugin.Master;
|
||||
|
||||
public class ArenaMaster implements Master
|
||||
{
|
||||
private MobArena plugin;
|
||||
private Configuration config;
|
||||
|
@ -3,6 +3,7 @@ package com.garbagemule.MobArena;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
@ -13,6 +14,7 @@ public class ArenaPlayer
|
||||
public String className;
|
||||
public Arena arena;
|
||||
public List<ItemStack> rewards;
|
||||
public List<Block> blocks;
|
||||
|
||||
protected boolean inArena, inLobby, inSpec, isReady;
|
||||
|
||||
@ -34,6 +36,7 @@ public class ArenaPlayer
|
||||
|
||||
className = arena.classMap.get(player);
|
||||
rewards = new LinkedList<ItemStack>();
|
||||
blocks = new LinkedList<Block>();
|
||||
}
|
||||
|
||||
public Player getPlayer() { return player; }
|
||||
|
@ -1,8 +1,10 @@
|
||||
package com.garbagemule.MobArena;
|
||||
|
||||
import org.bukkit.event.block.BlockBurnEvent;
|
||||
import org.bukkit.event.block.BlockIgniteEvent;
|
||||
import org.bukkit.event.block.BlockListener;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
|
||||
public class MABlockListener extends BlockListener
|
||||
@ -19,6 +21,12 @@ public class MABlockListener extends BlockListener
|
||||
for (Arena arena : am.arenas)
|
||||
arena.eventListener.onBlockBreak(event);
|
||||
}
|
||||
|
||||
public void onBlockBurn(BlockBurnEvent event)
|
||||
{
|
||||
for (Arena arena : am.arenas)
|
||||
arena.eventListener.onBlockBurn(event);
|
||||
}
|
||||
|
||||
public void onBlockPlace(BlockPlaceEvent event)
|
||||
{
|
||||
@ -31,4 +39,10 @@ public class MABlockListener extends BlockListener
|
||||
for (Arena arena : am.arenas)
|
||||
arena.eventListener.onBlockIgnite(event);
|
||||
}
|
||||
|
||||
public void onBlockPhysics(BlockPhysicsEvent event)
|
||||
{
|
||||
for (Arena arena : am.arenas)
|
||||
arena.eventListener.onBlockPhysics(event);
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.block.ContainerBlock;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
@ -55,14 +56,16 @@ public class MACommands implements CommandExecutor
|
||||
COMMANDS.add("setwarp"); // Set arena/lobby/spec
|
||||
COMMANDS.add("spawnpoints"); // List spawnpoints
|
||||
COMMANDS.add("addspawn"); // Add a spawnpoint
|
||||
COMMANDS.add("delspawn"); // Delete a spawnpoint
|
||||
COMMANDS.add("delspawn"); // Delete a spawnpoint
|
||||
COMMANDS.add("containers"); // List containers
|
||||
COMMANDS.add("addcontainer"); // Add a container block
|
||||
COMMANDS.add("delcontainer"); // Delete a container block
|
||||
COMMANDS.add("reset"); // Reset arena coordinates
|
||||
COMMANDS.add("addclass"); // Add a new class
|
||||
COMMANDS.add("delclass"); // Delete a class
|
||||
COMMANDS.add("checkdata"); // Check arena well formedness
|
||||
COMMANDS.add("auto-generate"); // Auto-generate arena
|
||||
COMMANDS.add("auto-degenerate"); // Restore cuboid
|
||||
COMMANDS.add("lol");
|
||||
}
|
||||
private boolean meanAdmins, showingRegion;
|
||||
private Server server;
|
||||
@ -155,6 +158,10 @@ public class MACommands implements CommandExecutor
|
||||
if (p.isInsideVehicle())
|
||||
p.leaveVehicle();
|
||||
|
||||
// Take entry fee and store inventory
|
||||
arena.takeFee(p);
|
||||
if (!arena.emptyInvJoin) MAUtils.storeInventory(p);
|
||||
|
||||
// If player is in a bed, unbed!
|
||||
if (p.isSleeping())
|
||||
{
|
||||
@ -1070,6 +1077,77 @@ public class MACommands implements CommandExecutor
|
||||
return true;
|
||||
}
|
||||
|
||||
if (base.equals("containers"))
|
||||
{
|
||||
if (!console && !(player && plugin.has(p, "mobarena.setup.containers")) && !op)
|
||||
{
|
||||
MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS);
|
||||
return true;
|
||||
}
|
||||
|
||||
StringBuffer buffy = new StringBuffer();
|
||||
List<String> containers = plugin.getConfig().getKeys("arenas." + am.selectedArena.configName() + ".coords.containers");
|
||||
|
||||
if (containers != null)
|
||||
{
|
||||
for (String s : containers)
|
||||
{
|
||||
buffy.append(s);
|
||||
buffy.append(" ");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
buffy.append(Msg.MISC_NONE);
|
||||
}
|
||||
|
||||
MAUtils.tellPlayer(sender, "Containers for arena '" + am.selectedArena.configName() + "': " + buffy.toString());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (base.equals("addcontainer"))
|
||||
{
|
||||
if (!(player && plugin.has(p, "mobarena.setup.addchest")) && !op)
|
||||
{
|
||||
MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS);
|
||||
return true;
|
||||
}
|
||||
if (arg1 == null || !arg1.matches("^[a-zA-Z][a-zA-Z0-9]*$"))
|
||||
{
|
||||
MAUtils.tellPlayer(sender, "Usage: /ma addchest <container name>");
|
||||
return true;
|
||||
}
|
||||
if (!(p.getTargetBlock(null, 50).getState() instanceof ContainerBlock))
|
||||
{
|
||||
MAUtils.tellPlayer(sender, "You must look at container.");
|
||||
return true;
|
||||
}
|
||||
|
||||
MAUtils.setArenaCoord(plugin.getConfig(), am.selectedArena, "containers." + arg1, p.getTargetBlock(null, 50).getLocation());
|
||||
MAUtils.tellPlayer(sender, "Container '" + arg1 + "' added for arena \"" + am.selectedArena.configName() + "\"");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (base.equals("delcontainer"))
|
||||
{
|
||||
if (!console && !(player && plugin.has(p, "mobarena.setup.delcontainer")) && !op)
|
||||
{
|
||||
MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS);
|
||||
return true;
|
||||
}
|
||||
if (arg1 == null || !arg1.matches("^[a-zA-Z][a-zA-Z0-9]*$"))
|
||||
{
|
||||
MAUtils.tellPlayer(sender, "Usage: /ma delcontainer <container name>");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (MAUtils.delArenaCoord(plugin.getConfig(), am.selectedArena, "containers." + arg1))
|
||||
MAUtils.tellPlayer(sender, "Container '" + arg1 + "' deleted for arena '" + am.selectedArena.configName() + "'");
|
||||
else
|
||||
MAUtils.tellPlayer(sender, "Could not find the container '" + arg1 + "' for arena '" + am.selectedArena.configName() + "'");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (base.equals("checkdata"))
|
||||
{
|
||||
if (!console && !(player && plugin.has(p, "mobarena.setup.checkdata")) && !op)
|
||||
|
@ -11,12 +11,15 @@ import org.bukkit.block.Sign;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Slime;
|
||||
import org.bukkit.entity.Wolf;
|
||||
import org.bukkit.event.Event.Result;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockBurnEvent;
|
||||
import org.bukkit.event.block.BlockEvent;
|
||||
import org.bukkit.event.block.BlockIgniteEvent;
|
||||
import org.bukkit.event.block.BlockIgniteEvent.IgniteCause;
|
||||
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.bukkit.event.entity.EntityCombustEvent;
|
||||
@ -41,6 +44,7 @@ import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.material.Attachable;
|
||||
import org.bukkit.material.Bed;
|
||||
import org.bukkit.material.Door;
|
||||
import org.bukkit.material.MaterialData;
|
||||
import org.bukkit.material.Redstone;
|
||||
|
||||
import com.garbagemule.MobArena.MAMessages.Msg;
|
||||
@ -57,14 +61,40 @@ public class MAListener implements ArenaListener
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public void onBlockPhysics(BlockPhysicsEvent event)
|
||||
{
|
||||
if (!arena.inRegion(event.getBlock().getLocation()) || arena.softRestore)
|
||||
return;
|
||||
|
||||
MaterialData data = event.getBlock().getState().getData();
|
||||
if (data instanceof Attachable || data instanceof Bed || data instanceof Door || data instanceof Redstone)
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
public void onBlockBreak(BlockBreakEvent event)
|
||||
{
|
||||
if (!arena.inRegion(event.getBlock().getLocation()) || arena.edit || (!arena.protect && arena.running))
|
||||
if (onBlockDestroy(event))
|
||||
return;
|
||||
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
public void onBlockBurn(BlockBurnEvent event)
|
||||
{
|
||||
if (onBlockDestroy(event))
|
||||
return;
|
||||
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
private boolean onBlockDestroy(BlockEvent event)
|
||||
{
|
||||
if (!arena.inRegion(event.getBlock().getLocation()) || arena.edit || (!arena.protect && arena.running))
|
||||
return true;
|
||||
|
||||
Block b = event.getBlock();
|
||||
if (arena.blocks.remove(b) || b.getType() == Material.TNT)
|
||||
return;
|
||||
return true;
|
||||
|
||||
if (arena.softRestore && arena.running)
|
||||
{
|
||||
@ -85,10 +115,10 @@ public class MAListener implements ArenaListener
|
||||
if (!arena.softRestoreDrops)
|
||||
b.setTypeId(0);
|
||||
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
public void onBlockPlace(BlockPlaceEvent event)
|
||||
@ -104,6 +134,7 @@ public class MAListener implements ArenaListener
|
||||
|
||||
if (mat == Material.WOODEN_DOOR || mat == Material.IRON_DOOR_BLOCK)
|
||||
arena.blocks.add(b.getRelative(0,1,0));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -116,8 +147,21 @@ public class MAListener implements ArenaListener
|
||||
if (!arena.inRegion(event.getBlock().getLocation()))
|
||||
return;
|
||||
|
||||
if (event.getCause() == IgniteCause.LIGHTNING)
|
||||
event.setCancelled(true);
|
||||
switch (event.getCause())
|
||||
{
|
||||
case LIGHTNING:
|
||||
event.setCancelled(true);
|
||||
break;
|
||||
case SPREAD:
|
||||
case FLINT_AND_STEEL:
|
||||
if (arena.running)
|
||||
arena.blocks.add(event.getBlock());
|
||||
else
|
||||
event.setCancelled(true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void onCreatureSpawn(CreatureSpawnEvent event)
|
||||
@ -125,8 +169,12 @@ public class MAListener implements ArenaListener
|
||||
if (!arena.inRegion(event.getLocation())) // || event.getSpawnReason() == SpawnReason.CUSTOM)
|
||||
return;
|
||||
|
||||
// If running == true, setCancelled(false), and vice versa.
|
||||
event.setCancelled(!arena.running);
|
||||
LivingEntity entity = (LivingEntity) event.getEntity();
|
||||
if (arena.running && entity instanceof Slime)
|
||||
arena.monsters.add(entity);
|
||||
else
|
||||
// If running == true, setCancelled(false), and vice versa.
|
||||
event.setCancelled(!arena.running);
|
||||
}
|
||||
|
||||
public void onEntityExplode(EntityExplodeEvent event)
|
||||
@ -532,7 +580,7 @@ public class MAListener implements ArenaListener
|
||||
|
||||
public void onPlayerTeleport(PlayerTeleportEvent event)
|
||||
{
|
||||
if (arena.edit || !arena.enabled || !arena.setup || arena.allowWarp)
|
||||
if (!arena.running || arena.edit || !arena.enabled || !arena.setup || arena.allowWarp)
|
||||
return;
|
||||
|
||||
if (!arena.inRegion(event.getTo()) && !arena.inRegion(event.getFrom()))
|
||||
|
@ -106,6 +106,11 @@ public class MAMessages
|
||||
{
|
||||
m.msg = msg;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -13,6 +13,7 @@ import org.bukkit.event.player.PlayerListener;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
|
||||
|
||||
public class MAPlayerListener extends PlayerListener
|
||||
{
|
||||
private MobArena plugin;
|
||||
@ -90,6 +91,6 @@ public class MAPlayerListener extends PlayerListener
|
||||
{
|
||||
MAUtils.checkForUpdates(plugin, p, false);
|
||||
}
|
||||
}, 100);
|
||||
}, 60);
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +64,10 @@ public class MASpawnThread implements Runnable
|
||||
if (arena.waveClear && wave > 1 && !arena.monsters.isEmpty())
|
||||
return;
|
||||
|
||||
// Check if we're on a boss wave
|
||||
if (!arena.waveClear && arena.bossWave != null)
|
||||
return;
|
||||
|
||||
// Grant rewards (if any) for this wave
|
||||
grantRewards(wave);
|
||||
|
||||
@ -82,7 +86,7 @@ public class MASpawnThread implements Runnable
|
||||
{
|
||||
List<Entity> tmp = new LinkedList<Entity>(arena.monsters);
|
||||
for (Entity e : tmp)
|
||||
if (e.isDead())
|
||||
if (e.isDead() || !arena.inRegion(e.getLocation()))
|
||||
arena.monsters.remove(e);
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,8 @@ import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import net.minecraft.server.WorldServer;
|
||||
|
||||
@ -36,7 +38,7 @@ import org.bukkit.util.config.Configuration;
|
||||
|
||||
import com.garbagemule.MobArena.MAMessages.Msg;
|
||||
import com.garbagemule.MobArena.util.EntityPosition;
|
||||
import com.garbagemule.MobArena.util.MAInventoryItem;
|
||||
import com.garbagemule.MobArena.util.InventoryItem;
|
||||
|
||||
public class MAUtils
|
||||
{
|
||||
@ -133,6 +135,20 @@ public class MAUtils
|
||||
|
||||
// ///////////////////////////////////////////////////////////////////// */
|
||||
|
||||
public static Map<String,Location> getArenaContainers(Configuration config, World world, String arena)
|
||||
{
|
||||
Map<String,Location> containers = new HashMap<String,Location>();
|
||||
String arenaPath = "arenas." + arena + ".coords.containers";
|
||||
|
||||
if (config.getKeys(arenaPath) == null)
|
||||
return containers;
|
||||
|
||||
for (String point : config.getKeys(arenaPath))
|
||||
containers.put(point, makeLocation(world, config.getString(arenaPath + "." + point)));
|
||||
|
||||
return containers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grab all the spawnpoints for a specific arena.
|
||||
*/
|
||||
@ -353,11 +369,11 @@ public class MAUtils
|
||||
{
|
||||
backupFile.createNewFile();
|
||||
|
||||
MAInventoryItem[] inv = new MAInventoryItem[armor.length + items.length];
|
||||
InventoryItem[] inv = new InventoryItem[armor.length + items.length];
|
||||
for (int i = 0; i < armor.length; i++)
|
||||
inv[i] = stackToItem(armor[i]);
|
||||
inv[i] = InventoryItem.parseItemStack(armor[i]);
|
||||
for (int i = 0; i < items.length; i++)
|
||||
inv[armor.length + i] = stackToItem(items[i]);
|
||||
inv[armor.length + i] = InventoryItem.parseItemStack(items[i]);
|
||||
|
||||
FileOutputStream fos = new FileOutputStream(backupFile);
|
||||
ObjectOutputStream oos = new ObjectOutputStream(fos);
|
||||
@ -389,7 +405,7 @@ public class MAUtils
|
||||
// Grab the MAInventoryItem array from the backup-file.
|
||||
FileInputStream fis = new FileInputStream(backupFile);
|
||||
ObjectInputStream ois = new ObjectInputStream(fis);
|
||||
MAInventoryItem[] fromFile = (MAInventoryItem[]) ois.readObject();
|
||||
InventoryItem[] fromFile = (InventoryItem[]) ois.readObject();
|
||||
ois.close();
|
||||
|
||||
// Split that shit.
|
||||
@ -397,17 +413,20 @@ public class MAUtils
|
||||
ItemStack[] items = new ItemStack[fromFile.length-4];
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
armor[i] = itemToStack(fromFile[i]);
|
||||
armor[i] = InventoryItem.toItemStack(fromFile[i]);
|
||||
for (int i = 4; i < fromFile.length; i++)
|
||||
items[i - 4] = itemToStack(fromFile[i]);
|
||||
items[i - 4] = InventoryItem.toItemStack(fromFile[i]);
|
||||
|
||||
// Restore the inventory.
|
||||
PlayerInventory inv = p.getInventory();
|
||||
inv.setArmorContents(armor);
|
||||
for (int i = 0; i < items.length; i++)
|
||||
inv.setItem(i, items[i]);
|
||||
/*
|
||||
for (ItemStack stack : items)
|
||||
if (stack != null)
|
||||
inv.addItem(stack);
|
||||
|
||||
*/
|
||||
// Remove the backup-file.
|
||||
backupFile.delete();
|
||||
}
|
||||
@ -421,20 +440,6 @@ public class MAUtils
|
||||
return true;
|
||||
}
|
||||
|
||||
private static MAInventoryItem stackToItem(ItemStack stack)
|
||||
{
|
||||
if (stack == null)
|
||||
return new MAInventoryItem(-1, -1, (short)0);
|
||||
return new MAInventoryItem(stack.getTypeId(), stack.getAmount(), stack.getDurability());
|
||||
}
|
||||
|
||||
private static ItemStack itemToStack(MAInventoryItem item)
|
||||
{
|
||||
if (item.getTypeId() == -1)
|
||||
return null;
|
||||
return new ItemStack(item.getTypeId(), item.getAmount(), item.getDurability());
|
||||
}
|
||||
|
||||
/* Checks if all inventory and armor slots are empty. */
|
||||
public static boolean hasEmptyInventory(Player p)
|
||||
{
|
||||
@ -636,6 +641,20 @@ public class MAUtils
|
||||
|
||||
// ///////////////////////////////////////////////////////////////////// */
|
||||
|
||||
/**
|
||||
* Check if a Location is inside two points (x1,y1,z1) (x2,y2,z2)
|
||||
*/
|
||||
public static boolean inRegion(Location loc, double x1, double y1, double z1, double x2, double y2, double z2)
|
||||
{
|
||||
double x = loc.getBlockX();
|
||||
double y = loc.getBlockY();
|
||||
double z = loc.getBlockZ();
|
||||
|
||||
return x >= x1 && x <= x2 &&
|
||||
y >= y1 && y <= y2 &&
|
||||
z >= z1 && z <= z2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a frame spanned by the two input coordinates.
|
||||
* @return An int arry holding x,y,z and the original type IDs of each block.
|
||||
@ -1153,6 +1172,7 @@ public class MAUtils
|
||||
|
||||
// Open the connection and don't redirect.
|
||||
HttpURLConnection con = (HttpURLConnection) baseURI.toURL().openConnection();
|
||||
con.setConnectTimeout(5000);
|
||||
con.setInstanceFollowRedirects(false);
|
||||
|
||||
String header = con.getHeaderField("Location");
|
||||
@ -1167,18 +1187,27 @@ public class MAUtils
|
||||
// Otherwise, grab the location header to get the real URI.
|
||||
String url = new URI(con.getHeaderField("Location")).toString();
|
||||
|
||||
// If the current version is the same as the thread version.
|
||||
if (url.contains(plugin.getDescription().getVersion().replace(".", "-")))
|
||||
{
|
||||
if (!response)
|
||||
return;
|
||||
|
||||
tellPlayer(p, "Your version of MobArena is up to date!");
|
||||
// Set up the regex and matcher
|
||||
Pattern regex = Pattern.compile("v([0-9]+-)*[0-9]+");
|
||||
Matcher matcher = regex.matcher(url);
|
||||
if (!matcher.find())
|
||||
return;
|
||||
|
||||
// Split the version strings
|
||||
String[] forumVersion = matcher.group().substring(1).split("-");
|
||||
String[] thisVersion = plugin.getDescription().getVersion().split("\\.");
|
||||
|
||||
// If the current version is older than the forum version, notify.
|
||||
for (int i = 0; i < Math.min(forumVersion.length, thisVersion.length); i++)
|
||||
{
|
||||
if (Integer.parseInt(forumVersion[i]) > Integer.parseInt(thisVersion[i]))
|
||||
{
|
||||
tellPlayer(p, "There is a new version of MobArena available!");;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, notify the player that there is a new version.
|
||||
tellPlayer(p, "There is a new version of MobArena available!");;
|
||||
if (response) tellPlayer(p, "Your version of MobArena is up to date!");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.garbagemule.MobArena;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -20,12 +21,14 @@ import com.nijikokun.bukkit.Permissions.Permissions;
|
||||
import com.garbagemule.MobArena.util.FileUtils;
|
||||
import com.garbagemule.register.payment.Method;
|
||||
import com.garbagemule.register.payment.Methods;
|
||||
import com.garbagemule.ArenaPlugin.ArenaPlugin;
|
||||
import com.garbagemule.ArenaPlugin.Master;
|
||||
|
||||
/**
|
||||
* MobArena
|
||||
* @author garbagemule
|
||||
*/
|
||||
public class MobArena extends JavaPlugin
|
||||
public class MobArena extends JavaPlugin implements ArenaPlugin
|
||||
{
|
||||
private Configuration config;
|
||||
private ArenaMaster am;
|
||||
@ -40,8 +43,10 @@ public class MobArena extends JavaPlugin
|
||||
// Global variables
|
||||
public static PluginDescriptionFile desc;
|
||||
public static File dir, arenaDir;
|
||||
public static final double MIN_PLAYER_DISTANCE = 256.0;
|
||||
public static final double MIN_PLAYER_DISTANCE = 15.0;
|
||||
public static final double MIN_PLAYER_DISTANCE_SQUARED = MIN_PLAYER_DISTANCE * MIN_PLAYER_DISTANCE;
|
||||
public static final int ECONOMY_MONEY_ID = -29;
|
||||
public static Random random = new Random();
|
||||
|
||||
public void onEnable()
|
||||
{
|
||||
@ -109,8 +114,10 @@ public class MobArena extends JavaPlugin
|
||||
|
||||
// Register events.
|
||||
pm.registerEvent(Event.Type.BLOCK_BREAK, blockListener, Priority.Highest, this);
|
||||
pm.registerEvent(Event.Type.BLOCK_BURN, blockListener, Priority.Highest, this);
|
||||
pm.registerEvent(Event.Type.BLOCK_PLACE, blockListener, Priority.Highest, this);
|
||||
pm.registerEvent(Event.Type.BLOCK_IGNITE, blockListener, Priority.Normal, this);
|
||||
pm.registerEvent(Event.Type.BLOCK_PHYSICS, blockListener, Priority.Normal, this);
|
||||
pm.registerEvent(Event.Type.BLOCK_IGNITE, blockListener, Priority.Highest, this);
|
||||
pm.registerEvent(Event.Type.PLAYER_INTERACT, playerListener, Priority.Normal, this);
|
||||
pm.registerEvent(Event.Type.PLAYER_DROP_ITEM, playerListener, Priority.Normal, this);
|
||||
pm.registerEvent(Event.Type.PLAYER_BUCKET_EMPTY, playerListener, Priority.Normal, this);
|
||||
@ -174,6 +181,11 @@ public class MobArena extends JavaPlugin
|
||||
public ArenaMaster getAM() { return am; } // More convenient.
|
||||
public ArenaMaster getArenaMaster() { return am; }
|
||||
|
||||
public Master getMaster()
|
||||
{
|
||||
return am;
|
||||
}
|
||||
|
||||
private String getHeader()
|
||||
{
|
||||
String sep = System.getProperty("line.separator");
|
||||
|
@ -3,13 +3,12 @@ package com.garbagemule.MobArena;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class MobArenaHandler
|
||||
{
|
||||
MobArena plugin;
|
||||
boolean ma = false;
|
||||
private MobArena plugin;
|
||||
|
||||
/**
|
||||
* Primary constructor.
|
||||
@ -17,26 +16,24 @@ public class MobArenaHandler
|
||||
*/
|
||||
public MobArenaHandler()
|
||||
{
|
||||
Plugin maPlugin = (MobArena) Bukkit.getServer().getPluginManager().getPlugin("MobArena");
|
||||
|
||||
if (maPlugin == null)
|
||||
return;
|
||||
|
||||
ma = true;
|
||||
plugin = (MobArena) maPlugin;
|
||||
plugin = (MobArena) Bukkit.getServer().getPluginManager().getPlugin("MobArena");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////
|
||||
|
||||
REGION/LOCATION METHODS
|
||||
|
||||
//////////////////////////////////////////////////////////////////*/
|
||||
|
||||
/**
|
||||
* Check if a Location is inside of an arena region.
|
||||
* Check if a Location is inside of any arena region.
|
||||
* @param loc A location.
|
||||
* @return true, if the Location is inside of any arena region.
|
||||
*/
|
||||
public boolean inRegion(Location loc)
|
||||
{
|
||||
// If the plugin doesn't exist, always return false.
|
||||
if (!ma || plugin.getAM() == null) return false;
|
||||
|
||||
// Return true if location is within just one arena's region.
|
||||
for (Arena arena : plugin.getAM().arenas)
|
||||
if (arena.inRegion(loc))
|
||||
return true;
|
||||
@ -45,26 +42,50 @@ public class MobArenaHandler
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a Location is inside of a specific arena region.
|
||||
* Check if a Location is inside of a specific arena region (by arena object).
|
||||
* @param arena An Arena object
|
||||
* @param loc A location
|
||||
* @return true, if the Location is inside of the arena region.
|
||||
*/
|
||||
public boolean inRegion(Arena arena, Location loc) { return (ma && arena != null && arena.inRegion(loc)); }
|
||||
public boolean inRegion(Arena arena, Location loc)
|
||||
{
|
||||
return (arena != null && arena.inRegion(loc));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a Location is inside of a specific arena region (by arena name).
|
||||
* @param arenaName The name of an arena
|
||||
* @param loc A location
|
||||
* @return true, if the Location is inside of the arena region.
|
||||
*/
|
||||
public boolean inRegion(String arenaName, Location loc)
|
||||
{
|
||||
Arena arena = plugin.getAM().getArenaWithName(arenaName);
|
||||
if (arena == null)
|
||||
throw new NullPointerException("There is no arena with that name");
|
||||
|
||||
return arena.inRegion(loc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a Location is inside of the region of an arena that is currently running.
|
||||
* @param loc A location.
|
||||
* @return true, if the Location is inside of the region of an arena that is currently running.
|
||||
*/
|
||||
public boolean inRunningRegion(Location loc) { return inRegion(loc, false, true); }
|
||||
public boolean inRunningRegion(Location loc)
|
||||
{
|
||||
return inRegion(loc, false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a Location is inside of the region of an arena that is currently enabled.
|
||||
* @param loc A location.
|
||||
* @return true, if the Location is inside of the region of an arena that is currently enabled.
|
||||
*/
|
||||
public boolean inEnabledRegion(Location loc) { return inRegion(loc, true, false); }
|
||||
public boolean inEnabledRegion(Location loc)
|
||||
{
|
||||
return inRegion(loc, true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Private helper method for inRunningRegion and inEnabledRegion
|
||||
@ -76,7 +97,7 @@ public class MobArenaHandler
|
||||
private boolean inRegion(Location loc, boolean enabled, boolean running)
|
||||
{
|
||||
// If the plugin doesn't exist, always return false.
|
||||
if (!ma || plugin.getAM() == null) return false;
|
||||
if (plugin.getAM() == null) return false;
|
||||
|
||||
// Return true if location is within just one arena's region.
|
||||
for (Arena arena : plugin.getAM().arenas)
|
||||
@ -87,40 +108,124 @@ public class MobArenaHandler
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////
|
||||
|
||||
PLAYER/MONSTER/PET METHODS
|
||||
|
||||
//////////////////////////////////////////////////////////////////*/
|
||||
|
||||
/**
|
||||
* Check if a player is in a MobArena arena (by Player).
|
||||
* @param player The player
|
||||
* @return true, if the player is in an arena
|
||||
*/
|
||||
public boolean isPlayerInArena(Player player)
|
||||
{
|
||||
return (plugin.getAM().getArenaWithPlayer(player) != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a player is in a MobArena arena (by name).
|
||||
* @param playerName The name of the player
|
||||
* @return true, if the player is in an arena
|
||||
*/
|
||||
public boolean isPlayerInArena(String playerName)
|
||||
{
|
||||
return (plugin.getAM().getArenaWithPlayer(playerName) != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the MobArena class of a given player.
|
||||
* @param player The player
|
||||
* @return The class name of the player if the player is in the arena, null otherwise
|
||||
*/
|
||||
public String getPlayerClass(Player player)
|
||||
{
|
||||
Arena arena = plugin.getAM().getArenaWithPlayer(player);
|
||||
if (arena == null) return null;
|
||||
|
||||
return arena.classMap.get(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the MobArena class of a given player in a given arena.
|
||||
* This method is faster than the above method, granted the Arena object is known.
|
||||
* @param arena The MobArena arena to check in
|
||||
* @param player The player to look up
|
||||
* @return The class name of the player, if the player is in the arena, null otherwise
|
||||
*/
|
||||
public String getPlayerClass(Arena arena, Player player)
|
||||
{
|
||||
return arena.classMap.get(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a monster is in a MobArena arena.
|
||||
* @param entity The monster entity
|
||||
* @return true, if the monster is in an arena
|
||||
*/
|
||||
public boolean isMonsterInArena(LivingEntity entity)
|
||||
{
|
||||
return plugin.getAM().getArenaWithMonster(entity) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a pet is in a MobArena arena.
|
||||
* @param wolf The pet wolf
|
||||
* @return true, if the pet is in an arena
|
||||
*/
|
||||
public boolean isPetInArena(LivingEntity wolf)
|
||||
{
|
||||
return plugin.getAM().getArenaWithPet(wolf) != null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////
|
||||
|
||||
ARENA GETTERS
|
||||
|
||||
//////////////////////////////////////////////////////////////////*/
|
||||
|
||||
/**
|
||||
* Get an Arena object at the given location.
|
||||
* @param loc A location
|
||||
* @return an Arena object, or null
|
||||
*/
|
||||
public Arena getArenaAtLocation(Location loc) { return (ma) ? plugin.getAM().getArenaAtLocation(loc) : null; }
|
||||
public Arena getArenaAtLocation(Location loc)
|
||||
{
|
||||
return plugin.getAM().getArenaAtLocation(loc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Arena object that the given player is currently in.
|
||||
* @param p A player
|
||||
* @return an Arena object, or null
|
||||
*/
|
||||
public Arena getArenaWithPlayer(Player p) { return (ma) ? plugin.getAM().getArenaWithPlayer(p) : null; }
|
||||
public Arena getArenaWithPlayer(Player p)
|
||||
{
|
||||
return plugin.getAM().getArenaWithPlayer(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Arena object that the given pet is currently in.
|
||||
* @param wolf A pet wolf
|
||||
* @return an Arena object, or null
|
||||
*/
|
||||
public Arena getArenaWithPet(Entity wolf) { return (ma) ? plugin.getAM().getArenaWithPet(wolf) : null; }
|
||||
public Arena getArenaWithPet(Entity wolf)
|
||||
{
|
||||
return plugin.getAM().getArenaWithPet(wolf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Arena object that the given monster is currently in.
|
||||
* @param monster A monster
|
||||
* @return an Arena object, or null
|
||||
*/
|
||||
public Arena getArenaWithMonster(Entity monster) { return (ma) ? plugin.getAM().getArenaWithMonster(monster) : null; }
|
||||
|
||||
/**
|
||||
* Check if the server is running MobArena.
|
||||
* @return true, if MobArena exists on the server.
|
||||
*/
|
||||
public boolean hasMA()
|
||||
public Arena getArenaWithMonster(Entity monster)
|
||||
{
|
||||
return ma;
|
||||
return plugin.getAM().getArenaWithMonster(monster);
|
||||
}
|
||||
}
|
||||
|
@ -5,17 +5,28 @@ import org.bukkit.block.ContainerBlock;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import com.garbagemule.MobArena.util.InventoryItem;
|
||||
|
||||
public class RepairableContainer extends RepairableBlock
|
||||
{
|
||||
private ItemStack[] contents;
|
||||
private InventoryItem[] items;
|
||||
|
||||
public RepairableContainer(BlockState state, boolean clear)
|
||||
{
|
||||
super(state);
|
||||
|
||||
|
||||
// Grab the inventory and its contents
|
||||
Inventory inv = ((ContainerBlock) state).getInventory();
|
||||
contents = inv.getContents().clone();
|
||||
ItemStack[] contents = inv.getContents();
|
||||
|
||||
// Initialize the items array
|
||||
items = new InventoryItem[contents.length];
|
||||
|
||||
// Turn every ItemStack into an InventoryItem
|
||||
for (int i = 0; i < items.length; i++)
|
||||
items[i] = InventoryItem.parseItemStack(contents[i]);
|
||||
|
||||
// Clear the inventory if prompted
|
||||
if (clear) inv.clear();
|
||||
}
|
||||
|
||||
@ -31,7 +42,15 @@ public class RepairableContainer extends RepairableBlock
|
||||
{
|
||||
super.repair();
|
||||
|
||||
// Grab the inventory
|
||||
ContainerBlock cb = (ContainerBlock) getWorld().getBlockAt(getX(),getY(),getZ()).getState();
|
||||
cb.getInventory().setContents(contents);
|
||||
Inventory inv = cb.getInventory();
|
||||
|
||||
// Turn every InventoryItem into an ItemStack
|
||||
for (int i = 0; i < items.length; i++)
|
||||
{
|
||||
InventoryItem item = items[i];
|
||||
inv.setItem(i, item != null ? item.toItemStack() : null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
259
src/com/garbagemule/MobArena/util/InventoryItem.java
Normal file
259
src/com/garbagemule/MobArena/util/InventoryItem.java
Normal file
@ -0,0 +1,259 @@
|
||||
package com.garbagemule.MobArena.util;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.material.MaterialData;
|
||||
|
||||
public class InventoryItem implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 739709220350581510L;
|
||||
private int id;
|
||||
private int amount;
|
||||
private Byte data;
|
||||
private short durability;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
* @param id The data value/type id of the ItemStack
|
||||
* @param amount The amount of the stack
|
||||
* @param data The MaterialData (possibly null) of the stack
|
||||
* @param durability The durability of the stack
|
||||
*/
|
||||
public InventoryItem(int id, int amount, Byte data, short durability)
|
||||
{
|
||||
this.id = id;
|
||||
this.amount = amount;
|
||||
this.data = data;
|
||||
this.durability = durability;
|
||||
}
|
||||
|
||||
/**
|
||||
* ItemStack constructor.
|
||||
* @param stack The ItemStack to base the InventoryItem off of.
|
||||
*/
|
||||
public InventoryItem(ItemStack stack)
|
||||
{
|
||||
if (stack == null)
|
||||
id = -1;
|
||||
|
||||
id = stack.getTypeId();
|
||||
amount = stack.getAmount();
|
||||
|
||||
// In case of "odd" items, don't attempt to get data and durability
|
||||
if (id < 0) return;
|
||||
|
||||
data = stack.getData() == null ? null : stack.getData().getData();
|
||||
durability = stack.getDurability();
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method for turning a (possibly null) InventoryItem into an ItemStack.
|
||||
* The method is useful if it is unknown whether an InventoryItem object is
|
||||
* null or not.
|
||||
* @param item The Inventory item to convert
|
||||
* @return An ItemStack representation of the InventoryItem, or null
|
||||
*/
|
||||
public static ItemStack toItemStack(InventoryItem item)
|
||||
{
|
||||
if (item == null)
|
||||
return null;
|
||||
|
||||
return item.toItemStack();
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method for converting an ItemStack to an InventoryItems.
|
||||
* @param stack The ItemStack to convert
|
||||
* @return An InventoryItem representation of the ItemStack, or null
|
||||
*/
|
||||
public static InventoryItem parseItemStack(ItemStack stack)
|
||||
{
|
||||
if (stack == null)
|
||||
return new InventoryItem(-1, -1, null, (short) 0);
|
||||
|
||||
return new InventoryItem(stack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method for converting an ItemStack array to an InventoryItem array.
|
||||
* @param stacks The ItemStack array
|
||||
* @return An InventoryItem array
|
||||
*/
|
||||
public static InventoryItem[] parseItemStacks(ItemStack[] stacks)
|
||||
{
|
||||
InventoryItem[] items = new InventoryItem[stacks.length];
|
||||
|
||||
for (int i = 0; i < items.length; i++)
|
||||
items[i] = parseItemStack(stacks[i]);
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a list of ItemStacks into an array of InventoryItems
|
||||
* @param stacks List of ItemStacks to convert
|
||||
* @return An InventoryItem array
|
||||
*/
|
||||
public static InventoryItem[] parseItemStacks(List<ItemStack> stacks)
|
||||
{
|
||||
InventoryItem[] items = new InventoryItem[stacks.size()];
|
||||
|
||||
for (int i = 0; i < items.length; i++)
|
||||
items[i] = parseItemStack(stacks.get(i));
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method for extracting all InventoryItems from an InventoryItem array.
|
||||
* @param id The type id of the items to extract
|
||||
* @param items The InventoryItem array
|
||||
* @return A list of all InventoryItems removed
|
||||
*/
|
||||
public static List<InventoryItem> extractAllFromArray(int id, InventoryItem[] items)
|
||||
{
|
||||
List<InventoryItem> list = new LinkedList<InventoryItem>();
|
||||
|
||||
for (int i = 0; i < items.length; i++)
|
||||
{
|
||||
if (items[i].getTypeId() == id)
|
||||
{
|
||||
list.add(items[i]);
|
||||
items[i].setTypeId(-1);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Static method for removing an InventoryItem from an InventoryItem array.
|
||||
* @param item The InventoryItem to remove
|
||||
* @param items The InventoryItem array to remove from
|
||||
* @return true, if the item was removed successfully, false otherwise
|
||||
*/
|
||||
public static boolean removeItemFromArray(InventoryItem item, InventoryItem[] items)
|
||||
{
|
||||
// Grab the total amount to remove
|
||||
int leftToRemove = item.getAmount();
|
||||
|
||||
for (int i = 0; i < items.length; i++)
|
||||
{
|
||||
if (items[i].getTypeId() != item.getTypeId())
|
||||
continue;
|
||||
|
||||
// Grab the amount
|
||||
int amount = items[i].getAmount();
|
||||
|
||||
// Reduce amount/nullify item
|
||||
if (amount > leftToRemove)
|
||||
{
|
||||
items[i].setAmount(amount - leftToRemove);
|
||||
leftToRemove = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
items[i].setTypeId(-1);
|
||||
leftToRemove -= amount;
|
||||
}
|
||||
|
||||
// If nothing left to remove, return true.
|
||||
if (leftToRemove == 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data value/type id of the item
|
||||
* @return A type id
|
||||
*/
|
||||
public int getTypeId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the data value/type id of the item
|
||||
* @param id A type id
|
||||
*/
|
||||
public void setTypeId(int id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the amount of the item
|
||||
* @return An amount
|
||||
*/
|
||||
public int getAmount()
|
||||
{
|
||||
return amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the amount of the item
|
||||
* @param amount An amount
|
||||
*/
|
||||
public void setAmount(int amount)
|
||||
{
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the MaterialData of the item
|
||||
* @return A MaterialData
|
||||
*/
|
||||
public MaterialData getData()
|
||||
{
|
||||
return new MaterialData(id, data == null ? (byte) 0 : data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the MaterialData of the item
|
||||
* @param data A MaterialData
|
||||
*/
|
||||
public void setData(MaterialData data)
|
||||
{
|
||||
this.data = data.getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the durability of the item
|
||||
* @return The item durability
|
||||
*/
|
||||
public short getDurability()
|
||||
{
|
||||
return durability;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the durability of the item
|
||||
* @param durability An item durability
|
||||
*/
|
||||
public void setDurability(short durability)
|
||||
{
|
||||
this.durability = durability;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert this InventoryItem to an ItemStack representation
|
||||
* @return An ItemStack representation of this InventoryItem, or null if the type id is -1
|
||||
*/
|
||||
public ItemStack toItemStack()
|
||||
{
|
||||
if (id == -1)
|
||||
return null;
|
||||
|
||||
ItemStack stack = new ItemStack(id, amount, durability);
|
||||
|
||||
if (data != null)
|
||||
stack.setData(getData());
|
||||
|
||||
return stack;
|
||||
}
|
||||
}
|
@ -12,6 +12,7 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.config.Configuration;
|
||||
|
||||
import com.garbagemule.MobArena.Arena;
|
||||
import com.garbagemule.MobArena.MAUtils;
|
||||
import com.garbagemule.MobArena.MobArena;
|
||||
import com.garbagemule.MobArena.waves.*;
|
||||
import com.garbagemule.MobArena.waves.Wave.*;
|
||||
@ -20,36 +21,56 @@ public class WaveUtils
|
||||
{
|
||||
/**
|
||||
* Get all the spawnpoints that have players nearby.
|
||||
*/
|
||||
*/
|
||||
public static List<Location> getValidSpawnpoints(Arena arena, Collection<Player> players)
|
||||
{
|
||||
long start = System.nanoTime();
|
||||
List<Location> result = new ArrayList<Location>();
|
||||
|
||||
double x1 = Double.NaN, y1 = Double.NaN, z1 = Double.NaN, // Bottom
|
||||
x2 = Double.NaN, y2 = Double.NaN, z2 = Double.NaN; // Top
|
||||
|
||||
// Get the region that the players span.
|
||||
for (Player p : players)
|
||||
{
|
||||
double x = p.getLocation().getBlockX();
|
||||
double y = p.getLocation().getBlockY();
|
||||
double z = p.getLocation().getBlockZ();
|
||||
|
||||
// Initialize the coordinates if they aren't already.
|
||||
if (Double.isNaN(x1))
|
||||
{
|
||||
x1 = x; y1 = y; z1 = z; // Bottom
|
||||
x2 = x; y2 = y; z2 = z; // Top
|
||||
continue;
|
||||
}
|
||||
|
||||
// Update x
|
||||
if (x < x1) x1 = x;
|
||||
else if (x > x2) x2 = x;
|
||||
|
||||
// Update y
|
||||
if (y < y1) y1 = y;
|
||||
else if (y > y2) y2 = y;
|
||||
|
||||
// Update z
|
||||
if (z < z1) z1 = z;
|
||||
else if (z > z2) z2 = z;
|
||||
}
|
||||
|
||||
// Expand by the minimum player distance.
|
||||
x1 -= MobArena.MIN_PLAYER_DISTANCE; y1 -= MobArena.MIN_PLAYER_DISTANCE; z1 -= MobArena.MIN_PLAYER_DISTANCE;
|
||||
x2 += MobArena.MIN_PLAYER_DISTANCE; y2 += MobArena.MIN_PLAYER_DISTANCE; z2 += MobArena.MIN_PLAYER_DISTANCE;
|
||||
|
||||
for (Location s : arena.getAllSpawnpoints())
|
||||
{
|
||||
for (Player p : players)
|
||||
{
|
||||
// If the player somehow got out of the arena world, kick him.
|
||||
if (!s.getWorld().getName().equals(p.getWorld().getName()))
|
||||
{
|
||||
MobArena.info("Player '" + p.getName() + "' is not in the right world. Kicking...");
|
||||
p.kickPlayer("[MobArena] Cheater! (Warped out of the arena world.)");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (s.distanceSquared(p.getLocation()) > MobArena.MIN_PLAYER_DISTANCE)
|
||||
continue;
|
||||
|
||||
if (MAUtils.inRegion(s, x1, y1, z1, x2, y2, z2))
|
||||
result.add(s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If no players are in range, just use all the spawnpoints.
|
||||
if (result.isEmpty())
|
||||
{
|
||||
MobArena.warning("Spawnpoints of arena '" + arena.configName() + "' may be too far apart!");
|
||||
result.addAll(arena.getAllSpawnpoints());
|
||||
return arena.getAllSpawnpoints();//result.addAll(arena.getAllSpawnpoints());
|
||||
}
|
||||
|
||||
// Else, return the valid spawnpoints.
|
||||
@ -75,7 +96,7 @@ public class WaveUtils
|
||||
}
|
||||
|
||||
dist = p.getLocation().distanceSquared(e.getLocation());
|
||||
if (dist < current && dist < MobArena.MIN_PLAYER_DISTANCE)
|
||||
if (dist < current && dist < MobArena.MIN_PLAYER_DISTANCE_SQUARED)
|
||||
{
|
||||
current = dist;
|
||||
result = p;
|
||||
|
316
src/com/garbagemule/MobArena/waves/BossAbility.java
Normal file
316
src/com/garbagemule/MobArena/waves/BossAbility.java
Normal file
@ -0,0 +1,316 @@
|
||||
package com.garbagemule.MobArena.waves;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Creature;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Fireball;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import com.garbagemule.MobArena.Arena;
|
||||
import com.garbagemule.MobArena.util.WaveUtils;
|
||||
|
||||
|
||||
public enum BossAbility
|
||||
{
|
||||
ARROWS("Arrow")
|
||||
{
|
||||
public void run(Arena arena, LivingEntity boss)
|
||||
{
|
||||
boss.shootArrow();
|
||||
}
|
||||
},
|
||||
FIREBALLS("Fireball")
|
||||
{
|
||||
public void run(Arena arena, LivingEntity boss)
|
||||
{
|
||||
Location bLoc = boss.getLocation();
|
||||
Location loc = bLoc.add(bLoc.getDirection().normalize().multiply(2).toLocation(boss.getWorld(), bLoc.getYaw(), bLoc.getPitch()));
|
||||
Fireball fireball = boss.getWorld().spawn(loc, Fireball.class);
|
||||
fireball.setIsIncendiary(false);
|
||||
}
|
||||
},
|
||||
FIREAURA("Fire Aura")
|
||||
{
|
||||
public void run(Arena arena, LivingEntity boss)
|
||||
{
|
||||
for (Player p : getNearbyPlayers(arena, boss, 5))
|
||||
p.setFireTicks(20);
|
||||
}
|
||||
},
|
||||
LIGHTNINGAURA("Lightning Aura")
|
||||
{
|
||||
public void run(Arena arena, LivingEntity boss)
|
||||
{
|
||||
Location base = boss.getLocation();
|
||||
Location ne = base.getBlock().getRelative( 2, 0, 2).getLocation();
|
||||
Location nw = base.getBlock().getRelative(-2, 0, 2).getLocation();
|
||||
Location se = base.getBlock().getRelative( 2, 0, -2).getLocation();
|
||||
Location sw = base.getBlock().getRelative(-2, 0, -2).getLocation();
|
||||
|
||||
arena.getWorld().strikeLightning(ne);
|
||||
arena.getWorld().strikeLightning(nw);
|
||||
arena.getWorld().strikeLightning(se);
|
||||
arena.getWorld().strikeLightning(sw);
|
||||
}
|
||||
},
|
||||
DISORIENTTARGET("Disorient Target")
|
||||
{
|
||||
public void run(Arena arena, LivingEntity boss)
|
||||
{
|
||||
LivingEntity target = getTarget(boss);
|
||||
if (target == null) return;
|
||||
|
||||
Location loc = target.getLocation();
|
||||
loc.setYaw(target.getLocation().getYaw() + 45 + (new Random()).nextInt(270));
|
||||
target.teleport(loc);
|
||||
}
|
||||
},
|
||||
ROOTTARGET("Root Target")
|
||||
{
|
||||
public void run(final Arena arena, LivingEntity boss)
|
||||
{
|
||||
final LivingEntity target = getTarget(boss);
|
||||
if (target == null) return;
|
||||
|
||||
final Location loc = target.getLocation();
|
||||
final int freezeTaskId = Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(arena.getPlugin(),
|
||||
new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
if (arena.getLivingPlayers().contains(target))
|
||||
target.teleport(loc);
|
||||
}
|
||||
}, 3, 3);
|
||||
|
||||
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(arena.getPlugin(),
|
||||
new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
Bukkit.getServer().getScheduler().cancelTask(freezeTaskId);
|
||||
}
|
||||
}, 45);
|
||||
}
|
||||
},
|
||||
LIVINGBOMB("Living Bomb")
|
||||
{
|
||||
public void run(final Arena arena, LivingEntity boss)
|
||||
{
|
||||
final LivingEntity target = getTarget(boss);
|
||||
if (target == null) return;
|
||||
|
||||
// Set the target on fire
|
||||
target.setFireTicks(60);
|
||||
|
||||
// Create an explosion after 3 seconds
|
||||
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(arena.getPlugin(),
|
||||
new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
if (!arena.getLivingPlayers().contains(target))
|
||||
return;
|
||||
|
||||
arena.getWorld().createExplosion(target.getLocation(), 2F);
|
||||
for(Player p : getNearbyPlayers(arena, target, 3))
|
||||
p.setFireTicks(40);
|
||||
}
|
||||
}, 61);
|
||||
}
|
||||
},
|
||||
CHAINLIGHTNING("Chain Lightning")
|
||||
{
|
||||
public void run(Arena arena, LivingEntity boss)
|
||||
{
|
||||
final LivingEntity target = getTarget(boss);
|
||||
if (target == null) return;
|
||||
|
||||
strikeLightning(arena, (Player) target, new LinkedList<Player>());
|
||||
}
|
||||
|
||||
private void strikeLightning(final Arena arena, final Player p, final List<Player> done)
|
||||
{
|
||||
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(arena.getPlugin(),
|
||||
new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
if (!arena.getLivingPlayers().contains(p))
|
||||
return;
|
||||
|
||||
// Smite the target
|
||||
arena.getWorld().strikeLightning(p.getLocation());
|
||||
done.add(p);
|
||||
|
||||
// Grab all nearby players
|
||||
List<Player> nearby = getNearbyPlayers(arena, p, 4);
|
||||
|
||||
// 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);
|
||||
}
|
||||
}, 8);
|
||||
}
|
||||
},
|
||||
WARPTOPLAYER("Warp")
|
||||
{
|
||||
public void run(Arena arena, LivingEntity boss)
|
||||
{
|
||||
List<Player> list = arena.getLivingPlayers();
|
||||
boss.teleport(list.get((new Random()).nextInt(list.size())));
|
||||
}
|
||||
},
|
||||
THROWTARGET("Throw Target")
|
||||
{
|
||||
public void run(Arena arena, LivingEntity boss)
|
||||
{
|
||||
LivingEntity target = getTarget(boss);
|
||||
if (target == null) return;
|
||||
|
||||
Location bLoc = boss.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));
|
||||
}
|
||||
},
|
||||
THROWNEARBY("Throw Nearby Players")
|
||||
{
|
||||
public void run(Arena arena, LivingEntity boss)
|
||||
{
|
||||
for (Player p : getNearbyPlayers(arena, boss, 5))
|
||||
{
|
||||
Location bLoc = boss.getLocation();
|
||||
Location loc = p.getLocation();
|
||||
Vector v = new Vector(loc.getX() - bLoc.getX(), 0, loc.getZ() - bLoc.getZ());
|
||||
p.setVelocity(v.normalize().setY(0.8));
|
||||
}
|
||||
}
|
||||
},
|
||||
THROWDISTANT("Throw Distant Players")
|
||||
{
|
||||
public void run(Arena arena, LivingEntity boss)
|
||||
{
|
||||
for (Player p : getDistantPlayers(arena, boss, 8))
|
||||
{
|
||||
Location bLoc = boss.getLocation();
|
||||
Location loc = p.getLocation();
|
||||
Vector v = new Vector(loc.getX() - bLoc.getX(), 0, loc.getZ() - bLoc.getZ());
|
||||
p.setVelocity(v.normalize().setY(0.8));
|
||||
}
|
||||
}
|
||||
},
|
||||
FETCHTARGET("Fetch Target")
|
||||
{
|
||||
public void run(Arena arena, LivingEntity boss)
|
||||
{
|
||||
LivingEntity target = getTarget(boss);
|
||||
if (target != null) target.teleport(boss);
|
||||
}
|
||||
},
|
||||
FETCHNEARBY("Fetch Nearby Players")
|
||||
{
|
||||
public void run(Arena arena, LivingEntity boss)
|
||||
{
|
||||
for (Player p : getNearbyPlayers(arena, boss, 5))
|
||||
p.teleport(boss);
|
||||
}
|
||||
},
|
||||
FETCHDISTANT("Fetch Distant Players")
|
||||
{
|
||||
public void run(Arena arena, LivingEntity boss)
|
||||
{
|
||||
for (Player p : getDistantPlayers(arena, boss, 8))
|
||||
p.teleport(boss);
|
||||
}
|
||||
};
|
||||
|
||||
private String name;
|
||||
|
||||
private BossAbility(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* The run-method that all boss abilities must define.
|
||||
* The method is called in the ability cycle for the given boss.
|
||||
* @param arena The Arena the boss is in
|
||||
* @param boss The boss entity
|
||||
*/
|
||||
public abstract void run(Arena arena, LivingEntity boss);
|
||||
|
||||
/**
|
||||
* Get the target player of the LivingEntity if possible.
|
||||
* @param entity The entity whose target to get
|
||||
* @return The target player, or null
|
||||
*/
|
||||
protected LivingEntity getTarget(LivingEntity entity)
|
||||
{
|
||||
if (entity instanceof Creature)
|
||||
{
|
||||
LivingEntity target = null;
|
||||
try
|
||||
{
|
||||
target = ((Creature) entity).getTarget();
|
||||
}
|
||||
catch (Exception e) {}
|
||||
|
||||
if (target instanceof Player)
|
||||
return target;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of nearby players
|
||||
* @param arena The arena
|
||||
* @param boss The boss
|
||||
* @param x The 'radius' in which to grab players
|
||||
* @return A list of nearby players
|
||||
*/
|
||||
protected List<Player> getNearbyPlayers(Arena arena, Entity boss, int x)
|
||||
{
|
||||
List<Player> result = new LinkedList<Player>();
|
||||
for (Entity e : boss.getNearbyEntities(x, x, x))
|
||||
if (arena.getLivingPlayers().contains(e))
|
||||
result.add((Player) e);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of distant players
|
||||
* @param arena The arena
|
||||
* @param boss The boss
|
||||
* @param x The 'radius' in which to exclude players
|
||||
* @return A list of distant players
|
||||
*/
|
||||
protected List<Player> getDistantPlayers(Arena arena, Entity boss, int x)
|
||||
{
|
||||
List<Player> result = new LinkedList<Player>();
|
||||
for (Player p : arena.getLivingPlayers())
|
||||
if (p.getLocation().distanceSquared(boss.getLocation()) > x*x)
|
||||
result.add(p);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static BossAbility fromString(String string)
|
||||
{
|
||||
return WaveUtils.getEnumFromString(BossAbility.class, string);
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
@ -9,8 +9,8 @@ import org.bukkit.Location;
|
||||
import org.bukkit.util.config.Configuration;
|
||||
|
||||
import com.garbagemule.MobArena.Arena;
|
||||
import com.garbagemule.MobArena.MAMessages.Msg;
|
||||
import com.garbagemule.MobArena.MAUtils;
|
||||
import com.garbagemule.MobArena.MAMessages.Msg;
|
||||
import com.garbagemule.MobArena.util.WaveUtils;
|
||||
|
||||
public class DefaultWave extends NormalWave
|
||||
|
@ -9,6 +9,7 @@ import org.bukkit.entity.Slime;
|
||||
import org.bukkit.entity.Wolf;
|
||||
|
||||
import com.garbagemule.MobArena.Arena;
|
||||
import com.garbagemule.MobArena.MobArena;
|
||||
import com.garbagemule.MobArena.util.WaveUtils;
|
||||
|
||||
public enum MACreature
|
||||
@ -25,7 +26,6 @@ public enum MACreature
|
||||
POWERED_CREEPER(CreatureType.CREEPER), POWERED_CREEPERS(CreatureType.CREEPER),
|
||||
ANGRY_WOLF(CreatureType.WOLF), ANGRY_WOLVES(CreatureType.WOLF),
|
||||
HUMAN(CreatureType.MONSTER), HUMANS(CreatureType.MONSTER),
|
||||
SLIME(CreatureType.SLIME), SLIMES(CreatureType.SLIME),
|
||||
GIANT(CreatureType.GIANT), GIANTS(CreatureType.GIANT),
|
||||
GHAST(CreatureType.GHAST), GHASTS(CreatureType.GHAST),
|
||||
|
||||
@ -33,7 +33,18 @@ public enum MACreature
|
||||
CHICKEN(CreatureType.CHICKEN), CHICKENS(CreatureType.CHICKEN),
|
||||
COW(CreatureType.COW), COWS(CreatureType.COW),
|
||||
PIG(CreatureType.PIG), PIGS(CreatureType.PIG),
|
||||
SHEEP(CreatureType.SHEEP), EXPLODING_SHEEP(CreatureType.SHEEP);
|
||||
SHEEP(CreatureType.SHEEP),
|
||||
SQUID(CreatureType.SQUID), SQUIDS(CreatureType.SQUID),
|
||||
|
||||
// Extended creatures
|
||||
EXPLODING_SHEEP(CreatureType.SHEEP),
|
||||
|
||||
// Slimes
|
||||
SLIME(CreatureType.SLIME), SLIMES(CreatureType.SLIME),
|
||||
SLIME_TINY(CreatureType.SLIME), SLIMES_TINY(CreatureType.SLIME),
|
||||
SLIME_SMALL(CreatureType.SLIME), SLIMES_SMALL(CreatureType.SLIME),
|
||||
SLIME_BIG(CreatureType.SLIME), SLIMES_BIG(CreatureType.SLIME),
|
||||
SLIME_HUGE(CreatureType.SLIME), SLIMES_HUGE(CreatureType.SLIME);
|
||||
|
||||
private CreatureType type;
|
||||
|
||||
@ -68,31 +79,26 @@ public enum MACreature
|
||||
case ANGRY_WOLVES:
|
||||
((Wolf) e).setAngry(true);
|
||||
break;
|
||||
case SLIME:
|
||||
case SLIMES:
|
||||
((Slime) e).setSize( (1 + MobArena.random.nextInt(3)) );
|
||||
break;
|
||||
case SLIME_TINY:
|
||||
case SLIMES_TINY:
|
||||
((Slime) e).setSize(1);
|
||||
break;
|
||||
case SLIME_SMALL:
|
||||
case SLIMES_SMALL:
|
||||
((Slime) e).setSize(2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
public static LivingEntity spawn(MACreature creature, World world, Location loc)
|
||||
{
|
||||
LivingEntity e = world.spawnCreature(loc, creature.type);
|
||||
|
||||
switch (creature)
|
||||
{
|
||||
case POWERED_CREEPERS:
|
||||
((Creeper) e).setPowered(true);
|
||||
case SLIME_BIG:
|
||||
case SLIMES_BIG:
|
||||
((Slime) e).setSize(3);
|
||||
break;
|
||||
case ANGRY_WOLVES:
|
||||
((Wolf) e).setAngry(true);
|
||||
case SLIME_HUGE:
|
||||
case SLIMES_HUGE:
|
||||
((Slime) e).setSize(4);
|
||||
break;
|
||||
case SLIMES:
|
||||
((Slime) e).setSize(2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1,18 +1,5 @@
|
||||
package com.garbagemule.MobArena.waves;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Creature;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Fireball;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import com.garbagemule.MobArena.Arena;
|
||||
import com.garbagemule.MobArena.util.WaveUtils;
|
||||
|
||||
@ -59,246 +46,10 @@ public interface Wave
|
||||
return (int) ( base * Math.pow(w, exp) );
|
||||
}
|
||||
}
|
||||
|
||||
public enum BossAbility
|
||||
{
|
||||
ARROWS("Arrow")
|
||||
{
|
||||
public void run(Arena arena, LivingEntity boss)
|
||||
{
|
||||
boss.shootArrow();
|
||||
}
|
||||
},
|
||||
FIREBALLS("Fireball")
|
||||
{
|
||||
public void run(Arena arena, LivingEntity boss)
|
||||
{
|
||||
Location bLoc = boss.getLocation();
|
||||
Location loc = bLoc.add(bLoc.getDirection().normalize().multiply(2).toLocation(boss.getWorld(), bLoc.getYaw(), bLoc.getPitch()));
|
||||
Fireball fireball = boss.getWorld().spawn(loc, Fireball.class);
|
||||
fireball.setIsIncendiary(false);
|
||||
}
|
||||
},
|
||||
FIREAURA("Fire aura")
|
||||
{
|
||||
public void run(Arena arena, LivingEntity boss)
|
||||
{
|
||||
for (Player p : getNearbyPlayers(arena, boss, 5))
|
||||
p.setFireTicks(20);
|
||||
}
|
||||
},
|
||||
LIGHTNINGAURA("Lightning aura")
|
||||
{
|
||||
public void run(Arena arena, LivingEntity boss)
|
||||
{
|
||||
Location base = boss.getLocation();
|
||||
Location ne = base.getBlock().getRelative( 2, 0, 2).getLocation();
|
||||
Location nw = base.getBlock().getRelative(-2, 0, 2).getLocation();
|
||||
Location se = base.getBlock().getRelative( 2, 0, -2).getLocation();
|
||||
Location sw = base.getBlock().getRelative(-2, 0, -2).getLocation();
|
||||
|
||||
arena.getWorld().strikeLightning(ne);
|
||||
arena.getWorld().strikeLightning(nw);
|
||||
arena.getWorld().strikeLightning(se);
|
||||
arena.getWorld().strikeLightning(sw);
|
||||
}
|
||||
},
|
||||
DISORIENTTARGET("Disorient target")
|
||||
{
|
||||
public void run(Arena arena, LivingEntity boss)
|
||||
{
|
||||
LivingEntity target = getTarget(boss);
|
||||
if (target == null) return;
|
||||
|
||||
Location loc = target.getLocation();
|
||||
loc.setYaw(target.getLocation().getYaw() + 45 + (new Random()).nextInt(270));
|
||||
target.teleport(loc);
|
||||
}
|
||||
},
|
||||
ROOTTARGET("Root target")
|
||||
{
|
||||
public void run(final Arena arena, LivingEntity boss)
|
||||
{
|
||||
final LivingEntity target = getTarget(boss);
|
||||
if (target == null) return;
|
||||
|
||||
final Location loc = target.getLocation();
|
||||
final int freezeTaskId = Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(arena.getPlugin(),
|
||||
new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
if (arena.getLivingPlayers().contains(target))
|
||||
target.teleport(loc);
|
||||
}
|
||||
}, 3, 3);
|
||||
|
||||
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(arena.getPlugin(),
|
||||
new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
Bukkit.getServer().getScheduler().cancelTask(freezeTaskId);
|
||||
}
|
||||
}, 45);
|
||||
}
|
||||
},
|
||||
WARPTOPLAYER("Warp to player")
|
||||
{
|
||||
public void run(Arena arena, LivingEntity boss)
|
||||
{
|
||||
List<Player> list = arena.getLivingPlayers();
|
||||
boss.teleport(list.get((new Random()).nextInt(list.size())));
|
||||
}
|
||||
},
|
||||
THROWTARGET("Throw target")
|
||||
{
|
||||
public void run(Arena arena, LivingEntity boss)
|
||||
{
|
||||
System.out.println("Throw target");
|
||||
LivingEntity target = getTarget(boss);
|
||||
if (target == null) return;
|
||||
|
||||
Location bLoc = boss.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));
|
||||
}
|
||||
},
|
||||
THROWNEARBY("Throw nearby players")
|
||||
{
|
||||
public void run(Arena arena, LivingEntity boss)
|
||||
{
|
||||
for (Player p : getNearbyPlayers(arena, boss, 5))
|
||||
{
|
||||
Location bLoc = boss.getLocation();
|
||||
Location loc = p.getLocation();
|
||||
Vector v = new Vector(loc.getX() - bLoc.getX(), 0, loc.getZ() - bLoc.getZ());
|
||||
p.setVelocity(v.normalize().setY(0.8));
|
||||
}
|
||||
}
|
||||
},
|
||||
THROWDISTANT("Throw distant players")
|
||||
{
|
||||
public void run(Arena arena, LivingEntity boss)
|
||||
{
|
||||
for (Player p : getDistantPlayers(arena, boss, 8))
|
||||
{
|
||||
Location bLoc = boss.getLocation();
|
||||
Location loc = p.getLocation();
|
||||
Vector v = new Vector(loc.getX() - bLoc.getX(), 0, loc.getZ() - bLoc.getZ());
|
||||
p.setVelocity(v.normalize().setY(0.8));
|
||||
}
|
||||
}
|
||||
},
|
||||
FETCHTARGET("Fetch target")
|
||||
{
|
||||
public void run(Arena arena, LivingEntity boss)
|
||||
{
|
||||
LivingEntity target = getTarget(boss);
|
||||
if (target != null) target.teleport(boss);
|
||||
}
|
||||
},
|
||||
FETCHNEARBY("Fetch nearby players")
|
||||
{
|
||||
public void run(Arena arena, LivingEntity boss)
|
||||
{
|
||||
for (Player p : getNearbyPlayers(arena, boss, 5))
|
||||
p.teleport(boss);
|
||||
}
|
||||
},
|
||||
FETCHDISTANT("Fetch distant players")
|
||||
{
|
||||
public void run(Arena arena, LivingEntity boss)
|
||||
{
|
||||
for (Player p : getDistantPlayers(arena, boss, 8))
|
||||
p.teleport(boss);
|
||||
}
|
||||
};
|
||||
|
||||
private String name;
|
||||
|
||||
private BossAbility(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* The run-method that all boss abilities must define.
|
||||
* The method is called in the ability cycle for the given boss.
|
||||
* @param arena The Arena the boss is in
|
||||
* @param boss The boss entity
|
||||
*/
|
||||
public abstract void run(Arena arena, LivingEntity boss);
|
||||
|
||||
/**
|
||||
* Get the target player of the LivingEntity if possible.
|
||||
* @param entity The entity whose target to get
|
||||
* @return The target player, or null
|
||||
*/
|
||||
protected LivingEntity getTarget(LivingEntity entity)
|
||||
{
|
||||
if (entity instanceof Creature)
|
||||
{
|
||||
LivingEntity target = null;
|
||||
try
|
||||
{
|
||||
target = ((Creature) entity).getTarget();
|
||||
}
|
||||
catch (Exception e) {}
|
||||
|
||||
if (target instanceof Player)
|
||||
return target;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of nearby players
|
||||
* @param arena The arena
|
||||
* @param boss The boss
|
||||
* @param x The 'radius' in which to grab players
|
||||
* @return A list of nearby players
|
||||
*/
|
||||
protected List<Player> getNearbyPlayers(Arena arena, Entity boss, int x)
|
||||
{
|
||||
List<Player> result = new LinkedList<Player>();
|
||||
for (Entity e : boss.getNearbyEntities(x, x, x))
|
||||
if (arena.getLivingPlayers().contains(e))
|
||||
result.add((Player) e);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of distant players
|
||||
* @param arena The arena
|
||||
* @param boss The boss
|
||||
* @param x The 'radius' in which to exclude players
|
||||
* @return A list of distant players
|
||||
*/
|
||||
protected List<Player> getDistantPlayers(Arena arena, Entity boss, int x)
|
||||
{
|
||||
List<Player> result = new LinkedList<Player>();
|
||||
for (Player p : arena.getLivingPlayers())
|
||||
if (p.getLocation().distanceSquared(boss.getLocation()) > x*x)
|
||||
result.add(p);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static BossAbility fromString(String string)
|
||||
{
|
||||
return WaveUtils.getEnumFromString(BossAbility.class, string);
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
public enum BossHealth
|
||||
{
|
||||
LOW(5), MEDIUM(9), HIGH(14), PSYCHO(25);
|
||||
LOW(8), MEDIUM(15), HIGH(25), PSYCHO(40);
|
||||
private int multiplier;
|
||||
|
||||
private BossHealth(int multiplier)
|
||||
|
Loading…
Reference in New Issue
Block a user