Page 1 of 1

help with waiting for items to appear before clicking it

Posted: Thu Dec 05, 2013 12:56 pm
by noobbotter
I was wondering if someone could tell me if there's a simpler way to do this? I have an area where I need to wait for an item to appear and then I can click on it. I need to do this several times before turning in the quest. Initially I would just have the bot run between the 2 or 3 areas where the item appears and do a rest for a certain amount of time before trying to click it to ensure enough time goes by for it to appear. The problems with this would be that if someone else were there, that would completely mess up the bot and the waypoints.

So to fix this issue I thought about having the bot wait in one spot between two of the locations where the item appears, and once an item appears, i clcik it (gather it) then go back to my waiting spot. I keep doing this until the quest is complete.

Another problem I'm faced with is that if I pick the first 2 and they are not available, it will see a third one and if it goes to pick it and the quest is complete, it will try to run through an obstacle and look too much like a bot. With that, I want to put a distance limit on the objects I'm watching for. and only click the ones that are within 200 units (Feet?) from me.

Here's the code I came up with:

Code: Select all

<!-- #  9 --><waypoint x="11111" z="2222" y="33" tag="finditem">
	local myitem = player:findNearestNameOrId(123456)
	if not myitem then -- if it doesn't find one at all, then wait for one
		repeat
			yrest(500)
			local myitem = player:findNearestNameOrId(118052)
		until 200 > distance(player.X, player.Z, myitem.X, myitem.Z) -- resting until there's one within range
		player:target_Object(myitem)
		mycheckQuest(987654) -- my custom function to check my quest status and return the done variable
		if done == "true" then
			__WPL:setWaypointIndex(__WPL:findWaypointTag("continue")) --quest done, continue to turn in quest
		end
	else -- this is run if it did find one
		if distance(player.X, player.Z, myitem.X, myitem.Z) > 200 then -- if not within range:
			repeat
				yrest(500)
				local myitem = player:findNearestNameOrId(118052)
			until 200 > distance(player.X, player.Z, myitem.X, myitem.Z) -- wait for one in range
			player:target_Object(myitem)
			mycheckQuest(987654) -- check quest
			if done == "true" then
			__WPL:setWaypointIndex(__WPL:findWaypointTag("continue")) --quest done, continue to turn in quest
		end
		else -- if it is in range:
			player:target_Object(myitem)
			mycheckQuest(987654) -- check quest
			if done == "true" then
				__WPL:setWaypointIndex(__WPL:findWaypointTag("continue")) --quest done, continue to turn in quest
			end
		end
	end
	__WPL:setWaypointIndex(__WPL:findWaypointTag("finditem")) -- at this point it gathered an item but quest isn't done so return to spot to wait for another
</waypoint>
I'm about 80% sure there's a much more efficient way to do this same thing but I can't figure out what it is. Can anyone provide some thoughts? Thanks.

Re: help with waiting for items to appear before clicking it

Posted: Thu Dec 05, 2013 2:17 pm
by Bill D Cat
Try this:

Code: Select all

<!-- #  9 --><waypoint x="11111" z="2222" y="33" tag="finditem">
	repeat
		local myitem = player:findNearestNameOrId(123456)
		if myitem and 200 > distance(myitem, player) then -- found item and it is in range
			player:target(myitem)
			mycheckQuest(987654) -- my custom function to check my quest status and return the done variable
			if done == true then
				__WPL:setWaypointIndex(__WPL:findWaypointTag("continue")) -- quest done, continue to turn in quest
			end
		else
			yrest(500) -- resting until there's one within range
		end
	until done == true
</waypoint>

Re: help with waiting for items to appear before clicking it

Posted: Thu Dec 05, 2013 2:26 pm
by noobbotter
Looking at it, it looks like it should work. I'll give it a try tonight. Thanks

Re: help with waiting for items to appear before clicking it

Posted: Thu Dec 05, 2013 2:36 pm
by Bill D Cat
Just a suggestion for your function mycheckQuest():

Consider adding a second argument that accepts the tag name to jump to if done == true. You'd just have to move the check into the function instead of the waypoint.

Code: Select all

mycheckQuest(987654) -- my custom function to check my quest status and return the done variable
if done == true then
    __WPL:setWaypointIndex(__WPL:findWaypointTag("continue")) -- quest done, continue to turn in quest
end
could then become

Code: Select all

mycheckQuest(987654, "continue")
by adding something like this to your function.

Code: Select all

function mycheckQuest(questID, doneTag)
--do stuff to check for quest status
if doneTag ~= nil and done == true then
   __WPL:setWaypointIndex(__WPL:findWaypointTag(doneTag))
end

Re: help with waiting for items to appear before clicking it

Posted: Thu Dec 05, 2013 11:29 pm
by rock5
Proper coding practices would suggest that mycheckQuest should return a value instead of changing a global variable. Eg.

Code: Select all

local done = mycheckQuest()
if done == true then
Doesn't matter but just saying...

Re: help with waiting for items to appear before clicking it

Posted: Fri Dec 06, 2013 11:45 am
by noobbotter
Well, When I was trying the "repeat code" the bot wasn't moving to go target an item, and I found that I couldn't press "end" or Ctrl-C to stop the code. After trying several things, I decided to change my code and do it without the repeat.

After I changed the code, more optimized this time than it was the first time, the bot wasn't targeting any items so I added some print statements to aid in trouble shooting. I found that it was finding the nearest item but wasn't doing anything when it was supposed to target it... then I realized I was trying to target the item variable instead of target the itemID. After I changed "player:target_Object(myitem)" to "player:target_Object(123456)", it started working. I haven't retried using the repeat code but this seems to be working pretty good:

Code: Select all

<!-- #  9 --><waypoint x="12358" z="1791" y="59" tag="finditems">
		local myitem = player:findNearestNameOrId(123456)
		local mydistance = distance(myitem, player)
		
		if myitem and 220 > distance(myitem, player) then -- found item and it is in range
			printf("item location is %s, distance is %s. its in range.\n",myitem.X,mydistance)
			player:moveTo(myitem, true);
			player:target_Object(123456)
			yrest(1500)
			mycheckQuest(987654) -- my custom function to check my quest status and return the done variable
			if done == "true" then
				if player.Z > 1800 then
					__WPL:setWaypointIndex(__WPL:findWaypointTag("gototurnin"))
				else
					__WPL:setWaypointIndex(__WPL:findWaypointTag("gototurnin2"))
				end
			else
				__WPL:setWaypointIndex(__WPL:findWaypointTag("finditems"))
			end
		else
			printf("Dont see grass")
			yrest(2000) -- resting until there's one within range
			__WPL:setWaypointIndex(__WPL:findWaypointTag("finditems"))
		end
	</waypoint>
Rock, how would I have that function return a value instead of doing it the way it currently does?:

My current code is:

Code: Select all

function mycheckQuest(questname)
	quest = questlog:getQuest(questname)
	if quest:isComplete() == true then
		done = "true";
	else
		done = "false";
	end
end
would it be like this?

Code: Select all

function mycheckQuest(questname)
	quest = questlog:getQuest(questname)
	if quest:isComplete() == true then
		return true
	end
end

Re: help with waiting for items to appear before clicking it

Posted: Sat Dec 07, 2013 2:22 am
by rock5
Well at the moment your function sets done to "true" or "false". So you want to replace

Code: Select all

done = "true"
to

Code: Select all

return "true"
And

Code: Select all

done = "false"
to

Code: Select all

return "false"
Then change

Code: Select all

mycheckQuest(987654)
to

Code: Select all

local done = mycheckQuest(987654)
Everything else remains the same.