OSRS [Kronos] click-on Range Cooking

R0cky 0wnz

Donator
Mar 6, 2008
2,590
160
0
Problem description: Kronos source only have "item on object" cooking, ie; bit annoying. This opens an interface similar to smelting

Fix:
In source search for "for (Food food : Food.values()) {" , found in Cooking.java
In the "static {" bracket, somewhere add the following:

Code:
        ObjectAction.register("range", "cook", (player, obj) -> {
            SkillItem i = new SkillItem(317).name("Raw Shrimps").addAction((p, amount, event) -> cook_2(p, Food.RAW_SHRIMPS, obj, amount, 896, false));
            SkillItem i2 = new SkillItem(321).name("Raw Anchovies").addAction((p, amount, event) -> cook_2(p, Food.RAW_ANCHOVIES, obj, amount, 896, false));
            SkillItem i3 = new SkillItem(359).name("Raw Tuna").addAction((p, amount, event) -> cook_2(p, Food.RAW_TUNA, obj, amount, 896, false));
            SkillItem i4 = new SkillItem(371).name("Raw Swordfish").addAction((p, amount, event) -> cook_2(p, Food.RAW_SWORDFISH, obj, amount, 896, false));
            SkillItem i5 = new SkillItem(7944).name("Raw Monkfish").addAction((p, amount, event) -> cook_2(p, Food.RAW_MONKFISH, obj, amount, 896, false));
            SkillItem i6 = new SkillItem(383).name("Raw Shark").addAction((p, amount, event) -> cook_2(p, Food.RAW_SHARK, obj, amount, 896, false));
            SkillItem i8 = new SkillItem(389).name("Raw Manta").addAction((p, amount, event) -> cook_2(p, Food.RAW_MANTA_RAY, obj, amount, 896, false));
            SkillItem i7 = new SkillItem(13439).name("Raw Anglerfish").addAction((p, amount, event) -> cook_2(p, Food.RAW_ANGLERFISH, obj, amount, 896, false));
            SkillDialogue.cook(player, i, i2, i3, i4, i5, i6, i7, i8);
        });

add this method in the same class
Code:
    private static void cook_2(Player player, Food food, GameObject obj, int amount, int anim, boolean fire) {
        if (!player.getStats().check(StatType.Cooking, food.levelRequirement, "cook " + food.descriptiveName))
            return;

        startCooking(player, food, obj, amount, anim, fire);
    }

8hOe74e.png
 

Attachments

  • 8hOe74e.png
    8hOe74e.png
    111.4 KB · Views: 280
Last edited:
  • Like
Reactions: Dexter Morgan
you might wanna add code to check which type of food are in the inventory
 
Things to notice:
1. You want the code to be easily maintainable for adding more food types.
2. You want to use OOP principes when handling things like this.

Updated: ObjectAction (This improves maintainability ad allows you to easily add more items)
Code:
ObjectAction.register("range", "cook", (player, obj) -> {
    SkillItem[] skillItems = {
        new SkillItem(317).name("Raw Shrimps"),
        new SkillItem(321).name("Raw Anchovies"),
        new SkillItem(359).name("Raw Tuna"),
        new SkillItem(371).name("Raw Swordfish"),
        new SkillItem(7944).name("Raw Monkfish"),
        new SkillItem(383).name("Raw Shark"),
        new SkillItem(389).name("Raw Manta"),
        new SkillItem(13439).name("Raw Anglerfish")
    };

    for (SkillItem item : skillItems) {
        item.addAction((p, amount, event) ->
            cookWithAmount(p, item.getFood(), obj, amount, 896, false)
        );
    }

    SkillDialogue.cook(player, skillItems);
});

Update: Updated the name of the method to "cookWithAmount" since "cook_2" is not really descriptive of the function
Code:
private static void cookWithAmount(Player player, Food food, GameObject obj, int amount, int anim, boolean fire) {
        if (!player.getStats().check(StatType.Cooking, food.levelRequirement, "cook " + food.descriptiveName))
            return;

        startCooking(player, food, obj, amount, anim, fire);
    }
 
  • Like
