v0.92 - Added multiple arenas, pet classes, Permissions, etc. and rewrote most of the code
This commit is contained in:
@@ -1,583 +0,0 @@
|
|||||||
package com.garbagemule.MobArena;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.bukkit.ChatColor;
|
|
||||||
import org.bukkit.Chunk;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.Server;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.entity.Entity;
|
|
||||||
import org.bukkit.entity.Item;
|
|
||||||
import org.bukkit.entity.LivingEntity;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.entity.Slime;
|
|
||||||
import org.bukkit.util.config.Configuration;
|
|
||||||
|
|
||||||
public class ArenaManager
|
|
||||||
{
|
|
||||||
// Convenience variables.
|
|
||||||
protected static MobArena plugin = null;
|
|
||||||
protected static Server server = null;
|
|
||||||
protected static World world = null;
|
|
||||||
protected static Location arenaLoc = null;
|
|
||||||
protected static Location lobbyLoc = null;
|
|
||||||
protected static Location spectatorLoc = null;
|
|
||||||
protected static boolean isRunning = false;
|
|
||||||
protected static boolean isSetup = false;
|
|
||||||
protected static boolean isEnabled = true;
|
|
||||||
protected static boolean isProtected = true;
|
|
||||||
protected static int wave = 0;
|
|
||||||
protected static int spawnTaskId = -1;
|
|
||||||
protected static int waveDelay, waveInterval, specialModulo, repairDelay;
|
|
||||||
protected static boolean checkUpdates, lightning, spawnMonsters;
|
|
||||||
protected static int spawnMonstersInt;
|
|
||||||
protected static MASpawnThread spawnThread = null;
|
|
||||||
|
|
||||||
// Location variables for the arena region.
|
|
||||||
protected static Location p1 = null;
|
|
||||||
protected static Location p2 = null;
|
|
||||||
|
|
||||||
// Configuration
|
|
||||||
protected static Configuration config = null;
|
|
||||||
|
|
||||||
// Spawn locations list and monster distribution fields.
|
|
||||||
protected static List<Location> spawnpoints = new ArrayList<Location>();
|
|
||||||
protected static int dZombies, dSkeletons, dSpiders, dCreepers, dWolves;
|
|
||||||
protected static int dPoweredCreepers, dPigZombies, dSlimes, dMonsters,
|
|
||||||
dAngryWolves, dGiants, dGhasts;
|
|
||||||
|
|
||||||
// Sets and Maps for storing players, their locations, and their rewards.
|
|
||||||
protected static Set<Player> playerSet = new HashSet<Player>();
|
|
||||||
protected static Set<Player> readySet = new HashSet<Player>();
|
|
||||||
protected static Map<Player,String> rewardMap = new HashMap<Player,String>();
|
|
||||||
protected static Map<Player,Location> locationMap = new HashMap<Player,Location>();
|
|
||||||
|
|
||||||
// Maps for storing player classes, class items and armor.
|
|
||||||
protected static List<String> classes = new ArrayList<String>();
|
|
||||||
protected static Map<Player,String> classMap = new HashMap<Player,String>();
|
|
||||||
protected static Map<String,String> classItemMap = new HashMap<String,String>();
|
|
||||||
protected static Map<String,String> classArmorMap = new HashMap<String,String>();
|
|
||||||
|
|
||||||
// Maps for rewards.
|
|
||||||
protected static Map<Integer,String> everyWaveMap = new HashMap<Integer,String>();
|
|
||||||
protected static Map<Integer,String> afterWaveMap = new HashMap<Integer,String>();
|
|
||||||
|
|
||||||
// Entities, blocks and items on MobArena floor.
|
|
||||||
protected static Set<LivingEntity> monsterSet = new HashSet<LivingEntity>();
|
|
||||||
protected static Set<Block> blockSet = new HashSet<Block>();
|
|
||||||
|
|
||||||
// Hook listeners
|
|
||||||
protected static Set<MobArenaListener> listeners = new HashSet<MobArenaListener>();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ///////////////////////////////////////////////////////////////////// //
|
|
||||||
|
|
||||||
INITIALIZATION AND UPDATE METHODS
|
|
||||||
|
|
||||||
// ///////////////////////////////////////////////////////////////////// */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the ArenaManager.
|
|
||||||
*/
|
|
||||||
public static void init(MobArena instance)
|
|
||||||
{
|
|
||||||
// If instance == null, simply update location variables.
|
|
||||||
if (instance != null)
|
|
||||||
{
|
|
||||||
// General variables.
|
|
||||||
config = MAUtils.getConfig();
|
|
||||||
plugin = instance;
|
|
||||||
server = plugin.getServer();
|
|
||||||
world = MAUtils.getWorld();
|
|
||||||
lightning = MAUtils.getBoolean("settings.lightning", true);
|
|
||||||
repairDelay = MAUtils.getInt("settings.repairdelay", 5);
|
|
||||||
spawnMonsters = MAUtils.spawnBypass(false);
|
|
||||||
|
|
||||||
// Class list and maps.
|
|
||||||
classes = MAUtils.getClasses();
|
|
||||||
classItemMap = MAUtils.getClassItems("items");
|
|
||||||
classArmorMap = MAUtils.getClassItems("armor");
|
|
||||||
|
|
||||||
// Waves and rewards.
|
|
||||||
waveDelay = MAUtils.getInt("settings.firstwavedelay", 5) * 20;
|
|
||||||
waveInterval = MAUtils.getInt("settings.waveinterval", 20) * 20;
|
|
||||||
specialModulo = MAUtils.getInt("settings.specialmodulo", 4);
|
|
||||||
everyWaveMap = MAUtils.getWaveMap("every");
|
|
||||||
afterWaveMap = MAUtils.getWaveMap("after");
|
|
||||||
|
|
||||||
// Monster distribution coefficients.
|
|
||||||
dZombies = MAUtils.getDistribution("zombies");
|
|
||||||
dSkeletons = MAUtils.getDistribution("skeletons");
|
|
||||||
dSpiders = MAUtils.getDistribution("spiders");
|
|
||||||
dCreepers = MAUtils.getDistribution("creepers");
|
|
||||||
dWolves = MAUtils.getDistribution("wolves");
|
|
||||||
|
|
||||||
dPoweredCreepers = MAUtils.getDistribution("poweredcreepers", "special");
|
|
||||||
dPigZombies = MAUtils.getDistribution("zombiepigmen", "special");
|
|
||||||
dSlimes = MAUtils.getDistribution("slimes", "special");
|
|
||||||
dMonsters = MAUtils.getDistribution("humans", "special");
|
|
||||||
dAngryWolves = MAUtils.getDistribution("angrywolves", "special");
|
|
||||||
dGiants = MAUtils.getDistribution("giants", "special");
|
|
||||||
dGhasts = MAUtils.getDistribution("ghasts", "special");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convenience variables.
|
|
||||||
arenaLoc = MAUtils.getCoords("arena");
|
|
||||||
lobbyLoc = MAUtils.getCoords("lobby");
|
|
||||||
spectatorLoc = MAUtils.getCoords("spectator");
|
|
||||||
p1 = MAUtils.getCoords("p1");
|
|
||||||
p2 = MAUtils.getCoords("p2");
|
|
||||||
spawnpoints = MAUtils.getSpawnPoints();
|
|
||||||
checkUpdates = MAUtils.getBoolean("settings.updatenotification", true);
|
|
||||||
|
|
||||||
// Set the boolean if all variables are valid.
|
|
||||||
ArenaManager.isSetup = MAUtils.verifyData();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates all relevant variables.
|
|
||||||
*/
|
|
||||||
public static void updateVariables()
|
|
||||||
{
|
|
||||||
init(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ///////////////////////////////////////////////////////////////////// //
|
|
||||||
|
|
||||||
ARENA METHODS
|
|
||||||
|
|
||||||
// ///////////////////////////////////////////////////////////////////// */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the current MobArena session.
|
|
||||||
*/
|
|
||||||
public static void startArena()
|
|
||||||
{
|
|
||||||
isRunning = true;
|
|
||||||
readySet.clear();
|
|
||||||
MAUtils.spawnBypass(true);
|
|
||||||
|
|
||||||
// Clear the floor for good measure.
|
|
||||||
clearEntities();
|
|
||||||
|
|
||||||
for (Player p : playerSet)
|
|
||||||
{
|
|
||||||
p.teleport(arenaLoc);
|
|
||||||
rewardMap.put(p,"");
|
|
||||||
}
|
|
||||||
|
|
||||||
spawnThread = new MASpawnThread();
|
|
||||||
spawnTaskId = server.getScheduler().scheduleSyncRepeatingTask(plugin,spawnThread,(long)waveDelay,(long)waveInterval);
|
|
||||||
|
|
||||||
tellAll("Let the slaughter begin!");
|
|
||||||
|
|
||||||
for (MobArenaListener m : listeners)
|
|
||||||
m.onArenaStart();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ends the current MobArena session.
|
|
||||||
* Clears the arena floor, gives all the players their rewards,
|
|
||||||
* and stops the spawning of monsters.
|
|
||||||
*/
|
|
||||||
public static void endArena()
|
|
||||||
{
|
|
||||||
isRunning = false;
|
|
||||||
wave = 0;
|
|
||||||
server.getScheduler().cancelTask(spawnTaskId);
|
|
||||||
MAUtils.spawnBypass(true);
|
|
||||||
|
|
||||||
killMonsters();
|
|
||||||
clearBlocks();
|
|
||||||
clearEntities();
|
|
||||||
giveRewards();
|
|
||||||
|
|
||||||
tellAll("Arena finished.");
|
|
||||||
|
|
||||||
for (MobArenaListener m : listeners)
|
|
||||||
m.onArenaEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempts to let a player join the arena session.
|
|
||||||
* Players must have an empty inventory to join the arena. Their
|
|
||||||
* location will be stored for when they leave.
|
|
||||||
*/
|
|
||||||
public static void playerJoin(Player p)
|
|
||||||
{
|
|
||||||
if (!isEnabled)
|
|
||||||
{
|
|
||||||
tellPlayer(p, "MobArena is not enabled.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!isSetup)
|
|
||||||
{
|
|
||||||
tellPlayer(p, "MobArena has not been set up yet!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (playerSet.contains(p))
|
|
||||||
{
|
|
||||||
tellPlayer(p, "You are already playing!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (isRunning)
|
|
||||||
{
|
|
||||||
tellPlayer(p, "Arena in progress. Type /ma spec to watch.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!MAUtils.hasEmptyInventory(p))
|
|
||||||
{
|
|
||||||
tellPlayer(p, "You must empty your inventory to join the arena.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
playerSet.add(p);
|
|
||||||
|
|
||||||
if (!locationMap.containsKey(p))
|
|
||||||
{
|
|
||||||
locationMap.put(p, p.getLocation());
|
|
||||||
}
|
|
||||||
|
|
||||||
p.teleport(lobbyLoc);
|
|
||||||
|
|
||||||
tellPlayer(p, "You joined the arena. Have fun!");
|
|
||||||
|
|
||||||
for (MobArenaListener m : listeners)
|
|
||||||
m.onPlayerJoin(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempts to remove a player from the arena session.
|
|
||||||
* The player is teleported back to his previous location, and
|
|
||||||
* is removed from all the sets and maps.
|
|
||||||
*/
|
|
||||||
public static void playerLeave(Player p)
|
|
||||||
{
|
|
||||||
if (!locationMap.containsKey(p))
|
|
||||||
{
|
|
||||||
tellPlayer(p, "You are not in the arena.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This must occur before playerSet.remove(p) to avoid teleport block.
|
|
||||||
p.teleport(locationMap.get(p));
|
|
||||||
locationMap.remove(p);
|
|
||||||
readySet.remove(p);
|
|
||||||
classMap.remove(p);
|
|
||||||
|
|
||||||
if (playerSet.remove(p))
|
|
||||||
MAUtils.clearInventory(p);
|
|
||||||
|
|
||||||
if (isRunning && playerSet.isEmpty())
|
|
||||||
endArena();
|
|
||||||
|
|
||||||
if (!readySet.isEmpty() && readySet.equals(playerSet))
|
|
||||||
startArena();
|
|
||||||
|
|
||||||
tellPlayer(p, "You left the arena. Thanks for playing!");
|
|
||||||
|
|
||||||
for (MobArenaListener m : listeners)
|
|
||||||
m.onPlayerLeave(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a joined arena player to the set of ready players.
|
|
||||||
*/
|
|
||||||
public static void playerReady(Player p)
|
|
||||||
{
|
|
||||||
readySet.add(p);
|
|
||||||
|
|
||||||
if (readySet.equals(playerSet))
|
|
||||||
startArena();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes a dead player from the arena session.
|
|
||||||
* The player is teleported safely back to the spectator area,
|
|
||||||
* and their health is restored. All sets and maps are updated.
|
|
||||||
* If this was the last player alive, the arena session ends.
|
|
||||||
*/
|
|
||||||
public static void playerDeath(Player p)
|
|
||||||
{
|
|
||||||
p.teleport(spectatorLoc);
|
|
||||||
MAUtils.clearInventory(p);
|
|
||||||
p.setFireTicks(0);
|
|
||||||
p.setHealth(20);
|
|
||||||
tellAll(p.getName() + " died!");
|
|
||||||
|
|
||||||
playerSet.remove(p);
|
|
||||||
classMap.remove(p);
|
|
||||||
|
|
||||||
if (isRunning && playerSet.isEmpty())
|
|
||||||
endArena();
|
|
||||||
|
|
||||||
for (MobArenaListener m : listeners)
|
|
||||||
m.onPlayerDeath(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Lets a player spectate the current arena session.
|
|
||||||
*/
|
|
||||||
public static void playerSpectate(Player p)
|
|
||||||
{
|
|
||||||
if (!playerSet.contains(p))
|
|
||||||
{
|
|
||||||
p.teleport(spectatorLoc);
|
|
||||||
tellPlayer(p, "Enjoy the show!");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tellPlayer(p, "Can't spectate when in the arena!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prints the list of players currently in the arena session.
|
|
||||||
*/
|
|
||||||
public static void playerList(Player p)
|
|
||||||
{
|
|
||||||
if (playerSet.isEmpty())
|
|
||||||
{
|
|
||||||
tellPlayer(p, "There is no one in the arena right now.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuffer list = new StringBuffer();
|
|
||||||
final String SEPARATOR = ", ";
|
|
||||||
for (Player player : playerSet)
|
|
||||||
{
|
|
||||||
list.append(player.getName());
|
|
||||||
list.append(SEPARATOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
tellPlayer(p, "Survivors: " + list.substring(0, list.length() - 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prints the list of players who aren't ready.
|
|
||||||
*/
|
|
||||||
public static void notReadyList(Player p)
|
|
||||||
{
|
|
||||||
if (!playerSet.contains(p) || isRunning)
|
|
||||||
{
|
|
||||||
tellPlayer(p, "You aren't in the lobby!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<Player> notReadySet = new HashSet<Player>(playerSet);
|
|
||||||
notReadySet.removeAll(readySet);
|
|
||||||
|
|
||||||
StringBuffer list = new StringBuffer();
|
|
||||||
final String SEPARATOR = ", ";
|
|
||||||
for (Player player : notReadySet)
|
|
||||||
{
|
|
||||||
list.append(player.getName());
|
|
||||||
list.append(SEPARATOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
tellPlayer(p, "Not ready: " + list.substring(0, list.length() - 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Forcefully starts the arena, causing all players in the
|
|
||||||
* playerSet who aren't ready to leave, and starting the
|
|
||||||
* arena for everyone else.
|
|
||||||
*/
|
|
||||||
public static void forceStart(Player p)
|
|
||||||
{
|
|
||||||
if (ArenaManager.isRunning)
|
|
||||||
{
|
|
||||||
ArenaManager.tellPlayer(p, "Arena has already started.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (ArenaManager.readySet.isEmpty())
|
|
||||||
{
|
|
||||||
ArenaManager.tellPlayer(p, "Can't force start, no players are ready.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<Player> set = new HashSet<Player>(playerSet);
|
|
||||||
for (Player player : set)
|
|
||||||
{
|
|
||||||
if (!ArenaManager.readySet.contains(player))
|
|
||||||
ArenaManager.playerLeave(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
ArenaManager.tellPlayer(p, "Forced arena start.");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Forcefully ends the arena, causing all players to leave and
|
|
||||||
* all relevant sets and maps to be cleared.
|
|
||||||
*/
|
|
||||||
public static void forceEnd(Player p)
|
|
||||||
{
|
|
||||||
if (ArenaManager.playerSet.isEmpty())
|
|
||||||
{
|
|
||||||
ArenaManager.tellPlayer(p, "No one is in the arena.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<Player> set = new HashSet<Player>(playerSet);
|
|
||||||
for (Player player : set)
|
|
||||||
ArenaManager.playerLeave(player);
|
|
||||||
|
|
||||||
// Just for good measure.
|
|
||||||
endArena();
|
|
||||||
|
|
||||||
ArenaManager.tellPlayer(p, "Forced arena end.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ///////////////////////////////////////////////////////////////////// //
|
|
||||||
|
|
||||||
CLEANUP METHODS
|
|
||||||
|
|
||||||
// ///////////////////////////////////////////////////////////////////// */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Kills all monsters currently on the arena floor.
|
|
||||||
*/
|
|
||||||
public static void killMonsters()
|
|
||||||
{
|
|
||||||
// Remove all monsters, then clear the Set.
|
|
||||||
for (LivingEntity e : monsterSet)
|
|
||||||
{
|
|
||||||
if (!e.isDead())
|
|
||||||
e.remove();
|
|
||||||
}
|
|
||||||
monsterSet.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes all the blocks on the arena floor.
|
|
||||||
*/
|
|
||||||
public static void clearBlocks()
|
|
||||||
{
|
|
||||||
// Remove all blocks, then clear the Set.
|
|
||||||
for (Block b : blockSet)
|
|
||||||
b.setType(Material.AIR);
|
|
||||||
|
|
||||||
blockSet.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes all items and slimes in the arena region.
|
|
||||||
*/
|
|
||||||
public static void clearEntities()
|
|
||||||
{
|
|
||||||
Chunk c1 = world.getChunkAt(p1);
|
|
||||||
Chunk c2 = world.getChunkAt(p2);
|
|
||||||
|
|
||||||
/* Yes, ugly nesting, but it's necessary. This bit
|
|
||||||
* removes all the entities in the arena region without
|
|
||||||
* bloatfully iterating through all entities in the
|
|
||||||
* world. Much faster on large servers especially. */
|
|
||||||
for (int i = c1.getX(); i <= c2.getX(); i++)
|
|
||||||
for (int j = c1.getZ(); j <= c2.getZ(); j++)
|
|
||||||
for (Entity e : world.getChunkAt(i,j).getEntities())
|
|
||||||
if ((e instanceof Item) || (e instanceof Slime))
|
|
||||||
e.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ///////////////////////////////////////////////////////////////////// //
|
|
||||||
|
|
||||||
CLASS AND REWARD METHODS
|
|
||||||
|
|
||||||
// ///////////////////////////////////////////////////////////////////// */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assigns a class to the player.
|
|
||||||
*/
|
|
||||||
public static void assignClass(Player p, String className)
|
|
||||||
{
|
|
||||||
classMap.put(p, className);
|
|
||||||
giveClassItems(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Grant a player their class-specific items.
|
|
||||||
*/
|
|
||||||
public static void giveClassItems(Player p)
|
|
||||||
{
|
|
||||||
String className = classMap.get(p);
|
|
||||||
String classItems = classItemMap.get(className);
|
|
||||||
String classArmor = classArmorMap.get(className);
|
|
||||||
|
|
||||||
MAUtils.giveItems(p, classItems, classArmor);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gives all the players the rewards they earned.
|
|
||||||
*/
|
|
||||||
public static void giveRewards()
|
|
||||||
{
|
|
||||||
/* This has to be delayed for players to actually receive
|
|
||||||
* their rewards after they die. Not sure why. */
|
|
||||||
server.getScheduler().scheduleSyncDelayedTask(plugin,
|
|
||||||
new Runnable()
|
|
||||||
{
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
for (Player p : rewardMap.keySet())
|
|
||||||
{
|
|
||||||
String r = rewardMap.get(p);
|
|
||||||
if (r.isEmpty()) continue;
|
|
||||||
|
|
||||||
tellPlayer(p, "Here are all of your rewards!");
|
|
||||||
MAUtils.giveItems(true, p, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
rewardMap.clear();
|
|
||||||
}}, 20);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ///////////////////////////////////////////////////////////////////// //
|
|
||||||
|
|
||||||
MISC METHODS
|
|
||||||
|
|
||||||
// ///////////////////////////////////////////////////////////////////// */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends a message to a player.
|
|
||||||
*/
|
|
||||||
public static void tellPlayer(Player p, String msg)
|
|
||||||
{
|
|
||||||
if (p == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
p.sendMessage(ChatColor.GREEN + "[MobArena] " + ChatColor.WHITE + msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends a message to all players in the arena.
|
|
||||||
*/
|
|
||||||
public static void tellAll(String msg)
|
|
||||||
{
|
|
||||||
Chunk c1 = world.getChunkAt(p1);
|
|
||||||
Chunk c2 = world.getChunkAt(p2);
|
|
||||||
|
|
||||||
for (int i = c1.getX(); i <= c2.getX(); i++)
|
|
||||||
for (int j = c1.getZ(); j <= c2.getZ(); j++)
|
|
||||||
for (Entity p : world.getChunkAt(i,j).getEntities())
|
|
||||||
if (p instanceof Player)
|
|
||||||
tellPlayer((Player)p, msg);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
package com.garbagemule.MobArena;
|
|
||||||
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.entity.LivingEntity;
|
|
||||||
import org.bukkit.event.entity.EntityListener;
|
|
||||||
import org.bukkit.event.entity.EntityDeathEvent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This listener acts as a type of death-listener.
|
|
||||||
* When a player is sufficiently low on health, and the next
|
|
||||||
* damaging blow will kill them, they are teleported to the
|
|
||||||
* spectator area, they have their hearts replenished, and all
|
|
||||||
* their items are stripped from them.
|
|
||||||
* By the end of the arena session, the rewards are given.
|
|
||||||
*/
|
|
||||||
// TO-DO: Perhaps implement TeamFluff's respawn-packet-code.
|
|
||||||
public class MADeathListener extends EntityListener
|
|
||||||
{
|
|
||||||
public MADeathListener(MobArena instance)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clears all player/monster drops on death. Also handles
|
|
||||||
* player death events.
|
|
||||||
*/
|
|
||||||
public void onEntityDeath(EntityDeathEvent event)
|
|
||||||
{
|
|
||||||
// If player, call player death and such.
|
|
||||||
if (event.getEntity() instanceof Player)
|
|
||||||
{
|
|
||||||
Player p = (Player) event.getEntity();
|
|
||||||
|
|
||||||
if (!ArenaManager.playerSet.contains(p))
|
|
||||||
return;
|
|
||||||
|
|
||||||
event.getDrops().clear();
|
|
||||||
ArenaManager.playerDeath(p);
|
|
||||||
p.getInventory().clear();
|
|
||||||
}
|
|
||||||
// If monster, remove from monster set
|
|
||||||
else if (event.getEntity() instanceof LivingEntity)
|
|
||||||
{
|
|
||||||
LivingEntity e = (LivingEntity) event.getEntity();
|
|
||||||
|
|
||||||
if (!ArenaManager.monsterSet.contains(e))
|
|
||||||
return;
|
|
||||||
|
|
||||||
event.getDrops().clear();
|
|
||||||
ArenaManager.monsterSet.remove(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
package com.garbagemule.MobArena;
|
|
||||||
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.player.PlayerListener;
|
|
||||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles the disabled commands.
|
|
||||||
*/
|
|
||||||
public class MADisabledCommands extends PlayerListener
|
|
||||||
{
|
|
||||||
private MobArena plugin;
|
|
||||||
|
|
||||||
public MADisabledCommands(MobArena instance)
|
|
||||||
{
|
|
||||||
plugin = instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event)
|
|
||||||
{
|
|
||||||
Player p = event.getPlayer();
|
|
||||||
|
|
||||||
if (!ArenaManager.playerSet.contains(p))
|
|
||||||
return;
|
|
||||||
|
|
||||||
String[] args = event.getMessage().split(" ");
|
|
||||||
|
|
||||||
if (!plugin.DISABLED_COMMANDS.contains(event.getMessage().substring(1).trim()) &&
|
|
||||||
!plugin.DISABLED_COMMANDS.contains(args[0]))
|
|
||||||
return;
|
|
||||||
|
|
||||||
event.setCancelled(true);
|
|
||||||
ArenaManager.tellPlayer(p, "You can't use that command in the arena!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
package com.garbagemule.MobArena;
|
|
||||||
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.player.PlayerListener;
|
|
||||||
import org.bukkit.event.player.PlayerQuitEvent;
|
|
||||||
import org.bukkit.event.player.PlayerKickEvent;
|
|
||||||
import org.bukkit.event.player.PlayerJoinEvent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This listener acts when a player is kicked or disconnected
|
|
||||||
* from the server. If 15 seconds pass, and the player hasn't
|
|
||||||
* reconnected, the player is forced to leave the arena.
|
|
||||||
*/
|
|
||||||
public class MADisconnectListener extends PlayerListener
|
|
||||||
{
|
|
||||||
public MADisconnectListener(MobArena instance)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onPlayerQuit(PlayerQuitEvent event)
|
|
||||||
{
|
|
||||||
Player p = event.getPlayer();
|
|
||||||
|
|
||||||
if (ArenaManager.playerSet.contains(p))
|
|
||||||
{
|
|
||||||
MAUtils.clearInventory(p);
|
|
||||||
ArenaManager.playerLeave(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onPlayerKick(PlayerKickEvent event)
|
|
||||||
{
|
|
||||||
Player p = event.getPlayer();
|
|
||||||
|
|
||||||
if (ArenaManager.playerSet.contains(p))
|
|
||||||
{
|
|
||||||
MAUtils.clearInventory(p);
|
|
||||||
ArenaManager.playerLeave(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onPlayerJoin(PlayerJoinEvent event)
|
|
||||||
{
|
|
||||||
if (!ArenaManager.checkUpdates)
|
|
||||||
return;
|
|
||||||
|
|
||||||
final Player p = event.getPlayer();
|
|
||||||
|
|
||||||
if (!event.getPlayer().isOp())
|
|
||||||
return;
|
|
||||||
|
|
||||||
ArenaManager.server.getScheduler().scheduleSyncDelayedTask(ArenaManager.plugin,
|
|
||||||
new Runnable()
|
|
||||||
{
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
MAUtils.checkForUpdates(p, false);
|
|
||||||
}
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
package com.garbagemule.MobArena;
|
|
||||||
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.block.Sign;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.Event.Result;
|
|
||||||
import org.bukkit.event.block.Action;
|
|
||||||
import org.bukkit.event.player.PlayerBucketEmptyEvent;
|
|
||||||
import org.bukkit.event.player.PlayerListener;
|
|
||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
|
||||||
import org.bukkit.event.player.PlayerDropItemEvent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This listener prevents players from sharing class-specific
|
|
||||||
* items (read: cheating) before the arena session starts.
|
|
||||||
*/
|
|
||||||
// TO-DO: Merge with MASignListener and MAReadyListener into MALobbyListener
|
|
||||||
public class MALobbyListener extends PlayerListener
|
|
||||||
{
|
|
||||||
public MALobbyListener(MobArena instance)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Players can only drop items when the arena session has started.
|
|
||||||
*/
|
|
||||||
public void onPlayerDropItem(PlayerDropItemEvent event)
|
|
||||||
{
|
|
||||||
Player p = event.getPlayer();
|
|
||||||
|
|
||||||
if (!ArenaManager.playerSet.contains(p))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (ArenaManager.isRunning)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ArenaManager.tellPlayer(p, "No sharing before the arena starts!");
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds liquid blocks to the blockset when players empty their buckets.
|
|
||||||
*/
|
|
||||||
public void onPlayerBucketEmpty(PlayerBucketEmptyEvent event)
|
|
||||||
{
|
|
||||||
if (!ArenaManager.playerSet.contains(event.getPlayer()))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!ArenaManager.isRunning)
|
|
||||||
{
|
|
||||||
event.getBlockClicked().getFace(event.getBlockFace()).setTypeId(0);
|
|
||||||
event.setCancelled(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Block liquid = event.getBlockClicked().getFace(event.getBlockFace());
|
|
||||||
ArenaManager.blockSet.add(liquid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the player hits an iron block or a sign, or if the player
|
|
||||||
* is trying to use an item.
|
|
||||||
*/
|
|
||||||
public void onPlayerInteract(PlayerInteractEvent event)
|
|
||||||
{
|
|
||||||
// Only do these checks if the arena isn't running.
|
|
||||||
if (ArenaManager.isRunning)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Player p = event.getPlayer();
|
|
||||||
|
|
||||||
if (!ArenaManager.playerSet.contains(p))
|
|
||||||
return;
|
|
||||||
|
|
||||||
Action a = event.getAction();
|
|
||||||
|
|
||||||
// Check if player is trying to use an item.
|
|
||||||
if ((a == Action.RIGHT_CLICK_AIR) || (a == Action.RIGHT_CLICK_BLOCK))
|
|
||||||
{
|
|
||||||
event.setUseItemInHand(Result.DENY);
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Iron block
|
|
||||||
if (event.hasBlock() && event.getClickedBlock().getTypeId() == 42)
|
|
||||||
{
|
|
||||||
if (ArenaManager.classMap.containsKey(p))
|
|
||||||
{
|
|
||||||
ArenaManager.tellPlayer(p, "You have been flagged as ready!");
|
|
||||||
ArenaManager.playerReady(p);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ArenaManager.tellPlayer(p, "You must first pick a class!");
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sign
|
|
||||||
if (event.hasBlock() && event.getClickedBlock().getState() instanceof Sign)
|
|
||||||
{
|
|
||||||
if (a == Action.RIGHT_CLICK_BLOCK)
|
|
||||||
{
|
|
||||||
ArenaManager.tellPlayer(p, "Punch the sign. Don't right-click.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cast the block to a sign to get the text on it.
|
|
||||||
Sign sign = (Sign) event.getClickedBlock().getState();
|
|
||||||
|
|
||||||
// Check if the first line of the sign is a class name.
|
|
||||||
String className = sign.getLine(0);
|
|
||||||
if (!ArenaManager.classes.contains(className))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Set the player's class.
|
|
||||||
ArenaManager.assignClass(p, className);
|
|
||||||
ArenaManager.tellPlayer(p, "You have chosen " + className + " as your class!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
package com.garbagemule.MobArena;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.entity.LivingEntity;
|
|
||||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
|
||||||
import org.bukkit.event.entity.EntityListener;
|
|
||||||
import org.bukkit.event.entity.EntityExplodeEvent;
|
|
||||||
import org.bukkit.event.entity.EntityCombustEvent;
|
|
||||||
import org.bukkit.event.entity.EntityTargetEvent;
|
|
||||||
import org.bukkit.event.entity.EntityTargetEvent.TargetReason;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prevents Creeper explosions from damaging the blocks of the
|
|
||||||
* arena, zombies and skeletons from burning in the sun, and
|
|
||||||
* monsters (mostly spiders) from losing their targets.
|
|
||||||
*/
|
|
||||||
public class MAMonsterListener extends EntityListener
|
|
||||||
{
|
|
||||||
private MobArena plugin;
|
|
||||||
|
|
||||||
public MAMonsterListener(MobArena instance)
|
|
||||||
{
|
|
||||||
plugin = instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prevents monsters from spawning inside the arena unless
|
|
||||||
* it's running.
|
|
||||||
*/
|
|
||||||
public void onCreatureSpawn(CreatureSpawnEvent event)
|
|
||||||
{
|
|
||||||
// If monster spawning is disabled, only spawn inside the region.
|
|
||||||
if (!ArenaManager.spawnMonsters)
|
|
||||||
{
|
|
||||||
if (ArenaManager.isRunning && MAUtils.inRegion(event.getLocation()))
|
|
||||||
return;
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, ignore spawns inside the region...
|
|
||||||
if (!MAUtils.inRegion(event.getLocation()))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!(event.getEntity() instanceof LivingEntity))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// .. And cancel those inside the region if the arena isn't running.
|
|
||||||
if (!ArenaManager.isRunning)
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles all explosion events, also from TNT.
|
|
||||||
*/
|
|
||||||
public void onEntityExplode(EntityExplodeEvent event)
|
|
||||||
{
|
|
||||||
// Check if any of the block "victims" are in the region.
|
|
||||||
if (!MAUtils.inRegion(event.getLocation()))
|
|
||||||
{
|
|
||||||
boolean inRegion = false;
|
|
||||||
for (Block b : event.blockList())
|
|
||||||
{
|
|
||||||
if (!MAUtils.inRegion(b.getLocation()))
|
|
||||||
continue;
|
|
||||||
inRegion = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!inRegion)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't drop any blocks from the explosion.
|
|
||||||
event.setYield(0);
|
|
||||||
|
|
||||||
// Store the blocks and their values in the map.
|
|
||||||
final HashMap<Block,Integer> blockMap = new HashMap<Block,Integer>();
|
|
||||||
|
|
||||||
for (Block b : event.blockList())
|
|
||||||
{
|
|
||||||
// Doors are wonky, so don't store them. Just smile and wave, and remove from set.
|
|
||||||
if (b.getType() == Material.WOODEN_DOOR || b.getType() == Material.IRON_DOOR_BLOCK || b.getType() == Material.CAKE_BLOCK)
|
|
||||||
{
|
|
||||||
ArenaManager.blockSet.remove(b);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If a block is in the blockSet, make sure it drops "naturally" so Oddjob doesn't cry.
|
|
||||||
if (ArenaManager.blockSet.remove(b))
|
|
||||||
{
|
|
||||||
ArenaManager.world.dropItemNaturally(b.getLocation(), new ItemStack(b.getTypeId(), 1));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If a block has extra data, store it as a fourth digit (thousand).
|
|
||||||
int type = b.getTypeId() + (b.getData() * 1000);
|
|
||||||
blockMap.put(b, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait a couple of ticks, then rebuild the blocks.
|
|
||||||
ArenaManager.server.getScheduler().scheduleSyncDelayedTask(plugin,
|
|
||||||
new Runnable()
|
|
||||||
{
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
for (Block b : blockMap.keySet())
|
|
||||||
{
|
|
||||||
int type = blockMap.get(b);
|
|
||||||
|
|
||||||
// Modulo 1000 to get the actual type id.
|
|
||||||
b.getLocation().getBlock().setTypeId(type % 1000);
|
|
||||||
|
|
||||||
/* If the type ID is greater than 1000, it means the block
|
|
||||||
* has extra data (stairs, levers, etc.). We subtract the
|
|
||||||
* block type data by dividing by 1000. Integer division
|
|
||||||
* always rounds by truncation. */
|
|
||||||
if (type > 1000)
|
|
||||||
b.getLocation().getBlock().setData((byte) (type / 1000));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, ArenaManager.repairDelay);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Zombie/skeleton combustion from the sun.
|
|
||||||
public void onEntityCombust(EntityCombustEvent event)
|
|
||||||
{
|
|
||||||
if (ArenaManager.monsterSet.contains(event.getEntity()))
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Monsters losing their targets.
|
|
||||||
public void onEntityTarget(EntityTargetEvent event)
|
|
||||||
{
|
|
||||||
if (!ArenaManager.isRunning)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!ArenaManager.monsterSet.contains(event.getEntity()))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (event.getReason() == TargetReason.FORGOT_TARGET)
|
|
||||||
event.setTarget(MASpawnThread.getClosestPlayer(event.getEntity()));
|
|
||||||
|
|
||||||
if (event.getReason() == TargetReason.TARGET_DIED)
|
|
||||||
event.setTarget(MASpawnThread.getClosestPlayer(event.getEntity()));
|
|
||||||
|
|
||||||
if (event.getReason() == TargetReason.CLOSEST_PLAYER)
|
|
||||||
event.setTarget(MASpawnThread.getClosestPlayer(event.getEntity()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
package com.garbagemule.MobArena;
|
|
||||||
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.player.PlayerListener;
|
|
||||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This listener prevents players from warping out of the arena, if
|
|
||||||
* they are in the arena session.
|
|
||||||
* Also prevents players from warping into the arena during a session.
|
|
||||||
*/
|
|
||||||
// TO-DO: Fix the bug that causes the message when people get stuck in walls.
|
|
||||||
public class MATeleportListener extends PlayerListener
|
|
||||||
{
|
|
||||||
public MATeleportListener(MobArena instance)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onPlayerTeleport(PlayerTeleportEvent event)
|
|
||||||
{
|
|
||||||
Player p = event.getPlayer();
|
|
||||||
Location to = event.getTo();
|
|
||||||
|
|
||||||
// If the player teleports from outside of the arena..
|
|
||||||
if (!ArenaManager.playerSet.contains(p))
|
|
||||||
{
|
|
||||||
if (!MAUtils.inRegion(to))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!ArenaManager.isRunning)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (ArenaManager.spectatorLoc.equals(to))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// ..into the region during a battle; cancel
|
|
||||||
ArenaManager.tellPlayer(p, "Can't warp to the arena during battle!");
|
|
||||||
ArenaManager.tellPlayer(p, "Type /ma spec to watch.");
|
|
||||||
event.setCancelled(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, only warp if to is in the locationMap, or a valid warp
|
|
||||||
if (ArenaManager.locationMap.get(p).equals(to) ||
|
|
||||||
ArenaManager.arenaLoc.equals(to) ||
|
|
||||||
ArenaManager.lobbyLoc.equals(to) ||
|
|
||||||
ArenaManager.spectatorLoc.equals(to))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// If warp isn't valid, notify the player
|
|
||||||
ArenaManager.tellPlayer(p, "Warping not allowed in the arena!");
|
|
||||||
ArenaManager.tellPlayer(p, "Type /ma leave to leave");
|
|
||||||
event.setCancelled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user