PVP Stats
This commit is contained in:
parent
5600f72d56
commit
9d71cd7893
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user