Linking effects with an items given name.

Discussion in 'Plugin Development' started by tommyhoogstra, Sep 13, 2013.

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

    tommyhoogstra

    Currently developing a character class plugin that will give certain potion effects when a full set of "god gear" is equipped.

    I am using the plugin http://dev.bukkit.org/bukkit-plugins/legendaryweapons/

    What I would like is when a player has a full set of "god gear" on they receive the effect e.g. Speed 5.

    This is what I have so far:
    Code:java
    1. package me.Hoogstra.Bukkit;
    2.  
    3. import java.util.logging.Logger;
    4.  
    5. import org.bukkit.ChatColor;
    6. import org.bukkit.Material;
    7. import org.bukkit.command.Command;
    8. import org.bukkit.command.CommandSender;
    9. import org.bukkit.entity.Player;
    10. import org.bukkit.event.EventHandler;
    11. import org.bukkit.event.Listener;
    12. import org.bukkit.event.inventory.InventoryCloseEvent;
    13.  
    14. import org.bukkit.inventory.ItemStack;
    15. import org.bukkit.plugin.java.JavaPlugin;
    16. import org.bukkit.potion.PotionEffect;
    17. import org.bukkit.potion.PotionEffectType;
    18.  
    19. public class test extends JavaPlugin{
    20.  
    21.  
    22. public final Logger logger = Logger.getLogger("Minecraft");
    23. public static test plugin;
    24. @Override
    25. public void onEnable() {
    26. this.logger.info("Enabled Test Plugin!");
    27. }
    28.  
    29. @Override
    30. public void onDisable() {
    31. this.logger.info("Disabled Test Plugin!");
    32.  
    33. }
    34.  
    35. @EventHandler
    36. public void onInventoryClose(InventoryCloseEvent event) {
    37. Player player = (Player) event.getView().getPlayer();
    38. ItemStack[] playerArmor = player.getInventory().getArmorContents();
    39. if((playerArmor[0] != null && playerArmor[0].getType() == Material.LEATHER_HELMET)
    40. && (playerArmor[1] != null && playerArmor[1].getType() == Material.LEATHER_CHESTPLATE)
    41. && (playerArmor[2] != null && playerArmor[2].getType() == Material.LEATHER_LEGGINGS)
    42. && (playerArmor[3] != null && playerArmor[3].getType() == Material.LEATHER_BOOTS)))
    43. {
    44. player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, Integer.MAX_VALUE,4));
    45. player.sendMessage("You have equipped the God Set of " + ChatColor.AQUA + "Zerox");
    46. }
    47. }
    48. }

    But as you can see that refers to the item ID's, not to mention that isn't even working for me.

    To go more in depth, one of the god gear items is [​IMG] which is a diamond helmet. The player will require the other 3 items EQUIPPED in order to get the beacon effects.

    How do I refer to the items name? And how do i actually trigger this event, only started java about a week ago, so be nice and very in depth as more questions may arise :)

    Thanks
     
  2. Get item names like this:
    Code:java
    1.  
    2. ItemStack i = /*...*/;
    3. if( i.hasItemMeta() && i.getItemMeta().hasDisplayName() )
    4. {
    5. String name = ChatColor.stripColor(i.getItemMeta().getDisplayName());
    6. }
    7.  
     
    tommyhoogstra likes this.
  3. Offline

    tommyhoogstra


    So i'm guessing i is the item you are getting the name from?
    So how would I go about interpreting this with my code above.

    I'm so bad, sorry :)

    Thanks for the fast reply, liked.
     
  4. You're welcome ;)
    You can put the code from above into a method so you can call it without copying & pasting the code multiple times:
    Code:
    public static String getCustomName(ItemStack i)
    {
    if( i == null ) return null;
    if( i.hasItemMeta() && i.getItemMeta().hasDisplayName() ) {
    return ChatColor.stripColor(i.getItemMeta().getDisplayName());
    }
     
    return null;
    }
    
    Then call it like this:
    Code:
    /* ... */
    if( getCustomName(playerArmor[0]) != null && getCustomName(playerArmor[0]).equalsIgnoreCase("Armor Name")
    && getCustomName(playerArmor[1]) != null && getCustomName(playerArmor[1]).equalsIgnoreCase("Armor Name")
    && getCustomName(playerArmor[2]) != null && getCustomName(playerArmor[2]).equalsIgnoreCase("Armor Name")
    && getCustomName(playerArmor[3]) != null && getCustomName(playerArmor[3]).equalsIgnoreCase("Armor Name") )
    {
    //Player has special armor
    }
    /* ... */
    
     
    tommyhoogstra likes this.
  5. Offline

    tommyhoogstra

    PeterK
    Thanks for that, it went in well, but the event isn't running upon closing my inventory, Am I missing something?
     
  6. Yes, there are multiple issues:
    • Java class names usually start with capital letters (change "test" to "Test")
    • Your class needs to implement the interface "Listener" in order to handle events:
      class Test extends JavaPlugin implements Listener
    • You need to register your EventHandlers:
      public void onEnable()
      {
      ...
      Bukkit.getPluginManager.registerEvents(this,this);
      }
     
    tommyhoogstra likes this.
  7. Offline

    tommyhoogstra

    PeterK
    Is the capital in the java class completely necessary? or just a convention.

    I went to add Bukkit.getPluginManager.registerEvents(this,this); to my on enable, and get getPluginManager cannot be resolved or is not a field - after importing org.bukkit.


    Thanks again peter!
     
  8. It's just a convention, otherwise your plugin would not have compiled in the first place.
    I made a typo there, getPluginManager is a method, forgot the brackets:
    Bukkit.getPluginManager().registerEvents(this,this);

    Always happy to help :)
     
    tommyhoogstra likes this.
  9. Offline

    tommyhoogstra

    God, how embarrassing, even I should have known that -.-.

    It seems it still isnt running the event or something isnt executing properly.
    I reconfigured it to my liking and went in game and equipped the items, and closed my inventory but no potion effect was applied.

    Code:java
    1. package me.Hoogstra.Bukkit;
    2.  
    3. import java.util.logging.Logger;
    4.  
    5.  
    6. import org.bukkit.Bukkit;
    7. import org.bukkit.ChatColor;
    8.  
    9. import org.bukkit.entity.Player;
    10. import org.bukkit.event.EventHandler;
    11. import org.bukkit.event.Listener;
    12. import org.bukkit.event.inventory.InventoryCloseEvent;
    13.  
    14. import org.bukkit.inventory.ItemStack;
    15. import org.bukkit.plugin.java.JavaPlugin;
    16. import org.bukkit.potion.PotionEffect;
    17. import org.bukkit.potion.PotionEffectType;
    18.  
    19. public class test extends JavaPlugin implements Listener{
    20.  
    21.  
    22. public final Logger logger = Logger.getLogger("Minecraft");
    23. public static test plugin;
    24. @Override
    25. public void onEnable() {
    26. this.logger.info("Enabled Test Plugin!");
    27. Bukkit.getPluginManager().registerEvents(this,this);
    28. }
    29.  
    30. @Override
    31. public void onDisable() {
    32. this.logger.info("Disabled Test Plugin!");
    33.  
    34. }
    35. public static String getCustomName(ItemStack i)
    36. {
    37. if( i == null ) return null;
    38. if( i.hasItemMeta() && i.getItemMeta().hasDisplayName() ) {
    39. return ChatColor.stripColor(i.getItemMeta().getDisplayName());
    40. }
    41.  
    42. return null;
    43. }
    44.  
    45. @EventHandler
    46. public void onInventoryClose(InventoryCloseEvent event) {
    47. Player player = (Player) event.getView().getPlayer();
    48. ItemStack[] playerArmor = player.getInventory().getArmorContents();
    49. if( getCustomName(playerArmor[0]) != null && getCustomName(playerArmor[0]).equalsIgnoreCase("Zeroxes Bone Visage")
    50. && getCustomName(playerArmor[1]) != null && getCustomName(playerArmor[1]).equalsIgnoreCase("Zeroxes Shadow Plate")
    51. && getCustomName(playerArmor[2]) != null && getCustomName(playerArmor[2]).equalsIgnoreCase("Zeroxes Platelegs")
    52. && getCustomName(playerArmor[3]) != null && getCustomName(playerArmor[3]).equalsIgnoreCase("Zeroxes Moonlanders") )
    53. {
    54. player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, Integer.MAX_VALUE,4));
    55. player.sendMessage("You have equipped the Assassin class.");
    56. }
    57. }


    PeterK solve this one sir, and you're forever my legend <3 thanks for all the help.
     
  10. Hm. I don't see any issues, try adding some debug output, maybe. Log something when the event gets called and print the results of getCustomName(playerArmor[0-3]) to console to see if there's anything wrong there.
     
  11. Offline

    tommyhoogstra

    PeterK

    Hi peter, I just added a player.sendMessage and that worked fine before the if statement starts

    Must be something within the code you gave me, Ill have a thorough look as well.
     
  12. tommyhoogstra Have you tried printing the method results to see if it returns the name properly?
     
  13. Offline

    tommyhoogstra

    Would adding " player.sendMessage(getCustomName(playerArmor[0-3]));" instead of a regular message work as it should, because nothing is outputted.
     
  14. sorry, should have worded that more clearly xD
    add this above the if-statement:
    Code:
    for( ItemStack item : playerArmor )
    {
    player.sendMessage(getCustomName(item));
    }
    
     
  15. Offline

    tommyhoogstra

    Works, [​IMG]
    I should of thought of using a for loop, god damn java syntax is getting to my head.

    Edit: It reads from boots to Helmet, that could be a cause?
     
  16. you have your item names the wrong way around, it seems :)
    First come the boots, then leggings, chestplate and helmet.
     
  17. Offline

    tommyhoogstra

    Couldn't I change this by perhaps making it
    Code:java
    1. getCustomName(playerArmor[3]) != null && getCustomName(playerArmor[3]).equalsIgnoreCase("Zeroxes Bone Visage")
    2. && getCustomName(playerArmor[2]) != null && getCustomName(playerArmor[2]).equalsIgnoreCase("Zeroxes Shadow Plate")
    3. && getCustomName(playerArmor[1]) != null && getCustomName(playerArmor[1]).equalsIgnoreCase("Zeroxes Platelegs")
    4. && getCustomName(playerArmor[0]) != null && getCustomName(playerArmor[0]).equalsIgnoreCase("Zeroxes Moonlanders") )

    Works!
     
  18. yes, that should work
     
    tommyhoogstra likes this.
  19. Offline

    tommyhoogstra

    Thanks bud, you're a legend.

    mc.kozancraft.com if you ever want to check it out in the future, might be some rewards for you.
     
  20. I'll make sure to drop by some time soon ;)
     
    tommyhoogstra likes this.
  21. Offline

    tommyhoogstra

    PeterK Omg, one more thing which I thought wouldn't be a problem.

    Upon taking the set off, it will keep the speed effect, how should I go about disabling this.
     
  22. just add this below your if-statement:
    Code:
    else // Not wearing the kit
    {
        player.removePotionEffect(PotionEffectType.SPEED)
    }
    
     
    tommyhoogstra likes this.
  23. Offline

    metalhedd

    Also, remember,

    1) dispensers are capable of equipping armor on a player. So you can't rely exclusively on the InventoryCloseEvent,
    2) Armor breaks, so the effect needs to stop when any 1 piece currently being worn breaks.
     
  24. Offline

    tommyhoogstra

    @mentalhedd what events do you suppose I use for this? All legendaries have a high unbreaking level, this will be a rare occurrence.
     
  25. Offline

    metalhedd

    The dispenser fires a normal BlockDispenseEvent, but that doesn't include anything about the player afaik so you'd have to search for the closest player and see if their armor has changed.

    As for the armor breaking, afaik, there is no event for that, so you'd have to listen to all the Damage events, and check if the armor breaks afterwards. (probably by scheduling a 0 tick delayed task)

    Neither of these are super easy to accomplish. good luck.
     
  26. Offline

    tommyhoogstra

    What if the set wasn't set to infinite, instead a reoccurring set time, e.g. 8 Seconds.
    And if all pieces are equipped, disable the reoccurring.
     
  27. Offline

    metalhedd

    that's a pretty good option too.
     
  28. Offline

    tommyhoogstra

    What would be an ideal way of doing this, while player has equipped?

    PeterK

    I have a new idea, and I must say im willing to donate if this can be accomplished because you've done so much for me already.

    Is it possible to give these effects if the player has a specific Item in their hand AND the armor equipped. This could resolve most of the problems as you could put it under a new event.
     
  29. Yes, it is possible.
    Code:java
    1.  
    2. @EventHandler
    3. public void onItemHeld( PlayerItemHeldEvent evt )
    4. {
    5. if( getCustomName(evt.getPlayer().getItemInHand()) == "Some items name" )
    6. {
    7. //do the checks as you would with the other event and add the effect.
    8. }
    9. else
    10. {
    11. //remove the effects from the player.
    12. }
    13. }
    14.  
     
    tommyhoogstra likes this.
  30. Offline

    tommyhoogstra

    Cheers! Got paypal?

    Edit: nvm fixed!
     
Thread Status:
Not open for further replies.

Share This Page