Jump to content

Keeps interacting with Anvil after a bit


Imthabawse

Recommended Posts

So whipped up a quick smither for some AFK gains and realized the bot will interact with the anvil after making a couple Platebody's. Would appreciate any feedback on why this is happening.

 

Spoiler

private void smithPlateBodys() throws InterruptedException {
    RS2Object anvil = getObjects().closest("Anvil");
    RS2Widget smithMenu = getWidgets().getWidgetContainingText("What would you like to make?");
    RS2Widget plateBody = getWidgets().get(312,15,2);

    if(!smithArea.contains(myPosition()) && !getBank().isOpen()) {
        log("Walking to Anvil...");
        getWalking().webWalk(smithArea);
    }
    if(!myPlayer().isAnimating() && smithArea.contains(myPosition()) && smithMenu == null && plateBody == null && !getDialogues().isPendingContinuation() && anvil != null && anvil.interact("Smith")) {
        log("Interacting with Anvil...");
        new ConditionalSleep(5000) {
            @Override
            public boolean condition() {
                return getWidgets().getWidgetContainingText("What would you like to make?") != null;
            }
        }.sleep();
    }
    if(smithMenu != null && plateBody != null && plateBody.interact("Smith All")) {
       log("Smithing Platebody's...");
        new ConditionalSleep(10000) {
            @Override
            public boolean condition() {
                return !readyToSmith() || getInventory().getAmount("Iron platebody") == 5;
            }
        }.sleep();
    }
    if(getDialogues().isPendingContinuation()) {
       log("Handling dialogue...");
        sleep(random(500,700));
        getDialogues().clickContinue();
    }
}

 

Link to comment
Share on other sites

1 hour ago, Neanel said:

Use sleepUntil:

 

& then just make a function like


private boolean canMakePlatebodies(){
        return getInventory().getAmount("Iron bar") >= 5;
}

//In your function
Sleep.sleepUntil(() -> !canMakePlatebodies, 5000);

 

Actually have my onLoop setup like so:

If (readyToSmith ()) {

smithPlates ();

}else {

bankPlates ();

readyToSmith is same as youre canMakePlatebodies

 

Pretty sure my logics just jumbled up.. made it in 10 min or so, so didnt expect it to work flawlessly. Appreciate your feedback though! 

Edited by Imthabawse
Link to comment
Share on other sites

Well that's exactly why he keeps interacting with the anvil again, the "readyToSmith()" function would still be true even if you are smithing because you'd have iron bars. With the "sleepUntil" he would be idle until you CAN'T smith anymore :)

At some point you're everything in your first if-statement is true which causes it to interact with the anvil again.

Link to comment
Share on other sites

Go look at how conditional sleeps work in the API. That should fix your issue. :) Rather than sleeping though, I suggest creating an animation timer. The benefit of this over a conditional sleep would be that should your event break through a level up etc, it'll react quicker than it would with your conditional sleep setup.

  • Like 2
Link to comment
Share on other sites

8 hours ago, Malcolm said:

I had this issue in my cannonballer script.

I ended up making an interaction timer instead of using a conditional sleep. If you use a conditional sleep you're stopping the thread for that time which is something I personally would avoid.

