Derogan Posted August 15, 2019 Share Posted August 15, 2019 Hey guys, I'm on a road creating third script, first combat (bit complex kills chickens pick ups raw chicken and then cooks it and goes to goblins, but haven't implemented much, because stuck at killing/looting). After few days managed to kill and loot filtered loot on the position npc was found. But the thing is sometimes after the chicken is dies bot attacks another chicken without going into loot function? I have no idea why. public class Main extends Script { AntiBanThread antiBanThread = new AntiBanThread(); String statusString; private Predicate<GroundItem> itemsToPick = g -> (g.getName().contains("Bones") || g.getName().contains("Feather") || g.getName().contains("Raw chicken")); NPC target; Position targetTile; private List<GroundItem> groundItemsToScan; @Override public int onLoop() throws InterruptedException { //Bury bones. if (inventory.contains("Bones")){ log("Bury bones"); Item bones = getInventory().getItem("Bones"); bones.interact("Bury"); } //Creates a tile where target was attacked and loots there if grounditems exists. if (!myPlayer().isUnderAttack() && myPlayer().getInteracting() == null && targetTile != null) { log("Will Loot"); lootStuff(); } //When out of food goes to kill chickens. if (!inventory.contains("Cooked Chicken") && myPlayer().getHealthPercent() > 60){ chickenKiller(); } return 4_000; } public void chickenKiller() { //I created two areas to where I am able to kill chicken because don't want to enter farm house or outside farmspot and the gate would fuck up everything if (chickenSpot()[0].contains(myPlayer()) || chickenSpot()[1].contains(myPlayer())){ log("Checking Area"); for (Area area : chickenSpot()) { if (area.contains(myPlayer())) { log("Is in farmingSpot will do the following"); if (inventory.contains("Raw chicken") && inventory.getAmount("Raw Chicken") >= random(10,15)) { log("Will cook chicken"); // cooking method } else { log("will kill chicken"); statusString = "Killing Chicken"; killMonster("Chicken"); } } }} else { log("Going to FarmSpot"); statusString = "Going to FarmSpot"; walking.webWalk(farmSpot()); } } private void killMonster(String monsterName) { //find target marks the spot target = getNpcs().closest(monsterName); targetTile = new Position(target.getX(), target.getY(), 0); if (!myPlayer().isUnderAttack() && target != null && !target.isUnderAttack() && !target.isAnimating()) { if (target.interact("Attack")) ; { new ConditionalSleep(3_500) { @Override public boolean condition() throws InterruptedException { return target.getHealthPercent() == 0; } }.sleep(); } } } private void lootStuff() { log("Entering loot stuff"); groundItemsToScan = getGroundItems().get(targetTile.getX(), target.getY()).stream().filter(itemsToPick).collect(Collectors.toList()); for (int i = 0; i < groundItemsToScan.size(); i++) { //static sleep to pick stuff before killing anything. if (groundItemsToScan.get(i).interact("Take")) { try{ sleep(1_000); } catch (InterruptedException e){ System.out.println(e); } } } } Quote Link to comment Share on other sites More sharing options...
Hybris Posted August 16, 2019 Share Posted August 16, 2019 (edited) if (target.interact("Attack")) ; The ";" shouldn't be there, also look into Lambda expressions for the conditional sleep: https://osbot.org/forum/topic/127193-conditional-sleep-with-lambda-expressions/ if (!myPlayer().isUnderAttack() && myPlayer().getInteracting() == null && targetTile != null) I didn't look very well at the code but I'm pretty sure the mistake is in here. Fixing the above mistake might fix this too, but it's probably still detecting that your player is under attack or interacting with something when it gets to this point & thus skipping the loot function. Edited August 16, 2019 by Hybris Quote Link to comment Share on other sites More sharing options...
Derogan Posted August 16, 2019 Author Share Posted August 16, 2019 @Hybris Thank you, didin't see that semi-colon. I will look in to it. And try to make changes in the if statement. Also I understand the conditional sleep with a return and a time out. As I understand this conditional sleep is executed untill a return matches the condition or timeout passes. But what wuold the interval mean. For example in the post you shared: public static boolean sleepUntil(final BooleanSupplier condition, final int timeout, final int interval) { return new Sleep(condition, timeout, interval).sleep(); } Quote Link to comment Share on other sites More sharing options...
Hybris Posted August 16, 2019 Share Posted August 16, 2019 4 hours ago, Derogan said: @Hybris Thank you, didin't see that semi-colon. I will look in to it. And try to make changes in the if statement. Also I understand the conditional sleep with a return and a time out. As I understand this conditional sleep is executed untill a return matches the condition or timeout passes. But what wuold the interval mean. For example in the post you shared: public static boolean sleepUntil(final BooleanSupplier condition, final int timeout, final int interval) { return new Sleep(condition, timeout, interval).sleep(); } Np let me know what the result is & I'm not exactly sure but I think the interval is how often it gets checked; like for example interval is 1000: the condition gets checked every second Quote Link to comment Share on other sites More sharing options...
Derogan Posted August 18, 2019 Author Share Posted August 18, 2019 @Hybris well it is still the same. Sometime it loots, sometime it skips and attacks chicken. Tried modyfing both logics Quote Link to comment Share on other sites More sharing options...
Leetkiss Posted August 18, 2019 Share Posted August 18, 2019 Please define these values, the code you posted doesn't contain them. chickenSpot() farmSpot() (I could make an educated guess but I would rather the code be precisely the same as yours to avoid issues) Quote Link to comment Share on other sites More sharing options...
Derogan Posted August 19, 2019 Author Share Posted August 19, 2019 On 8/18/2019 at 4:19 PM, Leetkiss said: Please define these values, the code you posted doesn't contain them. chickenSpot() farmSpot() (I could make an educated guess but I would rather the code be precisely the same as yours to avoid issues) Sorry for the last response, here are those areas: private Area[] chickenSpot() { return new Area[]{ new Area(3236, 3231, 3231, 3301), new Area(3231, 3295, 3225, 3301), }; } private Area farmSpot(){ return new Area(3231, 3297, 3236, 3290); } I make those because I want to be sure I kill them in that area to be sure not to be in the building or outside the farm hehe Quote Link to comment Share on other sites More sharing options...
Derogan Posted August 19, 2019 Author Share Posted August 19, 2019 For one thing I can see that the targetTile doesn't update if the chicken or any other monster moves, that's one thing. But still maybe a static sleep method is needed because I one shot the chickens? On that millisecond doesn't match the loop condition, but on the other millisecond matches the killchicken method, how do I solve this? Because if I set the return value in the onLoop higher than 500 ms, talking about 5 - 10 seconds, the onLoop cycle goes trough all functions and kills loots accordingly Quote Link to comment Share on other sites More sharing options...
Leetkiss Posted August 20, 2019 Share Posted August 20, 2019 (edited) 19 hours ago, Derogan said: For one thing I can see that the targetTile doesn't update if the chicken or any other monster moves, that's one thing. But still maybe a static sleep method is needed because I one shot the chickens? On that millisecond doesn't match the loop condition, but on the other millisecond matches the killchicken method, how do I solve this? Because if I set the return value in the onLoop higher than 500 ms, talking about 5 - 10 seconds, the onLoop cycle goes trough all functions and kills loots accordingly Yes your targetTile position was not updating correctly. You must remember that when an enemy (a chicken) dies there is a 2-5 second delay before the dead chicken body disappears and the loot appears on the ground. I have updated your killMonster() method so that the targetTile always updates correctly and that it loots as soon as your chicken is dead. private void killMonster(String monsterName) { //find target marks the spot target = getNpcs().closest(true, monsterName); // setting true it will find the Real Closest Chicken targetTile = new Position(target.getX(), target.getY(), 0); if (!myPlayer().isUnderAttack() && target != null && !target.isUnderAttack() && !target.isAnimating()) { log("Attacking chicken"); if (target.interact("Attack")) { log("Wait until the target chicken has 0 hp (waits a max of 30s, instantly stops waiting when the chicken dies though (0 hp)"); new ConditionalSleep(30000) { @Override public boolean condition() throws InterruptedException { return target.getHealthPercent() == 0; } }.sleep(); log("Setting the targetTile to where the chicken got 0hp"); targetTile = new Position(target.getX(), target.getY(), 0); log("The chicken body is still there!"); log("Wait until the target chicken body disappears and the loot appears"); new ConditionalSleep(9500) { @Override public boolean condition() throws InterruptedException { return target == null || !target.exists(); } }.sleep(); } } } You need your script to respond faster as well, this is a small but very important change, I have changed your onLoop() return from return 4000 to return random(100, 500); return random(100, 500); You should also add a chicken cooking method, you want it to cook chicken when: Your inventory contains Raw chicken Your inventory is full I updated your chickenKiller() method with this, I have left the body of cookChicken() blank -- you can code that part yourself, I don't want to do it all for you public void chickenKiller() { //I created two areas to where I am able to kill chicken because don't want to enter farm house or outside farmspot and the gate would fuck up everything if (chickenSpot()[0].contains(myPlayer()) || chickenSpot()[1].contains(myPlayer())){ log("Checking Area"); for (Area area : chickenSpot()) { if (area.contains(myPlayer())) { log("Is in farmingSpot will do the following"); if (inventory.contains("Raw chicken") && inventory.isFull()) { log("Will cook chicken"); statusString = "Cooking Chicken"; // cooking method cookChicken(); } else { log("will kill chicken"); statusString = "Killing Chicken"; killMonster("Chicken"); } } }} else { log("Going to FarmSpot"); statusString = "Going to FarmSpot"; walking.webWalk(farmSpot()); } } private void cookChicken() { } Edited August 20, 2019 by Leetkiss 1 Quote Link to comment Share on other sites More sharing options...
Derogan Posted August 20, 2019 Author Share Posted August 20, 2019 @Leetkiss thank you for your effort! I am planning to implement the cooking method, will share results Quote Link to comment Share on other sites More sharing options...