From d0199a85e09991293df017d1cf58895a622f19c6 Mon Sep 17 00:00:00 2001 From: hyperdefined Date: Sun, 30 Mar 2025 20:33:30 -0400 Subject: [PATCH] added damage done system --- .../java/lol/hyper/toolstats/ToolStats.java | 6 +- .../hyper/toolstats/events/AnvilEvent.java | 29 +- .../hyper/toolstats/events/EntityDamage.java | 309 +++++++++++------- .../hyper/toolstats/tools/ItemChecker.java | 3 + .../lol/hyper/toolstats/tools/ItemLore.java | 93 +++++- .../hyper/toolstats/tools/TokenCrafting.java | 7 + .../toolstats/tools/config/ConfigUpdater.java | 5 + .../toolstats/tools/config/TokenItems.java | 18 + .../tools/config/versions/Version11.java | 99 ++++++ src/main/resources/config.yml | 19 +- 10 files changed, 460 insertions(+), 128 deletions(-) create mode 100644 src/main/java/lol/hyper/toolstats/tools/config/versions/Version11.java diff --git a/src/main/java/lol/hyper/toolstats/ToolStats.java b/src/main/java/lol/hyper/toolstats/ToolStats.java index 7273105..42b0cfa 100644 --- a/src/main/java/lol/hyper/toolstats/ToolStats.java +++ b/src/main/java/lol/hyper/toolstats/ToolStats.java @@ -77,6 +77,10 @@ public final class ToolStats extends JavaPlugin { * Stores how much damage an armor piece has taken. */ public final NamespacedKey armorDamage = new NamespacedKey(this, "damage-taken"); + /** + * Stores how much damage a weapon has done. + */ + public final NamespacedKey damageDone = new NamespacedKey(this, "damage-done"); /** * Key for tracking new elytras that spawn. */ @@ -113,7 +117,7 @@ public final class ToolStats extends JavaPlugin { */ public final NamespacedKey originType = new NamespacedKey(this, "origin"); - public final int CONFIG_VERSION = 10; + public final int CONFIG_VERSION = 11; public final Logger logger = this.getLogger(); public final File configFile = new File(this.getDataFolder(), "config.yml"); public boolean tokens = false; diff --git a/src/main/java/lol/hyper/toolstats/events/AnvilEvent.java b/src/main/java/lol/hyper/toolstats/events/AnvilEvent.java index a763d52..77b1146 100644 --- a/src/main/java/lol/hyper/toolstats/events/AnvilEvent.java +++ b/src/main/java/lol/hyper/toolstats/events/AnvilEvent.java @@ -133,6 +133,10 @@ public class AnvilEvent implements Listener { addToken(event, tokenType, "mob-kills", clone); return; } + if (tokenType.equalsIgnoreCase("damage-done")) { + addToken(event, tokenType, "damage-done", clone); + return; + } return; } if (firstSlotMaterial == Material.BOW || firstSlotMaterial == Material.CROSSBOW) { @@ -148,6 +152,10 @@ public class AnvilEvent implements Listener { addToken(event, tokenType, "arrows-shot", clone); return; } + if (tokenType.equalsIgnoreCase("damage-done")) { + addToken(event, tokenType, "damage-done", clone); + return; + } return; } if (firstSlotMaterial == Material.ELYTRA) { @@ -203,7 +211,16 @@ public class AnvilEvent implements Listener { } case "damage-taken": { if (toolStats.config.getBoolean("enabled.armor-damage")) { - newItem.setItemMeta(toolStats.itemLore.updateDamage(newItem, 0.0, false)); + newItem.setItemMeta(toolStats.itemLore.updateArmorDamage(newItem, 0.0, false)); + } else { + event.setResult(null); + return; + } + break; + } + case "damage-done": { + if (toolStats.configTools.checkConfig(newItem.getType(), "damage-done")) { + newItem.setItemMeta(toolStats.itemLore.updateWeaponDamage(newItem, 0.0, false)); } else { event.setResult(null); return; @@ -338,7 +355,15 @@ public class AnvilEvent implements Listener { if (armorDamage == null) { return; } - meta = toolStats.itemLore.updateDamage(finalItem, -armorDamage, true); + meta = toolStats.itemLore.updateArmorDamage(finalItem, -armorDamage, true); + finalItem.setItemMeta(meta); + } + if (container.has(toolStats.damageDone)) { + Double damageDone = container.get(toolStats.damageDone, PersistentDataType.DOUBLE); + if (damageDone == null) { + return; + } + meta = toolStats.itemLore.updateArmorDamage(finalItem, -damageDone, true); finalItem.setItemMeta(meta); } if (container.has(toolStats.arrowsShot)) { diff --git a/src/main/java/lol/hyper/toolstats/events/EntityDamage.java b/src/main/java/lol/hyper/toolstats/events/EntityDamage.java index 83032dd..5d90c2f 100644 --- a/src/main/java/lol/hyper/toolstats/events/EntityDamage.java +++ b/src/main/java/lol/hyper/toolstats/events/EntityDamage.java @@ -18,12 +18,10 @@ package lol.hyper.toolstats.events; import lol.hyper.toolstats.ToolStats; +import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.Material; -import org.bukkit.entity.Arrow; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.entity.Trident; +import org.bukkit.entity.*; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -33,12 +31,14 @@ import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.projectiles.ProjectileSource; import java.util.*; public class EntityDamage implements Listener { private final ToolStats toolStats; + // track mobs that are killed by a player public final Set trackedMobs = new HashSet<>(); private final List ignoredCauses = Arrays.asList(EntityDamageEvent.DamageCause.SUICIDE, EntityDamageEvent.DamageCause.VOID, EntityDamageEvent.DamageCause.CUSTOM, EntityDamageEvent.DamageCause.KILL); @@ -62,105 +62,84 @@ public class EntityDamage implements Listener { return; } - // mob is going to die - if (mobBeingAttacked.getHealth() - event.getFinalDamage() <= 0) { - // a player is killing something - if (event.getDamager() instanceof Player attackingPlayer) { - if (attackingPlayer.getGameMode() == GameMode.CREATIVE || attackingPlayer.getGameMode() == GameMode.SPECTATOR) { - return; - } - PlayerInventory attackingPlayerInventory = attackingPlayer.getInventory(); - ItemStack heldItem = attackingPlayerInventory.getItemInMainHand(); - // only check certain items - if (!toolStats.itemChecker.isMeleeWeapon(heldItem.getType())) { - return; - } - // a player is killing another player - if (mobBeingAttacked instanceof Player) { - ItemMeta newItem = toolStats.itemLore.updatePlayerKills(heldItem, 1); - if (newItem != null) { - attackingPlayerInventory.getItemInMainHand().setItemMeta(newItem); - } - updateArmorDamage(((Player) mobBeingAttacked).getInventory(), event.getFinalDamage()); - return; - } - // player is killing regular mob - ItemMeta newItem = toolStats.itemLore.updateMobKills(heldItem, 1); - if (newItem != null) { - attackingPlayerInventory.getItemInMainHand().setItemMeta(newItem); - } - trackedMobs.add(mobBeingAttacked.getUniqueId()); - } - // trident is being thrown at something - if (event.getDamager() instanceof Trident trident) { - ItemStack newTrident = trident.getItemStack(); - ItemMeta newMeta; - // trident is killing player - if (mobBeingAttacked instanceof Player) { - updateArmorDamage(((Player) mobBeingAttacked).getInventory(), event.getFinalDamage()); - newMeta = toolStats.itemLore.updatePlayerKills(trident.getItemStack(), 1); - } else { - // trident is killing a mob - newMeta = toolStats.itemLore.updateMobKills(trident.getItemStack(), 1); - trackedMobs.add(mobBeingAttacked.getUniqueId()); - } - if (newMeta != null) { - newTrident.setItemMeta(newMeta); - trident.setItemStack(newTrident); - } - } - // arrow is being shot - if (event.getDamager() instanceof Arrow arrow) { - // if the shooter is a player - if (arrow.getShooter() instanceof Player shootingPlayer) { - if (shootingPlayer.getGameMode() == GameMode.CREATIVE || shootingPlayer.getGameMode() == GameMode.SPECTATOR) { - return; - } - PlayerInventory shootingPlayerInventory = shootingPlayer.getInventory(); - ItemStack heldBow = toolStats.itemChecker.getBow(shootingPlayerInventory); - if (heldBow == null) { - return; - } + Entity damager = event.getDamager(); + boolean playerAttacking = damager instanceof Player; + boolean playerBeingAttacked = mobBeingAttacked instanceof Player; + double finalDamage = event.getFinalDamage(); + boolean modDied = mobBeingAttacked.getHealth() - finalDamage <= 0; - boolean isMain = shootingPlayerInventory.getItemInMainHand().getType() == Material.BOW || shootingPlayerInventory.getItemInMainHand().getType() == Material.CROSSBOW; - boolean isOffHand = shootingPlayerInventory.getItemInOffHand().getType() == Material.BOW || shootingPlayerInventory.getItemInOffHand().getType() == Material.CROSSBOW; - - // player is shooting another player - if (mobBeingAttacked instanceof Player) { - ItemMeta newBow = toolStats.itemLore.updatePlayerKills(heldBow, 1); - if (newBow != null) { - if (isMain && isOffHand) { - shootingPlayerInventory.getItemInMainHand().setItemMeta(newBow); - } else if (isMain) { - shootingPlayerInventory.getItemInMainHand().setItemMeta(newBow); - } else if (isOffHand) { - shootingPlayerInventory.getItemInOffHand().setItemMeta(newBow); - } - } - updateArmorDamage(((Player) mobBeingAttacked).getInventory(), event.getFinalDamage()); - } else { - // player is shooting a mob - ItemMeta newBow = toolStats.itemLore.updateMobKills(heldBow, 1); - if (newBow != null) { - if (isMain && isOffHand) { - shootingPlayerInventory.getItemInMainHand().setItemMeta(newBow); - } else if (isMain) { - shootingPlayerInventory.getItemInMainHand().setItemMeta(newBow); - } else if (isOffHand) { - shootingPlayerInventory.getItemInOffHand().setItemMeta(newBow); - } - } - trackedMobs.add(mobBeingAttacked.getUniqueId()); - } - } - } - } - // player is taken damage but not being killed - if (mobBeingAttacked instanceof Player playerTakingDamage) { - if (playerTakingDamage.getGameMode() == GameMode.CREATIVE || playerTakingDamage.getGameMode() == GameMode.SPECTATOR) { + // player attacks something + if (playerAttacking) { + PlayerInventory playerAttackingInventory = ((Player) damager).getInventory(); + // make sure the item the player used is an item we want + if (!toolStats.itemChecker.isMeleeWeapon(playerAttackingInventory.getItemInMainHand().getType())) { return; } - updateArmorDamage(playerTakingDamage.getInventory(), event.getFinalDamage()); + + // update their weapon's damage + updateWeaponDamage(playerAttackingInventory, event.getFinalDamage()); + + // the mob the player attacked died + if (modDied) { + // player killed another player + if (playerBeingAttacked) { + updateWeaponKills(playerAttackingInventory, "player"); + } else { + // player kills a regular mob + updateWeaponKills(playerAttackingInventory, "mob"); + } + } + + trackedMobs.add(mobBeingAttacked.getUniqueId()); + Bukkit.getGlobalRegionScheduler().runDelayed(toolStats, scheduledTask -> trackedMobs.remove(mobBeingAttacked.getUniqueId()), 20); + } + + // something was hit by a trident + if (damager instanceof Trident trident) { + ProjectileSource source = trident.getShooter(); + if (source instanceof Player) { + // update the trident's tracked damage + updateTridentDamage(trident, finalDamage); + + // if the mob died from the trident + if (modDied) { + // if the trident killed a player, update the kills + if (playerBeingAttacked) { + updateTridentKills(trident, "player"); + } else { + // the trident killed a mob, update the kills + updateTridentKills(trident, "mob"); + } + } + + trackedMobs.add(mobBeingAttacked.getUniqueId()); + Bukkit.getGlobalRegionScheduler().runDelayed(toolStats, scheduledTask -> trackedMobs.remove(mobBeingAttacked.getUniqueId()), 20); + } + } + + // something was hit by an arrow + if (damager instanceof Arrow arrow) { + ProjectileSource source = arrow.getShooter(); + + // a player shot the arrow + if (source instanceof Player shootingPlayer) { + // update the player's bow damage + updateBowDamage(shootingPlayer.getInventory(), finalDamage); + + // if the mob died from the arrow + if (modDied) { + if (playerBeingAttacked) { + // player killed another player with an arrow + updateBowKills(shootingPlayer.getInventory(), "player"); + } else { + // player killed mob with an arrow + updateBowKills(shootingPlayer.getInventory(), "mob"); + } + } + + trackedMobs.add(mobBeingAttacked.getUniqueId()); + Bukkit.getGlobalRegionScheduler().runDelayed(toolStats, scheduledTask -> trackedMobs.remove(mobBeingAttacked.getUniqueId()), 20); + } } } @@ -176,28 +155,7 @@ public class EntityDamage implements Listener { return; } - // player is taken damage but not being killed - if (mobBeingAttacked instanceof Player playerTakingDamage) { - if (playerTakingDamage.getGameMode() == GameMode.CREATIVE || playerTakingDamage.getGameMode() == GameMode.SPECTATOR) { - return; - } - updateArmorDamage(playerTakingDamage.getInventory(), event.getFinalDamage()); - } - } - - @EventHandler(priority = EventPriority.MONITOR) - public void onDamage(EntityDamageByBlockEvent event) { - if (!(event.getEntity() instanceof LivingEntity mobBeingAttacked)) { - return; - } - - // ignore void and /kill damage - EntityDamageEvent.DamageCause cause = event.getCause(); - if (ignoredCauses.contains(cause)) { - return; - } - - // player is taken damage but not being killed + // player is taking damage if (mobBeingAttacked instanceof Player playerTakingDamage) { if (playerTakingDamage.getGameMode() == GameMode.CREATIVE || playerTakingDamage.getGameMode() == GameMode.SPECTATOR) { return; @@ -211,7 +169,7 @@ public class EntityDamage implements Listener { for (ItemStack armorPiece : armorContents) { if (armorPiece != null) { if (toolStats.itemChecker.isArmor(armorPiece.getType())) { - ItemMeta newItem = toolStats.itemLore.updateDamage(armorPiece, damage, false); + ItemMeta newItem = toolStats.itemLore.updateArmorDamage(armorPiece, damage, false); if (newItem != null) { armorPiece.setItemMeta(newItem); } @@ -221,4 +179,109 @@ public class EntityDamage implements Listener { // apply the new armor playerInventory.setArmorContents(armorContents); } + + private void updateBowDamage(PlayerInventory playerInventory, double damage) { + ItemStack heldBow = toolStats.itemChecker.getBow(playerInventory); + if (heldBow == null) { + return; + } + + boolean isMain = playerInventory.getItemInMainHand().getType() == Material.BOW || playerInventory.getItemInMainHand().getType() == Material.CROSSBOW; + boolean isOffHand = playerInventory.getItemInOffHand().getType() == Material.BOW || playerInventory.getItemInOffHand().getType() == Material.CROSSBOW; + ItemMeta newBowDamage = toolStats.itemLore.updateWeaponDamage(playerInventory.getItemInMainHand(), damage, false); + //toolStats.logger.info(newBowDamage.toString()); + + // player is shooting another player + if (newBowDamage != null) { + if (isMain && isOffHand) { + playerInventory.getItemInMainHand().setItemMeta(newBowDamage); + } else if (isMain) { + playerInventory.getItemInMainHand().setItemMeta(newBowDamage); + } else if (isOffHand) { + playerInventory.getItemInOffHand().setItemMeta(newBowDamage); + } + } + } + + private void updateBowKills(PlayerInventory playerInventory, String type) { + ItemStack heldBow = toolStats.itemChecker.getBow(playerInventory); + if (heldBow == null) { + return; + } + + boolean isMain = playerInventory.getItemInMainHand().getType() == Material.BOW || playerInventory.getItemInMainHand().getType() == Material.CROSSBOW; + boolean isOffHand = playerInventory.getItemInOffHand().getType() == Material.BOW || playerInventory.getItemInOffHand().getType() == Material.CROSSBOW; + + if (type.equalsIgnoreCase("mob")) { + // player is shooting a mob + ItemMeta newBow = toolStats.itemLore.updateMobKills(heldBow, 1); + if (newBow != null) { + if (isMain && isOffHand) { + playerInventory.getItemInMainHand().setItemMeta(newBow); + } else if (isMain) { + playerInventory.getItemInMainHand().setItemMeta(newBow); + } else if (isOffHand) { + playerInventory.getItemInOffHand().setItemMeta(newBow); + } + } + } + + if (type.equalsIgnoreCase("player")) { + ItemMeta newBowKills = toolStats.itemLore.updatePlayerKills(heldBow, 1); + if (newBowKills != null) { + if (isMain && isOffHand) { + playerInventory.getItemInMainHand().setItemMeta(newBowKills); + } else if (isMain) { + playerInventory.getItemInMainHand().setItemMeta(newBowKills); + } else if (isOffHand) { + playerInventory.getItemInOffHand().setItemMeta(newBowKills); + } + } + } + } + + private void updateTridentKills(Trident trident, String type) { + ItemStack newTrident = trident.getItemStack(); + ItemMeta newKills; + if (type.equalsIgnoreCase("player")) { + newKills = toolStats.itemLore.updatePlayerKills(trident.getItemStack(), 1); + } else { + newKills = toolStats.itemLore.updateMobKills(trident.getItemStack(), 1); + } + if (newKills != null) { + newTrident.setItemMeta(newKills); + trident.setItemStack(newTrident); + } + } + + private void updateTridentDamage(Trident trident, double damage) { + ItemStack newTrident = trident.getItemStack(); + ItemMeta newDamage = toolStats.itemLore.updateWeaponDamage(trident.getItemStack(), damage, false); + if (newDamage != null) { + newTrident.setItemMeta(newDamage); + trident.setItemStack(newTrident); + } + } + + private void updateWeaponDamage(PlayerInventory playerInventory, double damage) { + ItemStack heldWeapon = playerInventory.getItemInMainHand(); + ItemMeta newHeldWeaponMeta = toolStats.itemLore.updateWeaponDamage(heldWeapon, damage, false); + if (newHeldWeaponMeta != null) { + playerInventory.getItemInMainHand().setItemMeta(newHeldWeaponMeta); + } + } + + private void updateWeaponKills(PlayerInventory playerInventory, String type) { + ItemStack heldWeapon = playerInventory.getItemInMainHand(); + ItemMeta newHeldWeaponMeta = null; + if (type.equalsIgnoreCase("player")) { + newHeldWeaponMeta = toolStats.itemLore.updatePlayerKills(heldWeapon, 1); + } + if (type.equalsIgnoreCase("mob")) { + newHeldWeaponMeta = toolStats.itemLore.updateMobKills(heldWeapon, 1); + } + if (newHeldWeaponMeta != null) { + playerInventory.getItemInMainHand().setItemMeta(newHeldWeaponMeta); + } + } } diff --git a/src/main/java/lol/hyper/toolstats/tools/ItemChecker.java b/src/main/java/lol/hyper/toolstats/tools/ItemChecker.java index 05b3013..53c839d 100644 --- a/src/main/java/lol/hyper/toolstats/tools/ItemChecker.java +++ b/src/main/java/lol/hyper/toolstats/tools/ItemChecker.java @@ -333,6 +333,9 @@ public class ItemChecker { if (container.has(toolStats.flightTime)) { tokens.add("flight-time"); } + if (container.has(toolStats.damageDone)) { + tokens.add("damage-done"); + } if (tokens.isEmpty()) { return null; } diff --git a/src/main/java/lol/hyper/toolstats/tools/ItemLore.java b/src/main/java/lol/hyper/toolstats/tools/ItemLore.java index 109fa1c..4ac83f8 100644 --- a/src/main/java/lol/hyper/toolstats/tools/ItemLore.java +++ b/src/main/java/lol/hyper/toolstats/tools/ItemLore.java @@ -567,7 +567,7 @@ public class ItemLore { * @param damage The amount of damage to apply. * @param bypass Bypass the negative damage check. */ - public ItemMeta updateDamage(ItemStack armorPiece, double damage, boolean bypass) { + public ItemMeta updateArmorDamage(ItemStack armorPiece, double damage, boolean bypass) { // ignore if the damage is zero or negative if (damage < 0) { if (!bypass) { @@ -651,6 +651,97 @@ public class ItemLore { return meta; } + /** + * Add damage to a weapon. + * + * @param weapon The weapon to update. + * @param damage The amount of damage to apply. + * @param bypass Bypass the negative damage check. + */ + public ItemMeta updateWeaponDamage(ItemStack weapon, double damage, boolean bypass) { + // ignore if the damage is zero or negative + if (damage < 0) { + if (!bypass) { + return null; + } + } + ItemStack clone = weapon.clone(); + ItemMeta meta = clone.getItemMeta(); + if (meta == null) { + toolStats.logger.warning(clone + " does NOT have any meta! Unable to update stats."); + return null; + } + + PersistentDataContainer container = meta.getPersistentDataContainer(); + + // if it's disabled, don't update the stats + // check to see if the item has the stats, remove them if it does + if (!toolStats.configTools.checkConfig(clone.getType(), "damage-done")) { + if (container.has(toolStats.damageDone)) { + Double damageDone = container.get(toolStats.damageDone, PersistentDataType.DOUBLE); + if (damageDone == null) { + return null; + } + container.remove(toolStats.damageDone); + if (meta.hasLore()) { + String oldDamageDoneFormatted = toolStats.numberFormat.formatDouble(damageDone); + Component lineToRemove = toolStats.configTools.formatLore("damage-done", "{damage}", oldDamageDoneFormatted); + List newLore = removeLore(meta.lore(), lineToRemove); + meta.lore(newLore); + } + return meta; + } + return null; + } + + // check for tokens + boolean validToken = toolStats.itemChecker.checkTokens(container, "damage-done"); + // check for tokens + if (toolStats.config.getBoolean("tokens.enabled")) { + // if the item has stats but no token, add the token + if (container.has(toolStats.damageDone) && !validToken) { + String newTokens = toolStats.itemChecker.addTokensToExisting(clone); + if (newTokens != null) { + container.set(toolStats.tokenApplied, PersistentDataType.STRING, newTokens); + } + } + + // the item does not have a valid token + if (!validToken) { + return null; + } + } else { + if (!validToken) { + String newTokens = toolStats.itemChecker.addTokensToExisting(clone); + if (newTokens != null) { + container.set(toolStats.tokenApplied, PersistentDataType.STRING, newTokens); + } + } + } + + Double damageDone = 0.0; + if (container.has(toolStats.damageDone, PersistentDataType.DOUBLE)) { + damageDone = container.get(toolStats.damageDone, PersistentDataType.DOUBLE); + } + + if (damageDone == null) { + damageDone = 0.0; + toolStats.logger.warning(clone + " does not have valid damage-done set! Resting to zero. This should NEVER happen."); + } + + container.set(toolStats.damageDone, PersistentDataType.DOUBLE, damageDone + damage); + String oldDamageFormatted = toolStats.numberFormat.formatDouble(damageDone); + String newDamageFormatted = toolStats.numberFormat.formatDouble(damageDone + damage); + Component oldLine = toolStats.configTools.formatLore("damage-done", "{damage}", oldDamageFormatted); + Component newLine = toolStats.configTools.formatLore("damage-done", "{damage}", newDamageFormatted); + if (oldLine == null || newLine == null) { + return null; + } + List newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine); + meta.lore(newLore); + return meta; + } + /** * Add flight time to an elytra. * diff --git a/src/main/java/lol/hyper/toolstats/tools/TokenCrafting.java b/src/main/java/lol/hyper/toolstats/tools/TokenCrafting.java index 2e3a4b7..274ac56 100644 --- a/src/main/java/lol/hyper/toolstats/tools/TokenCrafting.java +++ b/src/main/java/lol/hyper/toolstats/tools/TokenCrafting.java @@ -86,6 +86,13 @@ public class TokenCrafting { armorDamageRecipe.setIngredient('C', Material.LEATHER_CHESTPLATE); recipes.add(armorDamageRecipe); + NamespacedKey damageDoneKey = new NamespacedKey(toolStats, "damage-done-token"); + ShapedRecipe damageDoneRecipe = new ShapedRecipe(damageDoneKey, toolStats.tokenItems.damageDone()); + damageDoneRecipe.shape(" P ", "PSP", " P "); + damageDoneRecipe.setIngredient('P', Material.PAPER); + damageDoneRecipe.setIngredient('S', Material.SHIELD); + recipes.add(damageDoneRecipe); + NamespacedKey arrowsShotKey = new NamespacedKey(toolStats, "arrows-shot-token"); ShapedRecipe arrowsShotRecipe = new ShapedRecipe(arrowsShotKey, toolStats.tokenItems.arrowsShot()); arrowsShotRecipe.shape(" P ", "PAP", " P "); diff --git a/src/main/java/lol/hyper/toolstats/tools/config/ConfigUpdater.java b/src/main/java/lol/hyper/toolstats/tools/config/ConfigUpdater.java index 8712c49..244d17d 100644 --- a/src/main/java/lol/hyper/toolstats/tools/config/ConfigUpdater.java +++ b/src/main/java/lol/hyper/toolstats/tools/config/ConfigUpdater.java @@ -56,5 +56,10 @@ public class ConfigUpdater { Version10 version10 = new Version10(toolStats); version10.update(); } + // Version 10 to 11 + if (version == 10) { + Version11 version11 = new Version11(toolStats); + version11.update(); + } } } diff --git a/src/main/java/lol/hyper/toolstats/tools/config/TokenItems.java b/src/main/java/lol/hyper/toolstats/tools/config/TokenItems.java index 81402c8..d735a2e 100644 --- a/src/main/java/lol/hyper/toolstats/tools/config/TokenItems.java +++ b/src/main/java/lol/hyper/toolstats/tools/config/TokenItems.java @@ -162,6 +162,24 @@ public class TokenItems { return token; } + public ItemStack damageDone() { + // set up the item + ItemStack token = new ItemStack(Material.PAPER); + ItemMeta tokenMeta = token.getItemMeta(); + PersistentDataContainer tokenData = tokenMeta.getPersistentDataContainer(); + + // set the title and lore + Component title = toolStats.configTools.format("tokens.data.damage-done.title"); + List lore = toolStats.configTools.getTokenLore("damage-done"); + tokenMeta.displayName(title); + tokenMeta.lore(lore); + + // set the PDC + tokenData.set(toolStats.tokenType, PersistentDataType.STRING, "damage-done"); + token.setItemMeta(tokenMeta); + return token; + } + public ItemStack arrowsShot() { // set up the item ItemStack token = new ItemStack(Material.PAPER); diff --git a/src/main/java/lol/hyper/toolstats/tools/config/versions/Version11.java b/src/main/java/lol/hyper/toolstats/tools/config/versions/Version11.java new file mode 100644 index 0000000..71fd4c2 --- /dev/null +++ b/src/main/java/lol/hyper/toolstats/tools/config/versions/Version11.java @@ -0,0 +1,99 @@ +/* + * This file is part of ToolStats. + * + * ToolStats is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * ToolStats is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ToolStats. If not, see . + */ + +package lol.hyper.toolstats.tools.config.versions; + +import lol.hyper.toolstats.ToolStats; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class Version11 { + + private final ToolStats toolStats; + + /** + * Used for updating from version 10 to 11. + * + * @param toolStats ToolStats instance. + */ + public Version11(ToolStats toolStats) { + this.toolStats = toolStats; + } + + /** + * Perform the config update. + */ + public void update() { + // save the old config first + try { + toolStats.config.save("plugins" + File.separator + "ToolStats" + File.separator + "config-10.yml"); + } catch (IOException exception) { + toolStats.logger.severe("Unable to save config-10.yml!"); + throw new RuntimeException(exception); + } + + // we make this super verbose so that admins can see what's being added + toolStats.logger.info("Updating config.yml to version 11."); + toolStats.config.set("config-version", 11); + + // add new tokens + toolStats.logger.info("Adding tokens.data.damage-done.title to config.yml."); + toolStats.config.set("tokens.data.damage-done.title", "&7ToolStats: &8Damage Done Token"); + List damageDoneLore = new ArrayList<>(); + damageDoneLore.add("&8Combine with a melee or ranged weapon in an anvil to track damage done."); + toolStats.config.set("tokens.data.damage-done.lore", damageDoneLore); + toolStats.logger.info("Adding tokens.data.damage-done.lore to config.yml."); + toolStats.config.set("tokens.data.damage-done.levels", 1); + toolStats.logger.info("Adding tokens.data.damage-done.levels to config.yml."); + + toolStats.logger.info("Adding tokens.data.remove.title to config.yml."); + toolStats.config.set("tokens.data.remove.title", "&7ToolStats: &8Remove Token"); + List removeLore = new ArrayList<>(); + removeLore.add("&8Combine in an anvil with to REMOVE ALL stats and tokens for this item."); + toolStats.config.set("tokens.data.remove.lore", removeLore); + toolStats.logger.info("Adding tokens.data.remove.lore to config.yml."); + toolStats.config.set("tokens.data.remove.levels", 1); + toolStats.logger.info("Adding tokens.data.remove.levels to config.yml."); + + toolStats.logger.info("Adding messages.damage-done to config.yml."); + toolStats.config.set("messages.damage-done", "&7Damage done: &8{damage}"); + + toolStats.config.set("enabled.damage-done.sword", true); + toolStats.config.set("enabled.damage-done.axe", true); + toolStats.config.set("enabled.damage-done.trident", true); + toolStats.config.set("enabled.damage-done.bow", true); + toolStats.config.set("enabled.damage-done.mace", true); + toolStats.logger.info("Adding enabled.damage-done.sword to config.yml"); + toolStats.logger.info("Adding enabled.damage-done.axe to config.yml"); + toolStats.logger.info("Adding enabled.damage-done.trident to config.yml"); + toolStats.logger.info("Adding enabled.damage-done.bow to config.yml"); + toolStats.logger.info("Adding enabled.damage-done.mace to config.yml"); + + // save the config and reload it + try { + toolStats.config.save("plugins" + File.separator + "ToolStats" + File.separator + "config.yml"); + } catch (IOException exception) { + toolStats.logger.severe("Unable to save config.yml!"); + throw new RuntimeException(exception); + } + toolStats.loadConfig(); + toolStats.logger.info("Config has been updated to version 11. A copy of version 10 has been saved as config-10.yml"); + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index aafebc4..38a55d1 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -39,6 +39,11 @@ tokens: lore: - "&8Combine with an armor piece in an anvil to track damage taken." levels: 1 + damage-done: + title: "&7ToolStats: &8Damage Done Token" + lore: + - "&8Combine with a melee or ranged weapon in an anvil to track damage done." + levels: 1 arrows-shot: title: "&7ToolStats: &8Arrows Shot Token" lore: @@ -54,6 +59,11 @@ tokens: lore: - "&8Combine in an anvil with to reset ALL stats for this item. Tokens on this item stay." levels: 1 + remove: + title: "&7ToolStats: &8Remove Token" + lore: + - "&8Combine in an anvil with to REMOVE ALL stats and tokens for this item." + levels: 1 enabled: # Will show ownership of items when they are created/found. @@ -113,6 +123,12 @@ enabled: bow: true armor: true fishing-rod: true + damage-done: + sword: true + axe: true + trident: true + bow: true + mace: true player-kills: sword: true axe: true @@ -181,6 +197,7 @@ messages: damage-taken: "&7Damage taken: &8{damage}" arrows-shot: "&7Arrows shot: &8{arrows}" flight-time: "&7Flight time: &8{time}" + damage-done: "&7Damage done: &8{damage}" # Set display name for mobs. See: https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/entity/EntityType.html mobs: ZOMBIE: "Zombie" @@ -203,4 +220,4 @@ number-formats: # This has no use currently, but can be used for future features for dupe detection. generate-hash-for-items: false -config-version: 10 \ No newline at end of file +config-version: 11 \ No newline at end of file