"Tagging" Items (to apply delays to individual items)

Discussion in 'Plugin Development' started by rogerin0, Jan 11, 2013.

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

    rogerin0

    Hi there,

    My plugin currently allows bones to launch projectiles on right-click. To limit the rate of fire, I'm attempting to add a one-second delay between each launch.

    Initially, I've thought of tagging the bone that was used to launch the projectile by setting its metadata to "Delay", and then removing this metadata value with a scheduled task that would execute a second later. Bones marked with "Delay" will not be able to launch projectiles.

    However, it turned out that setting metadata for ItemStack is not possible. So I used the same method except the metadata was given to the player instead of the bone item. This works, however, if the player has multiple bones in his inventory, he would not be able to alternate between them, as they would all share the same cooldown of one second.


    How would one be able to apply delays to individual items? Any solutions?
    Thanks in advance!
     
  2. Offline

    fireblast709

    You could use the lore for this one
     
  3. Offline

    stirante

    I think setting durability will be much easier.
     
  4. Offline

    fireblast709

    just not applicable for all items
     
  5. Offline

    stirante

    It's not applicable only for items which uses durability. He's using only bones.
     
  6. Offline

    fireblast709

    just saying before anyone tries for example a sword or hoe
     
  7. Offline

    rogerin0

    stirante fireblast709

    My concern is that, if something managed to stop the scheduled task from running, whether it be a server crash or whatever, the item would be stuck with the "this item is on cool-down" tag forever, rendering it useless. That's what makes metadata so much more appealing than permanently modifying the information of the item, because if the scheduled task is interrupted, the item will be corrected eventually on the next server restart.

    Any ideas?
     
  8. Offline

    Comphenix

    Then why not add one more level to the hierarchy and add a slot index to the cooldown, in addition to the player.

    You can do this with metadata, with a WeakHashMap or a HashMap that is cleaned up by a player quit event. Just store the time an item in a given slot was used in some fashion, for instance by using an array:
    Code:java
    1. public class ExampleMod extends JavaPlugin implements Listener {
    2. private Map<Player, long[]> cooldownsMap = new WeakHashMap<Player, long[]>();
    3.  
    4. /**
    5.   * The default cooldown in milliseconds.
    6.   */
    7. private static final int DEFAULT_COOLDOWN = 1000;
    8.  
    9. @Override
    10. public void onEnable() {
    11. getServer().getPluginManager().registerEvents(this, this);
    12. }
    13.  
    14. @EventHandler
    15. public void onPlayerRightClick(PlayerInteractEvent event) {
    16. Player player = event.getPlayer();
    17.  
    18. if (event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
    19. long[] cooldowns = cooldownsMap.get(player);
    20. long currentTime = System.currentTimeMillis();
    21.  
    22. // Index of the currently selected item
    23. int index = player.getInventory().getHeldItemSlot();
    24.  
    25. if (cooldowns == null || cooldowns[index] + DEFAULT_COOLDOWN < currentTime) {
    26. // Cooldown expired
    27. player.sendMessage("Action performed!");
    28.  
    29. // Allocate the array
    30. if (cooldowns == null) {
    31. cooldowns = new long[player.getInventory().getSize()];
    32. }
    33.  
    34. cooldowns[index] = currentTime;
    35. cooldownsMap.put(player, cooldowns);
    36. }
    37. }
    38. }
    39. }

    Sure, you could move the item out of the slot and reset the cooldown that way, but with a relatively short cooldown (1 second), that is probably not a concern.

    I also tried to index the map on the ItemStack itself (and the underlying net.minecraft.server handle it wraps), but it appears that the ItemStack object is inevitably cloned before a player interact event is invoked. You would have to store that data in the "tag" field (item meta), which is probably not a good idea for all the reasons you mentioned.
     
    devilquak likes this.
  9. Offline

    zXCaKeXz

    in PlayerJoinEvent, run through their inventory items and check if the item has the cooldown. if it does, remove the cooldown
     
  10. Offline

    microgeek

    I believe that MEtadata gets reset when the server is reloaded, not an issue.
     
  11. Offline

    zXCaKeXz

    metadatas cannot be applied to itemstacks, so he was referring to item lores/names
     
Thread Status:
Not open for further replies.

Share This Page