Compare commits

...

18 Commits
1.2.3 ... 1.3.2

Author SHA1 Message Date
hyperdefined
df23f40d6b Update pom.xml 2022-02-22 15:08:38 -05:00
hyperdefined
0221ee40cf handle logic of lore reset better 2022-02-22 15:07:51 -05:00
hyperdefined
a01d07af4a fixed removing new tag for elytras
this fixes #5
2022-02-22 15:07:30 -05:00
hyperdefined
e402d3078a Merge pull request #4 from hyperdefined/dependabot/maven/org.apache.maven.plugins-maven-compiler-plugin-3.10.0
Bump maven-compiler-plugin from 3.9.0 to 3.10.0
2022-02-14 21:07:02 -05:00
dependabot[bot]
4f44ca0777 Bump maven-compiler-plugin from 3.9.0 to 3.10.0
Bumps [maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.9.0 to 3.10.0.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.9.0...maven-compiler-plugin-3.10.0)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-compiler-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-02-14 11:38:14 +00:00
hyperdefined
53fd7f734c Update pom.xml 2022-02-12 20:47:52 -05:00
hyperdefined
75cd4fa17e fixed small typo 2022-02-12 20:47:32 -05:00
hyperdefined
e296c27a5b added comments to better explain what is going on 2022-02-11 19:19:05 -05:00
hyperdefined
adb1c637dc smh 2022-02-11 18:34:42 -05:00
hyperdefined
4b8f8061b4 Merge branch 'master' of https://github.com/hyperdefined/ToolStats 2022-02-11 15:09:49 -05:00
hyperdefined
464916e08b Update CommandToolStats.java 2022-02-11 15:09:32 -05:00
hyperdefined
6b6b65d1df Update README.md 2022-02-11 15:05:55 -05:00
hyperdefined
a1c39dffd0 Update pom.xml 2022-02-11 15:05:18 -05:00
hyperdefined
88eab81906 added tab completions to sub commands 2022-02-11 15:03:37 -05:00
hyperdefined
be233de90d fixed plugin.yml 2022-02-11 15:03:21 -05:00
hyperdefined
2437424e39 added reset lore command 2022-02-11 14:46:25 -05:00
hyperdefined
63b08062c8 Update CraftItem.java 2022-02-11 14:04:12 -05:00
hyperdefined
d23c2446dd fix fishing rods not updating lore correctly 2022-02-11 14:03:51 -05:00
15 changed files with 361 additions and 19 deletions

View File

