Jump to content

How to recheck the state of an RS2Object? (check if rock has been mined)


sombotdude

Recommended Posts

So I've been building a mining script and want a way to check if the rock being mined still exists whilst the player is mining it, say for instance another player manages to mine it before I do and then I can make the bot stop the mining animation and find another rock that has ore it and start mining that.

This is my mining function: 

private void mine(String chosenOre) {
        // Get rock to mine
        RS2Object rockToMine = getObjects().closest(object -> Rock.CLAY.hasOre(object));

        if (!playerAnimating()) { // Check if player is not animating
            if (rockToMine != null) { // Check if rock is not null
                if (rockToMine.interact("Mine")) { 
                    new ConditionalSleep(1000, 500) {
                        @Override
                        public boolean condition() throws InterruptedException {
                            return playerAnimating();
                        }
                    }.sleep();
                }
            }
        }
    }

What would be the best way to implement the check for if the rock being mined still exists? I have tried putting within the return of  the ConditionalSleep return rockToMine != null as  a check but I didnt work, which I am assuming is due to the state of the rock being checked, being the original one from when it had ore in at and not the updated state of the rock that is empty? If so how do you get the updated state of the currently selected object, to then check its current state?

Thanks in advance for any help.

Link to comment
Share on other sites

Thanks for the reply, I have actually being using that Explv's code snippet already in this script. So I changed my code to the following:

    private void mine(String chosenOre) {
        // Get rock to mine
        RS2Object rockToMine = getObjects().closest(object -> Rock.CLAY.hasOre(object));

        if (!playerAnimating()) { // Check if player is not animating
            if (rockToMine != null) { // Check if rock is not null
                if (rockToMine.interact("Mine")) {
                    new ConditionalSleep(3000, 500) {
                        @Override
                        public boolean condition() throws InterruptedException {
                            return Rock.CLAY.hasOre(rockToMine) && myPlayer().isAnimating();
                        }
                    }.sleep();
                }
            }
        }
    }

So in the conditional sleep's return I added the the hasOre check to the currently being mined ore, but it doesnt seem to be making a difference, if the rock gets mined by someone else, it just runs the full length of the animation and then tries to select another rock again.

Link to comment
Share on other sites

1 hour ago, sombotdude said:

Thanks for the reply, I have actually being using that Explv's code snippet already in this script. So I changed my code to the following:


    private void mine(String chosenOre) {
        // Get rock to mine
        RS2Object rockToMine = getObjects().closest(object -> Rock.CLAY.hasOre(object));

        if (!playerAnimating()) { // Check if player is not animating
            if (rockToMine != null) { // Check if rock is not null
                if (rockToMine.interact("Mine")) {
                    new ConditionalSleep(3000, 500) {
                        @Override
                        public boolean condition() throws InterruptedException {
                            return Rock.CLAY.hasOre(rockToMine) && myPlayer().isAnimating();
                        }
                    }.sleep();
                }
            }
        }
    }

So in the conditional sleep's return I added the the hasOre check to the currently being mined ore, but it doesnt seem to be making a difference, if the rock gets mined by someone else, it just runs the full length of the animation and then tries to select another rock again.


Currently you only mine a new rock if your player isn't animating, so of course it will wait for the animation to complete. You should try doing something like this instead:

 

private RS2Object rock = null;

@Override
public int onLoop() throws InterruptedException {
    // If we haven't looked for a rock yet, or the player isn't animating, or the current rock no longer has Clay
    if (rock == null || !myPlayer().isAnimating() || !Rock.CLAY.hasOre(rock)) {
        // Find a new rock
        rock = getObjects().closest(object -> Rock.CLAY.hasOre(object));
        // If a rock exists, and we successfully interact with it
        if (rock != null && rock.interact("Mine")) {
            new ConditionalSleep(3000, 500) { // Sleep for 3 seconds or until...
                @Override
                public boolean condition() throws InterruptedException {
                    // The player is animating, or someone else mined the rock
                    return myPlayer().isAnimating() || !Rock.CLAY.hasOre(rock);
                }
            }.sleep();
        }
    }
}

 