Reactions: R0cky 0wnz
Problem description: Kronos source only have "item on object" cooking, ie; bit annoying. This opens an interface similar to smelting

Fix:
In source search for "for (Food food : Food.values()) {" , found in Cooking.java
In the "static {" bracket, somewhere add the following:

Code:
        ObjectAction.register("range", "cook", (player, obj) -> {
            SkillItem i = new SkillItem(317).name("Raw Shrimps").addAction((p, amount, event) -> cook_2(p, Food.RAW_SHRIMPS, obj, amount, 896, false));
            SkillItem i2 = new SkillItem(321).name("Raw Anchovies").addAction((p, amount, event) -> cook_2(p, Food.RAW_ANCHOVIES, obj, amount, 896, false));
            SkillItem i3 = new SkillItem(359).name("Raw Tuna").addAction((p, amount, event) -> cook_2(p, Food.RAW_TUNA, obj, amount, 896, false));
            SkillItem i4 = new SkillItem(371).name("Raw Swordfish").addAction((p, amount, event) -> cook_2(p, Food.RAW_SWORDFISH, obj, amount, 896, false));
            SkillItem i5 = new SkillItem(7944).name("Raw Monkfish").addAction((p, amount, event) -> cook_2(p, Food.RAW_MONKFISH, obj, amount, 896, false));
            SkillItem i6 = new SkillItem(383).name("Raw Shark").addAction((p, amount, event) -> cook_2(p, Food.RAW_SHARK, obj, amount, 896, false));
            SkillItem i8 = new SkillItem(389).name("Raw Manta").addAction((p, amount, event) -> cook_2(p, Food.RAW_MANTA_RAY, obj, amount, 896, false));
            SkillItem i7 = new SkillItem(13439).name("Raw Anglerfish").addAction((p, amount, event) -> cook_2(p, Food.RAW_ANGLERFISH, obj, amount, 896, false));
            SkillDialogue.cook(player, i, i2, i3, i4, i5, i6, i7, i8);
        });

add this method in the same class
Code:
    private static void cook_2(Player player, Food food, GameObject obj, int amount, int anim, boolean fire) {
        if (!player.getStats().check(StatType.Cooking, food.levelRequirement, "cook " + food.descriptiveName))
            return;

        startCooking(player, food, obj, amount, anim, fire);
    }

8hOe74e.png



Why display a list of food items when there is a lot more than just those options?

This works a lot better lol

Code:
        ObjectAction.register("cooking range", 1, (p, obj) -> cookMultiOption(p, obj, 896, false));
        ObjectAction.register("clay oven", 1, (p, obj) -> cookMultiOption(p, obj, 896, false));
        ObjectAction.register("range", 1, (p, obj) -> cookMultiOption(p, obj, 896, false));
        ObjectAction.register("fire", 1, (p, obj) -> cookMultiOption(p, obj, 897, true));
        ObjectAction.register("stove", 1, (p, obj) -> cookMultiOption(p, obj, 896, false));
        ObjectAction.register("sulphur vent", 1, (p, obj) -> cookMultiOption(p, obj, 896, false));
        ObjectAction.register("cooking pot", 1, (p, obj) -> cookMultiOption(p, obj, 897, true));
        ObjectAction.register(5249, 1, (p, obj) -> cookMultiOption(p, obj, 897, true));