@@ -23,6 +23,8 @@ Here is everything it tracks:
The best part is, this data is stored on the item itself. You can also change how the lore is displayed on the items!
If item lore is ever incorrect, you can run `/toolstats reset` to reset the item lore so it's correct.
![Image](https://raw.githubusercontent.com/hyperdefined/ToolStats/master/images/image.png)
![Image](https://raw.githubusercontent.com/hyperdefined/ToolStats/master/images/image2.png)
![Image](https://raw.githubusercontent.com/hyperdefined/ToolStats/master/images/image3.png)

View File

@@ -23,7 +23,7 @@
<groupId>lol.hyper</groupId>
<artifactId>toolstats</artifactId>
<version>1.2.3</version>
<version>1.3.2</version>
<packaging>jar</packaging>
<name>ToolStats</name>
@@ -51,7 +51,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.9.0</version>
<version>3.10.0</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>

View File

@@ -152,6 +152,12 @@ public final class ToolStats extends JavaPlugin {
}
}
/**
* Checks the config to see if we want to show lore on certain items.
* @param itemStack The item to check.
* @param configName The config we are checking under.
* @return If we want to allow lore or not.
*/
public boolean checkConfig(ItemStack itemStack, String configName) {
String itemName = itemStack.getType().toString().toLowerCase();
String itemType = null;
@@ -202,6 +208,12 @@ public final class ToolStats extends JavaPlugin {
return false;
}
/**
* Gets the lore message from the config.
* @param configName The config name, "messages." is already in front.
* @param raw If you want the raw message with the formatting codes and placeholders.
* @return The lore message.
*/
public String getLoreFromConfig(String configName, boolean raw) {
String lore = config.getString("messages." + configName);
if (lore == null) {
@@ -235,6 +247,9 @@ public final class ToolStats extends JavaPlugin {
if (lore.contains("{damage}")) {
lore = lore.replace("{damage}", "");
}
if (lore.contains("{fish}")) {
lore = lore.replace("{fish}", "");
}
}
return lore;
}

View File

@@ -18,36 +18,255 @@
package lol.hyper.toolstats.commands;
import lol.hyper.toolstats.ToolStats;
import org.bukkit.ChatColor;
import lol.hyper.toolstats.UUIDDataType;
import org.bukkit.*;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class CommandToolStats implements CommandExecutor {
import java.text.SimpleDateFormat;
import java.util.*;
public class CommandToolStats implements TabExecutor {
private final ToolStats toolStats;
public CommandToolStats(ToolStats toolStats) {
this.toolStats = toolStats;
}
private final SimpleDateFormat format = new SimpleDateFormat("M/dd/yyyy", Locale.ENGLISH);
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if (!sender.hasPermission("toolstats.use")) {
sender.sendMessage(ChatColor.RED + "You do not have permission for this command.");
return true;
}
if (args.length == 0) {
sender.sendMessage(ChatColor.GREEN + "ToolStats version " + toolStats.getDescription().getVersion() + ". Created by hyperdefined.");
} else if (args.length == 1) {
if (args[0].equalsIgnoreCase("reload")) {
}
switch (args[0]) {
case "reload": {
if (sender.isOp() || sender.hasPermission("toolstats.reload")) {
toolStats.loadConfig();
sender.sendMessage(ChatColor.GREEN + "Configuration reloaded!");
} else {
sender.sendMessage(ChatColor.RED + "You do not have permission for this command.");
}
} else {
return true;
}
case "reset": {
if (args.length == 2 && args[1].equalsIgnoreCase("confirm")) {
Player player = (Player) sender;
ItemStack heldItem = player.getInventory().getItemInMainHand();
if (heldItem.getType() == Material.AIR) {
sender.sendMessage(ChatColor.RED + "You must hold an item!");
return true;
}
fixItemLore(heldItem, player);
sender.sendMessage(ChatColor.GREEN + "The lore was reset!");
return true;
}
sender.sendMessage(ChatColor.GREEN + "This will remove ALL current lore from the held item and replace it with the correct lore.");
sender.sendMessage(ChatColor.GREEN + "The item owner will be who ever is currently running this command.");
sender.sendMessage(ChatColor.GREEN + "Only use this if the tags on the tool are incorrect.");
sender.sendMessage(ChatColor.GREEN + "Type /toolstats reset confirm to confirm this.");
return true;
}
default: {
sender.sendMessage(ChatColor.RED + "Invalid sub-command.");
}
}
return true;
}
/**
* Fixes lore on a given item. This will wipe all lore and reapply our custom ones.
* @param original The item we are fixing.
* @param player The player running the command.
*/
private void fixItemLore(ItemStack original, Player player) {
ItemStack finalItem = original.clone();
ItemMeta finalMeta = finalItem.getItemMeta();
if (finalMeta == null) {
return;
}
PersistentDataContainer container = finalMeta.getPersistentDataContainer();
List<String> lore = new ArrayList<>();
String caughtByLore = toolStats.getLoreFromConfig("fished.caught-by", false);
String lootedByLore = toolStats.getLoreFromConfig("looted.found-by", false);
String tradedByLore = toolStats.getLoreFromConfig("traded.traded-by", false);
// make sure the config messages are not null
if (caughtByLore == null || lootedByLore == null || tradedByLore == null) {
return;
}
// determine how the item was originally created
// this doesn't get saved, so we just rely on the lore
// if there isn't a tag, default to crafted
String type = "DEFAULT";
if (finalMeta.hasLore()) {
if (finalMeta.getLore() != null) {
for (String line : finalMeta.getLore()) {
if (line.contains(caughtByLore)) {
type = "CAUGHT";
}
if (line.contains(lootedByLore)) {
type = "LOOTED";
}
if (line.contains(tradedByLore)) {
type = "TRADED";
}
}
}
}
// hard code elytras
if (finalItem.getType() == Material.ELYTRA) {
if (toolStats.config.getBoolean("enabled.elytra-tag")) {
lore.add(toolStats.getLoreFromConfig("looted.found-by", true).replace("{player}", player.getName()));
if (container.has(toolStats.timeCreated, PersistentDataType.LONG)) {
Long time = container.get(toolStats.timeCreated, PersistentDataType.LONG);
if (time != null) {
lore.add(toolStats.getLoreFromConfig("looted.found-on", true).replace("{date}", format.format(new Date(time))));
}
}
finalMeta.setLore(lore);
finalItem.setItemMeta(finalMeta);
int slot = player.getInventory().getHeldItemSlot();
player.getInventory().setItem(slot, finalItem);
return;
}
}
if (toolStats.checkConfig(original, "created-by")) {
if (container.has(toolStats.genericOwner, new UUIDDataType())) {
container.set(toolStats.genericOwner, new UUIDDataType(), player.getUniqueId());
// show how the item was created based on the previous lore
switch (type) {
case "DEFAULT": {
lore.add(toolStats.getLoreFromConfig("created.created-by", true).replace("{player}", player.getName()));
break;
}
case "CAUGHT": {
lore.add(toolStats.getLoreFromConfig("fished.caught-by", true).replace("{player}", player.getName()));
break;
}
case "LOOTED": {
lore.add(toolStats.getLoreFromConfig("looted.found-by", true).replace("{player}", player.getName()));
break;
}
case "TRADED": {
lore.add(toolStats.getLoreFromConfig("traded.traded-by", true).replace("{player}", player.getName()));
break;
}
}
}
}
if (toolStats.checkConfig(original, "created-date")) {
if (container.has(toolStats.timeCreated, PersistentDataType.LONG)) {
Long time = container.get(toolStats.timeCreated, PersistentDataType.LONG);
if (time != null) {
// show how when the item was created based on the previous lore
switch (type) {
case "DEFAULT": {
lore.add(toolStats.getLoreFromConfig("created.created-on", true).replace("{date}", format.format(new Date(time))));
break;
}
case "CAUGHT": {
lore.add(toolStats.getLoreFromConfig("fished.caught-on", true).replace("{date}", format.format(new Date(time))));
break;
}
case "LOOTED": {
lore.add(toolStats.getLoreFromConfig("looted.foundon", true).replace("{date}", format.format(new Date(time))));
break;
}
case "TRADED": {
lore.add(toolStats.getLoreFromConfig("traded.traded-on", true).replace("{date}", format.format(new Date(time))));
break;
}
}
}
}
}
if (toolStats.checkConfig(original, "player-kills")) {
if (container.has(toolStats.swordPlayerKills, PersistentDataType.INTEGER)) {
Integer kills = container.get(toolStats.swordPlayerKills, PersistentDataType.INTEGER);
if (kills != null) {
lore.add(toolStats.getLoreFromConfig("kills.player", true).replace("{kills}", Integer.toString(kills)));
}
}
}
if (toolStats.checkConfig(original, "mob-kills")) {
if (container.has(toolStats.swordMobKills, PersistentDataType.INTEGER)) {
Integer kills = container.get(toolStats.swordMobKills, PersistentDataType.INTEGER);
if (kills != null) {
lore.add(toolStats.getLoreFromConfig("kills.mob", true).replace("{kills}", Integer.toString(kills)));
}
}
}
if (toolStats.checkConfig(original, "blocks-mined")) {
if (container.has(toolStats.genericMined, PersistentDataType.INTEGER)) {
Integer blocksMined = container.get(toolStats.genericMined, PersistentDataType.INTEGER);
if (blocksMined != null) {
lore.add(toolStats.getLoreFromConfig("blocks-mined", true).replace("{blocks}", Integer.toString(blocksMined)));
}
}
}
if (toolStats.config.getBoolean("enabled.fish-caught")) {
if (container.has(toolStats.fishingRodCaught, PersistentDataType.INTEGER)) {
Integer fish = container.get(toolStats.fishingRodCaught, PersistentDataType.INTEGER);
if (fish != null) {
lore.add(toolStats.getLoreFromConfig("fished.fish-caught", true).replace("{fish}", Integer.toString(fish)));
}
}
}
if (toolStats.config.getBoolean("enabled.sheep-sheared")) {
if (container.has(toolStats.shearsSheared, PersistentDataType.INTEGER)) {
Integer sheep = container.get(toolStats.shearsSheared, PersistentDataType.INTEGER);
if (sheep != null) {
lore.add(toolStats.getLoreFromConfig("sheep-sheared", true).replace("{sheep}", Integer.toString(sheep)));
}
}
}
if (toolStats.config.getBoolean("enabled.armor-damage")) {
if (container.has(toolStats.armorDamage, PersistentDataType.INTEGER)) {
Integer damage = container.get(toolStats.armorDamage, PersistentDataType.INTEGER);
if (damage != null) {
lore.add(toolStats.getLoreFromConfig("damage-taken", true).replace("{damage}", Integer.toString(damage)));
}
}
}
finalMeta.setLore(lore);
finalItem.setItemMeta(finalMeta);
int slot = player.getInventory().getHeldItemSlot();
player.getInventory().setItem(slot, finalItem);
}
@Nullable
@Override
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
if (args.length == 1) {
if (sender.hasPermission("toolstats.reload")) {
return Arrays.asList("reset", "reload");
} else {
return Collections.singletonList("reset");
}
}
if (args.length == 2) {
if (args[0].equalsIgnoreCase("reset")) {
return Collections.singletonList("confirm");
}
}
return null;
}
}

View File

@@ -48,17 +48,21 @@ public class BlocksMined implements Listener {
return;
}
Player player = event.getPlayer();
// ignore creative mode
if (player.getGameMode() != GameMode.SURVIVAL) {
return;
}
// if the player mines something with their fist
ItemStack heldItem = player.getInventory().getItem(player.getInventory().getHeldItemSlot());
if (heldItem == null || heldItem.getType() == Material.AIR) {
return;
}
// only check certain items
String itemName = heldItem.getType().toString().toLowerCase();
if (Arrays.stream(validTools).noneMatch(itemName::contains)) {
return;
}
// if it's an item we want, update the stats
updateBlocksMined(heldItem);
}
@@ -67,6 +71,8 @@ public class BlocksMined implements Listener {
if (meta == null) {
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)) {
@@ -82,6 +88,11 @@ public class BlocksMined implements Listener {
String configLore = toolStats.getLoreFromConfig("blocks-mined", false);
String configLoreRaw = toolStats.getLoreFromConfig("blocks-mined", true);
if (configLore == null || configLoreRaw == null) {
toolStats.logger.warning("There is no lore message for messages.blocks-mined!");
return;
}
List<String> lore;
if (meta.hasLore()) {
lore = meta.getLore();
@@ -89,10 +100,6 @@ public class BlocksMined implements Listener {
boolean hasLore = false;
// we do a for loop like this, we can keep track of index
// this doesn't mess the lore up of existing items
if (configLore == null || configLoreRaw == null) {
toolStats.logger.warning("There is no lore message for messages.blocks-mined!");
return;
}
for (int x = 0; x < lore.size(); x++) {
if (lore.get(x).contains(configLore)) {
hasLore = true;
@@ -109,6 +116,7 @@ public class BlocksMined implements Listener {
lore = new ArrayList<>();
lore.add(configLoreRaw.replace("{blocks}", Integer.toString(blocksMined)));
}
// do we add the lore based on the config?
if (toolStats.checkConfig(itemStack, "blocks-mined")) {
meta.setLore(lore);
}

View File

@@ -53,14 +53,17 @@ public class ChunkPopulate implements Listener {
Bukkit.getScheduler().runTaskLater(toolStats, () -> {
Chunk chunk = event.getChunk();
for (Entity entity : chunk.getEntities()) {
// if there is a new item frame
if (entity instanceof ItemFrame) {
ItemFrame itemFrame = (ItemFrame) entity;
// if the item frame has an elytra
if (itemFrame.getItem().getType() == Material.ELYTRA) {
ItemStack elytraCopy = itemFrame.getItem();
ItemMeta meta = elytraCopy.getItemMeta();
if (meta == null) {
return;
}
// add the new tag so we know it's new
PersistentDataContainer container = meta.getPersistentDataContainer();
container.set(toolStats.newElytra, PersistentDataType.INTEGER, 1);
elytraCopy.setItemMeta(meta);

View File

@@ -56,32 +56,48 @@ public class CraftItem implements Listener {
return;
}
String name = itemStack.getType().toString().toLowerCase(Locale.ROOT);
// only check for items we want
for (String x : validItems) {
if (name.contains(x)) {
// if the player shift clicks, send them this warning
if (event.isShiftClick()) {
String configMessage = toolStats.config.getString("messages.shift-click-warning.crafting");
if (configMessage != null) {
event.getWhoClicked().sendMessage(ChatColor.translateAlternateColorCodes('&', configMessage));
if (configMessage.length() != 0) {
event.getWhoClicked().sendMessage(ChatColor.translateAlternateColorCodes('&', configMessage));
}
}
}
// test the item before setting it
if (addLore(itemStack, player) == null) {
return;
}
// set the result
event.setCurrentItem(addLore(itemStack, player));
}
}
}
/**
* Adds crafted tags to item.
* @param itemStack The item add item to.
* @param owner The player crafting.
* @return A copy of the item with the tags + lore.
*/
private ItemStack addLore(ItemStack itemStack, Player owner) {
// clone the item
ItemStack newItem = itemStack.clone();
ItemMeta meta = newItem.getItemMeta();
if (meta == null) {
return null;
}
// get the current time
long timeCreated = System.currentTimeMillis();
Date finalDate = new Date(timeCreated);
PersistentDataContainer container = meta.getPersistentDataContainer();
// if the item already has the tag
// this is to prevent duplicate tags
if (container.has(toolStats.timeCreated, PersistentDataType.LONG) || container.has(toolStats.genericOwner, PersistentDataType.LONG)) {
return null;
}
@@ -102,12 +118,14 @@ public class CraftItem implements Listener {
}
List<String> lore;
// get the current lore the item
if (meta.hasLore()) {
lore = meta.getLore();
assert lore != null;
} else {
lore = new ArrayList<>();
}
// do we add the lore based on the config?
if (toolStats.checkConfig(itemStack, "created-date")) {
lore.add(createdOnRaw.replace("{date}", format.format(finalDate)));
}

View File

@@ -64,10 +64,12 @@ public class EntityDamage implements Listener {
if (player.getGameMode() != GameMode.SURVIVAL) {
return;
}
// a player killed something with their fist
ItemStack heldItem = player.getInventory().getItem(player.getInventory().getHeldItemSlot());
if (heldItem == null || heldItem.getType() == Material.AIR) {
return;
}
// check items we want
String itemName = heldItem.getType().toString().toLowerCase();
if (Arrays.stream(validTools).noneMatch(itemName::contains)) {
return;
@@ -81,9 +83,11 @@ public class EntityDamage implements Listener {
player.getInventory().setItem(player.getInventory().getHeldItemSlot(), updateMobKills(heldItem));
trackedMobs.add(livingEntity.getUniqueId());
}
// trident is being thrown at something
if (event.getDamager() instanceof Trident) {
Trident trident = (Trident) event.getDamager();
ItemStack clone;
// trident is killing player
if (livingEntity instanceof Player) {
clone = updatePlayerKills(trident.getItem());
} else {
@@ -94,14 +98,18 @@ public class EntityDamage implements Listener {
}
trident.setItem(clone);
}
// arrow is being shot
if (event.getDamager() instanceof Arrow) {
Arrow arrow = (Arrow) event.getDamager();
// if the shooter is a player
if (arrow.getShooter() instanceof Player) {
Player player = (Player) arrow.getShooter();
ItemStack heldItem = player.getInventory().getItem(player.getInventory().getHeldItemSlot());
if (heldItem == null) {
return;
}
// if the player is holding the bow/crossbow
// if they switch then oh well
if (heldItem.getType() == Material.BOW || heldItem.getType() == Material.CROSSBOW) {
if (livingEntity instanceof Player) {
player.getInventory().setItem(player.getInventory().getHeldItemSlot(), updatePlayerKills(heldItem));
@@ -130,6 +138,7 @@ public class EntityDamage implements Listener {
return;
}
LivingEntity livingEntity = (LivingEntity) event.getEntity();
// player is taken damage but not being killed
if (livingEntity instanceof Player) {
Player player = (Player) livingEntity;
PlayerInventory inventory = player.getInventory();
@@ -147,6 +156,7 @@ public class EntityDamage implements Listener {
return;
}
LivingEntity livingEntity = (LivingEntity) event.getEntity();
// player is taken damage but not being killed
if (livingEntity instanceof Player) {
Player player = (Player) livingEntity;
PlayerInventory inventory = player.getInventory();
@@ -158,6 +168,11 @@ public class EntityDamage implements Listener {
}
}
/**
* Updates a weapon's player kills.
* @param itemStack The item to update.
* @return A copy of the item.
*/
private ItemStack updatePlayerKills(ItemStack itemStack) {
ItemStack finalItem = itemStack.clone();
ItemMeta meta = finalItem.getItemMeta();
@@ -207,6 +222,7 @@ public class EntityDamage implements Listener {
lore = new ArrayList<>();
lore.add(playerKillsLoreRaw.replace("{kills}", Integer.toString(playerKills)));
}
// do we add the lore based on the config?
if (toolStats.checkConfig(itemStack, "player-kills")) {
meta.setLore(lore);
}
@@ -214,6 +230,11 @@ public class EntityDamage implements Listener {
return finalItem;
}
/**
* Updates a weapon's mob kills.
* @param itemStack The item to update.
* @return A copy of the item.
*/
private ItemStack updateMobKills(ItemStack itemStack) {
ItemStack finalItem = itemStack.clone();
ItemMeta meta = finalItem.getItemMeta();
@@ -263,6 +284,7 @@ public class EntityDamage implements Listener {
lore = new ArrayList<>();
lore.add(mobKillsLoreRaw.replace("{kills}", Integer.toString(mobKills)));
}
// do we add the lore based on the config?
if (toolStats.checkConfig(itemStack, "mob-kills")) {
meta.setLore(lore);
}
@@ -270,6 +292,11 @@ public class EntityDamage implements Listener {
return finalItem;
}
/**
* Updates a player's armor damage stats.
* @param itemStack The armor piece.
* @param damage How much damage is being added.
*/
private void updateArmorDamage(ItemStack itemStack, double damage) {
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {

View File

@@ -43,6 +43,7 @@ public class EntityDeath implements Listener {
return;
}
UUID livingEntityUUID = event.getEntity().getUniqueId();
// if it's a mob we are tracking that matters
if (toolStats.mobKill.trackedMobs.contains(livingEntityUUID)) {
for (ItemStack current : event.getDrops()) {
String name = current.getType().toString().toLowerCase(Locale.ROOT);
@@ -56,6 +57,11 @@ public class EntityDeath implements Listener {
}
}
/**
* Adds "drop by" tag to item.
* @param itemStack The item to add lore to.
* @param mob The mob or player name.
*/
private void addLore(ItemStack itemStack, String mob) {
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {
@@ -87,7 +93,7 @@ public class EntityDeath implements Listener {
lore = new ArrayList<>();
}
if (!hasTag) {
lore.add(droppedByLoreRaw.replace("X", mob));
lore.add(droppedByLoreRaw.replace("{name}", mob));
}
if (toolStats.config.getBoolean("enabled.dropped-by")) {
meta.setLore(lore);

View File

@@ -57,10 +57,13 @@ public class GenerateLoot implements Listener {
return;
}
Inventory chest = inventoryHolder.getInventory();
// run task later since if it runs on the same tick it breaks idk
Bukkit.getScheduler().runTaskLater(toolStats, () -> {
Player player = (Player) chest.getViewers().get(0);
// do a classic for loot so we keep track of chest index of item
for (int i = 0; i < chest.getContents().length; i++) {
ItemStack itemStack = chest.getItem(i);
// ignore air
if (itemStack == null || itemStack.getType() == Material.AIR) {
continue;
}
@@ -75,6 +78,12 @@ public class GenerateLoot implements Listener {
},1);
}
/**
* Adds lore to newly generated items.
* @param itemStack The item to add lore to.
* @param owner The player that found the item.
* @return The item with the lore.
*/
private ItemStack addLore(ItemStack itemStack, Player owner) {
ItemStack newItem = itemStack.clone();
ItemMeta meta = itemStack.getItemMeta();

View File

@@ -61,13 +61,17 @@ public class PickupItem implements Listener {
PersistentDataContainer container = meta.getPersistentDataContainer();
// the elytra has the new key, set the lore to it
if (container.has(toolStats.newElytra, PersistentDataType.INTEGER)) {
container.remove(toolStats.newElytra);
addLore(itemStack, (Player) event.getEntity());
}
}
}
}
/**
* Adds "looted by" tags for elytras.
* @param itemStack The elytra to add lore to.
* @param owner The player who found it.
*/
private void addLore(ItemStack itemStack, Player owner) {
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {
@@ -78,6 +82,7 @@ public class PickupItem implements Listener {
PersistentDataContainer container = meta.getPersistentDataContainer();
container.set(toolStats.timeCreated, PersistentDataType.LONG, timeCreated);
container.set(toolStats.genericOwner, new UUIDDataType(), owner.getUniqueId());
container.remove(toolStats.newElytra);
String foundByLoreRaw = toolStats.getLoreFromConfig("looted.found-by", true);
String foundOnLoreRaw = toolStats.getLoreFromConfig("looted.found-on", true);

View File

@@ -75,6 +75,10 @@ public class PlayerFish implements Listener {
}
}
/**
* Updates a fishing rod's count.
* @param itemStack The fishing rod to update.
*/
private void updateFishCount(ItemStack itemStack) {
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {
@@ -129,6 +133,11 @@ public class PlayerFish implements Listener {
itemStack.setItemMeta(meta);
}
/**
* Adds "caught by" tags to newly fished items.
* @param itemStack The item to add lore to.
* @param owner The player who caught the item.
*/
private void addNewLore(ItemStack itemStack, Player owner) {
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {

View File

@@ -51,17 +51,23 @@ public class SheepShear implements Listener {
if (!(entity instanceof Sheep)) {
return;
}
// check if the player is right-clicking with shears only
ItemStack heldItem = player.getInventory().getItem(player.getInventory().getHeldItemSlot());
if (heldItem == null || heldItem.getType() == Material.AIR || heldItem.getType() != Material.SHEARS) {
return;
}
Sheep sheep = (Sheep) entity;
// make sure the sheep is not sheared
if (!sheep.isSheared()) {
addLore(heldItem);
}
}
/**
* Adds tags to shears.
* @param itemStack The shears.
*/
private void addLore(ItemStack itemStack) {
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {

View File

@@ -57,11 +57,15 @@ public class VillagerTrade implements Listener {
return;
}
Inventory inventory = event.getClickedInventory();
// only check villager inventories
if (inventory instanceof MerchantInventory) {
// only check the result slot (the item you receive)
if (event.getSlotType() == InventoryType.SlotType.RESULT) {
ItemStack item = event.getCurrentItem();
// only check items we want
for (String x : validItems) {
if (item.getType().toString().toLowerCase(Locale.ROOT).contains(x)) {
// if the player shift clicks show the warning
if (event.isShiftClick()) {
String configMessage = toolStats.config.getString("messages.shift-click-warning.trading");
if (configMessage != null) {
@@ -72,6 +76,8 @@ public class VillagerTrade implements Listener {
if (newItem == null) {
return;
}
// this gets delayed since villager inventories suck for no reason
// if you don't delay this it doesn't work idk
Bukkit.getScheduler().runTaskLater(toolStats, ()-> event.setCurrentItem(newItem), 5);
}
}
@@ -79,6 +85,12 @@ public class VillagerTrade implements Listener {
}
}
/**
* Adds "traded by" tags to item.
* @param itemStack The item to add lore.
* @param owner The player who traded.
* @return The item with lore.
*/
private ItemStack addLore(ItemStack itemStack, Player owner) {
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {

View File

@@ -8,8 +8,11 @@ commands:
toolstats:
usage: /toolstats
description: Main command.
permission: randomenchant.reload
permission: toolstats.main
permissions:
randomenchant.reload:
description: Allows the usage of /randomenchant reload
default: op
toolstats.main:
description: Allows the usage of /toolstats
default: true
toolstats.reload:
description: Allows the usage of /toolstats reload
default: op