Need help with a custom item plugin i made.

Discussion in 'Plugin Development' started by trusebruse, May 19, 2013.

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

    trusebruse

    I made a plugin today that were supposed to give players powers when they bless a altar. The altar is made of 9 diamond blocks in a crafting table. Everything works fine except that you can rightclick any block to get powers and not just by the altar.

    Since the altarblock is just a renamed diamondblock, How do i controll it in eclipse?
    //Trusebruse

    Code:
    Code:
    package me.trusebruse.prayer;
    import java.util.ArrayList;
     
    import org.bukkit.ChatColor;
    import org.bukkit.Material;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.Action;
    import org.bukkit.event.player.PlayerInteractEvent;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.ShapelessRecipe;
    import org.bukkit.inventory.meta.ItemMeta;
    import org.bukkit.plugin.java.JavaPlugin;
    import org.bukkit.potion.PotionEffect;
    import org.bukkit.potion.PotionEffectType;
     
     
     
    public class Prayer extends JavaPlugin implements Listener{
       
        public void onEnable(){
            //Altar Block
            getServer().getPluginManager().registerEvents(this,this);
            ItemStack i = new ItemStack(Material.DIAMOND_BLOCK, 1);
            ItemMeta meta = i.getItemMeta();
            meta.setDisplayName(ChatColor.GOLD+"Altar");
            ArrayList<String> lore = new ArrayList<String>();
            lore.add("Pray on this for temporary power.");
            meta.setLore(lore);
            i.setItemMeta(meta);
            ShapelessRecipe Altar = new ShapelessRecipe(i);
            Altar.addIngredient(9, Material.DIAMOND_BLOCK);
            getServer().addRecipe(Altar);
        } 
     
     
        //Effects 
        @EventHandler
        public void onPlayerInteract(PlayerInteractEvent event){
            if(event.getAction() == Action.RIGHT_CLICK_BLOCK){
                Player player = event.getPlayer();
                player.addPotionEffect(new PotionEffect(PotionEffectType.REGENERATION, 3000, 0));
                player.addPotionEffect(new PotionEffect(PotionEffectType.NIGHT_VISION, 10000, 100));
                player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 1000, 1));
                player.addPotionEffect(new PotionEffect(PotionEffectType.FIRE_RESISTANCE, 1000, 0));
                if (player.hasPermission("altar.use"));
            }
        }
    }
     
  2. Offline

    CubieX

    Well you have set a new DisplayName for your altar block.
    So you can check if the Block which is right clicked is a DIAMOND_BLOCK anf if so,
    check if theDisplayName is saying "Altar".
    Then it is an altar block and you can add your effects.
    If you were able to set this data, I'm sure you are also able to check it. ;)
     
  3. Offline

    trusebruse

    I didn't get that. Note: I'm very new to java and programming whatsoever. I'm doing this for learning porposes for the most part. So how do i check if block the block i'm right clicking on is a diamond block?

    EDIT: Very much of that code was taken from others because i wanted to see the structure of java a little bit more.

    Someone have any idea?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 1, 2016
  4. Offline

    CubieX

    Sorry. My first post did not cover your whole problem...

    This is not as easy as I first thought.
    I've never before used MetaData for anything.
    I just read some info and browsed the API for it.
    Problem is: When placing this block from your special ItemStack, the added MetaData (like the DisplayName "Altar") will not transfer over to the placed block.

    You could do this manually. But another problem is: MetaData is not remanent.
    So on server restart it will be lost.

    It seems like "registering" this special block by saving it's location to a file would be the only way to
    achieve, what you are trying to do.

    I implemented and tested this.
    Please ask if you don't understand what or why I'm doing something here. (You want to learn, right? ;) )

    To check if the placed block should be an "Altar"-block and save it to your config.yml,
    you could do something like that in your "BlockPlaceEvent" handler:
    Code:
    if(e.getBlock().getType() == Material.DIAMOND_BLOCK)
          {
            if(e.getItemInHand().getItemMeta().getDisplayName().equals("§6Altar"))
            {
                e.getPlayer().sendMessage("Recognized DisplayName of this ItemStack: Altar");
                Block b = e.getBlock();
           
                plugin.getConfig().set("altarblocks." + b.getX() + "_" + b.getY() + "_" + b.getZ() + "_" + b.getWorld().getName(), "");                   
                plugin.saveConfig();
                e.getPlayer().sendMessage("Block saved as Altar block in config");
            }
          }
    This block is now saved in your config.yml with it's location and the world.
    All blocks saved there will be treated as "Altar" blocks.

    And to check if a block is a registered Altar block when a player right clicks it, you could do
    something like this in your PlayerInteractEvent:
    Code:
    if(e.getClickedBlock().getType() == Material.DIAMOND_BLOCK)
            {
                Block b = e.getClickedBlock();
                                 
                if(plugin.getConfig().getConfigurationSection("altarblocks").contains(b.getX() + "_" + b.getY() + "_" + b.getZ() + "_" + b.getWorld().getName()))
                {
                  e.getPlayer().sendMessage("This is an Altar block!");
                }
            }
    So if a player right clicks a diamond block, it will try to find the block in your config.yml and if it's found, that means it's an "Altar" block.

    You will have to remove the suiting entry from the config file when the block gets broken.
    Otherwise your config.yml will be someday filled with invalid entries.
    This is done in the BlockBreakEvent.
    Code:
    if(e.getBlock().getType() == Material.DIAMOND_BLOCK)
          {
            Block b = e.getBlock();
                                 
            if(plugin.getConfig().getConfigurationSection("altarblocks").contains(b.getX() + "_" + b.getY() + "_" + b.getZ() + "_" + b.getWorld().getName()))
            {
                plugin.getConfig().set("altarblocks." + b.getX() + "_" + b.getY() + "_" + b.getZ() + "_" + b.getWorld().getName(), null);
                plugin.saveConfig();
                e.getPlayer().sendMessage("This Altar block has been deleted from file!");
            }
          }
    Your config will look like this, if some altar blocks are already registered:
    Code:
    altarblocks:
      89_69_-9_ccraft4: ''
      91_69_-6_ccraft4: ''
      88_69_-4_ccraft4: ''

    This will work. However, I can't say if this is the "best" sloution for this task.
     
    AndyMcB1 likes this.
  5. Offline

    trusebruse

    Seems pretty good but is there any way to make players on the server place the block, bless it, break it and walk away with it?
     
  6. Offline

    CubieX

    I don't know if I understand you correctly.

    Placing an "Altar" block is possible with my code above.
    "Blessing" is done in your code. (if you mean with this, they will get those potion effects.)
    Breaking and retrieving the special Item:
    Here you have to check in the BlockBreakEvent if this is an Alatar block (see my code)
    and then get the drops of the broken block (block.getDrops()).
    This ItemStack can be updated with MetaData exactly like you did in your onEnable() method, and the player can pick it up and use it again.
     
  7. Offline

    trusebruse

    Alright... I'll try your code out if you could send me the complete code for me to replace. Thanks. :)
     
  8. Offline

    CubieX

    This is all code I used, except for the three handlers I mentioned.
    You already created an EventHandler for the PlaxerInteractEvent in your code in your first post.
    So it should be no problem to create the other two also. One for the BlockBreakEvent and one for the BlockPlaceEvent.
    Create those handlers and then you can use my code with little to no change in those handlers.
    Of course you have to apply those potion effects instead of using my debug messages in the PlayerInteractEvent handler. ;)
     
  9. Offline

    trusebruse

    But you see, I only gets lots of errors when i replace my code with yours. (plugin can not be resolved, e can not be resolved) and so on.. Please make your three codes complete because i have no time to figure out what to do about the errors right now. I'm short on time :3
     
  10. Offline

    CubieX

    Not my problem.
    It's your plugin. Not mine. Take your time to learn. It will be rewarding.
    But "Copy and Paste" is nothing you should be looking for.
    I gave you more explicit code than I normally would. Learn to adapt that.
    You only need the most basic understanding of JAVA to do it.

    Sorry. Perharps someone else is willing to help you more.
     
  11. Offline

    Minnymin3

    Just use metadata. i.e. set the diamond block's data to 7 and then check of the block is a diamond block and then check if the data is 7.
     
  12. Offline

    trusebruse

    And what's the code for that? :)
     
  13. Offline

    Minnymin3

    block.setData((byte)7);
     
  14. Offline

    trusebruse

    That code did not work.

    DescriptionResourcePathLocationType
    Syntax error on token ")", delete this tokenPrayer.java/Prayer/src/me/trusebruse/prayerline 37Java Problem
    Syntax error on token "(", = expected after this tokenPrayer.java/Prayer/src/me/trusebruse/prayerline 37Java Problem
    Syntax error on token "(", Identifier expectedPrayer.java/Prayer/src/me/trusebruse/prayerline 37Java Problem

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 1, 2016
  15. Offline

    Minnymin3

  16. Offline

    trusebruse

    Code:
    package me.trusebruse.prayer;
    import java.util.ArrayList;
     
    import org.bukkit.ChatColor;
    import org.bukkit.Material;
    import org.bukkit.block.Block;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.Action;
    import org.bukkit.event.player.PlayerInteractEvent;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.ShapelessRecipe;
    import org.bukkit.inventory.meta.ItemMeta;
    import org.bukkit.metadata.MetadataValue;
    import org.bukkit.plugin.java.JavaPlugin;
    import org.bukkit.potion.PotionEffect;
    import org.bukkit.potion.PotionEffectType;
     
     
     
    public class Prayer extends JavaPlugin implements Listener{
       
        public void onEnable(){
            //Altar Block
            getServer().getPluginManager().registerEvents(this,this);
            ItemStack i = new ItemStack(Material.DIAMOND_BLOCK, 1);
            ItemMeta meta = i.getItemMeta();
            meta.setDisplayName(ChatColor.GOLD+"Altar");
            ArrayList<String> lore = new ArrayList<String>();
            lore.add("Pray on this for temporary power.");
            meta.setLore(lore);
            i.setItemMeta(meta);
            ShapelessRecipe Altar = new ShapelessRecipe(i);
            Altar.addIngredient(9, Material.DIAMOND_BLOCK);
            getServer().addRecipe(Altar); } 
            block.setData((byte)7);
           
           
           
     
     
        //Effects 
        @EventHandler
        public void onPlayerInteract(PlayerInteractEvent event)
        {
            if(event.getAction() == Action.RIGHT_CLICK_BLOCK)
            {
                event.getPlayer().sendMessage(ChatColor.GOLD+ "You absorbed powers from the gods.");
                Player player = event.getPlayer();
                player.addPotionEffect(new PotionEffect(PotionEffectType.REGENERATION, 3000, 0));
                player.addPotionEffect(new PotionEffect(PotionEffectType.NIGHT_VISION, 10000, 100));
                player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 1000, 1));
                player.addPotionEffect(new PotionEffect(PotionEffectType.FIRE_RESISTANCE, 1000, 0));
                if (player.hasPermission("altar.use"));}
            {
     
  17. Offline

    Minnymin3

    no dont put in your onEnable! make an event to detect when a player places an altar (check the name) and then set the data to 7. Then check if the block that they clicked on is a diamond block with data 7. Then make an event handler for block breaking and check if the block is a diamond block with data 7 and drop an altar item.
     
  18. Offline

    trusebruse

    But that's not really the problem you see.. I want to fix the problem with that you just have to righclick anywhere and not just an altar get the effects.
    EDIT: And due to this you can't even break or place blocks.
     
  19. Offline

    socram8888

    Have a look at this: https://github.com/socram8888/netherbrick

    I am creating a "prototype" NetherBrick ItemStack in a private variable, and then I register crafting and smelting. It is a basic one-file that shows how to create a customized item.

    Well, for what you want to do, remove the smelting code, remove or modify the recipe, add a Listener for PlayerInteractEvent. Inside that listener, compare if whatever the player has in its hand isSimilar (see http://jd.bukkit.org/rb/apidocs/org/bukkit/inventory/ItemStack.html ) to the "prototype" ItemStack you created at the start, and if it is, add the player the potion effects.
     
  20. Offline

    Minnymin3

    That will fix your problem. But (not to be mean) id learn a bit more java before writing plugins.
    Im saying this because you have an if statement that does absolutely nothing.
     
  21. Offline

    trusebruse

    Yeah i know i have to study more java but i tought if i made plugin i would learn but it wasn't that easy.
    But first of i want to complete this plugin and i'll try socram8888 's code because it seems to work out better.
     
  22. Offline

    socram8888

    I recommend you using:
    Code:
    getServer().addRecipe(recipe);
    rather than:
    Code:
    Bukkit.addRecibe(recipe);
    as I'm doing in the plugin, because it is more correct (using static methods tend to break Java's modularity). I haven't fixed it because updating a plugin for something that Minecraft already has by default is pointless.
     
  23. Offline

    trusebruse

    Whelp.. i've tried for a long time figuring out how i could fix it.. I't won't work and now i have to go for the day so i hope you'll help me tomorrow ;)
     
  24. Offline

    trusebruse

    I kept trying to fix it and i almost got it. One error, how do i fix?:
    DescriptionResourcePathLocationType
    The method createBrick() from the type Prayer is never used locallyPrayer.java/Prayer/src/me/trusebruse/prayerline 20Java Problem

    Code:
    Code:
    package me.trusebruse.prayer;
     
    import org.bukkit.ChatColor;
    import org.bukkit.Material;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.block.Action;
    import org.bukkit.event.player.PlayerInteractEvent;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.ItemMeta;
    import org.bukkit.plugin.java.JavaPlugin;
    import org.bukkit.potion.PotionEffect;
    import org.bukkit.potion.PotionEffectType;
     
    public class Prayer extends JavaPlugin {
        private ItemStack Altar;
        private short DIAMOND_BLOCK;
        private String Altar_Block;
       
            private void createBrick() {
                Altar = new ItemStack(Material.CLAY_BRICK, 1, DIAMOND_BLOCK);
                ItemMeta meta = Altar.getItemMeta();
                meta.setDisplayName(ChatColor.RESET + Altar_Block);
                Altar.setItemMeta(meta);
            };
        public ItemStack getAltar() {
            return this.Altar;
        };
     
        //Effects 
        @EventHandler
        public void onPlayerInteract(PlayerInteractEvent event)
        {
            if(event.getAction() == Action.RIGHT_CLICK_BLOCK)
            {
                event.getPlayer().sendMessage(ChatColor.GOLD+ "You absorbed powers from the gods.");
                Player player = event.getPlayer();
                player.addPotionEffect(new PotionEffect(PotionEffectType.REGENERATION, 3000, 0));
                player.addPotionEffect(new PotionEffect(PotionEffectType.NIGHT_VISION, 10000, 100));
                player.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 1000, 1));
                player.addPotionEffect(new PotionEffect(PotionEffectType.FIRE_RESISTANCE, 1000, 0));
                if (player.hasPermission("altar.use"));}
            {
     
                 
                  event.setCancelled(true);
                  event.getPlayer().sendMessage(ChatColor.AQUA+ "The gods won't transfer powers to you yet.");
                  }
        }
    }
     
     
                 
    
     
  25. Offline

    Rocoty

    Remove it? Or invoke it somewhere? It is never used locally, just as it tells you.
    On a side note, this is not an error, just a warning. The code will still compile.
     
  26. Offline

    trusebruse

    But the thing is, if I remove it i'll get tons of errors.
     
  27. Offline

    Rocoty

    I don't see how you possibly could. The method is never referenced anywhere
     
  28. Offline

    trusebruse

    Well it does,
    DescriptionResourcePathLocationType
    Syntax error on token "ItemStack", @ expectedPrayer.java/Prayer/src/me/trusebruse/prayerline 25Java Problem
    Syntax error on token "}", delete this tokenPrayer.java/Prayer/src/me/trusebruse/prayerline 24Java Problem
    Syntax error on token(s), misplaced construct(s)Prayer.java/Prayer/src/me/trusebruse/prayerline 20Java Problem
    Syntax error on token ";", { expected after this tokenPrayer.java/Prayer/src/me/trusebruse/prayerline 18Java Problem

    EDIT: Redmarks over the whole method.
     
  29. Offline

    Rocoty

    Did you remove the entire method? Let me see your code
     
  30. Offline

    trusebruse

    You have it on the other page you know. I didn't do anything to it except removing the private void createBrick() {
     
Thread Status:
Not open for further replies.

Share This Page