Code:
    private static void cookMultiOption(Player player, GameObject obj, int anim, boolean fire) {
        List<SkillItem> skillItems = new ArrayList<>();
        for (Food food : Food.values()) {
            if (player.getInventory().hasId(food.rawID) && player.getStats().check(StatType.Cooking, food.levelRequirement)) {
                skillItems.add(new SkillItem(food.cookedID).addAction((p, amount, event) -> startCooking(p, food, obj, amount, anim, fire)));
                if (food.sinew > 0)
                    skillItems.add(new SkillItem(food.sinew).addAction((p, amount, event) -> dryMeat(p, food, obj, amount, anim)));
            }
        }

        if (!skillItems.isEmpty()) {
            SkillItem[] food = skillItems.toArray(new SkillItem[skillItems.size()]);
            SkillDialogue.cook(player, food);
        } else {
            player.sendMessage("Nothing interesting happens.");
        }
    }
 
Why display a list of food items when there is a lot more than just those options?

This works a lot better lol

Code:
        ObjectAction.register("cooking range", 1, (p, obj) -> cookMultiOption(p, obj, 896, false));
        ObjectAction.register("clay oven", 1, (p, obj) -> cookMultiOption(p, obj, 896, false));
        ObjectAction.register("range", 1, (p, obj) -> cookMultiOption(p, obj, 896, false));
        ObjectAction.register("fire", 1, (p, obj) -> cookMultiOption(p, obj, 897, true));
        ObjectAction.register("stove", 1, (p, obj) -> cookMultiOption(p, obj, 896, false));
        ObjectAction.register("sulphur vent", 1, (p, obj) -> cookMultiOption(p, obj, 896, false));
        ObjectAction.register("cooking pot", 1, (p, obj) -> cookMultiOption(p, obj, 897, true));
        ObjectAction.register(5249, 1, (p, obj) -> cookMultiOption(p, obj, 897, true));

Code:
    private static void cookMultiOption(Player player, GameObject obj, int anim, boolean fire) {
        List<SkillItem> skillItems = new ArrayList<>();
        for (Food food : Food.values()) {
            if (player.getInventory().hasId(food.rawID) && player.getStats().check(StatType.Cooking, food.levelRequirement)) {
                skillItems.add(new SkillItem(food.cookedID).addAction((p, amount, event) -> startCooking(p, food, obj, amount, anim, fire)));
                if (food.sinew > 0)
                    skillItems.add(new SkillItem(food.sinew).addAction((p, amount, event) -> dryMeat(p, food, obj, amount, anim)));
            }
        }

        if (!skillItems.isEmpty()) {
            SkillItem[] food = skillItems.toArray(new SkillItem[skillItems.size()]);
            SkillDialogue.cook(player, food);
        } else {
            player.sendMessage("Nothing interesting happens.");
        }
    }

Im here to share a snippet "lol", if you can do it better, here take a pat on your back.

Why display a list of food items when there is a lot more than just those options?

This works a lot better lol

Code:
        ObjectAction.register("cooking range", 1, (p, obj) -> cookMultiOption(p, obj, 896, false));
        ObjectAction.register("clay oven", 1, (p, obj) -> cookMultiOption(p, obj, 896, false));
        ObjectAction.register("range", 1, (p, obj) -> cookMultiOption(p, obj, 896, false));
        ObjectAction.register("fire", 1, (p, obj) -> cookMultiOption(p, obj, 897, true));
        ObjectAction.register("stove", 1, (p, obj) -> cookMultiOption(p, obj, 896, false));
        ObjectAction.register("sulphur vent", 1, (p, obj) -> cookMultiOption(p, obj, 896, false));
        ObjectAction.register("cooking pot", 1, (p, obj) -> cookMultiOption(p, obj, 897, true));
        ObjectAction.register(5249, 1, (p, obj) -> cookMultiOption(p, obj, 897, true));

