Merge pull request #99 from acstache/bleeding

1.2.5-R1.3/1.2.5-R2.0 onEnable fix, plus many more
This commit is contained in:
garbagemule 2012-07-12 15:19:52 -07:00
commit 96857585a9
24 changed files with 427 additions and 83 deletions

Binary file not shown.

View File

@ -1,7 +1,7 @@
name: MobArena name: MobArena
author: garbagemule author: garbagemule
main: com.garbagemule.MobArena.MobArena main: com.garbagemule.MobArena.MobArena
version: 0.94.4.65 version: 0.94.4.75
softdepend: [Spout,MultiVerse,XcraftGate,Towny,Heroes,MagicSpells,Vault] softdepend: [Spout,MultiVerse,XcraftGate,Towny,Heroes,MagicSpells,Vault]
commands: commands:
ma: ma:

View File

@ -0,0 +1,5 @@
Knight: -1
Tank: -1
Archer: -1
Chemist: -1
Oddjob: -1

View File

@ -101,6 +101,12 @@ public class ArenaClass
else if (stack.getType() == Material.BONE) { else if (stack.getType() == Material.BONE) {
pets += stack.getAmount(); pets += stack.getAmount();
} }
else if (stack.getAmount() > 64) {
while (stack.getAmount() > 64) {
items.add(new ItemStack(stack.getType(), 64));
stack.setAmount(stack.getAmount() - 64);
}
}
items.add(stack); items.add(stack);
} }
@ -229,7 +235,7 @@ public class ArenaClass
/** /**
* Used by isWeapon() to determine if an ItemStack is a weapon type. * Used by isWeapon() to determine if an ItemStack is a weapon type.
*/ */
private static int[] weaponTypes = new int[]{256,257,258,267,268,269,270,271,272,273,274,275,276,277,278,279,283,284,285,286,290,291,292,293,294}; private static int[] weaponTypes = new int[]{256,257,258,261,267,268,269,270,271,272,273,274,275,276,277,278,279,283,284,285,286,290,291,292,293,294};
/** /**
* Returns true, if the ItemStack appears to be a weapon, in which case * Returns true, if the ItemStack appears to be a weapon, in which case

View File

@ -72,8 +72,9 @@ public class ArenaImpl implements Arena
private Leaderboard leaderboard; private Leaderboard leaderboard;
// Player stuff // Player stuff
private InventoryManager inventoryManager; private InventoryManager inventoryManager;
private RewardManager rewardManager; private RewardManager rewardManager;
private ClassLimitManager limitManager;
private Map<Player,ArenaPlayer> arenaPlayerMap; private Map<Player,ArenaPlayer> arenaPlayerMap;
private Map<Player,PlayerData> playerData = new HashMap<Player,PlayerData>(); private Map<Player,PlayerData> playerData = new HashMap<Player,PlayerData>();
@ -100,6 +101,7 @@ public class ArenaImpl implements Arena
private Map<Integer,List<ItemStack>> everyWaveMap, afterWaveMap; private Map<Integer,List<ItemStack>> everyWaveMap, afterWaveMap;
// Logging // Logging
private boolean logging;
private ArenaLog log; private ArenaLog log;
private LogSessionBuilder sessionBuilder; private LogSessionBuilder sessionBuilder;
private LogTotalsBuilder totalsBuilder; private LogTotalsBuilder totalsBuilder;
@ -124,6 +126,7 @@ public class ArenaImpl implements Arena
this.enabled = settings.getBoolean("enabled", false); this.enabled = settings.getBoolean("enabled", false);
this.protect = settings.getBoolean("protect", true); this.protect = settings.getBoolean("protect", true);
this.logging = settings.getBoolean("logging", true);
this.running = false; this.running = false;
this.edit = false; this.edit = false;
@ -143,8 +146,9 @@ public class ArenaImpl implements Arena
this.randoms = new HashSet<Player>(); this.randoms = new HashSet<Player>();
// Classes, items and permissions // Classes, items and permissions
this.classes = plugin.getArenaMaster().getClasses(); this.classes = plugin.getArenaMaster().getClasses();
this.attachments = new HashMap<Player,PermissionAttachment>(); this.attachments = new HashMap<Player,PermissionAttachment>();
this.limitManager = new ClassLimitManager(this, classes);
// Blocks and pets // Blocks and pets
this.repairQueue = new PriorityBlockingQueue<Repairable>(100, new RepairableComparator()); this.repairQueue = new PriorityBlockingQueue<Repairable>(100, new RepairableComparator());
@ -170,11 +174,13 @@ public class ArenaImpl implements Arena
Time time = Enums.getEnumFromString(Time.class, timeString); Time time = Enums.getEnumFromString(Time.class, timeString);
this.timeStrategy = (time != null ? new TimeStrategyLocked(time) : new TimeStrategyNull()); this.timeStrategy = (time != null ? new TimeStrategyLocked(time) : new TimeStrategyNull());
this.dir = new File(plugin.getDataFolder() + File.separator + "arenas" + File.separator + name); if (logging) {
this.sessionBuilder = new YMLSessionBuilder(new File(dir, "log_session.yml")); this.dir = new File(plugin.getDataFolder() + File.separator + "arenas" + File.separator + name);
this.totalsBuilder = new YMLTotalsBuilder(new File(dir, "log_totals.yml")); this.sessionBuilder = new YMLSessionBuilder(new File(dir, "log_session.yml"));
this.totalsBuilder = new YMLTotalsBuilder(new File(dir, "log_totals.yml"));
this.log = new ArenaLog(this, sessionBuilder, totalsBuilder); this.log = new ArenaLog(this, sessionBuilder, totalsBuilder);
}
} }
@ -219,6 +225,18 @@ public class ArenaImpl implements Arena
@Override @Override
public void setProtected(boolean value) { public void setProtected(boolean value) {
protect = value; protect = value;
settings.set("protect", protect);
}
@Override
public boolean isLogging() {
return logging;
}
@Override
public void setLogging(boolean value) {
logging = value;
settings.set("logging", logging);
} }
@Override @Override
@ -367,6 +385,11 @@ public class ArenaImpl implements Arena
return monsterManager; return monsterManager;
} }
@Override
public ClassLimitManager getClassLimitManager() {
return limitManager;
}
@Override @Override
public ArenaLog getLog() { public ArenaLog getLog() {
return log; return log;
@ -408,6 +431,7 @@ public class ArenaImpl implements Arena
for (Player p : randoms) { for (Player p : randoms) {
assignRandomClass(p); assignRandomClass(p);
} }
randoms.clear();
// Then check if there are still players left. // Then check if there are still players left.
if (arenaPlayers.isEmpty()) { if (arenaPlayers.isEmpty()) {
@ -416,6 +440,14 @@ public class ArenaImpl implements Arena
// Teleport players, give full health, initialize map // Teleport players, give full health, initialize map
for (Player p : arenaPlayers) { for (Player p : arenaPlayers) {
// TODO figure out how people die in lobby and get sent to spectator area early
// Remove player from spec list to avoid invincibility issues
if (inSpec(p)) {
specPlayers.remove(p);
System.out.println("[MobArena] Player " + p.getName() + " joined the arena from the spec area!");
System.out.println("[MobArena] Invincibility glitch attempt stopped!");
}
p.teleport(region.getArenaWarp()); p.teleport(region.getArenaWarp());
//movePlayerToLocation(p, region.getArenaWarp()); //movePlayerToLocation(p, region.getArenaWarp());
setHealth(p, 20); setHealth(p, 20);
@ -434,9 +466,13 @@ public class ArenaImpl implements Arena
// Spawn pets (must happen after 'running = true;') // Spawn pets (must happen after 'running = true;')
spawnPets(); spawnPets();
// Clear the classes in use map, as they're no longer needed
limitManager.clearClassesInUse();
// Start logging // Start logging
rewardManager.reset(); rewardManager.reset();
log.start(); if (logging)
log.start();
// Initialize leaderboards and start displaying info. // Initialize leaderboards and start displaying info.
leaderboard.initialize(); leaderboard.initialize();
@ -471,7 +507,8 @@ public class ArenaImpl implements Arena
leaderboard.update(); leaderboard.update();
// Finish logging // Finish logging
log.end(); if (logging)
log.end();
// Stop spawning. // Stop spawning.
stopSpawner(); stopSpawner();
@ -580,18 +617,19 @@ public class ArenaImpl implements Arena
removePotionEffects(p); removePotionEffects(p);
ArenaPlayer ap = arenaPlayerMap.get(p); ArenaPlayer ap = arenaPlayerMap.get(p);
if (ap != null && running) log.playerDeath(ap); if (logging)
if (ap != null && running)
log.playerDeath(ap);
restoreInvAndExp(p);
if (inLobby(p) || inArena(p)) { if (inLobby(p) || inArena(p)) {
inventoryManager.clearInventory(p);
inventoryManager.restoreInventory(p);
rewardManager.grantRewards(p);
refund(p); refund(p);
//p.updateInventory();
} }
else if (inSpec(p)) {
inventoryManager.restoreInventory(p); if (inLobby(p)) {
//p.updateInventory(); if (ap.getArenaClass() != null) {
limitManager.playerLeftClass(ap.getArenaClass());
}
} }
movePlayerToEntry(p); movePlayerToEntry(p);
@ -609,7 +647,9 @@ public class ArenaImpl implements Arena
plugin.getServer().getPluginManager().callEvent(event); plugin.getServer().getPluginManager().callEvent(event);
ArenaPlayer ap = arenaPlayerMap.get(p); ArenaPlayer ap = arenaPlayerMap.get(p);
if (ap != null) log.playerDeath(ap); if (logging)
if (ap != null)
log.playerDeath(ap);
arenaPlayers.remove(p); arenaPlayers.remove(p);
@ -643,7 +683,9 @@ public class ArenaImpl implements Arena
if (settings.getBoolean("spectate-on-death", true)) { if (settings.getBoolean("spectate-on-death", true)) {
movePlayerToSpec(p); movePlayerToSpec(p);
restoreInvAndExp(p); Messenger.tellPlayer(p, Msg.SPEC_FROM_ARENA);
Messenger.tellPlayer(p, Msg.MISC_MA_LEAVE_REMINDER);
//restoreInvAndExp(p);
} else { } else {
restoreInvAndExp(p); restoreInvAndExp(p);
movePlayerToEntry(p); movePlayerToEntry(p);
@ -701,7 +743,7 @@ public class ArenaImpl implements Arena
private void removePotionEffects(Player p) { private void removePotionEffects(Player p) {
for (PotionEffect effect : p.getActivePotionEffects()) { for (PotionEffect effect : p.getActivePotionEffects()) {
p.addPotionEffect(new PotionEffect(effect.getType(), 0, 0), true); p.removePotionEffect(effect.getType());
} }
} }
@ -873,6 +915,9 @@ public class ArenaImpl implements Arena
if (!settings.getBoolean("keep-exp", false)) { if (!settings.getBoolean("keep-exp", false)) {
playerData.get(p).restoreData(); playerData.get(p).restoreData();
} }
else {
p.setFoodLevel(playerData.get(p).food());
}
} }
@Override @Override
@ -944,6 +989,11 @@ public class ArenaImpl implements Arena
arenaClass.grantItems(p); arenaClass.grantItems(p);
} }
@Override
public void addRandomPlayer(Player p) {
randoms.add(p);
}
@Override @Override
public void assignRandomClass(Player p) public void assignRandomClass(Player p)
{ {
@ -963,7 +1013,7 @@ public class ArenaImpl implements Arena
} }
assignClass(p, className); assignClass(p, className);
Messenger.tellPlayer(p, Msg.LOBBY_CLASS_PICKED, className); Messenger.tellPlayer(p, Msg.LOBBY_CLASS_PICKED, TextUtils.camelCase(className), getClassLogo(className));
} }
@Override @Override

View File

@ -88,6 +88,7 @@ public class ArenaListener
private Arena arena; private Arena arena;
private ArenaRegion region; private ArenaRegion region;
private MonsterManager monsters; private MonsterManager monsters;
private ClassLimitManager classLimits;
private boolean softRestore, private boolean softRestore,
softRestoreDrops, softRestoreDrops,
@ -97,6 +98,7 @@ public class ArenaListener
pvpEnabled, pvpEnabled,
foodRegen, foodRegen,
lockFoodLevel; lockFoodLevel;
@SuppressWarnings("unused")
private boolean allowTeleport, private boolean allowTeleport,
canShare, canShare,
allowMonsters, allowMonsters,
@ -129,12 +131,24 @@ public class ArenaListener
this.canShare = s.getBoolean("share-items-in-arena", true); this.canShare = s.getBoolean("share-items-in-arena", true);
this.autoIgniteTNT = s.getBoolean("auto-ignite-tnt", false); this.autoIgniteTNT = s.getBoolean("auto-ignite-tnt", false);
this.classLimits = arena.getClassLimitManager();
this.allowMonsters = arena.getWorld().getAllowMonsters(); this.allowMonsters = arena.getWorld().getAllowMonsters();
this.banned = new HashSet<Player>(); this.banned = new HashSet<Player>();
} }
public void onBlockBreak(BlockBreakEvent event) { public void onBlockBreak(BlockBreakEvent event) {
if (!arena.getRegion().contains(event.getBlock().getLocation()))
return;
if (!arena.inArena(event.getPlayer())) {
if (arena.inEditMode())
return;
else
event.setCancelled(true);
}
if (onBlockDestroy(event)) if (onBlockDestroy(event))
return; return;
@ -142,24 +156,30 @@ public class ArenaListener
} }
public void onBlockBurn(BlockBurnEvent event) { public void onBlockBurn(BlockBurnEvent event) {
if (onBlockDestroy(event)) if (!arena.getRegion().contains(event.getBlock().getLocation()) || onBlockDestroy(event))
return; return;
event.setCancelled(true); event.setCancelled(true);
} }
private boolean onBlockDestroy(BlockEvent event) { private boolean onBlockDestroy(BlockEvent event) {
if (!arena.getRegion().contains(event.getBlock().getLocation()) || arena.inEditMode() || (!arena.isProtected() && arena.isRunning())) if (arena.inEditMode())
return true; return true;
if (!arena.isRunning())
return false;
Block b = event.getBlock(); Block b = event.getBlock();
if (arena.removeBlock(b) || b.getType() == Material.TNT) if (arena.removeBlock(b) || b.getType() == Material.TNT)
return true; return true;
if (softRestore && arena.isRunning()) { if (softRestore) {
BlockState state = b.getState(); if (arena.isProtected())
return false;
BlockState state = b.getState();
Repairable r = null; Repairable r = null;
if (state instanceof InventoryHolder) if (state instanceof InventoryHolder)
r = new RepairableContainer(state); r = new RepairableContainer(state);
else if (state instanceof Sign) else if (state instanceof Sign)
@ -173,7 +193,6 @@ public class ArenaListener
if (!softRestoreDrops) if (!softRestoreDrops)
b.setTypeId(0); b.setTypeId(0);
return true; return true;
} }
@ -256,8 +275,13 @@ public class ArenaListener
} }
if (event.getSpawnReason() != SpawnReason.CUSTOM) { if (event.getSpawnReason() != SpawnReason.CUSTOM) {
event.setCancelled(true); if (event.getSpawnReason() == SpawnReason.BUILD_IRONGOLEM || event.getSpawnReason() == SpawnReason.BUILD_SNOWMAN) {
return; monsters.addGolem(event.getEntity());
}
else {
event.setCancelled(true);
return;
}
} }
LivingEntity entity = (LivingEntity) event.getEntity(); LivingEntity entity = (LivingEntity) event.getEntity();
@ -345,6 +369,9 @@ public class ArenaListener
else if (monsters.removeMonster(event.getEntity())) { else if (monsters.removeMonster(event.getEntity())) {
onMonsterDeath(event); onMonsterDeath(event);
} }
else if (monsters.removeGolem(event.getEntity())) {
Messenger.tellAll(arena, Msg.GOLEM_DIED);
}
} }
private void onPlayerDeath(PlayerDeathEvent event, Player player) { private void onPlayerDeath(PlayerDeathEvent event, Player player) {
@ -450,7 +477,7 @@ public class ArenaListener
else if (damagee instanceof Player) { else if (damagee instanceof Player) {
onPlayerDamage(event, (Player) damagee, damager); onPlayerDamage(event, (Player) damagee, damager);
} }
// Snowman // Snowmen melting
else if (damagee instanceof Snowman && event.getCause() == DamageCause.MELTING) { else if (damagee instanceof Snowman && event.getCause() == DamageCause.MELTING) {
event.setCancelled(true); event.setCancelled(true);
} }
@ -462,6 +489,10 @@ public class ArenaListener
else if (monsters.getMonsters().contains(damagee)) { else if (monsters.getMonsters().contains(damagee)) {
onMonsterDamage(event, damagee, damager); onMonsterDamage(event, damagee, damager);
} }
// Player made golems
else if (monsters.getGolems().contains(damagee)) {
onGolemDamage(event, damagee, damager);
}
} }
private void onPlayerDamage(EntityDamageEvent event, Player player, Entity damager) { private void onPlayerDamage(EntityDamageEvent event, Player player, Entity damager) {
@ -510,6 +541,21 @@ public class ArenaListener
} }
} }
private void onGolemDamage(EntityDamageEvent event, Entity golem, Entity damager) {
if (damager instanceof Player) {
Player p = (Player) damager;
if (!arena.inArena(p)) {
event.setCancelled(true);
return;
}
if (!pvpEnabled) {
event.setCancelled(true);
return;
}
}
}
private void onBossDamage(EntityDamageEvent event, LivingEntity monster, Entity damager) { private void onBossDamage(EntityDamageEvent event, LivingEntity monster, Entity damager) {
// Health the boss back up. // Health the boss back up.
monster.setHealth(monster.getMaxHealth()); monster.setHealth(monster.getMaxHealth());
@ -743,6 +789,31 @@ public class ArenaListener
return; return;
} }
ArenaClass oldAC = arena.getArenaPlayer(p).getArenaClass();
ArenaClass newAC = arena.getClasses().get(className);
// If they already had a class, make sure to change the "in use" in the Class Limit Manager
if (oldAC != null) {
p.sendMessage("already had a class");
// If they picked the same sign, don't do anything
if (oldAC.equals(newAC)) {
p.sendMessage("picked the same class");
return;
}
System.out.println("decrementing the classesInUse of " + oldAC.getName());
classLimits.playerLeftClass(oldAC);
}
// If they can not join the class, deny them
if (!classLimits.canPlayerJoinClass(newAC)) {
Messenger.tellPlayer(p, Msg.LOBBY_CLASS_FULL);
return;
}
// Increment the "in use" in the Class Limit Manager
System.out.println("incrementing the classesInUse of " + newAC.getName());
classLimits.playerPickedClass(newAC);
// Delay the inventory stuff to ensure that right-clicking works. // Delay the inventory stuff to ensure that right-clicking works.
delayAssignClass(p, className); delayAssignClass(p, className);
} }
@ -750,20 +821,23 @@ public class ArenaListener
private void delayAssignClass(final Player p, final String className) { private void delayAssignClass(final Player p, final String className) {
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin,new Runnable() { plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin,new Runnable() {
public void run() { public void run() {
arena.assignClass(p, className); if (!className.equalsIgnoreCase("random")) {
arena.assignClass(p, className);
if (!className.equalsIgnoreCase("random"))
Messenger.tellPlayer(p, Msg.LOBBY_CLASS_PICKED, TextUtils.camelCase(className), arena.getClassLogo(className)); Messenger.tellPlayer(p, Msg.LOBBY_CLASS_PICKED, TextUtils.camelCase(className), arena.getClassLogo(className));
else }
else {
arena.addRandomPlayer(p);
Messenger.tellPlayer(p, Msg.LOBBY_CLASS_RANDOM); Messenger.tellPlayer(p, Msg.LOBBY_CLASS_RANDOM);
}
} }
}); });
} }
public void onPlayerQuit(PlayerQuitEvent event) { public void onPlayerQuit(PlayerQuitEvent event) {
Player p = event.getPlayer(); Player p = event.getPlayer();
if (!arena.isEnabled() || (!arena.inArena(p) && !arena.inLobby(p))) if (!arena.isEnabled() || (!arena.inArena(p) && !arena.inLobby(p) && !arena.inSpec(p))) {
return; return;
}
arena.playerLeave(p); arena.playerLeave(p);
banned.add(p); banned.add(p);
@ -772,7 +846,7 @@ public class ArenaListener
public void onPlayerKick(PlayerKickEvent event) { public void onPlayerKick(PlayerKickEvent event) {
Player p = event.getPlayer(); Player p = event.getPlayer();
if (!arena.isEnabled() || (!arena.inArena(p) && !arena.inLobby(p))) { if (!arena.isEnabled() || (!arena.inArena(p) && !arena.inLobby(p) && !arena.inSpec(p))) {
return; return;
} }

View File

@ -24,6 +24,7 @@ import com.garbagemule.MobArena.ArenaClass.ArmorType;
import com.garbagemule.MobArena.framework.Arena; import com.garbagemule.MobArena.framework.Arena;
import com.garbagemule.MobArena.framework.ArenaMaster; import com.garbagemule.MobArena.framework.ArenaMaster;
import com.garbagemule.MobArena.util.ItemParser; import com.garbagemule.MobArena.util.ItemParser;
import com.garbagemule.MobArena.util.TextUtils;
import com.garbagemule.MobArena.util.config.Config; import com.garbagemule.MobArena.util.config.Config;
import com.garbagemule.MobArena.util.config.ConfigSection; import com.garbagemule.MobArena.util.config.ConfigSection;
import com.garbagemule.MobArena.util.config.ConfigUtils; import com.garbagemule.MobArena.util.config.ConfigUtils;
@ -424,6 +425,7 @@ public class ArenaMasterImpl implements ArenaMaster
} }
private boolean addRemoveClassPermission(String classname, String perm, boolean add) { private boolean addRemoveClassPermission(String classname, String perm, boolean add) {
classname = TextUtils.camelCase(classname);
String path = "classes." + classname; String path = "classes." + classname;
if (config.getConfigSection(path) == null) if (config.getConfigSection(path) == null)
return false; return false;
@ -433,16 +435,19 @@ public class ArenaMasterImpl implements ArenaMaster
// Get any previous nodes // Get any previous nodes
List<String> nodes = section.getStringList("permissions", null); List<String> nodes = section.getStringList("permissions", null);
if (nodes.contains(perm))
return false;
// Add or remove. if (nodes.contains(perm) && add) {
if (add) { return false;
}
else if (nodes.contains(perm) && !add) {
nodes.remove(perm);
}
else if (!nodes.contains(perm) && add) {
removeContradictions(nodes, perm); removeContradictions(nodes, perm);
nodes.add(perm); nodes.add(perm);
} }
else { else if (!nodes.contains(perm) && !add) {
nodes.remove(perm); return false;
} }
// Replace the set. // Replace the set.

View File

@ -0,0 +1,93 @@
package com.garbagemule.MobArena;
import java.util.HashMap;
import java.util.Map;
import com.garbagemule.MobArena.framework.Arena;
import com.garbagemule.MobArena.util.config.ConfigSection;
import com.garbagemule.MobArena.util.config.ConfigUtils;
public class ClassLimitManager
{
private HashMap<ArenaClass, Integer> classLimits, classesInUse;
private ConfigSection limits;
private MobArena plugin;
private Map<String, ArenaClass> classes;
public ClassLimitManager(Arena arena, Map<String, ArenaClass> classes) {
this.plugin = arena.getPlugin();
ConfigUtils.addMissingNodes(plugin, plugin.getMAConfig(), "arenas." + arena.configName() + ".class-limits", "class-limits.yml");
this.limits = new ConfigSection(plugin.getMAConfig(), "arenas." + arena.configName() + ".class-limits");
//TODO figure out why limits is not loading the proper values from the config
//TODO perhaps send along the limits config section from the ArenaImpl class?
//TODO try to use ArenaRegion's config stuff to set up CLM properly
this.classes = classes;
this.classLimits = new HashMap<ArenaClass, Integer>();
this.classesInUse = new HashMap<ArenaClass, Integer>();
loadLimitMap();
initInUseMap();
}
private void loadLimitMap() {
for (ArenaClass ac : classes.values()) {
classLimits.put(ac, limits.getInt(ac.getName(), -1));
}
}
private void initInUseMap() {
for (ArenaClass ac : classes.values()) {
classesInUse.put(ac, 0);
}
}
/**
* This is the class a player is changing to
* @param ac the new ArenaClass
*/
public void playerPickedClass(ArenaClass ac) {
classesInUse.put(ac, classesInUse.get(ac) + 1);
debug();
}
/**
* This is the class a player left
* @param ac the current/old ArenaClass
*/
public void playerLeftClass(ArenaClass ac) {
classesInUse.put(ac, classesInUse.get(ac) - 1);
debug();
}
/**
* Checks to see if a player can pick a specific class
* @param ac the ArenaClass to check
* @return true/false
*/
public boolean canPlayerJoinClass(ArenaClass ac) {
debug();
if (classLimits.get(ac) <= -1)
return true;
else if (classesInUse.get(ac) >= classLimits.get(ac))
return false;
else
return true;
}
public void clearClassesInUse() {
classesInUse.clear();
initInUseMap();
debug();
}
private void debug() {
System.out.println("classesInUse:");
for (ArenaClass ac : classesInUse.keySet())
System.out.println(ac.getName() + " has " + classesInUse.get(ac).intValue() + " players using it.");
System.out.println();
System.out.println("classLimits:");
for (ArenaClass ac : classLimits.keySet())
System.out.println(ac.getName() + " has a limit of " + classLimits.get(ac).intValue() + " players.");
}
}

