Help Needed, Partly.

Discussion in 'Plugin Development' started by MeRPG, Jan 5, 2013.

?

Would you use this plugin?

  1. Yes

    50.0%
  2. No

    50.0%
  3. Maybe so

    0 vote(s)
    0.0%
Thread Status:
Not open for further replies.
  1. Offline

    MeRPG

    Hi! After finishing my latest plugin, wich has no point in being published (No config, set for my own server), I am eager to begin the next one. This one is a bit more complicated. I just need sugustions on how to format it, as I am already a moderate coder. I will put a star (*#) next to parts I don't know how to do. Here's an overveiw:
    Plugin title: Frame Those Shops!
    Function:
    Creation:
    Admin places Item Frame.
    Admin points at the frame and types: /fs set [price]
    Plugin checks if admin has perms.
    Plugin detects what the Admin is holding(*1), and creates an ItemFrame where he/she is
    pointing(*2),containing that Item(*3).
    The item frame is given the data(*4), and the job is done.
    Using:
    Player left clicks Item Frame.
    Plugin checks if the clicked frame is a shop(*5).
    If it is not, the plugin would cancel the action and return.
    If it is, the plugin would get info from the frame, such as cost, and the item in it(*6).
    The plugin would then send the player a message with that info.
    The player could then right click the Frame.
    The plugin would now check if the clicked frame is a shop(*5).
    If it is not, the plugin would cancel the action and return.
    If it is, the plugin would get info from the frame, such as cost, and the item in it(*6).
    Frame Those Shops would then check if the player has enough money to buy the item.
    If they did not, they would receive a message notifying them.
    If they did, they would be charged and receive a message and their item.
    Deleting:
    Admin points at the frame and types: /fs set [price]
    Plugin checks if admin has perms.
    Deletes frame.

    Simple enough. A few details, I code huge plugins in one class. This will be done the same way. No biggie.
    When you respond, please note wich number you have a solution to. Here's what I have so far:
    Code:
    package frameshop;
     
     
     
    import java.util.Set;
     
    import org.bukkit.Bukkit;
    import org.bukkit.Material;
    import org.bukkit.block.Block;
    import org.bukkit.block.BlockFace;
    import org.bukkit.block.Sign;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.Action;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.plugin.Plugin;
    import org.bukkit.plugin.java.JavaPlugin;
     
    import cosine.boseconomy.BOSEconomy;
     
    public class Main extends JavaPlugin implements Listener {
        @Override
        public void onEnable(){
            getLogger().info("Frame Those Shops has been enabled.");
            Bukkit.getPluginManager().registerEvents(this, this);
     
        }
     
        @Override
        public void onDisable() {
            getLogger().info("Frame Those Shops has been disabled.");
     
        }
        BOSEconomy economy = null;
     
        public void loadBOSEconomy()
        {
            // Attempt to get the plugin instance for BOSEconomy.
            Plugin temp = this.getServer().getPluginManager().getPlugin("BOSEconomy");
           
            // Check whether BOSEconomy is loaded.
            if(temp == null)
                // BOSEconomy is not loaded on the server.
                economy = null;
            else
                // BOSEconomy is now stored in the "economy" variable.
                economy = (BOSEconomy)temp;
        }
     
     
        @EventHandler
        //This is the using section
        public void onPlayerInteractEvent(final Player player, final Action action, final ItemStack item, final Block block, final BlockFace face) {
            if(action == Action.LEFT_CLICK_BLOCK && block != null){
                if(block.getTypeId() == 389){
                    if(/*Is a frame shop(*5)*/){//expected error
                        String name = /*What's for sale?*/.toString();//expected error
                        String cost = /*Price*/.toString(); //works fine here, fails on line 72. //expected error
                        player.sendMessage("This is a shop. The item for sale is 1: " + name + ". It costs:" + cost + ".");
                    }else{
                        return;
                    }
                }
            }else if(action == Action.RIGHT_CLICK_BLOCK && block != null){
                if(block.getTypeId() == 389){
                    if(/*Is a frame shop(*5)*/){//expected error
                        String name = /*What's for sale?*/.toString();//expected error
                        int price = /*Cost?x-1*/
                        String cost = Integer.toString(price); // IDK why I get an error here, it works fine on line 61.
                        player.sendMessage("Thanks for buying 1 " + name + ". It cost you " + cost + "."); //expected with failure on line 72
                        String sender = player.toString();
                        economy.addPlayerMoney(sender, price, true);
                    }else{
                        return;
                    }
                }
            }
        }
        //Creation Script
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args){
            if(cmd.getName().equalsIgnoreCase("fs")){
                if(args[0] == "set"){
                    ItemStack item = /*held item*/;//expected error
                    //Creates the item frame and sets data
                }else if(args[0] == "remove"){
                    //Get rid of the item Frame
                }
            }
           
            return true;
        }
    }
    
    Any help is greatly appriciated.
    MeRPG
     
  2. Offline

    hockeygoalie5

    1. Get the admin's player class. player.getItemInHand() I think is the method.
    2. player.getTargetBlock() will get the block at which he is looking. You can then get the block in front of the target block and set it to a frame.
    3. Here, you will probably have to edit the frame's NBT tags. It's not as scary as it looks, do some Googling.
    4. If you mean store its cost and the like, I would create a Shop class. The class can have all the fields you need like cost, item, the item frame it's in, etc.
    5. What I would normally do here is load all of the frames from a SQLite database in onEnable(). Then, create and store a Shop class in an ArrayList field. I would create a method to search this ArrayList that will return the Shop that's associated with the block I give in the arguments, and return null if not found. To check if it's a shop, just do a getShop() != null.
    6. These can be methods in your Shop class.
    Let me know if you can't figure these out yourself and need specifics.
     
  3. Offline

    fireblast709

    3. ItemFrame in Javadocs, read it... it contains the .setItem(ItemStack) method which sets the ItemStack in the frame, no NBT needed.
    Use a HashMap<String, Shop> to store the ItemFrames that are shops, with String being a String representation of the block coords
     
  4. Offline

    MeRPG

    Okay, I have a few questions.
    1) How would I get the block in front of the block being looked at?
    2)I can't seem to convert CommandSender to Player.
    3)For #4, I don't understand what you are getting at, creating a new class. could you provide me with an example?
    4)I have never used hash maps and dont know how. is there a location i could learn about them?
     
  5. Offline

    hockeygoalie5

    1. After reading your request more, the ItemFrame should be the block that you get from getTargetBlock(). I thought you were wanting to create a frame where the player was looking, and not that there was one already there.
    2. To convert one class in Java to another, you cast it. To cast CommandSender to Player, use:
      Code:
      Player player = (Player) sender;
    3. Classes are what make the objects in Java. Your main file you put in the original post is a class. Make a new class that has methods, fields, and a constructor for shops. If anything I said previously doesn't make sense, I recommend learning more general Java before diving into Bukkit development.
    4. HashMaps are easy to use, just Google it to learn about them. You don't really need one in this case, though. You could store the block's coordinates into a string in a HashMap like fireblast709 suggests, but I would store it as a Location field in your Shop class.
     
  6. Offline

    MeRPG

    Well, I am trying to create a new frame. Sorry I failed to clarify that.
    For the new class, would'nt it have to write data to the class every time I created an Item Frame Shop?
    I do know what a class is and how it works, I meant what to put in it.
     
  7. Offline

    ZeusAllMighty11


    Only when it comes to storage time, should be when data is written (to an external file). I don't understand your question very well, sorry.
     
  8. Offline

    MeRPG

    Another request, looka at line 72 under the RIGHT_CLICK_BLOCK action's part of the if statement. this is the line.
    String cost = Integer.toString(price);
    eclipse is giving me this error:
    - cost cannot be resolved to a variable.
    - String cannot be resolved to a variable.
    - Syntax error, insert ";" to complete LocalVariableDeclarationStatement.
    Would this be because price is not finished?

    What I'm saying is that I don't know what I would be storing in the class hockeygoalie5 told me to make.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jul 8, 2016
  9. Offline

    hockeygoalie5

    Store the item frame, the shop's owner (if you have and want one), and the cost. Here's an example of it:
    Code:
    public class Shop {
        private int cost;
        private Player owner;
        private ItemFrame frame;
        private ItemStack item;
        public Shop(Player owner, ItemFrame frame, int cost) {
            this.cost = cost;
            this.owner = owner;
            this.frame = frame;
            item = frame.getItem();
        }
        public int getCost() {
            return cost;
        }
        public Player getOwner() {
            return owner;
        }
        public ItemFrame getFrame() {
            return frame;
        }
        public ItemStack getItem() {
            return item;
        }
    }
    
    You will need to store the item frame, cost, and owner to a database (or a YAML file if you don't care to learn SQL and don't mind if it's ugly), so when the server goes down it's all saved.
     
  10. Offline

    MeRPG

    You know, it would be eisier to use an existing frame. I'll do that.
     
  11. Offline

    hockeygoalie5

    Yep, just have them place a frame, put an item in it, then run the command with the cost.
     
  12. Offline

    MeRPG

    So this would store a frame and it's data?
    I mean if I stored it in YAML
     
  13. Offline

    hockeygoalie5

    Yes. When a player runs the command to set a store, create a new Shop with all the information and store that shop in an ArrayList so that it is saved. Also, in your onEnable, load all of the shops you stored offline when the server went down and do the same.
     
  14. Offline

    MeRPG

    Okay, getTargetBlock is not working.
    Here's my syntax: ItemFrame frame = player.getTargetBlock();
    I don't see why this won't work. it wants the arguments "player.getTargetBlock(HashSet<Byte>, int);"

    Well, I agian feel stupid asking, but after googling several ArrayList tutorials, I can't figure out how to store a shop in an ArrayList. Here's what I have. Any pointers to my mistakes with the ArrayList would be appriciated.
    Main:
    Code:
    package frameshop;
     
     
     
    import java.util.ArrayList;
    import java.util.Set;
    import frameshop.Shop;
     
    import org.bukkit.Bukkit;
    import org.bukkit.Material;
    import org.bukkit.block.Block;
    import org.bukkit.block.BlockFace;
    import org.bukkit.block.Sign;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.Action;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.plugin.Plugin;
    import org.bukkit.plugin.java.JavaPlugin;
     
    import cosine.boseconomy.BOSEconomy;
     
    public class Main extends JavaPlugin implements Listener {
        @Override
        public void onEnable(){
            getLogger().info("Frame Those Shops has been enabled.");
            Bukkit.getPluginManager().registerEvents(this, this);
            ArrayList shops = new ArrayList();
            getLogger().info("Frame Those Shops has loaded " + shops.size() + "shops.");
        }
     
        @Override
        public void onDisable() {
            getLogger().info("Frame Those Shops has been disabled.");
     
        }
        BOSEconomy economy = null;
     
        public void loadBOSEconomy()
        {
            // Attempt to get the plugin instance for BOSEconomy.
            Plugin temp = this.getServer().getPluginManager().getPlugin("BOSEconomy");
           
            // Check whether BOSEconomy is loaded.
            if(temp == null)
                // BOSEconomy is not loaded on the server.
                economy = null;
            else
                // BOSEconomy is now stored in the "economy" variable.
                economy = (BOSEconomy)temp;
        }
     
     
        @EventHandler
        //This is the using section
        public void onPlayerInteractEvent(final Player player, final Action action, final ItemStack item, final Block block, final BlockFace face) {
            if(action == Action.LEFT_CLICK_BLOCK && block != null){
                if(block.getTypeId() == 389){
                    if(/*Is a frame shop(*5)*/){
                        int price = Shop.getCost();
                        String name = Shop.getItem().toString();
                        String cost = Integer.toString(price);
                        player.sendMessage("This is a shop. The item for sale is 1: " + name + ". It costs:" + cost + ".");
                    }else{
                        return;
                    }
                }
            }else if(action == Action.RIGHT_CLICK_BLOCK && block != null){
                if(block.getTypeId() == 389){
                    if(/*Is a frame shop(*5)*/){
                        String name = Shop.getItem().toString();
                        int price = Shop.getCost();
                        String cost = Integer.toString(price);
                        player.sendMessage("Thanks for buying 1 " + name + ". It cost you " + cost + ".");
                        String sender = player.toString();
                        economy.addPlayerMoney(sender, -price, true);
                    }else{
                        return;
                    }
                }
            }
        }
        //Creation Script
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args){
            if(cmd.getName().equalsIgnoreCase("fs")){
                if(args[0] == "set"){
                    String playername = sender.getName();
                    Player player = (Player) sender;
                    ItemStack item = player.getItemInHand();
                    ItemFrame frame = player.getTargetBlock();
                    int price = Shop.getCost();
                    shops.add(Shop(player, frame, -price));
                   
                }else if(args[0] == "remove"){
                   
                }
            }
           
            return true;
        }
    }
    
    Shop:
    Code:
    package frameshop;
     
    import org.bukkit.entity.ItemFrame;
    import org.bukkit.entity.Player;
    import org.bukkit.inventory.ItemStack;
     
    public class Shop {
        private static int cost;
        private Player owner;
        private ItemFrame frame;
        private static ItemStack item;
        public Shop(Player owner, ItemFrame frame, int cost) {
            this.cost = cost;
            this.owner = owner;
            this.frame = frame;
            item = frame.getItem();
        }
     
        public static int getCost() {
            return cost;
        }
        public Player getOwner() {
            return owner;
        }
        public ItemFrame getFrame() {
            return frame;
        }
        public static ItemStack getItem() {
            return item;
        }
     
    }
    
    P.S. Eclipse made me change some things to "Static"
     
  15. Offline

    fireblast709

    *kicks MeRPG for using static*
    Do you have any idea what kind of dramatic mistake you made here?
     
  16. Offline

    hockeygoalie5

    As FireBlast said, don't use static. Eclipse made you change them to static because you were accessing the methods in a static way, Shop.getItem(). Instead, you need to create an instance of Shop and call the methods for it. Here's how you'll create the shops and store them in an ArrayList:
    Code:
    ArrayList<Shop> shops = new ArrayList<Shop>();
    
    Code:
    Shop shop = new Shop(player, frame, cost);
    shops.add(shop);
    
    Then, you can create a method to retrieve a shop from an item frame:
    Code:
    public Shop getShop(ItemFrame frame) {
        for(Shop s : shops) {
            if(s.getFrame() == frame) {
                return s;
            }
        }
        return null;
    }
    
    Then, you can create an onPlayerInteract listener to have the players buy an item:
    Code:
    // Where e is onPlayerInteractEvent
    if(e.getAction() ==Action.RIGHT_CLICK_BLOCK) {
        if(e.getClickedBlock().getState() instanceof ItemFrame) {
            ItemFrame frame = (ItemFrame) e.getClickedBlock().getState();
            if(getShop(frame) != null) {
                Shop shop = getShop(frame);
                // Use Shop's methods with the instance created above
            }
        }
    }
    
    Now, about getTargetBlock(); The HashSet is a list of blocks to be ignored, and the int is a max distance. You can just use null, and a good number as arguments:
    Code:
    getTargetBlock(null, 10);
    
    Now, don't go off and copy-pasta everything. Try to just understand the code I've provided, then write your own. Let me know if you need more information about anything, and if you need it, check Bukkit's wiki for help on events.

    He didn't, so explaining his dramatic mistake would've been helpful, with all due respect.
     
    MeRPG likes this.
  17. Offline

    fireblast709

    Yea I tried to let him search first, and try to find out on his own. If he needed more help he would've posted on here ;3
     
  18. Offline

    MeRPG

    This creation of an ArrayList (The above code). I assume this goes in the onEnable() section?
     
  19. Offline

    CubixCoders

    No it doesn't belong in any method. it should be under the public class Main and such not in a method
     
  20. Offline

    MeRPG

    Ok.
     
  21. Offline

    MeRPG

    Ok, Finally I finnished my plugin! Thanks guys, but I have one last problem. I compiled it, but bukkit says:
    Code:
    2013-01-26 15:43:17 [SEVERE] Could not load 'plugins\FrameThoseShops.jar' in folder 'plugins'
    org.bukkit.plugin.InvalidDescriptionException: name 'Frame Those Shops!' contains invalid characters.
        at org.bukkit.plugin.PluginDescriptionFile.loadMap(PluginDescriptionFile.java:191)
        at org.bukkit.plugin.PluginDescriptionFile.<init>(PluginDescriptionFile.java:42)
        at org.bukkit.plugin.java.JavaPluginLoader.getPluginDescription(JavaPluginLoader.java:252)
        at org.bukkit.plugin.SimplePluginManager.loadPlugins(SimplePluginManager.java:132)
        at org.bukkit.craftbukkit.v1_4_6.CraftServer.loadPlugins(CraftServer.java:239)
        at org.bukkit.craftbukkit.v1_4_6.CraftServer.reload(CraftServer.java:591)
        at org.bukkit.Bukkit.reload(Bukkit.java:184)
        at org.bukkit.command.defaults.ReloadCommand.execute(ReloadCommand.java:23)
        at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:186)
        at org.bukkit.craftbukkit.v1_4_6.CraftServer.dispatchCommand(CraftServer.java:514)
        at org.bukkit.craftbukkit.v1_4_6.CraftServer.dispatchServerCommand(CraftServer.java:506)
        at net.minecraft.server.v1_4_6.DedicatedServer.al(DedicatedServer.java:260)
        at net.minecraft.server.v1_4_6.DedicatedServer.r(DedicatedServer.java:225)
        at net.minecraft.server.v1_4_6.MinecraftServer.q(MinecraftServer.java:494)
        at net.minecraft.server.v1_4_6.MinecraftServer.run(MinecraftServer.java:427)
        at net.minecraft.server.v1_4_6.ThreadServerApplication.run(SourceFile:849)
    I don't know why. this is my plugin.yml file:
    Code:
    name: FrameThoseShops
    main: frameshop.Main
    version: 1
    commands:
      fs:
          description: Sets and removes shops.
          usage: /<command> [set/remove] [cost]
          permission: <plugin name>.fs
          permission-message: You don't have <permission> 
    Thanks in advance,
    -MeRPG
     
  22. Offline

    hockeygoalie5

    Did you name in the plugin.yml used to be "Frame Those Shops!"? Try double-checking the plugin.yml to make sure it saved and compile again.
     
  23. Offline

    MeRPG

    Ok. I checked that and fixed it. Another error has arisen, though. Here's the error:
    Code:
    [SEVERE] [FrameThoseShops] FrameThoseShops v1 attempted to register an invalid EventHandler method signature "public void frameshop.Main.onPlayerInteractEvent(org.bukkit.entity.Player,org.bukkit.event.block.Action,org.bukkit.inventory.ItemStack,org.bukkit.block.Block,org.bukkit.block.BlockFace)" in class frameshop.Main
    Well, here's my onEnable():
    Code:
        @Override
        public void onEnable(){
            getLogger().info("Frame Those Shops has been enabled.");
            Bukkit.getPluginManager().registerEvents(this, this);
            Bukkit.getPluginCommand("fs").register(null);
        }
    Thanks in advance.
     
Thread Status:
Not open for further replies.

Share This Page