Link to comment
Share on other sites

47 minutes ago, NoxMerc said:

So solve this. You know your player is going to keep animating if the rock is mined out, so maybe your condition shouldn't be relying solely on the player's animation?

Yep that's what I thought and was trying to implement with this: 

new ConditionalSleep(3000, 500) {
                        @Override
                        public boolean condition() throws InterruptedException {
                            return Rock.CLAY.hasOre(rockToMine) && myPlayer().isAnimating();
                        }
                    }.sleep();

But it still just resulted in the mining animation playing for its full length in almost all cases.

Link to comment
Share on other sites

41 minutes ago, Explv said:


Currently you only mine a new rock if your player isn't animating, so of course it will wait for the animation to complete. You should try doing something like this instead:

 


private RS2Object rock = null;

@Override
public int onLoop() throws InterruptedException {
    // If we haven't looked for a rock yet, or the player isn't animating, or the current rock no longer has Clay
    if (rock == null || !myPlayer().isAnimating() || !Rock.CLAY.hasOre(rock)) {
        // Find a new rock
        rock = getObjects().closest(object -> Rock.CLAY.hasOre(object));
        // If a rock exists, and we successfully interact with it
        if (rock != null && rock.interact("Mine")) {
            new ConditionalSleep(3000, 500) { // Sleep for 3 seconds or until...
                @Override
                public boolean condition() throws InterruptedException {
                    // The player is animating, or someone else mined the rock
                    return myPlayer().isAnimating() || !Rock.CLAY.hasOre(rock);
                }
            }.sleep();
        }
    }
}

 

Thanks for the reply, ahh right I see now what I was doing wrong and this looks exactly like what I should be doing. But even using that code it still continues the animation if someone else has mined the rock before my player. I added some extra code to try and get a better understand of what was going on: 

if (rockToMine == null || !myPlayer().isAnimating() || !Rock.CLAY.hasOre(rockToMine)) {
            rockToMine = getObjects().closest(object -> Rock.CLAY.hasOre(object));
            if (rockToMine != null && rockToMine.interact("Mine")) {
                new ConditionalSleep(3000, 1000) {
                    @Override
                    public boolean condition() throws InterruptedException {
                        if (!Rock.CLAY.hasOre(rockToMine)) {
                            log("Rock has no ore!");
                            return true;
                        } else if (!myPlayer().isAnimating()) {
                            log("Animation finished!");
                            return true;
                        } else {
                            return false;
                        }
                    }
                }.sleep();
            }
        }

When checking the log, the "Rock has no ore!" never appears, which is confusing as I have watched the bot in times when the rock is empty of ore and the animation is still continuing regardless, it never reaches the "Rock has no ore!" output, just only ever outputting "Animation finished", whenever the animation has finished.

I also changed the sleep conditional return to myPlayer().isAnimating() to !myPlayer().isAnimating()  as wouldn't I want it to return true if the player had stopped animating, to break the sleep conditional? 

Link to comment
Share on other sites

Two things.

The biggest sin you're committing is that you're acquiring an RS2Object, storing it in a variable, and then waiting for one of its properties (modifiedColors) to magically change. Do you see the issue here?

The other is that clay respawns relatively quickly. You're checking once every second if the rock (with the magically-updating fields??) doesn't have ore, but what if clay always has ore between one-second intervals?

Link to comment
Share on other sites

Look at using the stored rocks position and writing a condition that finds the same rock on that position and checks if it doesn’t have ore, rather than checking the referenced rock. 

private boolean checkRockHasOreAtPosition(Position p){

    RS2Object rock = getObjects().getAll()
      .stream()
      .filter(obj -> obj.getPosition().equals(p) && Rock.CLAY.hasOre(obj))
      .findFirst()
      .orElse(null);

    return rock != null;

}

Something like that 

Edited by jca
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...