Just make a variable for when your last movement was and then do something like this.


                if (myPlayer().isAnimating()) {
                    lastAnimation = System.currentTimeMillis();
                } else if (System.currentTimeMillis() > (lastAnimation + 3000)) {
                    if (furnace.interact("Smelt")) { ...


                   

 

 

The correct solution.

Link to comment
Share on other sites

Try avoid re-checking the same logic cases and instead structure your code to run the fewest number of checks as possible:

private void smithPlateBodys() throws InterruptedException {
	
	if(smithArea.contains(myPosition())) {
		
		RS2Object anvil = getObjects().closest("Anvil");
		RS2Widget smithMenu = getWidgets().getWidgetContainingText("What would you like to make?");
		RS2Widget plateBody = getWidgets().get(312,15,2);
		
		if (getDialogues().isPendingContinuation()) {
			
			log("Handling dialogue...");
			
			if (getDialogues().clickContinue()) {
				sleep(random(500,700));
			}
			
		} else if (smithMenu != null && plateBody != null) {
			
			log("Smithing Platebody's...");
			new ConditionalSleep(10000) {
				@Override
				public boolean condition() {
					return !readyToSmith() || getInventory().getAmount("Iron platebody") == 5;
				}
			}.sleep();
			
		} else if (anvil != null && !myPlayer().isAnimating()) {
			
			log("Interacting with Anvil...");
			if (anvil.interact("Smith")) {
				
				new ConditionalSleep(5000) {
					@Override
					public boolean condition() {
						return getWidgets().getWidgetContainingText("What would you like to make?") != null;
					}
				}.sleep();
			}
		}
		
	} else {
		
		log("Walking to Anvil...");
		if (getWalking().webWalk(smithArea)) {
			sleep(random(500,700));
		}
	}
}

 

  • Like 1
Link to comment
Share on other sites

1 hour ago, liverare said:

Try avoid re-checking the same logic cases and instead structure your code to run the fewest number of checks as possible:


private void smithPlateBodys() throws InterruptedException {
	
	if(smithArea.contains(myPosition())) {
		
		RS2Object anvil = getObjects().closest("Anvil");
		RS2Widget smithMenu = getWidgets().getWidgetContainingText("What would you like to make?");
		RS2Widget plateBody = getWidgets().get(312,15,2);
		
		if (getDialogues().isPendingContinuation()) {
			
			log("Handling dialogue...");
			
			if (getDialogues().clickContinue()) {
				sleep(random(500,700));
			}
			
		} else if (smithMenu != null && plateBody != null) {
			
			log("Smithing Platebody's...");
			new ConditionalSleep(10000) {
				@Override
				public boolean condition() {
					return !readyToSmith() || getInventory().getAmount("Iron platebody") == 5;
				}
			}.sleep();
			
		} else if (anvil != null && !myPlayer().isAnimating()) {
			
			log("Interacting with Anvil...");
			if (anvil.interact("Smith")) {
				
				new ConditionalSleep(5000) {
					@Override
					public boolean condition() {
						return getWidgets().getWidgetContainingText("What would you like to make?") != null;
					}
				}.sleep();
			}
		}
		
	} else {
		
		log("Walking to Anvil...");
		if (getWalking().webWalk(smithArea)) {
			sleep(random(500,700));
		}
	}
}

 

Got this working. Thanks a lot. Will still be looking into animation timers as I've had this problem in scripts where your animation bounces from -1 to animating within seconds.

Link to comment
Share on other sites

3 hours ago, Imthabawse said:

Got this working. Thanks a lot. Will still be looking into animation timers as I've had this problem in scripts where your animation bounces from -1 to animating within seconds.

You don't need to watch for animations:

// Some basic mathematics...

long barsInInventory = inventory.getAmount("Bronze bar");
long barsPerPlatebody = 5;
long platebodiesWeCanMake = (barsInInventory / barsPerPlatebody);

// let's figure out how long we need to sleep
long timeToMakeEachPlatebody = 1500; // 1.5 seconds (might be more or less don't know)
long timeToMakePlatebodies = (platebodiesWeCanMake * timeToMakeEachPlatebody);
long timeToMakePlatebodiesWithRandomOffset = (timeToMakePlatebodies + random(500, 1500)); // + 0.5 to 1.5 seconds

if (anvil.interact("Smith")) {
	
	new ConditionalSleep(timeToMakePlatebodiesWithRandomOffset) {
		
		@Override
		public boolean condition() {
			
			// if any of the following happen, then we need to wake up!
			
			return getDialogues().isPendingContinuation() // level up message
			 || inventory.getAmount("Bronze bar") == 0 // we're out of bronze bars
			 || (inventory.getAmount("Bronze bar") / barsPerPlatebody) == 0; // we don't have enough bars to make another platebody
		}
		
	}.sleep();
	
}

 

  • Heart 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...