Jump to content

Few functions onLoop is skipped


Derogan

Recommended Posts

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);
                }
                }
            }

        }

 

Link to comment
Share on other sites

 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 by Hybris
Link to comment
Share on other sites

@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();
    }

 

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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 by Leetkiss
  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...