tokens update

This commit is contained in:
hyperdefined
2025-01-25 16:56:03 -05:00
parent ff578e170e
commit 30b26533ef
21 changed files with 1705 additions and 531 deletions

View File

@@ -0,0 +1,195 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.PrepareAnvilEvent;
import org.bukkit.inventory.AnvilInventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import java.util.Locale;
public class AnvilEvent implements Listener {
private final ToolStats toolStats;
public AnvilEvent(ToolStats toolStats) {
this.toolStats = toolStats;
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onAnvilEvent(PrepareAnvilEvent event) {
AnvilInventory inventory = event.getInventory();
ItemStack firstSlot = inventory.getItem(0);
ItemStack secondSlot = inventory.getItem(1);
// make sure both slots have items
if (firstSlot == null || secondSlot == null) {
return;
}
Material firstSlotMaterial = firstSlot.getType();
Material secondSlotMaterial = secondSlot.getType();
// make sure the first item is a valid item
if (!toolStats.itemChecker.isValidItem(firstSlotMaterial)) {
return;
}
PersistentDataContainer firstSlotContainer = firstSlot.getItemMeta().getPersistentDataContainer();
PersistentDataContainer secondSlotContainer = secondSlot.getItemMeta().getPersistentDataContainer();
// make sure the 2nd item is one of ours
if (secondSlotMaterial != Material.PAPER || !secondSlotContainer.has(toolStats.tokenType, PersistentDataType.STRING)) {
return;
}
//get the type from the token
String tokenType = secondSlotContainer.get(toolStats.tokenType, PersistentDataType.STRING);
if (tokenType == null) {
return;
}
// clone the item
ItemStack clone = firstSlot.clone();
// if the item is a mining tool
if (toolStats.itemChecker.isMineTool(firstSlotMaterial)) {
if (firstSlotMaterial.toString().toLowerCase(Locale.ROOT).contains("hoe")) {
// the item is a hoe
addToken(event, tokenType, "crops-mined", clone);
} else {
// since shears will fall under here, check if the token is for sheep sheared
if (firstSlotMaterial == Material.SHEARS && tokenType.equals("sheep-sheared")) {
addToken(event, tokenType, "sheep-sheared", clone);
return;
}
addToken(event, tokenType, "blocks-mined", clone);
}
return;
}
if (toolStats.itemChecker.isArmor(firstSlotMaterial)) {
addToken(event, tokenType, "damage-taken", clone);
return;
}
if (toolStats.itemChecker.isMeleeWeapon(firstSlotMaterial)) {
if (tokenType.equalsIgnoreCase("player-kills")) {
addToken(event, tokenType, "player-kills", clone);
return;
}
if (tokenType.equalsIgnoreCase("mobs-kills")) {
addToken(event, tokenType, "mobs-kills", clone);
return;
}
return;
}
if (firstSlotMaterial == Material.BOW || firstSlotMaterial == Material.CROSSBOW) {
if (tokenType.equalsIgnoreCase("player-kills")) {
addToken(event, tokenType, "player-kills", clone);
return;
}
if (tokenType.equalsIgnoreCase("mobs-kills")) {
addToken(event, tokenType, "mobs-kills", clone);
return;
}
if (tokenType.equalsIgnoreCase("arrows-shot")) {
addToken(event, tokenType, "arrows-shot", clone);
return;
}
return;
}
if (firstSlotMaterial == Material.ELYTRA) {
addToken(event, tokenType, "flight-time", clone);
return;
}
if (firstSlotMaterial == Material.FISHING_ROD) {
addToken(event, tokenType, "fish-caught", clone);
}
}
/**
* Add token to an item.
*
* @param event The anvil event.
* @param attemptToken The token in the 2nd slot of the anvil. The one the player wants to add.
* @param targetToken The token we are checking for. This should match the tool.
* @param firstSlotItem The item in the first slot.
*/
private void addToken(PrepareAnvilEvent event, String attemptToken, String targetToken, ItemStack firstSlotItem) {
// make sure the token we are using is for this tool
if (!attemptToken.equalsIgnoreCase(targetToken)) {
event.setResult(null);
return;
}
// if the item already has the token, ignore
if (toolStats.itemChecker.checkTokens(firstSlotItem.getItemMeta().getPersistentDataContainer(), targetToken)) {
event.setResult(null);
return;
}
// apply the token and set the result
ItemStack newItem = toolStats.itemChecker.addToken(firstSlotItem, targetToken);
switch (targetToken) {
case "crops-mined": {
event.setResult(toolStats.itemLore.updateCropsMined(newItem, 0));
break;
}
case "blocks-mined": {
event.setResult(toolStats.itemLore.updateBlocksMined(newItem, 0));
break;
}
case "damage-taken": {
event.setResult(toolStats.itemLore.updateDamage(newItem, 0.0));
break;
}
case "mob-kills": {
event.setResult(toolStats.itemLore.updateMobKills(newItem, 0));
break;
}
case "player-kills": {
event.setResult(toolStats.itemLore.updatePlayerKills(newItem, 0));
break;
}
case "arrows-shot": {
event.setResult(toolStats.itemLore.updateArrowsShot(newItem, 0));
break;
}
case "sheep-sheared": {
event.setResult(toolStats.itemLore.updateSheepSheared(newItem, 0));
break;
}
case "flight-time": {
event.setResult(toolStats.itemLore.updateFlightTime(newItem, 0));
break;
}
case "fish-caught": {
event.setResult(toolStats.itemLore.updateFishCaught(newItem, 0));
break;
}
}
event.getView().setRepairCost(toolStats.itemChecker.getCost(targetToken));
}
}

View File

@@ -18,7 +18,6 @@
package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Material;
@@ -31,11 +30,7 @@ import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import java.util.List;
import java.util.Locale;
public class BlocksMined implements Listener {
@@ -69,91 +64,29 @@ public class BlocksMined implements Listener {
return;
}
// if the item is a hoe
if (heldItem.getType().toString().toLowerCase(Locale.ROOT).contains("hoe")) {
// player is breaking crops with a hoe
if (block.getBlockData() instanceof Ageable) {
updateCropsMined(heldItem, (Ageable) block.getBlockData());
if (block.getBlockData() instanceof Ageable ageable) {
// ignore crops that are not fully grown
if (ageable.getAge() != ageable.getMaximumAge()) {
return;
}
ItemStack newItem = toolStats.itemLore.updateCropsMined(heldItem, 1);
if (newItem != null) {
// replace item in main hand
inventory.setItemInMainHand(newItem);
}
}
} else {
// item is not a hoe
// update the blocks mined
updateBlocksMined(heldItem);
}
}
private void updateBlocksMined(ItemStack playerTool) {
ItemMeta meta = playerTool.getItemMeta();
if (meta == null) {
toolStats.logger.warning(playerTool + " does NOT have any meta! Unable to update stats.");
return;
}
// read the current stats from the item
// if they don't exist, then start from 0
Integer blocksMined = 0;
PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.genericMined, PersistentDataType.INTEGER)) {
blocksMined = container.get(toolStats.genericMined, PersistentDataType.INTEGER);
}
if (blocksMined == null) {
blocksMined = 0;
toolStats.logger.warning(playerTool + " does not have valid generic-mined set! Resting to zero. This should NEVER happen.");
}
container.set(toolStats.genericMined, PersistentDataType.INTEGER, blocksMined + 1);
// do we add the lore based on the config?
if (toolStats.configTools.checkConfig(playerTool.getType(), "blocks-mined")) {
String oldBlocksMinedFormatted = toolStats.numberFormat.formatInt(blocksMined);
String newBlocksMinedFormatted = toolStats.numberFormat.formatInt(blocksMined + 1);
Component oldLine = toolStats.configTools.formatLore("blocks-mined", "{blocks}", oldBlocksMinedFormatted);
Component newLine = toolStats.configTools.formatLore("blocks-mined", "{blocks}", newBlocksMinedFormatted);
if (oldLine == null || newLine == null) {
return;
ItemStack newItem = toolStats.itemLore.updateBlocksMined(heldItem, 1);
if (newItem != null) {
toolStats.logger.info(newItem.toString());
// replace item in main hand
inventory.setItemInMainHand(newItem);
}
List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.lore(newLore);
}
playerTool.setItemMeta(meta);
}
private void updateCropsMined(ItemStack playerTool, Ageable block) {
// ignore crops that are not fully grown
if (block.getAge() != block.getMaximumAge()) {
return;
}
ItemMeta meta = playerTool.getItemMeta();
if (meta == null) {
toolStats.logger.warning(playerTool + " does NOT have any meta! Unable to update stats.");
return;
}
// read the current stats from the item
// if they don't exist, then start from 0
Integer cropsMined = 0;
PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.cropsHarvested, PersistentDataType.INTEGER)) {
cropsMined = container.get(toolStats.cropsHarvested, PersistentDataType.INTEGER);
}
if (cropsMined == null) {
cropsMined = 0;
toolStats.logger.warning(playerTool + " does not have valid crops-mined set! Resting to zero. This should NEVER happen.");
}
container.set(toolStats.cropsHarvested, PersistentDataType.INTEGER, cropsMined + 1);
// do we add the lore based on the config?
if (toolStats.configTools.checkConfig(playerTool.getType(), "blocks-mined")) {
String oldCropsMinedFormatted = toolStats.numberFormat.formatInt(cropsMined);
String newCropsMinedFormatted = toolStats.numberFormat.formatInt(cropsMined + 1);
Component oldLine = toolStats.configTools.formatLore("crops-harvested", "{crops}", oldCropsMinedFormatted);
Component newLine = toolStats.configTools.formatLore("crops-harvested", "{crops}", newCropsMinedFormatted);
if (oldLine == null || newLine == null) {
return;
}
List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.lore(newLore);
}
playerTool.setItemMeta(meta);
}
}

