Jump to content
Frequently Asked Questions
  • Are you not able to open the client? Try following our getting started guide
  • Still not working? Try downloading and running JarFix
  • Help! My bot doesn't do anything! Enable fresh start in client settings and restart the client
  • How to purchase with PayPal/OSRS/Crypto gold? You can purchase vouchers from other users
  • How to pass enums in Java?


    Diggington

    Recommended Posts

    I have a pretty simple method to get the player's best owned piece of gear:

    public String GetBestOwnedMeleeGloves(){
        String bestItem = "";
        for(ItemCollections.BasicMeleeArmourTiers tier : ItemCollections.BasicMeleeArmourTiers.values()){
            for(ItemCollections.BasicGloves item : ItemCollections.BasicGloves.values()){
                String currentItem = tier.name() + " " + item.name();
                String formattedItem = currentItem.substring(0, 1).toUpperCase() + currentItem.substring(1).toLowerCase();
    
                if (Inventory.contains(formattedItem) || Equipment.contains(formattedItem) || allBankItems.contains(formattedItem)){
                    if (HasSkillRequirement(formattedItem, Skill.DEFENCE)){
                        bestItem = formattedItem;
                    }
                }
            }
        }
    
        return bestItem;
    }

    Here's the class which contains the enums I'm looping through in the above code:

    public class ItemCollections {
    
        //THE ORDER OF THESE IS IMPORTANT
        //THE ORDER DICTATES THE BEST TYPE OF WEAPON OWNED BY THE PLAYER
        //FROM LEAST TO MOST EFFICIENT
        public enum BasicMeleeArmourTiers{
            LEATHER,
            BRONZE,
            IRON,
            STEEL,
            BLACK,
            MITHRIL,
            ADAMANT,
            RUNE,
            GRANITE,
            DRAGON,
            OBSIDIAN,
            BANDOS,
            JUSTICIAR,
            TORVA,
        }
    
        public enum BasicHelmets{
            MED_HELM,
            FULL_HELM
        }
    
        public enum BasicChest{
            CHAINBODY,
            PLATEBODY,
        }
    
        public enum BasicLegs{
            PLATESKIRT,
            PLATELEGS
        }
    
        public enum BasicShield{
            SQ_SHIELD,
            KITESHIELD
        }
    
        public enum BasicBoots{
            BOOTS
        }
    
        public enum BasicGloves{
            GLOVES
        }
    
    }

    Say I wanted to create a generic method to grab the best piece of gear of each type. How do I go about passing in the enum as a method parameter to use in the inner loop? Something like:

    private static String GetBestArmourPiece(Enum<?> item){
        String bestItem = "";
    
        for (item i : item.values()){
    
            String fomattedText = i.name().replace("_", " ");
            String currentItem = tier.name() + " " + fomattedText;
            String formattedCurrentItem = currentItem.substring(0,1).toUpperCase() + currentItem.substring(1).toLowerCase();
    
            if (Inventory.contains(formattedCurrentItem) || Equipment.contains(formattedCurrentItem) || allBankItems.contains(formattedCurrentItem)){
                if (!formattedCurrentItem.equals("")){
                    bestItem = formattedCurrentItem;
                }
            }
        }
        return bestItem;
    }
    Link to comment
    Share on other sites

    What do you want to pass into GetBestArmourPiece? It woud have to get a value that sets the type.

    private static String GetBestArmourPiece(itemTypes itemType){
        String bestItem = "";
        switch(itemType){
    		case HELMET:
    			bestItem = GetBestHelmet();
    		break;
    		case BODY:
    			bestItem = GetBestBody();
    		break;
    		.	
    		.
    		.
    	}
        return bestItem;
    }
    Link to comment
    Share on other sites

    6 hours ago, Gorn said:

    What do you want to pass into GetBestArmourPiece? It woud have to get a value that sets the type.

    private static String GetBestArmourPiece(itemTypes itemType){
        String bestItem = "";
        switch(itemType){
    		case HELMET:
    			bestItem = GetBestHelmet();
    		break;
    		case BODY:
    			bestItem = GetBestBody();
    		break;
    		.	
    		.
    		.
    	}
        return bestItem;
    }

    Yeah, this is similar to what I'm doing now, but I was just wondering if there was a better way. For example, when I call GetBestArmourPiece, I could pass in the enum of armour pieces that I wanted to get. For example:

    for(ItemCollections.BasicMeleeArmourTiers tier : ItemCollections.BasicMeleeArmourTiers.values()){
            String bestHelm = GetBestArmourPiece(ItemCollections.BasicHelmets);
            String bestBody = GetBestArmourPiece(ItemCollections.BasicChest);
            //ETC ETC ETC
    }

    Can I pass enums like this?

    Link to comment
    Share on other sites

    No you don't pass enums like that because enums are static. But the problem u have here isnt with enums. All the enums u showed here are just lists of strings anyway (that's how u are using them). This item system is just bad so creating anything in it is gonna be a headache. Like how do you represent for example mithril gloves in this? enum + enum? One enum for mithril and one enum for gloves and then turn it into a string to get mithril gloves lol. I hope u see the problem here isnt passing around enums.

     

    Not even talking about all that extra string formatting which is cancer because it needs memory allocation.

    Link to comment
    Share on other sites

    8 hours ago, Gorn said:

    No you don't pass enums like that because enums are static. But the problem u have here isnt with enums. All the enums u showed here are just lists of strings anyway (that's how u are using them). This item system is just bad so creating anything in it is gonna be a headache. Like how do you represent for example mithril gloves in this? enum + enum? One enum for mithril and one enum for gloves and then turn it into a string to get mithril gloves lol. I hope u see the problem here isnt passing around enums.

     

    Not even talking about all that extra string formatting which is cancer because it needs memory allocation.

    OK, I see your point. Enums probably aren't the best way to go about this. Probably better to just turn it into a literal list of strings instead.

    Link to comment
    Share on other sites

    Replacing strings with enums is normal but you are doing it the other way, turning enums into strings. I think they only added it in as last resort, if you wrote yourself into a pickle and need an ugly way out. Definetly not the default way of using enums. Having enums for the items is fine but keep it simple, one enum for each item slot. That should work on small to mid size scripts just fine.

    If u actualy want a better way then start by making a better database. I was asking about something here some time ago and yeeter pointed me to this project. Somebody already made a databse of all osrs items.

    https://github.com/osrsbox/osrsbox-db/tree/master/docs

    items-complete.json is the full database.

    You definetly want to trim it down somehow just to items your bots will actualy encounter because it's over 20000 entries. Maybe make some automatic system for that 😉 I'm only mentioning this because u said u wanted a better way. I think this is the better way. But honestly just having enums for the items and then one extra for setting the type like I suggested in the first post is fine. Maybe ditch the convention and just name them like the actual items are named, so u don't have to format the string. 

    Link to comment
    Share on other sites

    And my suggestion in the first post is bad so don't write it like that. Like what is the items "type"? it's very vague. Is shield and defender the same item type? If so then we are really just talking about item slots. Dreambot has this enum built in so you don't even have to write it.

    https://dreambot.org/javadocs/org/dreambot/api/methods/container/impl/equipment/EquipmentSlot.html

    So the function shoud probably look something like this

    String GetBestArmorPiece(EquipmentSlot slot){
    	switch(slot){
    	case AMULET:
    		GetBestAmulet();
    	break;
    	etc.
    	}
    }

    idealy it would return Class<Item> or maybe id of the item

    Link to comment
    Share on other sites

    That database of items is crazy, I didn't know that existed so thanks for linking it.

    Here's my new solution, not the most elegant but it's reduced the amount of code and string manipulation required:

    public String GetBestArmourPiece(String tier, List<String> list, Skill skillRequirement){
        String bestItem = "";
    
        for (String item : list){
            String currentItem = tier + " " + item;
            if (Inventory.contains(currentItem) || Equipment.contains(currentItem) || allBankItems.contains(currentItem)){
                if (HasSkillRequirement(currentItem, skillRequirement)){
                    bestItem = currentItem;
                }
            }
        }
        return bestItem;
    }

    I'm pretty happy with how it's functioning for now, but will keep that JSON "database" in my back pocket if I ever need to refactor

    Edited by Diggington
    im an idiot
    Link to comment
    Share on other sites

    • 4 weeks later...

    Create an account or sign in to comment

    You need to be a member in order to leave a comment

    Create an account

    Sign up for a new account in our community. It's easy!

    Register a new account

    Sign in

    Already have an account? Sign in here.

    Sign In Now
    ×
    ×
    • Create New...

    Important Information

    We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.