View File

@ -247,6 +247,10 @@ public class MASpawnThread implements Runnable
continue; continue;
} }
// TODO remove debug message
Location l = p.getLocation();
System.out.println("Player: " + p.getName() + " found at location:" + l.getX() + ", " + l.getY() + ", " + l.getZ());
Messenger.tellPlayer(p, "Leaving so soon?"); Messenger.tellPlayer(p, "Leaving so soon?");
p.getInventory().clear(); p.getInventory().clear();
arena.playerLeave(p); arena.playerLeave(p);
@ -299,7 +303,7 @@ public class MASpawnThread implements Runnable
Messenger.warning("Could not add null reward. Please check the config-file!"); Messenger.warning("Could not add null reward. Please check the config-file!");
} }
else if (reward.getTypeId() == MobArena.ECONOMY_MONEY_ID) { else if (reward.getTypeId() == MobArena.ECONOMY_MONEY_ID) {
if (plugin.giveMoney(p, reward.getAmount())) { if (plugin.giveMoney(p, reward.getAmount())) { // Money already awarded here, not needed at end of match as well
Messenger.tellPlayer(p, Msg.WAVE_REWARD, plugin.economyFormat(reward.getAmount())); Messenger.tellPlayer(p, Msg.WAVE_REWARD, plugin.economyFormat(reward.getAmount()));
} }
else { else {

View File

@ -17,7 +17,7 @@ import com.garbagemule.MobArena.waves.MABoss;
public class MonsterManager public class MonsterManager
{ {
private Set<LivingEntity> monsters, sheep; private Set<LivingEntity> monsters, sheep, golems;
private Set<Wolf> pets; private Set<Wolf> pets;
private Map<LivingEntity,MABoss> bosses; private Map<LivingEntity,MABoss> bosses;
private Map<LivingEntity,List<ItemStack>> suppliers; private Map<LivingEntity,List<ItemStack>> suppliers;
@ -25,6 +25,7 @@ public class MonsterManager
public MonsterManager() { public MonsterManager() {
this.monsters = new HashSet<LivingEntity>(); this.monsters = new HashSet<LivingEntity>();
this.sheep = new HashSet<LivingEntity>(); this.sheep = new HashSet<LivingEntity>();
this.golems = new HashSet<LivingEntity>();
this.pets = new HashSet<Wolf>(); this.pets = new HashSet<Wolf>();
this.bosses = new HashMap<LivingEntity,MABoss>(); this.bosses = new HashMap<LivingEntity,MABoss>();
this.suppliers = new HashMap<LivingEntity,List<ItemStack>>(); this.suppliers = new HashMap<LivingEntity,List<ItemStack>>();
@ -33,6 +34,7 @@ public class MonsterManager
public void reset() { public void reset() {
monsters.clear(); monsters.clear();
sheep.clear(); sheep.clear();
golems.clear();
pets.clear(); pets.clear();
bosses.clear(); bosses.clear();
suppliers.clear(); suppliers.clear();
@ -41,6 +43,7 @@ public class MonsterManager
public void clear() { public void clear() {
removeAll(monsters); removeAll(monsters);
removeAll(sheep); removeAll(sheep);
removeAll(golems);
removeAll(pets); removeAll(pets);
removeAll(bosses.keySet()); removeAll(bosses.keySet());
removeAll(suppliers.keySet()); removeAll(suppliers.keySet());
@ -80,6 +83,18 @@ public class MonsterManager
return sheep.remove(e); return sheep.remove(e);
} }
public Set<LivingEntity> getGolems() {
return golems;
}
public void addGolem(LivingEntity e) {
golems.add(e);
}
public boolean removeGolem(LivingEntity e) {
return golems.remove(e);
}
public Set<Wolf> getPets() { public Set<Wolf> getPets() {
return pets; return pets;
} }

View File

@ -7,6 +7,7 @@ public enum Msg
ARENA_START("Let the slaughter begin!", "Arena started!", Material.REDSTONE_TORCH_ON), ARENA_START("Let the slaughter begin!", "Arena started!", Material.REDSTONE_TORCH_ON),
ARENA_END("Arena finished.", "Arena finished.", Material.REDSTONE_TORCH_OFF), ARENA_END("Arena finished.", "Arena finished.", Material.REDSTONE_TORCH_OFF),
ARENA_DOES_NOT_EXIST("That arena does not exist. Type /ma arenas for a list.", "Can't find arena."), ARENA_DOES_NOT_EXIST("That arena does not exist. Type /ma arenas for a list.", "Can't find arena."),
ARENA_LBOARD_NOT_FOUND("That arena does not have a leaderboard set up."),
JOIN_NOT_ENABLED("MobArena is not enabled.", "MobArena disabled.", Material.REDSTONE_TORCH_OFF), JOIN_NOT_ENABLED("MobArena is not enabled.", "MobArena disabled.", Material.REDSTONE_TORCH_OFF),
JOIN_IN_OTHER_ARENA("You are already in an arena! Leave that one first.", "In another arena."), JOIN_IN_OTHER_ARENA("You are already in an arena! Leave that one first.", "In another arena."),
JOIN_ARENA_NOT_ENABLED("This arena is not enabled.", "Arena disabled.", Material.REDSTONE_TORCH_OFF), JOIN_ARENA_NOT_ENABLED("This arena is not enabled.", "Arena disabled.", Material.REDSTONE_TORCH_OFF),
@ -28,7 +29,9 @@ public enum Msg
LEAVE_NOT_PLAYING("You are not in the arena.", "Not in arena."), LEAVE_NOT_PLAYING("You are not in the arena.", "Not in arena."),
LEAVE_PLAYER_LEFT("You left the arena. Thanks for playing!", "Left arena.", Material.WOOD_DOOR), LEAVE_PLAYER_LEFT("You left the arena. Thanks for playing!", "Left arena.", Material.WOOD_DOOR),
PLAYER_DIED("% died!", "% died!", Material.BONE), PLAYER_DIED("% died!", "% died!", Material.BONE),
GOLEM_DIED("A friendly Golem has died!", "A Golem has died!", Material.PUMPKIN),
SPEC_PLAYER_SPECTATE("Enjoy the show!", "Enjoy the show!"), SPEC_PLAYER_SPECTATE("Enjoy the show!", "Enjoy the show!"),
SPEC_FROM_ARENA("Enjoy the rest of the show!", "Enjoy the show!"),
SPEC_NOT_RUNNING("This arena isn't running.", "Arena not running.", Material.REDSTONE_TORCH_OFF), SPEC_NOT_RUNNING("This arena isn't running.", "Arena not running.", Material.REDSTONE_TORCH_OFF),
SPEC_EMPTY_INV("Empty your inventory first!", "Empty your inventory.", Material.CHEST), SPEC_EMPTY_INV("Empty your inventory first!", "Empty your inventory.", Material.CHEST),
SPEC_ALREADY_PLAYING("Can't spectate when in the arena!", "Already playing!"), SPEC_ALREADY_PLAYING("Can't spectate when in the arena!", "Already playing!"),
@ -43,6 +46,7 @@ public enum Msg
LOBBY_DROP_ITEM("No sharing allowed at this time!", "Can't drop items here."), LOBBY_DROP_ITEM("No sharing allowed at this time!", "Can't drop items here."),
LOBBY_PLAYER_READY("You have been flagged as ready!", "Flagged as ready!"), LOBBY_PLAYER_READY("You have been flagged as ready!", "Flagged as ready!"),
LOBBY_PICK_CLASS("You must first pick a class!", "Pick a class first!"), LOBBY_PICK_CLASS("You must first pick a class!", "Pick a class first!"),
LOBBY_CLASS_FULL("This class can no longer be selected, class limit reached!", "Class limit reached!"),
LOBBY_NOT_ENOUGH_PLAYERS("Not enough players to start. Need at least % players.", "Need more players."), LOBBY_NOT_ENOUGH_PLAYERS("Not enough players to start. Need at least % players.", "Need more players."),
LOBBY_RIGHT_CLICK("Punch the sign. Don't right-click.", "Punch the sign."), LOBBY_RIGHT_CLICK("Punch the sign. Don't right-click.", "Punch the sign."),
LOBBY_CLASS_PICKED("You have chosen % as your class!", "%"), LOBBY_CLASS_PICKED("You have chosen % as your class!", "%"),

View File

@ -15,6 +15,7 @@ import com.garbagemule.MobArena.framework.Arena;
public class RewardManager public class RewardManager
{ {
@SuppressWarnings("unused")
private MobArena plugin; private MobArena plugin;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private Arena arena; private Arena arena;
@ -57,13 +58,12 @@ public class RewardManager
} }
if (stack.getTypeId() == MobArena.ECONOMY_MONEY_ID) { if (stack.getTypeId() == MobArena.ECONOMY_MONEY_ID) {
plugin.giveMoney(p, stack.getAmount()); // plugin.giveMoney(p, stack.getAmount()); - removed to fix double money rewards
continue; continue;
} }
p.getInventory().addItem(stack); p.getInventory().addItem(stack);
} }
rewarded.add(p); rewarded.add(p);
} }
} }

View File

@ -185,6 +185,7 @@ public class CommandHandler implements CommandExecutor
register(RemoveClassCommand.class); register(RemoveClassCommand.class);
register(RemoveClassPermCommand.class); register(RemoveClassPermCommand.class);
register(RemoveContainerCommand.class); register(RemoveContainerCommand.class);
register(RemoveLeaderboardCommand.class);
register(RemoveSpawnpointCommand.class); register(RemoveSpawnpointCommand.class);
register(SetArenaCommand.class); register(SetArenaCommand.class);
register(SetClassCommand.class); register(SetClassCommand.class);

View File

@ -10,7 +10,7 @@ import com.garbagemule.MobArena.framework.ArenaMaster;
@CommandInfo( @CommandInfo(
name = "listclasses", name = "listclasses",
pattern = "(list)?class(.)*", pattern = "(list)?classes(.)*",
usage = "/ma listclasses", usage = "/ma listclasses",
desc = "list all current classes", desc = "list all current classes",
permission = "mobarena.setup.classes" permission = "mobarena.setup.classes"

View File

@ -0,0 +1,56 @@
package com.garbagemule.MobArena.commands.setup;
import org.bukkit.command.CommandSender;
import com.garbagemule.MobArena.Messenger;
import com.garbagemule.MobArena.Msg;
import com.garbagemule.MobArena.commands.Command;
import com.garbagemule.MobArena.commands.CommandInfo;
import com.garbagemule.MobArena.framework.ArenaMaster;
@CommandInfo(
name = "removeleaderboard",
pattern = "(del(.)*|r(e)?m(ove)?)leaderboard",
usage = "/ma removeleaderboard <arenaname>",
desc = "remove the selected arena's leaderboard",
permission = "mobarena.setup.leaderboards"
)
public class RemoveLeaderboardCommand implements Command{
@Override
public boolean execute(ArenaMaster am, CommandSender sender, String... args) {
// Grab the argument, if any.
String arg1 = (args.length > 0 ? args[0] : "");
// If no argument, use the currently selected arena
if (arg1.equals("")) {
if (am.getSelectedArena().getRegion().getLeaderboard() != null) {
am.getSelectedArena().getRegion().set("leaderboard", null);
Messenger.tellPlayer(sender, "Leaderboard for " + am.getSelectedArena().arenaName() + " successfully removed!");
return true;
}
else {
Messenger.tellPlayer(sender, Msg.ARENA_LBOARD_NOT_FOUND);
}
}
else {
if (am.getArenaWithName(arg1) != null) {
if (am.getSelectedArena().getRegion().getLeaderboard() != null) {
am.getArenaWithName(arg1).getRegion().set("leaderboard", null);
Messenger.tellPlayer(sender, "Leaderboard for " + am.getArenaWithName(arg1).arenaName() + " successfully removed!");
return true;
}
else {
Messenger.tellPlayer(sender, Msg.ARENA_LBOARD_NOT_FOUND);
}
}
else {
Messenger.tellPlayer(sender, "Usage: /ma removeleaderboard <arenaname>");
return false;
}
}
return false;
}
}

View File

@ -29,17 +29,24 @@ public class JoinCommand implements Command
String arg1 = (args.length > 0 ? args[0] : null); String arg1 = (args.length > 0 ? args[0] : null);
// Run some rough sanity checks, and grab the arena to join. // Run some rough sanity checks, and grab the arena to join.
Arena arena = Commands.getArenaToJoinOrSpec(am, p, arg1); Arena toArena = Commands.getArenaToJoinOrSpec(am, p, arg1);
if (arena == null) { Arena fromArena = am.getArenaWithPlayer(p);
if (toArena == null) {
return false;
}
// Deny joining from other arenas
if (fromArena != null && (fromArena.inArena(p) || fromArena.inLobby(p))) {
Messenger.tellPlayer(p, Msg.JOIN_ALREADY_PLAYING);
return false; return false;
} }
// Per-arena sanity checks // Per-arena sanity checks
if (!arena.canJoin(p)) { if (!toArena.canJoin(p)) {
return false; return false;
} }
// Join the arena! // Join the arena!
return arena.playerJoin(p, p.getLocation()); return toArena.playerJoin(p, p.getLocation());
} }
} }

View File

@ -13,6 +13,7 @@ import org.bukkit.inventory.ItemStack;
import com.garbagemule.MobArena.ArenaClass; import com.garbagemule.MobArena.ArenaClass;
import com.garbagemule.MobArena.ArenaListener; import com.garbagemule.MobArena.ArenaListener;
import com.garbagemule.MobArena.ArenaPlayer; import com.garbagemule.MobArena.ArenaPlayer;
import com.garbagemule.MobArena.ClassLimitManager;
import com.garbagemule.MobArena.MASpawnThread; import com.garbagemule.MobArena.MASpawnThread;
import com.garbagemule.MobArena.MobArena; import com.garbagemule.MobArena.MobArena;
import com.garbagemule.MobArena.MonsterManager; import com.garbagemule.MobArena.MonsterManager;
@ -48,6 +49,10 @@ public interface Arena
public void setProtected(boolean value); public void setProtected(boolean value);
public boolean isLogging();
public void setLogging(boolean value);
public boolean isRunning(); public boolean isRunning();
public boolean inEditMode(); public boolean inEditMode();
@ -100,6 +105,8 @@ public interface Arena
public MonsterManager getMonsterManager(); public MonsterManager getMonsterManager();
public ClassLimitManager getClassLimitManager();
public void revivePlayer(Player p); public void revivePlayer(Player p);
public ArenaLog getLog(); public ArenaLog getLog();
@ -172,6 +179,8 @@ public interface Arena
public void assignClass(Player p, String className); public void assignClass(Player p, String className);
public void addRandomPlayer(Player p);
public void assignRandomClass(Player p); public void assignRandomClass(Player p);
public void assignClassPermissions(Player p); public void assignClassPermissions(Player p);

View File

@ -40,7 +40,7 @@ public class MAGlobalListener implements Listener
// // // //
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
//TODO watch block physics, piston extend, and piston retract events
@EventHandler(priority = EventPriority.HIGHEST) @EventHandler(priority = EventPriority.HIGHEST)
public void blockBreak(BlockBreakEvent event) { public void blockBreak(BlockBreakEvent event) {
for (Arena arena : am.getArenas()) for (Arena arena : am.getArenas())

View File

@ -16,9 +16,9 @@ import com.garbagemule.MobArena.util.config.Config;
public class YMLSessionBuilder implements LogSessionBuilder public class YMLSessionBuilder implements LogSessionBuilder
{ {
private final String GENERAL = "general-info."; private final String GENERAL = "general-info";
private final String PLAYERS = "players."; private final String PLAYERS = "players";
private final String CLASSES = "class-distribution."; private final String CLASSES = "class-distribution";
private Config config; private Config config;
private long start, end; private long start, end;
@ -31,42 +31,42 @@ public class YMLSessionBuilder implements LogSessionBuilder
@Override @Override
public void buildStartTime() { public void buildStartTime() {
start = new Date().getTime(); start = new Date().getTime();
config.set(GENERAL + "start-time", TimeUtils.toDateTime(start)); config.set(GENERAL + ".start-time", TimeUtils.toDateTime(start));
} }
@Override @Override
public void buildEndTime() { public void buildEndTime() {
end = new Date().getTime(); end = new Date().getTime();
config.set(GENERAL + "end-time", TimeUtils.toDateTime(end)); config.set(GENERAL + ".end-time", TimeUtils.toDateTime(end));
} }
@Override @Override
public void buildDuration() { public void buildDuration() {
String duration = TimeUtils.toTime(end - start); String duration = TimeUtils.toTime(end - start);
config.set(GENERAL + "duration", duration); config.set(GENERAL + ".duration", duration);
} }
@Override @Override
public void buildLastWave(int lastWave) { public void buildLastWave(int lastWave) {
config.set(GENERAL + "last-wave", lastWave); config.set(GENERAL + ".last-wave", lastWave);
} }
@Override @Override
public void buildNumberOfPlayers(int amount) { public void buildNumberOfPlayers(int amount) {
config.set(GENERAL + "number-of-players", amount); config.set(GENERAL + ".number-of-players", amount);
} }
@Override @Override
public void buildClassDistribution(Map<String,MutableInt> classDistribution) { public void buildClassDistribution(Map<String,MutableInt> classDistribution) {
for (Entry<String,MutableInt> entry : classDistribution.entrySet()) { for (Entry<String,MutableInt> entry : classDistribution.entrySet()) {
int amount = entry.getValue().value(); int amount = entry.getValue().value();
config.set(CLASSES + entry.getKey(), amount); config.set(CLASSES + "." + entry.getKey(), amount);
} }
} }
@Override @Override
public void buildPlayerEntry(ArenaLogPlayerEntry entry, List<ItemStack> rewards) { public void buildPlayerEntry(ArenaLogPlayerEntry entry, List<ItemStack> rewards) {
String path = PLAYERS + entry.playername + "."; String path = PLAYERS + "." + entry.playername + ".";
// Name and class // Name and class
config.set(path + "name", entry.playername); config.set(path + "name", entry.playername);
@ -106,8 +106,11 @@ public class YMLSessionBuilder implements LogSessionBuilder
} }
private void reset() { private void reset() {
config.set(GENERAL, null); if(config.get(GENERAL) != null)
config.set(CLASSES, null); config.set(GENERAL, null);
config.set(PLAYERS, null); if(config.get(CLASSES) != null)
config.set(CLASSES, null);
if(config.get(PLAYERS) != null)
config.set(PLAYERS, null);
} }
} }

View File

@ -193,7 +193,7 @@ public class ArenaRegion
// Region expand // Region expand
public void expandUp(int amount) { public void expandUp(int amount) {
p2.setY(Math.min(127D, p2.getY() + amount)); p2.setY(Math.min(arena.getWorld().getMaxHeight(), p2.getY() + amount));
set(RegionPoint.P2, p2); set(RegionPoint.P2, p2);
} }
@ -221,7 +221,7 @@ public class ArenaRegion
// Lobby expand // Lobby expand
public void expandLobbyUp(int amount) { public void expandLobbyUp(int amount) {
l2.setY(Math.min(127D, l2.getY() + amount)); l2.setY(Math.min(arena.getWorld().getMaxHeight(), l2.getY() + amount));
set(RegionPoint.L2, l2); set(RegionPoint.L2, l2);
} }

View File

@ -57,12 +57,12 @@ public class ItemParser
int lvl = entry.getValue(); int lvl = entry.getValue();
// <eid>:<level>; // <eid>:<level>;
enchantments += "; " + id + ":" + lvl; enchantments += ";" + id + ":" + lvl;
} }
// Trim off the leading ';' if it is there // Trim off the leading ';' if it is there
if (!enchantments.equals("")) { if (!enchantments.equals("")) {
enchantments = enchantments.substring(2); enchantments = enchantments.substring(1);
} }
// <item> // <item>
@ -149,7 +149,7 @@ public class ItemParser
} }
private static ItemStack withDataAndAmount(String item, String data, String amount) { private static ItemStack withDataAndAmount(String item, String data, String amount) {
Material m = getMaterial(item.toUpperCase()); Material m = getMaterial(item);
short d = getData(data, m); short d = getData(data, m);
int a = getAmount(amount); int a = getAmount(amount);

View File

@ -89,6 +89,7 @@ public enum MACreature
public LivingEntity spawn(Arena arena, World world, Location loc) { public LivingEntity spawn(Arena arena, World world, Location loc) {
LivingEntity e = world.spawnCreature(loc, type); LivingEntity e = world.spawnCreature(loc, type);
//TODO change this to: LivingEntity e = (LivingEntity) world.spawnEntity(loc, type);
switch (this) { switch (this) {
case SHEEP: case SHEEP:

View File

@ -250,9 +250,9 @@ public class WaveParser
} }
} }
// As well as the ability interval. // As well as the ability interval and ability announce.
int interval = config.getInt("ability-interval", 3) * 20; result.setAbilityInterval(config.getInt("ability-interval", 3) * 20);
result.setAbilityInterval(interval); result.setAbilityAnnounce(config.getBoolean("ability-announce", true));
return result; return result;
} }