View File

@@ -17,11 +17,9 @@
package lol.hyper.toolstats.events;
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
import lol.hyper.toolstats.ToolStats;
import lol.hyper.toolstats.tools.UUIDDataType;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.entity.Player;
@@ -29,9 +27,7 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.CraftItemEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
@@ -39,7 +35,6 @@ import org.bukkit.persistence.PersistentDataType;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.function.Consumer;
public class CraftItem implements Listener {

View File

@@ -18,10 +18,12 @@
package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats;
import net.kyori.adventure.text.Component;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.entity.*;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Trident;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
@@ -30,9 +32,6 @@ import org.bukkit.event.entity.EntityDamageByEntityEvent;
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.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import java.util.*;
@@ -77,11 +76,17 @@ public class EntityDamage implements Listener {
}
// a player is killing another player
if (mobBeingAttacked instanceof Player) {
updatePlayerKills(heldItem);
ItemStack newItem = toolStats.itemLore.updatePlayerKills(heldItem, 1);
if (newItem != null) {
attackingPlayerInventory.setItemInMainHand(newItem);
}
return;
}
// player is killing regular mob
updateMobKills(heldItem);
ItemStack newItem = toolStats.itemLore.updateMobKills(heldItem, 1);
if (newItem != null) {
attackingPlayerInventory.setItemInMainHand(newItem);
}
trackedMobs.add(mobBeingAttacked.getUniqueId());
}
// trident is being thrown at something
@@ -89,10 +94,10 @@ public class EntityDamage implements Listener {
ItemStack newTrident;
// trident is killing player
if (mobBeingAttacked instanceof Player) {
newTrident = tridentPlayerKills(trident.getItemStack());
newTrident = toolStats.itemLore.updatePlayerKills(trident.getItemStack(), 1);
} else {
// trident is killing a mob
newTrident = tridentMobKills(trident.getItemStack());
newTrident = toolStats.itemLore.updateMobKills(trident.getItemStack(), 1);
trackedMobs.add(mobBeingAttacked.getUniqueId());
}
if (newTrident != null) {
@@ -106,9 +111,9 @@ public class EntityDamage implements Listener {
if (shootingPlayer.getGameMode() == GameMode.CREATIVE || shootingPlayer.getGameMode() == GameMode.SPECTATOR) {
return;
}
PlayerInventory inventory = shootingPlayer.getInventory();
ItemStack main = inventory.getItemInMainHand();
ItemStack offHand = inventory.getItemInOffHand();
PlayerInventory shootingPlayerInventory = shootingPlayer.getInventory();
ItemStack main = shootingPlayerInventory.getItemInMainHand();
ItemStack offHand = shootingPlayerInventory.getItemInOffHand();
boolean isMain = main.getType() == Material.BOW || main.getType() == Material.CROSSBOW;
boolean isOffHand = offHand.getType() == Material.BOW || offHand.getType() == Material.CROSSBOW;
ItemStack heldBow = null;
@@ -126,9 +131,16 @@ public class EntityDamage implements Listener {
// player is shooting another player
if (mobBeingAttacked instanceof Player) {
updatePlayerKills(heldBow);
ItemStack newItem = toolStats.itemLore.updatePlayerKills(heldBow, 1);
if (newItem != null) {
shootingPlayerInventory.setItemInMainHand(newItem);
}
} else {
updateMobKills(heldBow);
// player is shooting a mob
ItemStack newItem = toolStats.itemLore.updateMobKills(heldBow, 1);
if (newItem != null) {
shootingPlayerInventory.setItemInMainHand(newItem);
}
trackedMobs.add(mobBeingAttacked.getUniqueId());
}
}
@@ -140,13 +152,21 @@ public class EntityDamage implements Listener {
return;
}
PlayerInventory playerInventory = playerTakingDamage.getInventory();
for (ItemStack armorPiece : playerInventory.getArmorContents()) {
ItemStack[] armorContents = playerInventory.getArmorContents();
for (int i = 0; i < armorContents.length; i++) {
ItemStack armorPiece = armorContents[i];
if (armorPiece != null) {
if (toolStats.itemChecker.isArmor(armorPiece.getType())) {
updateDamage(armorPiece, event.getFinalDamage());
ItemStack newItem = toolStats.itemLore.updateDamage(armorPiece, event.getFinalDamage());
if (newItem != null) {
armorContents[i] = newItem;
}
}
}
}
// apply the new armor
playerInventory.setArmorContents(armorContents);
}
}
@@ -168,13 +188,21 @@ public class EntityDamage implements Listener {
return;
}
PlayerInventory playerInventory = playerTakingDamage.getInventory();
for (ItemStack armorPiece : playerInventory.getArmorContents()) {
ItemStack[] armorContents = playerInventory.getArmorContents();
for (int i = 0; i < armorContents.length; i++) {
ItemStack armorPiece = armorContents[i];
if (armorPiece != null) {
if (toolStats.itemChecker.isArmor(armorPiece.getType())) {
updateDamage(armorPiece, event.getFinalDamage());
ItemStack newItem = toolStats.itemLore.updateDamage(armorPiece, event.getFinalDamage());
if (newItem != null) {
armorContents[i] = newItem;
}
}
}
}
// apply the new armor
playerInventory.setArmorContents(armorContents);
}
}
@@ -196,216 +224,21 @@ public class EntityDamage implements Listener {
return;
}
PlayerInventory playerInventory = playerTakingDamage.getInventory();
for (ItemStack armorPiece : playerInventory.getArmorContents()) {
ItemStack[] armorContents = playerInventory.getArmorContents();
for (int i = 0; i < armorContents.length; i++) {
ItemStack armorPiece = armorContents[i];
if (armorPiece != null) {
if (toolStats.itemChecker.isArmor(armorPiece.getType())) {
updateDamage(armorPiece, event.getFinalDamage());
ItemStack newItem = toolStats.itemLore.updateDamage(armorPiece, event.getFinalDamage());
if (newItem != null) {
armorContents[i] = newItem;
}
}
}
}
}
}
/**
* Updates a weapon's player kills.
*
* @param itemStack The item to update.
*/
private void updatePlayerKills(ItemStack itemStack) {
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {
toolStats.logger.warning(itemStack + " does NOT have any meta! Unable to update stats.");
return;
// apply the new armor
playerInventory.setArmorContents(armorContents);
}
Integer playerKills = 0;
PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.swordPlayerKills, PersistentDataType.INTEGER)) {
playerKills = container.get(toolStats.swordPlayerKills, PersistentDataType.INTEGER);
}
if (playerKills == null) {
playerKills = 0;
toolStats.logger.warning(itemStack + " does not have valid player-kills set! Resting to zero. This should NEVER happen.");
}
container.set(toolStats.swordPlayerKills, PersistentDataType.INTEGER, playerKills + 1);
// do we add the lore based on the config?
if (toolStats.configTools.checkConfig(itemStack.getType(), "player-kills")) {
String oldPlayerKillsFormatted = toolStats.numberFormat.formatInt(playerKills);
String newPlayerKillsFormatted = toolStats.numberFormat.formatInt(playerKills + 1);
Component oldLine = toolStats.configTools.formatLore("kills.player", "{kills}", oldPlayerKillsFormatted);
Component newLine = toolStats.configTools.formatLore("kills.player", "{kills}", newPlayerKillsFormatted);
if (oldLine == null || newLine == null) {
return;
}
List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.lore(newLore);
}
itemStack.setItemMeta(meta);
}
/**
* Updates a weapon's mob kills.
*
* @param itemStack The item to update.
*/
private void updateMobKills(ItemStack itemStack) {
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {
toolStats.logger.warning(itemStack + " does NOT have any meta! Unable to update stats.");
return;
}
Integer mobKills = 0;
PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.swordMobKills, PersistentDataType.INTEGER)) {
mobKills = container.get(toolStats.swordMobKills, PersistentDataType.INTEGER);
}
if (mobKills == null) {
mobKills = 0;
toolStats.logger.warning(itemStack + " does not have valid mob-kills set! Resting to zero. This should NEVER happen.");
}
container.set(toolStats.swordMobKills, PersistentDataType.INTEGER, mobKills + 1);
// do we add the lore based on the config?
if (toolStats.configTools.checkConfig(itemStack.getType(), "mob-kills")) {
String oldMobKillsFormatted = toolStats.numberFormat.formatInt(mobKills);
String newMobKillsFormatted = toolStats.numberFormat.formatInt(mobKills + 1);
Component oldLine = toolStats.configTools.formatLore("kills.mob", "{kills}", oldMobKillsFormatted);
Component newLine = toolStats.configTools.formatLore("kills.mob", "{kills}", newMobKillsFormatted);
if (oldLine == null || newLine == null) {
return;
}
List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.lore(newLore);
}
itemStack.setItemMeta(meta);
}
/**
* Updates a player's armor damage stats.
*
* @param itemStack The armor piece.
* @param damage How much damage is being added.
*/
private void updateDamage(ItemStack itemStack, double damage) {
// ignore if the damage is zero or negative
if (damage < 0) {
return;
}
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {
toolStats.logger.warning(itemStack + " does NOT have any meta! Unable to update stats.");
return;
}
Double damageTaken = 0.0;
PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.armorDamage, PersistentDataType.DOUBLE)) {
damageTaken = container.get(toolStats.armorDamage, PersistentDataType.DOUBLE);
}
if (damageTaken == null) {
damageTaken = 0.0;
toolStats.logger.warning(itemStack + " does not have valid damage-taken set! Resting to zero. This should NEVER happen.");
}
container.set(toolStats.armorDamage, PersistentDataType.DOUBLE, damageTaken + damage);
if (toolStats.config.getBoolean("enabled.armor-damage")) {
String oldDamageFormatted = toolStats.numberFormat.formatDouble(damageTaken);
String newDamageFormatted = toolStats.numberFormat.formatDouble(damageTaken + damage);
Component oldLine = toolStats.configTools.formatLore("damage-taken", "{damage}", oldDamageFormatted);
Component newLine = toolStats.configTools.formatLore("damage-taken", "{damage}", newDamageFormatted);
if (oldLine == null || newLine == null) {
return;
}
List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.lore(newLore);
}
itemStack.setItemMeta(meta);
}
/**
* Updates a trident's mob kills.
*
* @param trident The item to update.
*/
private ItemStack tridentMobKills(ItemStack trident) {
ItemStack newTrident = trident.clone();
ItemMeta meta = newTrident.getItemMeta();
if (meta == null) {
toolStats.logger.warning(newTrident + " does NOT have any meta! Unable to update stats.");
return null;
}
Integer mobKills = 0;
PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.swordMobKills, PersistentDataType.INTEGER)) {
mobKills = container.get(toolStats.swordMobKills, PersistentDataType.INTEGER);
}
if (mobKills == null) {
mobKills = 0;
toolStats.logger.warning(newTrident + " does not have valid mob-kills set! Resting to zero. This should NEVER happen.");
}
container.set(toolStats.swordMobKills, PersistentDataType.INTEGER, mobKills + 1);
// do we add the lore based on the config?
if (toolStats.configTools.checkConfig(newTrident.getType(), "mob-kills")) {
String oldMobKillsFormatted = toolStats.numberFormat.formatInt(mobKills);
String newMobKillsFormatted = toolStats.numberFormat.formatInt(mobKills + 1);
Component oldLine = toolStats.configTools.formatLore("kills.mob", "{kills}", oldMobKillsFormatted);
Component newLine = toolStats.configTools.formatLore("kills.mob", "{kills}", newMobKillsFormatted);
if (oldLine == null || newLine == null) {
return null;
}
List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.lore(newLore);
}
newTrident.setItemMeta(meta);
return newTrident;
}
/**
* Updates a trident's player kills.
*
* @param trident The item to update.
*/
private ItemStack tridentPlayerKills(ItemStack trident) {
ItemStack newTrident = trident.clone();
ItemMeta meta = newTrident.getItemMeta();
if (meta == null) {
toolStats.logger.warning(newTrident + " does NOT have any meta! Unable to update stats.");
return null;
}
Integer playerKills = 0;
PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.swordPlayerKills, PersistentDataType.INTEGER)) {
playerKills = container.get(toolStats.swordPlayerKills, PersistentDataType.INTEGER);
}
if (playerKills == null) {
playerKills = 0;
toolStats.logger.warning(newTrident + " does not have valid player-kills set! Resting to zero. This should NEVER happen.");
}
container.set(toolStats.swordPlayerKills, PersistentDataType.INTEGER, playerKills + 1);
// do we add the lore based on the config?
if (toolStats.configTools.checkConfig(newTrident.getType(), "player-kills")) {
String oldPlayerKillsFormatted = toolStats.numberFormat.formatInt(playerKills);
String newPlayerKillsFormatted = toolStats.numberFormat.formatInt(playerKills + 1);
Component oldLine = toolStats.configTools.formatLore("kills.player", "{kills}", oldPlayerKillsFormatted);
Component newLine = toolStats.configTools.formatLore("kills.player", "{kills}", newPlayerKillsFormatted);
if (oldLine == null || newLine == null) {
return null;
}
List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.lore(newLore);
}
newTrident.setItemMeta(meta);
return newTrident;
}
}

