PVP Stats

This commit is contained in:
Sam 2017-09-09 18:29:22 +01:00
parent 5600f72d56
commit 9d71cd7893
5 changed files with 357 additions and 3 deletions

View File

@ -30,7 +30,11 @@ public class HubGameManager extends MiniPlugin
private static final int MIN_PLAYERS_COUNTDOWN = 20;
private static final int MAX_PLAYERS_COUNTDOWN = 5;
private static final int PREPARE_COUNTDOWN = 5;
private static final String HEADER_FOOTER = C.cDGreen + C.Strike + "================================";
private static final String HEADER_FOOTER = C.cDGreen + C.Strike + "================================================";
public static String getHeaderFooter()
{
return HEADER_FOOTER;
}
private final NewNPCManager _npcManager;

View File

@ -0,0 +1,348 @@
package mineplex.hub.hubgame.common.damage;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.EntityShootBowEvent;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerItemConsumeEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import mineplex.core.common.jsonchat.ClickEvent;
import mineplex.core.common.jsonchat.Color;
import mineplex.core.common.jsonchat.HoverEvent;
import mineplex.core.common.jsonchat.JsonMessage;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.LineFormat;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilText;
import mineplex.core.common.util.UtilTextBottom;
import mineplex.core.common.util.UtilTextMiddle;
import mineplex.hub.hubgame.CycledGame.GameState;
import mineplex.hub.hubgame.HubGame;
import mineplex.hub.hubgame.HubGameManager;
import mineplex.hub.hubgame.common.HubGameComponent;
import mineplex.hub.hubgame.event.HubGameStateChangeEvent;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
public class PVPTrackerComponent extends HubGameComponent<HubGame>
{
private static final String STATS_COMMAND = "/duelstats";
private static final String HEART = C.cRed + "" + C.Reset;
private static final DecimalFormat FORMAT = new DecimalFormat("0.#");
private final Map<Player, PVPStats> _stats;
public PVPTrackerComponent(HubGame game)
{
super(game);
_stats = new HashMap<>();
}
@EventHandler(priority = EventPriority.LOWEST)
public void playerDeath(PlayerDeathEvent event)
{
Player player = event.getEntity();
Player killer = player.getKiller();
if (killer == null || !_game.isAlive(killer))
{
return;
}
PVPStats playerStats = _stats.get(player);
PVPStats killerStats = _stats.get(killer);
playerStats.EndHealth = 0;
killerStats.EndHealth = killer.getHealth();
}
@EventHandler(priority = EventPriority.MONITOR)
public void damage(CustomDamageEvent event)
{
if (event.isCancelled())
{
return;
}
Player damagee = event.GetDamageePlayer();
Player damager = event.GetDamagerPlayer(true);
if (damagee == null)
{
return;
}
PVPStats damageeStats = _stats.get(damagee);
if (!_game.isAlive(damagee))
{
return;
}
damageeStats.CurrentCombo = 0;
damageeStats.DamageTaken += event.GetDamage();
if (damager == null)
{
return;
}
PVPStats damagerStats = _stats.get(damager);
damagerStats.DamageDealt += event.GetDamage();
if (event.GetCause() == DamageCause.ENTITY_ATTACK)
{
UtilTextBottom.display(FORMAT.format(damagee.getHealth() / 2D) + HEART, damager);
damagerStats.CurrentCombo++;
if (damagerStats.CurrentCombo > damagerStats.MaxCombo)
{
damagerStats.MaxCombo = damagerStats.CurrentCombo;
}
}
if (event.GetCause() == DamageCause.PROJECTILE)
{
damagerStats.ArrowsHit++;
damager.sendMessage(F.main(_game.getManager().getName(), F.name(damagee.getName()) + " is at " + C.cRedB + FORMAT.format(damagee.getHealth() / 2D) + HEART + C.mBody + "."));
}
}
@EventHandler
public void appleEat(PlayerItemConsumeEvent event)
{
Player player = event.getPlayer();
if (event.getItem().getType() != Material.GOLDEN_APPLE || !_game.isAlive(player))
{
return;
}
_stats.get(player).ApplesUsed++;
}
@EventHandler(priority = EventPriority.MONITOR)
public void blockPlace(BlockPlaceEvent event)
{
if (event.isCancelled())
{
return;
}
Player player = event.getPlayer();
if (!_game.isAlive(player))
{
return;
}
_stats.get(player).BlocksPlaced++;
}
@EventHandler(priority = EventPriority.MONITOR)
public void blockBreak(BlockBreakEvent event)
{
if (event.isCancelled())
{
return;
}
Player player = event.getPlayer();
if (!_game.isAlive(player))
{
return;
}
_stats.get(player).BlocksBroken++;
}
@EventHandler
public void shootBow(EntityShootBowEvent event)
{
if (!(event.getEntity() instanceof Player))
{
return;
}
Player player = (Player) event.getEntity();
if (!_game.isAlive(player))
{
return;
}
_stats.get(player).ArrowsShot++;
}
@EventHandler
public void start(HubGameStateChangeEvent event)
{
if (event.getState() != GameState.Prepare || !event.getGame().equals(_game))
{
return;
}
mainLoop:
for (Player player : _game.getAlivePlayers())
{
for (Player other : _game.getAlivePlayers())
{
if (!player.equals(other))
{
_stats.put(player, new PVPStats(other));
continue mainLoop;
}
}
}
}
@EventHandler
public void end(HubGameStateChangeEvent event)
{
if (event.getState() != GameState.Waiting || !event.getGame().equals(_game))
{
return;
}
UtilServer.runSyncLater(() ->
{
for (Player player : _game.getAlivePlayers())
{
PVPStats stats = _stats.get(player);
stats.Complete = true;
player.playSound(player.getLocation(), Sound.ORB_PICKUP, 1, 0.5F);
player.sendMessage("");
new JsonMessage(" Click to view the match summary for this match! ")
.color(Color.GREEN)
.bold()
.click(ClickEvent.RUN_COMMAND, STATS_COMMAND)
.hover(HoverEvent.SHOW_TEXT, C.cYellow + "Click here to view the match summary.")
.sendToPlayer(player);
player.sendMessage("");
}
}, 10);
}
@EventHandler
public void playerQuit(PlayerQuitEvent event)
{
PVPStats stats = _stats.remove(event.getPlayer());
if (stats != null)
{
stats.Complete = true;
}
}
@EventHandler
public void command(PlayerCommandPreprocessEvent event)
{
if (!event.getMessage().equals(STATS_COMMAND))
{
return;
}
Player player = event.getPlayer();
PVPStats stats = _stats.get(player);
if (stats == null)
{
return;
}
event.setCancelled(true);
PVPStats other = _stats.get(stats.Opponent);
if (other == null || !stats.Complete || !other.Complete)
{
player.sendMessage(F.main(_game.getManager().getName(), "Sorry but it seems that we cannot display the stats for that match anymore."));
return;
}
player.sendMessage(HubGameManager.getHeaderFooter());
player.sendMessage(UtilText.centerChat(C.cGreenB + player.getName() + C.cWhite + " v " + C.cRedB + stats.Opponent.getName(), LineFormat.CHAT));
player.sendMessage("");
sendStat(player, "Health", stats.EndHealth, other.EndHealth, HEART);
sendStat(player, "Damage Dealt", stats.DamageDealt, other.DamageDealt, HEART);
sendStat(player, "Damage Taken", stats.DamageTaken, other.DamageTaken, HEART);
sendStat(player, "Apples Used", stats.ApplesUsed, other.ApplesUsed, "");
sendStat(player, "Blocks Placed", stats.BlocksPlaced, other.BlocksPlaced, "");
sendStat(player, "Blocks Broken", stats.BlocksBroken, other.BlocksBroken, "");
new JsonMessage(getStatString(
"Bow Accuracy",
((double) stats.ArrowsHit / Math.max(1, stats.ArrowsShot) * 100D),
((double) other.ArrowsHit / Math.max(1, other.ArrowsShot) * 100D),
"%"))
.hover(HoverEvent.SHOW_TEXT,
getStatString("Arrows Shot", stats.ArrowsShot, other.ArrowsShot, "") + "\n" +
getStatString("Arrows Hit", stats.ArrowsHit, other.ArrowsHit, "")
)
.sendToPlayer(player);
sendStat(player, "Combo", stats.MaxCombo, other.MaxCombo, "");
player.sendMessage("");
player.sendMessage(C.cDGreen + "Hover over values to find out more information!");
player.sendMessage(HubGameManager.getHeaderFooter());
}
private void sendStat(Player player, String statName, double statA, double statB, String suffix)
{
new JsonMessage(getStatString(statName, statA, statB, suffix))
.sendToPlayer(player);
}
private String getStatString(String statName, double statA, double statB, String suffix)
{
boolean aHigher = statA > statB;
boolean equal = statA == statB;
String statString =
C.cGreen + (aHigher || equal ? C.Bold : "") + FORMAT.format(statA) + C.cWhite + suffix +
" v " +
C.cRed + (!aHigher || equal ? C.Bold : "") + FORMAT.format(statB) + C.cWhite + suffix;
return UtilText.centerChat(C.cWhiteB + statName + statString, LineFormat.CHAT);
}
private class PVPStats
{
Player Opponent;
double EndHealth;
double DamageDealt;
double DamageTaken;
int ApplesUsed;
int BlocksPlaced;
int BlocksBroken;
int ArrowsShot;
int ArrowsHit;
int CurrentCombo;
int MaxCombo;
boolean Complete;
PVPStats(Player opponent)
{
Opponent = opponent;
}
}
}