Code:
    private static void cookMultiOption(Player player, GameObject obj, int anim, boolean fire) {
        List<SkillItem> skillItems = new ArrayList<>();
        for (Food food : Food.values()) {
            if (player.getInventory().hasId(food.rawID) && player.getStats().check(StatType.Cooking, food.levelRequirement)) {
                skillItems.add(new SkillItem(food.cookedID).addAction((p, amount, event) -> startCooking(p, food, obj, amount, anim, fire)));
                if (food.sinew > 0)
                    skillItems.add(new SkillItem(food.sinew).addAction((p, amount, event) -> dryMeat(p, food, obj, amount, anim)));
            }
        }

        if (!skillItems.isEmpty()) {
            SkillItem[] food = skillItems.toArray(new SkillItem[skillItems.size()]);
            SkillDialogue.cook(player, food);
        } else {
            player.sendMessage("Nothing interesting happens.");
        }
    }

so server has to loop trough 40 foods every time someone clicks a range? doesn't sound too efficient to me. (lol)

edit -> 40 x 28 inventory. sounds fun!

Things to notice:
1. You want the code to be easily maintainable for adding more food types.
2. You want to use OOP principes when handling things like this.

Updated: ObjectAction (This improves maintainability ad allows you to easily add more items)
Code:
ObjectAction.register("range", "cook", (player, obj) -> {
    SkillItem[] skillItems = {
        new SkillItem(317).name("Raw Shrimps"),
        new SkillItem(321).name("Raw Anchovies"),
        new SkillItem(359).name("Raw Tuna"),
        new SkillItem(371).name("Raw Swordfish"),
        new SkillItem(7944).name("Raw Monkfish"),
        new SkillItem(383).name("Raw Shark"),
        new SkillItem(389).name("Raw Manta"),
        new SkillItem(13439).name("Raw Anglerfish")
    };

    for (SkillItem item : skillItems) {
        item.addAction((p, amount, event) ->
            cookWithAmount(p, item.getFood(), obj, amount, 896, false)
        );
    }

    SkillDialogue.cook(player, skillItems);
});

Update: Updated the name of the method to "cookWithAmount" since "cook_2" is not really descriptive of the function
Code:
private static void cookWithAmount(Player player, Food food, GameObject obj, int amount, int anim, boolean fire) {
        if (!player.getStats().check(StatType.Cooking, food.levelRequirement, "cook " + food.descriptiveName))
            return;

        startCooking(player, food, obj, amount, anim, fire);
    }

you forgot "getFood()" method for skillitem

and "You want to use OOP principes when handling things like this." could you collaborate based on my code?
 
Im here to share a snippet "lol", if you can do it better, here take a pat on your back.



so server has to loop trough 40 foods every time someone clicks a range? doesn't sound too efficient to me. (lol)

edit -> 40 x 28 inventory. sounds fun!



you forgot "getFood()" method for skillitem

and "You want to use OOP principes when handling things like this." could you collaborate based on my code?

Efficiency is not important here. You're talking about a practically insignificant number of iterations, especially for an action that is not happening all the time. Always prefer maintainable code over optimizations that don't really matter. Plus player#hasItem doesn't necessarily have to be an O(28) operation, you can maintain a hashset internally (for example) and for slight overhead on add/remove operations, you get more efficiency in search by itemId. Go the other way, keep a (itemId, food) map in Food enum, only loop thru player's inventory. Find intersection of two lists. There are lots of ways to make this more efficient if necessary, but the other dude is closer to the right idea - you don't start with the idea that something needs to be "efficient" (when it doesn't).

Also its not rlly OO principles, just general programming ones. If you find yourself basically copy pasting a chunk of code 9 times, usually you can pull that out into something else.
First guy - make it extensible for more food options
Second guy - make it more extensible to all types of ranges

Plus there's nothing wrong with writing bad code in the first place, but you can iterate on it once you know what you want.
 
  • Like
Reactions: R0cky 0wnz
In cases like these, it helps to just follow what RS does. They have a lot of overhead costs so they need to be extra careful with any code that may cause performance to suffer.

As an example, in OSRS, this interface works by iterating over every slot in the player's inventory, and doing either a param check on the item in that slot, or looking up the respective data entry through other means(most likely iterating in that scenario). In addition to that, the iteration is cut short once 10 distinct results are obtained.