View File

@@ -61,14 +61,25 @@ public class PlayerFish implements Listener {
return;
}
ItemStack fishingRod = getItemStack(player);
ItemStack fishingRod = getFishingRod(player.getInventory());
// player swapped items?
if (fishingRod == null) {
return;
}
// update the fishing rod!
updateFishCount(fishingRod);
ItemStack newFishingRod = toolStats.itemLore.updateFishCaught(fishingRod, 1);
if (newFishingRod != null) {
PlayerInventory inventory = player.getInventory();
boolean isMain = inventory.getItemInMainHand().getType() == Material.FISHING_ROD;
boolean isOffHand = inventory.getItemInOffHand().getType() == Material.FISHING_ROD;
if (isMain) {
inventory.setItemInMainHand(newFishingRod);
}
if (isOffHand) {
inventory.setItemInOffHand(newFishingRod);
}
}
// check if the player caught an item
if (event.getCaught() == null) {
@@ -84,62 +95,30 @@ public class PlayerFish implements Listener {
}
}
private static @Nullable ItemStack getItemStack(Player player) {
PlayerInventory inventory = player.getInventory();
boolean isMainHand = inventory.getItemInMainHand().getType() == Material.FISHING_ROD;
boolean isOffHand = inventory.getItemInOffHand().getType() == Material.FISHING_ROD;
ItemStack fishingRod = null;
if (isMainHand) {
fishingRod = inventory.getItemInMainHand();
/**
* Get the player's fishing rod.
*
* @param inventory Their inventory.
* @return Their fishing rod, either main or offhand.
*/
private static @Nullable ItemStack getFishingRod(PlayerInventory inventory) {
ItemStack main = inventory.getItemInMainHand();
ItemStack offHand = inventory.getItemInOffHand();
boolean isMain = main.getType() == Material.FISHING_ROD;
boolean isOffHand = offHand.getType() == Material.FISHING_ROD;
// if the player is holding a fishing rod in their main hand, use that one
// if the fishing rod is in their offhand instead, use that one after checking main hand
// Minecraft prioritizes main hand if the player holds in both hands
if (isMain) {
return main;
}
if (isOffHand) {
fishingRod = inventory.getItemInOffHand();
return offHand;
}
// if the player is hold fishing rods in both hands
// default to main hand since that takes priority
if (isMainHand && isOffHand) {
fishingRod = inventory.getItemInMainHand();
}
return fishingRod;
}
/**
* Update a fishing rod's fish count.
*
* @param fishingRod The fishing rod to update.
*/
private void updateFishCount(ItemStack fishingRod) {
ItemMeta meta = fishingRod.getItemMeta();
if (meta == null) {
toolStats.logger.warning(fishingRod + " does NOT have any meta! Unable to update stats.");
return;
}
Integer fishCaught = 0;
PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.fishingRodCaught, PersistentDataType.INTEGER)) {
fishCaught = container.get(toolStats.fishingRodCaught, PersistentDataType.INTEGER);
}
if (fishCaught == null) {
fishCaught = 0;
toolStats.logger.warning(fishingRod + " does not have valid fish-caught set! Resting to zero. This should NEVER happen.");
}
container.set(toolStats.fishingRodCaught, PersistentDataType.INTEGER, fishCaught + 1);
if (toolStats.config.getBoolean("enabled.fish-caught")) {
String oldFishFormatted = toolStats.numberFormat.formatInt(fishCaught);
String newFishFormatted = toolStats.numberFormat.formatInt(fishCaught + 1);
Component oldLine = toolStats.configTools.formatLore("fished.fish-caught", "{fish}", oldFishFormatted);
Component newLine = toolStats.configTools.formatLore("fished.fish-caught", "{fish}", newFishFormatted);
if (oldLine == null || newLine == null) {
return;
}
List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.lore(newLore);
}
fishingRod.setItemMeta(meta);
return null;
}
/**

View File

@@ -18,7 +18,6 @@
package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats;
import net.kyori.adventure.text.Component;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@@ -26,12 +25,9 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.inventory.PlayerInventory;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class PlayerMove implements Listener {
@@ -55,54 +51,18 @@ public class PlayerMove implements Listener {
} else {
// player is not flying
if (playerStartFlight.containsKey(player)) {
trackFlight(player, playerStartFlight.get(player));
PlayerInventory inventory = player.getInventory();
ItemStack chest = inventory.getChestplate();
// make sure the player is wearing an elytra
if (chest != null && chest.getType() == Material.ELYTRA) {
long duration = (System.currentTimeMillis() - playerStartFlight.get(player));
ItemStack newItem = toolStats.itemLore.updateFlightTime(chest, duration);
if (newItem != null) {
inventory.setChestplate(newItem);
}
}
playerStartFlight.remove(player);
}
}
}
private void trackFlight(Player player, long startTime) {
ItemStack chest = player.getInventory().getChestplate();
// make sure their chest piece is an elytra
if (chest == null || chest.getType() != Material.ELYTRA) {
return;
}
ItemMeta meta = chest.getItemMeta();
if (meta == null) {
toolStats.logger.warning(chest + " does NOT have any meta! Unable to update stats.");
return;
}
// read the current stats from the item
// if they don't exist, then start from 0
Long flightTime = 0L;
PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.flightTime, PersistentDataType.LONG)) {
flightTime = container.get(toolStats.flightTime, PersistentDataType.LONG);
}
if (flightTime == null) {
flightTime = 0L;
toolStats.logger.warning(flightTime + " does not have valid flight-time set! Resting to zero. This should NEVER happen.");
}
// get the duration of the flight
long duration = (System.currentTimeMillis() - startTime);
double newDuration = flightTime + duration;
container.set(toolStats.flightTime, PersistentDataType.LONG, flightTime + duration);
// do we add the lore based on the config?
if (toolStats.config.getBoolean("enabled.flight-time")) {
String oldFlightFormatted = toolStats.numberFormat.formatDouble((double) flightTime / 1000);
String newFlightFormatted = toolStats.numberFormat.formatDouble(newDuration / 1000);
Component oldLine = toolStats.configTools.formatLore("flight-time", "{time}", oldFlightFormatted);
Component newLine = toolStats.configTools.formatLore("flight-time", "{time}", newFlightFormatted);
if (oldLine == null || newLine == null) {
return;
}
List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.lore(newLore);
}
chest.setItemMeta(meta);
}
}

View File

@@ -0,0 +1,61 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.PrepareItemCraftEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
public class PrepareCraft implements Listener {
private final ToolStats toolStats;
public PrepareCraft(ToolStats toolStats) {
this.toolStats = toolStats;
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onCraft(PrepareItemCraftEvent event) {
// get the items in the crafting grid
ItemStack[] grid = event.getInventory().getMatrix();
for (ItemStack item : grid) {
if (item == null || item.getType() != Material.PAPER) {
continue;
}
toolStats.logger.info(item.getType().toString());
ItemMeta meta = item.getItemMeta();
if (meta == null) {
continue;
}
// if the paper item has our PDC, cancel it
PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.tokenType)) {
toolStats.logger.info("has PDC");
event.getInventory().setResult(null);
} else {
toolStats.logger.info("no PDC");
}
}
}
}

View File

@@ -18,7 +18,6 @@
package lol.hyper.toolstats.events;
import lol.hyper.toolstats.ToolStats;
import net.kyori.adventure.text.Component;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.entity.Entity;
@@ -30,13 +29,8 @@ import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public class SheepShear implements Listener {
private final ToolStats toolStats;
@@ -71,9 +65,26 @@ public class SheepShear implements Listener {
}
// update the stats
addLore(heldShears);
ItemStack newItem = toolStats.itemLore.updateSheepSheared(heldShears, 1);
if (newItem != null) {
PlayerInventory inventory = player.getInventory();
boolean isMain = inventory.getItemInMainHand().getType() == Material.SHEARS;
boolean isOffHand = inventory.getItemInOffHand().getType() == Material.SHEARS;
if (isMain) {
inventory.setItemInMainHand(newItem);
}
if (isOffHand) {
inventory.setItemInOffHand(newItem);
}
}
}
/**
* Get the player's shears.
*
* @param inventory Their inventory.
* @return Their shears, either main or offhand.
*/
private static @Nullable ItemStack getShears(PlayerInventory inventory) {
ItemStack main = inventory.getItemInMainHand();
ItemStack offHand = inventory.getItemInOffHand();
@@ -93,42 +104,4 @@ public class SheepShear implements Listener {
return null;
}
/**
* Adds tags to shears.
*
* @param newShears The shears.
*/
private void addLore(ItemStack newShears) {
ItemMeta meta = newShears.getItemMeta();
if (meta == null) {
toolStats.logger.warning(newShears + " does NOT have any meta! Unable to update stats.");
return;
}
Integer sheepSheared = 0;
PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.shearsSheared, PersistentDataType.INTEGER)) {
sheepSheared = container.get(toolStats.shearsSheared, PersistentDataType.INTEGER);
}
if (sheepSheared == null) {
sheepSheared = 0;
toolStats.logger.warning(newShears + " does not have valid sheared set! Resting to zero. This should NEVER happen.");
}
container.set(toolStats.shearsSheared, PersistentDataType.INTEGER, sheepSheared + 1);
if (toolStats.config.getBoolean("enabled.sheep-sheared")) {
String oldSheepFormatted = toolStats.numberFormat.formatInt(sheepSheared);
String newSheepFormatted = toolStats.numberFormat.formatInt(sheepSheared + 1);
Component oldLine = toolStats.configTools.formatLore("sheep-sheared", "{sheep}", oldSheepFormatted);
Component newLine = toolStats.configTools.formatLore("sheep-sheared", "{sheep}", newSheepFormatted);
if (oldLine == null || newLine == null) {
return;
}
List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.lore(newLore);
}
newShears.setItemMeta(meta);
}
}