View File

@ -77,7 +77,7 @@ public class BlockRecorderComponent extends HubGameComponent<CycledGame>
@EventHandler
public void end(HubGameStateChangeEvent event)
{
if (event.getState() != GameState.Waiting)
if (event.getState() != GameState.Waiting || !event.getGame().equals(_game))
{
return;
}

View File

@ -27,7 +27,7 @@ public class TeleportIntoMapComponent extends HubGameComponent<HubGame>
@EventHandler
public void prepare(HubGameStateChangeEvent event)
{
if (event.getState() != GameState.Prepare)
if (event.getState() != GameState.Prepare || !event.getGame().equals(_game))
{
return;
}

View File

@ -17,6 +17,7 @@ import mineplex.hub.hubgame.CycledGame;
import mineplex.hub.hubgame.HubGameManager;
import mineplex.hub.hubgame.HubGameType;
import mineplex.hub.hubgame.common.damage.DamageComponent;
import mineplex.hub.hubgame.common.damage.PVPTrackerComponent;
import mineplex.hub.hubgame.common.general.GameTimeoutComponent;
import mineplex.hub.hubgame.common.general.InventoryEditComponent;
import mineplex.hub.hubgame.common.general.PrepareFreezeComponent;
@ -71,6 +72,7 @@ public class Duels extends CycledGame
super(manager, HubGameType.DUELS);
registerComponent(new DamageComponent(this));
registerComponent(new PVPTrackerComponent(this));
registerComponent(new TeleportIntoMapComponent(this, _worldData.getDataLocation("YELLOW")));
registerComponent(new PrepareFreezeComponent(this));
registerComponent(new InventoryEditComponent(this));