In your RSPSified case, you'd ideally do the same - iterate over the inventory, and do a hashmap lookup to find the food corresponding to the respective item id.
 
  • Like
Reactions: Dexter Morgan
In cases like these, it helps to just follow what RS does. They have a lot of overhead costs so they need to be extra careful with any code that may cause performance to suffer.

As an example, in OSRS, this interface works by iterating over every slot in the player's inventory, and doing either a param check on the item in that slot, or looking up the respective data entry through other means(most likely iterating in that scenario). In addition to that, the iteration is cut short once 10 distinct results are obtained.

In your RSPSified case, you'd ideally do the same - iterate over the inventory, and do a hashmap lookup to find the food corresponding to the respective item id.
Thank you.

Efficiency is not important here. You're talking about a practically insignificant number of iterations, especially for an action that is not happening all the time. Always prefer maintainable code over optimizations that don't really matter. Plus player#hasItem doesn't necessarily have to be an O(28) operation, you can maintain a hashset internally (for example) and for slight overhead on add/remove operations, you get more efficiency in search by itemId. Go the other way, keep a (itemId, food) map in Food enum, only loop thru player's inventory. Find intersection of two lists. There are lots of ways to make this more efficient if necessary, but the other dude is closer to the right idea - you don't start with the idea that something needs to be "efficient" (when it doesn't).

Also its not rlly OO principles, just general programming ones. If you find yourself basically copy pasting a chunk of code 9 times, usually you can pull that out into something else.
First guy - make it extensible for more food options
Second guy - make it more extensible to all types of ranges

Plus there's nothing wrong with writing bad code in the first place, but you can iterate on it once you know what you want.

"especially for an action that is not happening all the time"

A dumb question - what happens when there's a auto clicker at 1ms (1000 times/sec), that spam clicks an object? ie, 28 (inv) x 40 (food enums) x 1000, every sec? (1,1 million/sec)

what if there were 10 ass holes doing it at the same time; ie, 10mil results per sec.

it doesn't mater because of how powerful JVM is?


would that in theory lag the server?
 
Thank you.



"especially for an action that is not happening all the time"

A dumb question - what happens when there's a auto clicker at 1ms (1000 times/sec), that spam clicks an object? ie, 28 (inv) x 40 (food enums) x 1000, every sec? (1,1 million/sec)

what if there were 10 ass holes doing it at the same time; ie, 10mil results per sec.

it doesn't mater because of how powerful JVM is?


would that in theory lag the server?
If the server is designed correctly, this would have no impact:
- Only one interaction(clicking/use item/use spell on objects, ground items, npcs or players) may exist for an entity at any given time. It just overwrites the previous attempt, and the code itself is not actually executed until towards end of that same cycle, meaning even if you spam-click it, it will only run the code once, for whatever your last click was that the server accepted.
- The server only accepts up to 10 packets of a specific packet group per cycle. E.g. you can only request a total of 10 examines from the server, regardless of what type the examine is - you could request 5 items, 5 objects and 5 npcs, but the NPCs will not send until the tick after.


But given the assumption that the above was not true, yes, your point would be perfectly valid; if it wasn't bound, that code could be considered dangerous.
 
Thank you.



"especially for an action that is not happening all the time"

A dumb question - what happens when there's a auto clicker at 1ms (1000 times/sec), that spam clicks an object? ie, 28 (inv) x 40 (food enums) x 1000, every sec? (1,1 million/sec)

what if there were 10 ass holes doing it at the same time; ie, 10mil results per sec.

it doesn't mater because of how powerful JVM is?


would that in theory lag the server?

What happens when theres an autoclicker at .01ms with a "more efficient approach". Taking user input like this is dangerous in many ways this code would be far from your worst problem
 

Users who are viewing this thread (total: 1, members: 0, guests: 1)

Who read this thread (total members: 8)