View File

@ -25,7 +25,7 @@ public class BossWave extends AbstractWave
private BossHealth health; private BossHealth health;
private List<Ability> abilities; private List<Ability> abilities;
private boolean activated; private boolean activated, abilityAnnounce;
private int abilityInterval; private int abilityInterval;
@ -34,6 +34,7 @@ public class BossWave extends AbstractWave
this.bosses = new HashSet<MABoss>(); this.bosses = new HashSet<MABoss>();
this.abilities = new ArrayList<Ability>(); this.abilities = new ArrayList<Ability>();
this.activated = false; this.activated = false;
this.abilityAnnounce = false;
this.setType(WaveType.BOSS); this.setType(WaveType.BOSS);
} }
@ -78,6 +79,14 @@ public class BossWave extends AbstractWave
this.abilityInterval = abilityInterval; this.abilityInterval = abilityInterval;
} }
public boolean getAbilityAnnounce() {
return abilityAnnounce;
}
public void setAbilityAnnounce(boolean abilityAnnounce) {
this.abilityAnnounce = abilityAnnounce;
}
public void activateAbilities(Arena arena) { public void activateAbilities(Arena arena) {
if (activated) { if (activated) {
return; return;
@ -89,7 +98,9 @@ public class BossWave extends AbstractWave
} }
public void announceAbility(Ability ability, MABoss boss, Arena arena) { public void announceAbility(Ability ability, MABoss boss, Arena arena) {
AbilityInfo info = ability.getClass().getAnnotation(AbilityInfo.class); if(getAbilityAnnounce()) {
Messenger.tellAll(arena, Msg.WAVE_BOSS_ABILITY, info.name()); AbilityInfo info = ability.getClass().getAnnotation(AbilityInfo.class);
Messenger.tellAll(arena, Msg.WAVE_BOSS_ABILITY, info.name());
}
} }
} }