mirror of
https://github.com/garbagemule/MobArena.git
synced 2024-11-23 02:55:46 +01:00
Added basic Leaderboards functionality.
This commit is contained in:
parent
5c3f65fabe
commit
515d29a714
BIN
MobArena.jar
BIN
MobArena.jar
Binary file not shown.
@ -1,6 +1,6 @@
|
||||
name: MobArena
|
||||
main: com.garbagemule.MobArena.MobArena
|
||||
version: 0.94.3.7
|
||||
version: 0.94.3.8
|
||||
softdepend: [Spout,Permissions,MultiVerse,XcraftGate,Towny,Heroes,MagicSpells]
|
||||
commands:
|
||||
ma:
|
||||
@ -83,6 +83,7 @@ permissions:
|
||||
mobarena.setup.containers: true
|
||||
mobarena.setup.addcontainer: true
|
||||
mobarena.setup.delcontainer: true
|
||||
mobarena.setup.leaderboards: true
|
||||
mobarena.setup.checkdata: true
|
||||
mobarena.setup.autogenerate: true
|
||||
mobarena.setup.autodegenerate: true
|
||||
@ -140,6 +141,9 @@ permissions:
|
||||
mobarena.setup.delcontainer:
|
||||
description: Delete a container.
|
||||
default: false
|
||||
mobarena.setup.leaderboards:
|
||||
description: Set up leaderboards.
|
||||
default: false
|
||||
mobarena.setup.checkdata:
|
||||
description: Check which points need to be set up.
|
||||
default: false
|
||||
|
@ -6,7 +6,9 @@ import java.io.FileOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
@ -45,6 +47,7 @@ import org.bukkit.permissions.PermissionAttachment;
|
||||
import org.bukkit.util.config.Configuration;
|
||||
|
||||
import com.garbagemule.MobArena.MAMessages.Msg;
|
||||
import com.garbagemule.MobArena.leaderboards.Leaderboard;
|
||||
import com.garbagemule.MobArena.repairable.Repairable;
|
||||
import com.garbagemule.MobArena.repairable.RepairableComparator;
|
||||
import com.garbagemule.MobArena.repairable.RepairableContainer;
|
||||
@ -112,6 +115,8 @@ public class Arena
|
||||
|
||||
// Logging
|
||||
protected ArenaLog log;
|
||||
protected Map<Player,ArenaPlayer> arenaPlayerMap;
|
||||
protected Leaderboard leaderboard;
|
||||
|
||||
protected MAListener eventListener;
|
||||
|
||||
@ -148,6 +153,7 @@ public class Arena
|
||||
repairables = new LinkedList<Repairable>();
|
||||
containables = new LinkedList<Repairable>();
|
||||
attachments = new HashMap<Player,PermissionAttachment>();
|
||||
arenaPlayerMap = new HashMap<Player,ArenaPlayer>();
|
||||
|
||||
running = false;
|
||||
edit = false;
|
||||
@ -194,6 +200,7 @@ public class Arena
|
||||
p.setHealth(20);
|
||||
p.setFoodLevel(20);
|
||||
assignClassPermissions(p);
|
||||
arenaPlayerMap.put(p, new ArenaPlayer(p, this, plugin));
|
||||
}
|
||||
|
||||
// Copy the singleWaves Set for polling.
|
||||
@ -213,6 +220,9 @@ public class Arena
|
||||
log = new ArenaLog(plugin, this);
|
||||
log.start();
|
||||
|
||||
// Initialize leaderboards and start displaying info.
|
||||
leaderboard.initialize();
|
||||
|
||||
// Announce and notify.
|
||||
MAUtils.tellAll(this, Msg.ARENA_START);
|
||||
|
||||
@ -235,6 +245,9 @@ public class Arena
|
||||
// Set the boolean.
|
||||
running = false;
|
||||
|
||||
// Stop tracking leaderboards
|
||||
leaderboard.update();
|
||||
|
||||
// Finish logging
|
||||
log.end();
|
||||
if (logging != null)
|
||||
@ -262,6 +275,7 @@ public class Arena
|
||||
// Announce and clear sets.
|
||||
MAUtils.tellAll(this, Msg.ARENA_END, true);
|
||||
arenaPlayers.clear();
|
||||
arenaPlayerMap.clear();
|
||||
lobbyPlayers.clear();
|
||||
readyPlayers.clear();
|
||||
notifyPlayers.clear();
|
||||
@ -321,12 +335,13 @@ public class Arena
|
||||
{
|
||||
storePlayerData(p, loc);
|
||||
MAUtils.sitPets(p);
|
||||
p.setHealth(20);
|
||||
if (plugin.getHeroManager() != null)
|
||||
{
|
||||
Hero hero = plugin.getHeroManager().getHero(p);
|
||||
hero.setHealth(hero.getMaxHealth());
|
||||
hero.syncHealth();
|
||||
}
|
||||
p.setHealth(20);
|
||||
p.setFoodLevel(20);
|
||||
p.setGameMode(GameMode.SURVIVAL);
|
||||
movePlayerToLobby(p);
|
||||
@ -510,7 +525,7 @@ public class Arena
|
||||
if (p == null || log.players.get(p) == null)
|
||||
return;
|
||||
|
||||
log.players.get(p).kills++;
|
||||
arenaPlayerMap.get(p).getStats().kills++;
|
||||
}
|
||||
|
||||
public void restoreInvAndGiveRewardsDelayed(final Player p)
|
||||
@ -633,6 +648,7 @@ public class Arena
|
||||
{
|
||||
Hero hero = plugin.getHeroManager().getHero(p);
|
||||
hero.setHealth(health * hero.getMaxHealth() / 20);
|
||||
hero.syncHealth();
|
||||
}
|
||||
}
|
||||
|
||||
@ -685,7 +701,7 @@ public class Arena
|
||||
else restoreInvAndGiveRewards(p);
|
||||
|
||||
if (log != null && spawnThread != null)
|
||||
log.players.get(p).lastWave = spawnThread.getWave() - 1;
|
||||
arenaPlayerMap.get(p).getStats().lastWave = spawnThread.getWave() - 1;
|
||||
}
|
||||
|
||||
public void repairBlocks()
|
||||
@ -898,6 +914,7 @@ public class Arena
|
||||
spawnpoints = MAUtils.getArenaSpawnpoints(config, world, configName);
|
||||
spawnpointsBoss = MAUtils.getArenaBossSpawnpoints(config, world, configName);
|
||||
containers = MAUtils.getArenaContainers(config, world, configName);
|
||||
leaderboard = new Leaderboard(plugin, this, config);
|
||||
|
||||
// NEW WAVES
|
||||
singleWaves = WaveUtils.getWaves(this, config, WaveBranch.SINGLE);
|
||||
@ -1214,6 +1231,22 @@ public class Arena
|
||||
return arenaPlayers;
|
||||
}
|
||||
|
||||
public Collection<ArenaPlayer> getArenaPlayerSet()
|
||||
{
|
||||
return arenaPlayerMap.values();
|
||||
}
|
||||
|
||||
public List<ArenaPlayerStatistics> getArenaPlayerStatistics(Comparator<ArenaPlayerStatistics> comparator)
|
||||
{
|
||||
List<ArenaPlayerStatistics> list = new ArrayList<ArenaPlayerStatistics>();
|
||||
|
||||
for (ArenaPlayer ap : arenaPlayerMap.values())
|
||||
list.add(ap.getStats());
|
||||
|
||||
Collections.sort(list, comparator);
|
||||
return list;
|
||||
}
|
||||
|
||||
public List<Player> getNonreadyPlayers()
|
||||
{
|
||||
List<Player> result = new LinkedList<Player>();
|
||||
|
@ -126,16 +126,16 @@ public class ArenaLog
|
||||
|
||||
public void playerKill(Player p)
|
||||
{
|
||||
players.get(p).kills++;
|
||||
players.get(p).getStats().kills++;
|
||||
}
|
||||
|
||||
public void playerDamager(Player p, int damage)
|
||||
{
|
||||
players.get(p).dmgDone += damage;
|
||||
players.get(p).getStats().dmgDone += damage;
|
||||
}
|
||||
|
||||
public void playerDamagee(Player p, int damage)
|
||||
{
|
||||
players.get(p).dmgTaken += damage;
|
||||
players.get(p).getStats().dmgTaken += damage;
|
||||
}
|
||||
}
|
||||
|
@ -16,18 +16,10 @@ public class ArenaPlayer
|
||||
public List<ItemStack> rewards;
|
||||
public List<Block> blocks;
|
||||
|
||||
private ArenaPlayerStatistics stats;
|
||||
|
||||
protected boolean inArena, inLobby, inSpec, isReady;
|
||||
|
||||
// Session fields.
|
||||
public int kills, dmgDone, dmgTaken, swings, hits, deaths, lastWave;
|
||||
public int flagCaps, flagAttempts, flagReturns; // BG: Capture the Pumpkin
|
||||
public int baseCaps; // BG: Domination
|
||||
|
||||
// All-time fields.
|
||||
protected int totalKills, totalDmgDone, totalDmgTaken, totalSwings, totalHits, totalDeaths;
|
||||
protected int totalFlagCaps, totalFlagAttempts, totalFlagReturns; // BG: Capture the Pumpkin
|
||||
protected int totalBaseCaps; // BG: Domination
|
||||
|
||||
public ArenaPlayer(Player player, Arena arena, MobArena plugin)
|
||||
{
|
||||
this.player = player;
|
||||
@ -37,9 +29,12 @@ public class ArenaPlayer
|
||||
className = arena.classMap.get(player);
|
||||
rewards = new LinkedList<ItemStack>();
|
||||
blocks = new LinkedList<Block>();
|
||||
|
||||
stats = new ArenaPlayerStatistics(this);
|
||||
}
|
||||
|
||||
public Player getPlayer() { return player; }
|
||||
public Arena getArena() { return arena; }
|
||||
public String getClassName() { return className; }
|
||||
public ArenaPlayerStatistics getStats() { return stats; }
|
||||
}
|
||||
|
74
src/com/garbagemule/MobArena/ArenaPlayerStatistics.java
Normal file
74
src/com/garbagemule/MobArena/ArenaPlayerStatistics.java
Normal file
@ -0,0 +1,74 @@
|
||||
package com.garbagemule.MobArena;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class ArenaPlayerStatistics
|
||||
{
|
||||
private String playerName, className;
|
||||
private ArenaPlayer player;
|
||||
public int kills, dmgDone, dmgTaken, swings, hits, lastWave;
|
||||
|
||||
public ArenaPlayerStatistics(ArenaPlayer player)
|
||||
{
|
||||
this.player = player;
|
||||
this.playerName = player.getPlayer().getName();
|
||||
this.className = player.getClassName();
|
||||
}
|
||||
|
||||
public ArenaPlayerStatistics(Player p, Arena arena, MobArena plugin)
|
||||
{
|
||||
this(new ArenaPlayer(p, arena, plugin));
|
||||
}
|
||||
|
||||
public ArenaPlayer getArenaPlayer()
|
||||
{
|
||||
return player;
|
||||
}
|
||||
|
||||
public static Comparator<ArenaPlayerStatistics> killComparator()
|
||||
{
|
||||
return new Comparator<ArenaPlayerStatistics>()
|
||||
{
|
||||
public int compare(ArenaPlayerStatistics s1, ArenaPlayerStatistics s2)
|
||||
{
|
||||
if (s1.kills > s2.kills)
|
||||
return 1;
|
||||
else if (s1.kills < s2.kills)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static Comparator<ArenaPlayerStatistics> waveComparator()
|
||||
{
|
||||
return new Comparator<ArenaPlayerStatistics>()
|
||||
{
|
||||
public int compare(ArenaPlayerStatistics s1, ArenaPlayerStatistics s2)
|
||||
{
|
||||
if (s1.lastWave > s2.lastWave)
|
||||
return 1;
|
||||
else if (s1.lastWave < s2.lastWave)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static Comparator<ArenaPlayerStatistics> dmgDoneComparator()
|
||||
{
|
||||
return new Comparator<ArenaPlayerStatistics>()
|
||||
{
|
||||
public int compare(ArenaPlayerStatistics s1, ArenaPlayerStatistics s2)
|
||||
{
|
||||
if (s1.dmgDone > s2.dmgDone)
|
||||
return 1;
|
||||
else if (s1.dmgDone < s2.dmgDone)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -1,10 +1,14 @@
|
||||
package com.garbagemule.MobArena;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
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.BlockPlaceEvent;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
|
||||
import com.garbagemule.MobArena.leaderboards.Stats;
|
||||
|
||||
public class MABlockListener extends BlockListener
|
||||
{
|
||||
@ -39,6 +43,37 @@ public class MABlockListener extends BlockListener
|
||||
arena.eventListener.onBlockIgnite(event);
|
||||
}
|
||||
|
||||
public void onSignChange(SignChangeEvent event)
|
||||
{
|
||||
if (!event.getPlayer().hasPermission("mobarena.setup.leaderboards"))
|
||||
return;
|
||||
|
||||
if (event.getLine(0).startsWith("[MA]"))
|
||||
{
|
||||
String text = event.getLine(0).substring((4));
|
||||
Arena arena;
|
||||
Stats stat;
|
||||
if ((arena = am.getArenaWithName(text)) != null)
|
||||
{
|
||||
arena.eventListener.onSignChange(event);
|
||||
setSignLines(event, ChatColor.GREEN + "MobArena", ChatColor.YELLOW + arena.arenaName(), ChatColor.AQUA + "Players", "---------------");
|
||||
}
|
||||
else if ((stat = Stats.fromString(text)) != null)
|
||||
{
|
||||
setSignLines(event, ChatColor.GREEN + "", "", ChatColor.AQUA + stat.getFullName(), "---------------");
|
||||
MAUtils.tellPlayer(event.getPlayer(), "Stat sign created.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setSignLines(SignChangeEvent event, String s1, String s2, String s3, String s4)
|
||||
{
|
||||
event.setLine(0, s1);
|
||||
event.setLine(1, s2);
|
||||
event.setLine(2, s3);
|
||||
event.setLine(3, s4);
|
||||
}
|
||||
|
||||
/*
|
||||
public void onBlockPhysics(BlockPhysicsEvent event)
|
||||
{
|
||||
|
@ -21,6 +21,7 @@ import org.bukkit.event.block.BlockBurnEvent;
|
||||
import org.bukkit.event.block.BlockEvent;
|
||||
import org.bukkit.event.block.BlockIgniteEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.block.SignChangeEvent;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.bukkit.event.entity.EndermanPickupEvent;
|
||||
import org.bukkit.event.entity.EndermanPlaceEvent;
|
||||
@ -49,6 +50,7 @@ import org.bukkit.material.Door;
|
||||
import org.bukkit.material.Redstone;
|
||||
|
||||
import com.garbagemule.MobArena.MAMessages.Msg;
|
||||
import com.garbagemule.MobArena.leaderboards.Leaderboard;
|
||||
import com.garbagemule.MobArena.repairable.*;
|
||||
|
||||
public class MAListener implements ArenaListener
|
||||
@ -154,6 +156,13 @@ public class MAListener implements ArenaListener
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void onSignChange(SignChangeEvent event)
|
||||
{
|
||||
arena.leaderboard = new Leaderboard(plugin, arena, event.getBlock().getLocation());
|
||||
MAUtils.setArenaCoord(plugin.getConfig(), arena, "leaderboard", event.getBlock().getLocation());
|
||||
MAUtils.tellPlayer(event.getPlayer(), "Leaderboard made. Now set up the stat signs!");
|
||||
}
|
||||
|
||||
public void onCreatureSpawn(CreatureSpawnEvent event)
|
||||
{
|
||||
@ -331,7 +340,7 @@ public class MAListener implements ArenaListener
|
||||
|
||||
// Log damage
|
||||
if (!event.isCancelled())
|
||||
arena.log.players.get(player).dmgTaken += event.getDamage();
|
||||
arena.arenaPlayerMap.get(player).getStats().dmgTaken += event.getDamage();
|
||||
}
|
||||
|
||||
private void onPetDamage(EntityDamageEvent event, Wolf pet, Entity damager)
|
||||
@ -352,13 +361,13 @@ public class MAListener implements ArenaListener
|
||||
return;
|
||||
}
|
||||
|
||||
arena.log.players.get((Player) damager).dmgDone += event.getDamage();
|
||||
arena.log.players.get((Player) damager).hits++;
|
||||
arena.arenaPlayerMap.get((Player) damager).getStats().dmgDone += event.getDamage();
|
||||
arena.arenaPlayerMap.get((Player) damager).getStats().hits++;
|
||||
}
|
||||
else if (damager instanceof Wolf && arena.pets.contains(damager))
|
||||
{
|
||||
event.setDamage(1);
|
||||
arena.log.players.get((Player) ((Wolf) damager).getOwner()).dmgDone += event.getDamage();
|
||||
arena.arenaPlayerMap.get((Player) ((Wolf) damager).getOwner()).getStats().dmgDone += event.getDamage();
|
||||
}
|
||||
else if (damager instanceof LivingEntity)
|
||||
{
|
||||
@ -465,7 +474,7 @@ public class MAListener implements ArenaListener
|
||||
if (!arena.running || !arena.arenaPlayers.contains(event.getPlayer()))
|
||||
return;
|
||||
|
||||
arena.log.players.get(event.getPlayer()).swings++;
|
||||
arena.arenaPlayerMap.get(event.getPlayer()).getStats().swings++;
|
||||
}
|
||||
|
||||
public void onPlayerDropItem(PlayerDropItemEvent event)
|
||||
|
@ -125,6 +125,7 @@ public class MobArena extends JavaPlugin
|
||||
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.Highest, this);
|
||||
pm.registerEvent(Event.Type.SIGN_CHANGE, blockListener, Priority.Normal, 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);
|
||||
|
257
src/com/garbagemule/MobArena/leaderboards/Leaderboard.java
Normal file
257
src/com/garbagemule/MobArena/leaderboards/Leaderboard.java
Normal file
@ -0,0 +1,257 @@
|
||||
package com.garbagemule.MobArena.leaderboards;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.util.config.Configuration;
|
||||
|
||||
import com.garbagemule.MobArena.Arena;
|
||||
import com.garbagemule.MobArena.ArenaPlayer;
|
||||
import com.garbagemule.MobArena.ArenaPlayerStatistics;
|
||||
import com.garbagemule.MobArena.MobArena;
|
||||
import com.garbagemule.MobArena.util.ConfigUtils;
|
||||
|
||||
public class Leaderboard
|
||||
{
|
||||
private MobArena plugin;
|
||||
private Arena arena;
|
||||
|
||||
private Location topLeft;
|
||||
private Sign topLeftSign;
|
||||
private BlockFace direction;
|
||||
private int rows, cols, trackingId;
|
||||
|
||||
private List<LeaderboardColumn> boards;
|
||||
private List<ArenaPlayerStatistics> stats;
|
||||
|
||||
private boolean isValid;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
* Creates a new leaderboard with no signs or locations or anything.
|
||||
* @param plugin MobArena instance.
|
||||
* @param arena The arena to which this leaderboard belongs.
|
||||
*/
|
||||
public Leaderboard(MobArena plugin, Arena arena)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
this.arena = arena;
|
||||
this.boards = new ArrayList<LeaderboardColumn>();
|
||||
this.stats = new ArrayList<ArenaPlayerStatistics>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Config constructor.
|
||||
* Used to create a leaderboard from the location persisted in the config-file.
|
||||
* @param plugin MobArena instance.
|
||||
* @param arena The arena to which this leaderboard belongs.
|
||||
* @param config The config-file in which the location is specified.
|
||||
*/
|
||||
public Leaderboard(MobArena plugin, Arena arena, Configuration config)
|
||||
{
|
||||
this(plugin, arena);
|
||||
|
||||
// Grab the coords from the config-file.
|
||||
String coords = config.getString("arenas." + arena.configName() + ".coords.leaderboard", null);
|
||||
|
||||
if (coords != null)
|
||||
{
|
||||
// Grab the top left sign.
|
||||
topLeft = ConfigUtils.parseLocation(arena.getWorld(), coords);
|
||||
|
||||
// If it is a sign, validate.
|
||||
if (topLeft.getBlock().getState() instanceof Sign)
|
||||
isValid = isGridWellFormed();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Location constructor.
|
||||
* Used to create a leaderboard on-the-fly from the location from the SignChangeEvent.
|
||||
* @param plugin MobArena instance.
|
||||
* @param arena The arena to which this leaderboard belongs.
|
||||
* @param topLeft The location at which the main leaderboard sign exists.
|
||||
*/
|
||||
public Leaderboard(MobArena plugin, Arena arena, Location topLeft)
|
||||
{
|
||||
this(plugin, arena);
|
||||
|
||||
if (!(topLeft.getBlock().getState() instanceof Sign))
|
||||
throw new IllegalArgumentException("Block must be a sign!");
|
||||
|
||||
this.topLeft = topLeft;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grab all adjacent signs and register the individual columns.
|
||||
*/
|
||||
public void initialize()
|
||||
{
|
||||
if (!isGridWellFormed())
|
||||
return;
|
||||
|
||||
initializeBoards();
|
||||
initializeStats();
|
||||
}
|
||||
|
||||
public void update()
|
||||
{
|
||||
Collections.sort(stats, ArenaPlayerStatistics.waveComparator());
|
||||
|
||||
for (LeaderboardColumn column : boards)
|
||||
column.update(stats);
|
||||
}
|
||||
|
||||
public void startTracking()
|
||||
{
|
||||
trackingId = Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(plugin,
|
||||
new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
update();
|
||||
}
|
||||
}, 100, 100);
|
||||
}
|
||||
|
||||
public void stopTracking()
|
||||
{
|
||||
Bukkit.getServer().getScheduler().cancelTask(trackingId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the leaderboards grid is well-formed.
|
||||
* @return true, if the grid is well-formed, false otherwise.
|
||||
*/
|
||||
private boolean isGridWellFormed()
|
||||
{
|
||||
if (topLeft == null)
|
||||
return false;
|
||||
|
||||
BlockState state = topLeft.getBlock().getState();
|
||||
|
||||
if (!(state instanceof Sign))
|
||||
{
|
||||
MobArena.error("Leaderboards for '" + arena.configName() + "' could not be established!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Grab the top left sign and set up a copy for parsing.
|
||||
this.topLeftSign = (Sign) state;
|
||||
Sign current = this.topLeftSign;
|
||||
|
||||
// Calculate matrix dimensions.
|
||||
this.direction = getRightDirection(current);
|
||||
this.rows = getSignCount(current, BlockFace.DOWN);
|
||||
this.cols = getSignCount(current, direction);
|
||||
|
||||
// Require at least 2x2 to be valid
|
||||
if (rows <= 1 || cols <= 1)
|
||||
return false;
|
||||
|
||||
// Get the left-most sign in the current row.
|
||||
Sign first = getAdjacentSign(current, BlockFace.DOWN);
|
||||
|
||||
for (int i = 1; i < rows; i++)
|
||||
{
|
||||
// Back to the first sign of the row.
|
||||
current = first;
|
||||
for (int j = 1; j < cols; j++)
|
||||
{
|
||||
// Grab the sign to the right, if not a sign, grid is ill-formed.
|
||||
current = getAdjacentSign(current, direction);
|
||||
if (current == null) return false;
|
||||
}
|
||||
|
||||
// Hop down to the next row.
|
||||
first = getAdjacentSign(first, BlockFace.DOWN);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the leaderboards.
|
||||
* Requires: The grid MUST be valid!
|
||||
*/
|
||||
private void initializeBoards()
|
||||
{
|
||||
boards.clear();
|
||||
Sign header = this.topLeftSign;
|
||||
Sign current;
|
||||
|
||||
do
|
||||
{
|
||||
// Strip the sign of any colors.
|
||||
String name = ChatColor.stripColor(header.getLine(2));
|
||||
|
||||
// Grab the stat to track.
|
||||
Stats stat = Stats.getByFullName(name);
|
||||
if (stat == null) continue;
|
||||
|
||||
// Create the list of signs
|
||||
List<Sign> signs = new ArrayList<Sign>();
|
||||
current = header;
|
||||
for (int i = 1; i < rows; i++)
|
||||
{
|
||||
current = getAdjacentSign(current, BlockFace.DOWN);
|
||||
signs.add(current);
|
||||
}
|
||||
|
||||
// Create the column.
|
||||
LeaderboardColumn column = LeaderboardColumn.create(stat.getShortName(), header, signs);
|
||||
if (column == null) continue;
|
||||
this.boards.add(column);
|
||||
}
|
||||
while ((header = getAdjacentSign(header, direction)) != null);
|
||||
}
|
||||
|
||||
private void initializeStats()
|
||||
{
|
||||
stats.clear();
|
||||
for (ArenaPlayer ap : arena.getArenaPlayerSet())
|
||||
stats.add(ap.getStats());
|
||||
}
|
||||
|
||||
private int getSignCount(Sign s, BlockFace direction)
|
||||
{
|
||||
int i = 1;
|
||||
|
||||
BlockState state = s.getBlock().getState();
|
||||
while ((state = state.getBlock().getRelative(direction).getState()) instanceof Sign)
|
||||
i++;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
private Sign getAdjacentSign(Sign s, BlockFace direction)
|
||||
{
|
||||
BlockState state = s.getBlock().getRelative(direction).getState();
|
||||
if (state instanceof Sign)
|
||||
return (Sign) state;
|
||||
return null;
|
||||
}
|
||||
|
||||
private BlockFace getRightDirection(Sign s)
|
||||
{
|
||||
byte data = s.getRawData();
|
||||
|
||||
if (data == 2) return BlockFace.NORTH;
|
||||
if (data == 3) return BlockFace.SOUTH;
|
||||
if (data == 4) return BlockFace.WEST;
|
||||
if (data == 5) return BlockFace.EAST;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isValid()
|
||||
{
|
||||
return isValid;
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
package com.garbagemule.MobArena.leaderboards;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.block.Sign;
|
||||
|
||||
import com.garbagemule.MobArena.ArenaPlayerStatistics;
|
||||
|
||||
public class LeaderboardColumn
|
||||
{
|
||||
private Field field;
|
||||
private Sign header;
|
||||
private List<Sign> signs;
|
||||
|
||||
private LeaderboardColumn(String statname, Sign header, List<Sign> signs) throws Exception
|
||||
{
|
||||
this.field = ArenaPlayerStatistics.class.getDeclaredField(statname);
|
||||
this.header = header;
|
||||
this.signs = signs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely create a new LeaderboardColumn.
|
||||
* Avoid the try-catch blocks by creating columns with this method.
|
||||
* @param statname The name of the stat to track
|
||||
* @param header The header sign
|
||||
* @param signs A list of signs
|
||||
* @return A new LeaderboardColumn, or null
|
||||
*/
|
||||
public static LeaderboardColumn create(String statname, Sign header, List<Sign> signs)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new LeaderboardColumn(statname, header, signs);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void update(List<ArenaPlayerStatistics> stats)
|
||||
{
|
||||
// Make sure the stats will fit on the signs.
|
||||
int range = Math.min(stats.size(), signs.size()*4);
|
||||
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < range; i++)
|
||||
{
|
||||
// Grab the right sign.
|
||||
Sign s = signs.get(i/4);
|
||||
|
||||
// Get the stat value.
|
||||
field.setAccessible(true);
|
||||
Object o = field.get(stats.get(i));
|
||||
field.setAccessible(false);
|
||||
|
||||
// Set the value on the right line.
|
||||
s.setLine(i % 4, o.toString());
|
||||
s.update();
|
||||
}
|
||||
}
|
||||
catch (Exception e) { e.printStackTrace(); }
|
||||
}
|
||||
|
||||
public Sign getHeader()
|
||||
{
|
||||
return header;
|
||||
}
|
||||
|
||||
public List<Sign> getSigns()
|
||||
{
|
||||
return signs;
|
||||
}
|
||||
}
|
49
src/com/garbagemule/MobArena/leaderboards/Stats.java
Normal file
49
src/com/garbagemule/MobArena/leaderboards/Stats.java
Normal file
@ -0,0 +1,49 @@
|
||||
package com.garbagemule.MobArena.leaderboards;
|
||||
|
||||
import com.garbagemule.MobArena.util.WaveUtils;
|
||||
|
||||
public enum Stats
|
||||
{
|
||||
players("Players", "playerName"),
|
||||
className("Class", "className"),
|
||||
kills("Kills", "kills"),
|
||||
dmgDone("Damage Done", "dmgDone"),
|
||||
dmgTaken("Damage Taken", "dmgTaken"),
|
||||
swings("Swings", "swings"),
|
||||
hits("Hits", "hits"),
|
||||
lastWave("Last Wave", "lastWave");
|
||||
|
||||
private String name, shortName;
|
||||
|
||||
private Stats(String name, String shortName)
|
||||
{
|
||||
this.name = name;
|
||||
this.shortName = shortName;
|
||||
}
|
||||
|
||||
public String getShortName()
|
||||
{
|
||||
return shortName;
|
||||
}
|
||||
|
||||
public String getFullName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public static Stats fromString(String name)
|
||||
{
|
||||
if (name.equals("class"))
|
||||
return Stats.className;
|
||||
return WaveUtils.getEnumFromStringCaseSensitive(Stats.class, name);
|
||||
}
|
||||
|
||||
public static Stats getByFullName(String name)
|
||||
{
|
||||
|
||||
for (Stats s : Stats.values())
|
||||
if (s.name.equals(name))
|
||||
return s;
|
||||
return null;
|
||||
}
|
||||
}
|
47
src/com/garbagemule/MobArena/util/ConfigUtils.java
Normal file
47
src/com/garbagemule/MobArena/util/ConfigUtils.java
Normal file
@ -0,0 +1,47 @@
|
||||
package com.garbagemule.MobArena.util;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
|
||||
public class ConfigUtils
|
||||
{
|
||||
public static Location parseLocation(World world, String coords)
|
||||
{
|
||||
String[] parts = coords.split(",");
|
||||
if (parts.length != 5)
|
||||
throw new IllegalArgumentException("Input string must contain x, y, z, yaw and pitch");
|
||||
|
||||
Integer x = getInt(parts[0]);
|
||||
Integer y = getInt(parts[1]);
|
||||
Integer z = getInt(parts[2]);
|
||||
Float yaw = getFloat(parts[3]);
|
||||
Float pitch = getFloat(parts[4]);
|
||||
|
||||
if (x == null || y == null || z == null || yaw == null || pitch == null)
|
||||
throw new NullPointerException("Some of the parsed values are null!");
|
||||
|
||||
return new Location(world, x, y, z, yaw, pitch);
|
||||
}
|
||||
|
||||
private static Integer getInt(String s)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Integer.parseInt(s.trim());
|
||||
}
|
||||
catch (Exception e) {}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Float getFloat(String s)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Float.parseFloat(s.trim());
|
||||
}
|
||||
catch (Exception e) {}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@ -542,4 +542,20 @@ public class WaveUtils
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the enum value of a string, null if it doesn't exist.
|
||||
*/
|
||||
public static <T extends Enum<T>> T getEnumFromStringCaseSensitive(Class<T> c, String string)
|
||||
{
|
||||
if(c != null && string != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Enum.valueOf(c, string);
|
||||
}
|
||||
catch(IllegalArgumentException ex) { }
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -129,11 +129,11 @@ public class PlainText
|
||||
buffy.append("- ");
|
||||
buffy.append(TextUtils.padRight(name, NAME)); buffy.append(pad);
|
||||
buffy.append(TextUtils.padRight(ap.getClassName(), CLASS)); buffy.append(pad);
|
||||
buffy.append(TextUtils.padLeft(ap.lastWave, WAVE)); buffy.append(pad);
|
||||
buffy.append(TextUtils.padLeft(ap.kills, KILLS)); buffy.append(pad);
|
||||
buffy.append(TextUtils.padLeft(ap.dmgDone, DMGDONE)); buffy.append(pad);
|
||||
buffy.append(TextUtils.padLeft(ap.dmgTaken, DMGTAKEN)); buffy.append(pad);
|
||||
buffy.append(TextUtils.padLeft(((ap.swings != 0) ? ap.hits*100/ap.swings : 0), ACCURACY-1)); buffy.append("%"); buffy.append(pad);
|
||||
buffy.append(TextUtils.padLeft(ap.getStats().lastWave, WAVE)); buffy.append(pad);
|
||||
buffy.append(TextUtils.padLeft(ap.getStats().kills, KILLS)); buffy.append(pad);
|
||||
buffy.append(TextUtils.padLeft(ap.getStats().dmgDone, DMGDONE)); buffy.append(pad);
|
||||
buffy.append(TextUtils.padLeft(ap.getStats().dmgTaken, DMGTAKEN)); buffy.append(pad);
|
||||
buffy.append(TextUtils.padLeft(((ap.getStats().swings != 0) ? ap.getStats().hits*100/ap.getStats().swings : 0), ACCURACY-1)); buffy.append("%"); buffy.append(pad);
|
||||
buffy.append(MAUtils.listToString(ap.rewards));
|
||||
|
||||
result.add(buffy.toString());
|
||||
|
@ -59,12 +59,12 @@ public class Totals
|
||||
for (ArenaPlayer ap : log.players.values())
|
||||
{
|
||||
// Basic values
|
||||
updateInt(totals,"players." + ap.player.getName() + ".games-played", 1, true);
|
||||
updateInt(totals,"players." + ap.player.getName() + ".kills", ap.kills, true);
|
||||
updateInt(totals,"players." + ap.player.getName() + ".damage-done", ap.dmgDone, true);
|
||||
updateInt(totals,"players." + ap.player.getName() + ".damage-taken", ap.dmgTaken, true);
|
||||
updateInt(totals,"players." + ap.player.getName() + ".swings", ap.swings, true);
|
||||
updateInt(totals,"players." + ap.player.getName() + ".hits", ap.hits, true);
|
||||
updateInt(totals,"players." + ap.player.getName() + ".games-played", 1, true);
|
||||
updateInt(totals,"players." + ap.player.getName() + ".kills", ap.getStats().kills, true);
|
||||
updateInt(totals,"players." + ap.player.getName() + ".damage-done", ap.getStats().dmgDone, true);
|
||||
updateInt(totals,"players." + ap.player.getName() + ".damage-taken", ap.getStats().dmgTaken, true);
|
||||
updateInt(totals,"players." + ap.player.getName() + ".swings", ap.getStats().swings, true);
|
||||
updateInt(totals,"players." + ap.player.getName() + ".hits", ap.getStats().hits, true);
|
||||
|
||||
// Class count
|
||||
updateInt(totals,"players." + ap.player.getName() + ".classes." + ap.className,1,true);
|
||||
@ -131,7 +131,7 @@ public class Totals
|
||||
{
|
||||
int kills = 0;
|
||||
for (ArenaPlayer ap : log.players.values())
|
||||
kills += ap.kills;
|
||||
kills += ap.getStats().kills;
|
||||
return kills;
|
||||
}
|
||||
|
||||
@ -149,9 +149,9 @@ public class Totals
|
||||
if (!ap.className.equals(className))
|
||||
continue;
|
||||
|
||||
kills += ap.kills;
|
||||
dmgDone += ap.dmgDone;
|
||||
dmgTaken += ap.dmgTaken;
|
||||
kills += ap.getStats().kills;
|
||||
dmgDone += ap.getStats().dmgDone;
|
||||
dmgTaken += ap.getStats().dmgTaken;
|
||||
}
|
||||
return new int[]{kills, dmgDone, dmgTaken};
|
||||
}
|
||||
|
@ -48,12 +48,12 @@ public class XML
|
||||
Element p = new Element("player").setAttribute(new Attribute("name", entry.getKey().getName()));
|
||||
ArenaPlayer ap = entry.getValue();
|
||||
|
||||
p.addContent(new Element("last-wave").addContent(ap.lastWave + ""));
|
||||
p.addContent(new Element("kills").addContent(ap.lastWave + ""));
|
||||
p.addContent(new Element("damage-done").addContent(ap.dmgDone + ""));
|
||||
p.addContent(new Element("damage-taken").addContent(ap.dmgTaken + ""));
|
||||
p.addContent(new Element("swings").addContent(ap.swings + ""));
|
||||
p.addContent(new Element("hits").addContent(ap.hits + ""));
|
||||
p.addContent(new Element("last-wave").addContent(ap.getStats().lastWave + ""));
|
||||
p.addContent(new Element("kills").addContent(ap.getStats().lastWave + ""));
|
||||
p.addContent(new Element("damage-done").addContent(ap.getStats().dmgDone + ""));
|
||||
p.addContent(new Element("damage-taken").addContent(ap.getStats().dmgTaken + ""));
|
||||
p.addContent(new Element("swings").addContent(ap.getStats().swings + ""));
|
||||
p.addContent(new Element("hits").addContent(ap.getStats().hits + ""));
|
||||
|
||||
// Rewards
|
||||
Element rw = new Element("rewards");
|
||||
|
@ -43,12 +43,12 @@ public class YAML
|
||||
String p = entry.getKey().getName();
|
||||
ArenaPlayer ap = entry.getValue();
|
||||
|
||||
config.setProperty("player-data." + p + ".last-wave", ap.lastWave);
|
||||
config.setProperty("player-data." + p + ".kills", ap.kills);
|
||||
config.setProperty("player-data." + p + ".damage-done", ap.dmgDone);
|
||||
config.setProperty("player-data." + p + ".damage-taken", ap.dmgTaken);
|
||||
config.setProperty("player-data." + p + ".swings", ap.swings);
|
||||
config.setProperty("player-data." + p + ".hits", ap.hits);
|
||||
config.setProperty("player-data." + p + ".last-wave", ap.getStats().lastWave);
|
||||
config.setProperty("player-data." + p + ".kills", ap.getStats().kills);
|
||||
config.setProperty("player-data." + p + ".damage-done", ap.getStats().dmgDone);
|
||||
config.setProperty("player-data." + p + ".damage-taken", ap.getStats().dmgTaken);
|
||||
config.setProperty("player-data." + p + ".swings", ap.getStats().swings);
|
||||
config.setProperty("player-data." + p + ".hits", ap.getStats().hits);
|
||||
for (ItemStack stack : ap.rewards)
|
||||
{
|
||||
boolean money = stack.getTypeId() == MobArena.ECONOMY_MONEY_ID;
|
||||
|
Loading…
Reference in New Issue
Block a user