need a logical solution to this problem please!

Discussion in 'Plugin Development' started by johnny_boy, Dec 23, 2019.

Thread Status:
Not open for further replies.
  1. Offline

    johnny_boy

    In essence I've decided to develop a plugin that rots certain food in minecraft over 3 minecraft days. I know I'm going to need a BukkitRunnable running every second or so to update how the food is rotting however I need help with this criteria:

    • Food should change status once every minecraft day and should change regardless of where it has been placed. inventory/chest/shulker box/backpack/etc [If placed in an enderchest, if possible, deny rotting until it is removed again]

    • Fresh, stale, and musty food should not be allowed to stack with eachother, but food items that are fresh can stack with fresh and etc.

    I have no idea how to track every individual item. The only thing I can think of is creating a unique id for every item but this means I can't stack them (I don't think?). If you need more information/are confused then say below but thanks for reading.
     
  2. Online

    KarimAKL

    I think you can listen for the InventoryClickEvent & InventoryDragEvent, then save the location if the item was moved.

    You can give the item an NBT tag like "FRESH", "STALE", "MUSTY", "ROTTEN", then they won't stack with anything that doesn't have the same NBT tag.
     
  3. Offline

    johnny_boy

    saving the location then using that as an id of sorts so i can track how rottened an item is - would that work as an ID system?
     
  4. Online

    KarimAKL

    @johnny_boy I was thinking of something like this:
    Code:Java
    1. // A class to hold information about the items
    2. public class CustomItem {
    3.  
    4. // A list of all the items, you can get or remove items from this
    5. public static final List<CustomItem> items = new ArrayList<>();
    6.  
    7. public final ItemStack item; // The item
    8. public Inventory inventory; // The inventory it's stored in
    9. public int slot; // The slot it's stored in
    10. public final long time; // The time it was created
    11.  
    12. public CustomItem(ItemStack item, Inventory inventory, int slot) {
    13. this.item = item;
    14. this.inventory = inventory;
    15. this.slot = slot;
    16. this.time = System.currentTimeMillis();
    17. items.add(this); // Adds the item to the list
    18. }
    19.  
    20. public State getState() {
    21. State state = null;
    22. for (int i = State.values(); i > 0; i--) {
    23. State s = State.getState(i - 1);
    24. if (time < s.time) continue;
    25. state = s;
    26. break;
    27. }
    28. return state;
    29. }
    30.  
    31. public static CustomItem getItem(Inventory inventory, int slot) {
    32. ItemStack item = inventory.getItem(slot);
    33. for (CustomItem customItem : items) if (customItem.item.isSimilar(item) && customItem.inventory.equals(inventory) && customItem.slot == slot) return customItem;
    34. return null;
    35. }
    36.  
    37. public enum State {
    38.  
    39. // These are just example times
    40. FRESH(0), // It starts as fresh
    41. STALE(12000 * 20 * 1000), // It becomes stale after half a day
    42. MUSTY(24000 * 20 * 1000), // It becomes musty after one day
    43. ROTTEN(3 * 24000 * 20 * 1000); // It becomes rotten after three days
    44.  
    45. public final long time; // The time it takes for it to get this state
    46.  
    47. private State(long time) {
    48. this.time = time;
    49. }
    50.  
    51. public static State getState(int ordinal) {
    52. for (State state : values()) if (s.ordinal() == ordinal) return state;
    53. return null;
    54. }
    55. }
    56. }
    57.  
    58. // In your Listener
    59. @EventHandler
    60. private void onClick(InventoryClickEvent event) {
    61. Inventory inventory = ...;
    62. int slot = ...;
    63. CustomItem customItem = CustomItem.getItem(inventory, slot);
    64. customItem.inventory = inventory;
    65. customItem.slot = slot;
    66. }

    Note: I wrote this as an example, i haven't tested it, neither have i checked for null, etc.
     
  5. Offline

    Irantwomiles

    I wouldn't do it with a BukkitRunnable, instead I would store the time where the item was put in the different types of chest and compare that time with the current one when you look at the item. Also if you name a steak something custom, it wont stack with other steak as long as they dont have the same name (could be if they have different item meta).
     
    KarimAKL likes this.
  6. Online

    KarimAKL

    @Irantwomiles They don't stack as long as the ItemMeta is different, not only because of the name, which is why i recommended NBT, that way you won't be forced to include it in the name or lore.
     
    Irantwomiles likes this.
  7. Offline

    Irantwomiles

    I have personally really never used NBT so I can't really give any advice on it, but there are multiple ways of going about this and I think both of ours are valid solutions to the same problem. Although I believe NBT could possibly break on older versions of bukkit/spigot as mojang does change some of these things per version.
     
  8. I was wondering if I could maybe help with some parts of this plugin? A similar plugin already exists (called "FoodExpiry"), but it only works on 1.13+, and doesn't seem to have more than one expiration stage. I know how to make a plugin like this compatible in 1.8-1.14+; using some special NMS code or an external library, item attributes can be modified in all of those versions. The horse.jumpStrength attribute could be used to store a timestamp for when the item was created, and it could be made completely hidden from the item's lore. If you want I could code the part that calculates and updates item age in a way that works on all versions, and you could make most of the features.
     
  9. Online

    KarimAKL

    Yes, i believe they're both valid solutions. I just didn't want to force @johnny_boy to include it in the name or lore.

    You are correct; since NBT tags require NMS, it would break on different versions if you don't use reflection or abstraction.
    I'd recommend abstraction over reflection, though you could just update it if it's a custom plugin.
     
Thread Status:
Not open for further replies.

Share This Page