View File

@@ -62,9 +62,26 @@ public class ShootBow implements Listener {
return;
}
updateArrowsShot(heldBow);
ItemStack newItem = toolStats.itemLore.updateArrowsShot(heldBow, 1);
if (newItem != null) {
PlayerInventory inventory = player.getInventory();
boolean isMain = inventory.getItemInMainHand().getType() == Material.BOW || inventory.getItemInMainHand().getType() == Material.CROSSBOW;
boolean isOffHand = inventory.getItemInOffHand().getType() == Material.BOW || inventory.getItemInOffHand().getType() == Material.CROSSBOW;
if (isMain) {
inventory.setItemInMainHand(newItem);
}
if (isOffHand) {
inventory.setItemInOffHand(newItem);
}
}
}
/**
* Get the player's bow/crossbow.
*
* @param inventory Their inventory.
* @return Their bow/crossbow, either main or offhand.
*/
private static @Nullable ItemStack getBow(PlayerInventory inventory) {
ItemStack main = inventory.getItemInMainHand();
ItemStack offHand = inventory.getItemInOffHand();
@@ -84,40 +101,4 @@ public class ShootBow implements Listener {
return null;
}
private void updateArrowsShot(ItemStack bow) {
ItemMeta meta = bow.getItemMeta();
if (meta == null) {
toolStats.logger.warning(bow + " does NOT have any meta! Unable to update stats.");
return;
}
// read the current stats from the item
// if they don't exist, then start from 0
Integer arrowsShot = 0;
PersistentDataContainer container = meta.getPersistentDataContainer();
if (container.has(toolStats.arrowsShot, PersistentDataType.INTEGER)) {
arrowsShot = container.get(toolStats.arrowsShot, PersistentDataType.INTEGER);
}
if (arrowsShot == null) {
arrowsShot = 0;
toolStats.logger.warning(arrowsShot + " does not have valid arrows-shot set! Resting to zero. This should NEVER happen.");
}
container.set(toolStats.arrowsShot, PersistentDataType.INTEGER, arrowsShot + 1);
// do we add the lore based on the config?
if (toolStats.config.getBoolean("enabled.arrows-shot")) {
String oldArrowsFormatted = toolStats.numberFormat.formatInt(arrowsShot);
String newArrowsFormatted = toolStats.numberFormat.formatInt(arrowsShot + 1);
Component oldLine = toolStats.configTools.formatLore("arrows-shot", "{arrows}", oldArrowsFormatted);
Component newLine = toolStats.configTools.formatLore("arrows-shot", "{arrows}", newArrowsFormatted);
if (oldLine == null || newLine == null) {
return;
}
List<Component> newLore = toolStats.itemLore.updateItemLore(meta, oldLine, newLine);
meta.lore(newLore);
}
bow.setItemMeta(meta);
}
}