Page 1 of 2

Party botting

Posted: Sat Jan 01, 2011 3:17 pm
by JackBlonder
I have a problem with party botting.
The second bot (priest) works (targets enemy and casts spells) if the partyleader (warrior) is played manually but doesn't work (doesn't target enemy) if the partyleader is botted.

Any suggestions?

Waypointfile of second party member:

Code: Select all

<?xml version="1.0" encoding="utf-8"?><waypoints>
	<onLoad>
	while (true) do

		local combatstate
		
		combatstate = RoMScript("GetPlayerCombatState();");
		
		while (combatstate == true) do
			-- sendMacro("DEFAULT_CHAT_FRAME:AddMessage('|cffffff00RB Party in fight|r')")
			RoMScript("TargetUnit('party1target');");
						
			player:fight()
			
			combatstate = RoMScript("GetPlayerCombatState();");
			yrest(1000);
		end

		inventory:update()
		player:checkPotions()
		local target = player:getTarget();
		player:checkSkills(true, target);
		player:update()
		RoMScript("FollowUnit('party1');"); 
	end
	</onLoad>
</waypoints>

Re: Party botting

Posted: Sun Jan 02, 2011 12:41 am
by rock5
Why are you using GetPlayerCombatState() that requires a RoMScript command? Can't you use the player.Fighting variable? It should return the same value.

As to your problem, I've confirmed it. It's probably because the bot doesn't quite reproduce targeting like manually clicking or tabbing to target. For example the target frame usually doesn't appear.

If I remember correctly there used to be a command in the bot that made the target frame appear but it was removed because it wasn't necessary. Maybe if we re-implemented it, it would fix your problem? I can't remember what the command was and can't find it. Can anyone else remember?

Re: Party botting

Posted: Sun Jan 02, 2011 12:58 am
by Administrator
rock5 wrote: If I remember correctly there used to be a command in the bot that made the target frame appear but it was removed because it wasn't necessary. Maybe if we re-implemented it, it would fix your problem? I can't remember what the command was and can't find it. Can anyone else remember?
That's when we used to use the TAB key to select targets. Now, we just set the player's target in memory. It has the strange side-effect of not showing the target frame until you get hit due to not properly sending an event signal down to the GUI.

Re: Party botting

Posted: Sun Jan 02, 2011 4:02 am
by rock5
Administrator wrote: That's when we used to use the TAB key to select targets. Now, we just set the player's target in memory. It has the strange side-effect of not showing the target frame until you get hit due to not properly sending an event signal down to the GUI.
I must not be remembering properly. i thought when we first implemented memory targeting we encountered this problem of the target frame not appearing and a command was added to make it appear but we removed it later because it wasn't necessary. I get the impression we removed it because it was a RoMScript command. It's all a bit fuzzy. :)

Anyway I spent some time trying to find what other values might need to be changed so other players can read your target, but failed. I'll try again tomorrow.

Re: Party botting

Posted: Sun Jan 02, 2011 5:30 am
by JackBlonder
Thanks for your effort.
I'll try to use player.Fighting instead and find a workaround for the target problem.

Re: Party botting

Posted: Sun Jan 02, 2011 11:44 am
by JackBlonder
How can I check if my target is the target of the party leader?

Edit:

This almost does what it should do but sometimes I get a client crash.
I think it's a memory access problem.
Therefor I wanted to check if Enemy is target of the party leader

Code: Select all

<onLoad>
	while (true) do
		local Enemy
		
		while ( player.Battling == true ) do
			--sendMacro("DEFAULT_CHAT_FRAME:AddMessage('|cffffff00RB Party is fighting|r')")
			
			Enemy = player:findEnemy(false,nil,nil)

			if (Enemy ~= nil and Enemy ~= 0 and Enemy ~= null and Enemy.HP > 0) then
				
				player:target(Enemy)
				player.TargetPtr = Enemy.Address
				player:fight()
			end
			

		end
				
		RoMScript("FollowUnit('party1');"); 	
		player:update()

	end
	</onLoad>

Re: Party botting

Posted: Sun Jan 02, 2011 7:59 pm
by rock5
How do you know who the party leader is?

Re: Party botting

Posted: Mon Jan 03, 2011 12:15 am
by lisa
My guess would be he always has the same group setup.

Melee is party leader
priest is party member

So when on priest character, the 'party1' will always be the party leader as such as there is only 2 characters in party.

Re: Party botting

Posted: Mon Jan 03, 2011 12:29 am
by rock5
lisa wrote:My guess would be he always has the same group setup.

Melee is party leader
priest is party member

So when on priest character, the 'party1' will always be the party leader as such as there is only 2 characters in party.
In that situation I would get the players name first.

Code: Select all

leaderName = RoMScript("UnitName('party1')")
Then I'd 'find' the player by name. This uses the object class but the address should be the same.

Code: Select all

leaderObj = player:findNearestNameOrId(leaderName)
Then create a pawn of that player.

Code: Select all

leader = CPawn(leaderObj.Address)
Then it's just a matter of comparing addresses.

Code: Select all

if player.TargetPtr == leader.TargetPtr then
    -- Have the same target
    ...
end

Re: Party botting

Posted: Mon Jan 03, 2011 10:46 am
by JackBlonder
@lisa: Guessed right ;)
@rock5: That will help alot. Thanks

Re: Party botting

Posted: Wed Jan 05, 2011 5:21 am
by JackBlonder
Comparing TargetPtr did not work for me.
I think the two pointers point to different memory positions.
But I got it to work by comparing player.Target and leader.Target but I'm not sure if this correct.

Code: Select all

	<onLoad>
		local leader
		local leaderName
		local leaderObj
		local Enemy
		
		leaderName = RoMScript("UnitName('party1')")
		sendMacro("DEFAULT_CHAT_FRAME:AddMessage('|cffffff00RB Assist: "..leaderName.." |r')")
			
		leaderObj = player:findNearestNameOrId(leaderName)
		leader = CPawn(leaderObj.Address)
		
	while (true) do
		
		while ( player.Battling == true ) do
			
			Enemy = player:findEnemy(false,nil,nil)
			player:target(Enemy)
			player.TargetPtr = Enemy.Address
			player:update()
			
			--sendMacro("DEFAULT_CHAT_FRAME:AddMessage('|cffffff00RB Party is fighting|r')")		
			--sendMacro("DEFAULT_CHAT_FRAME:AddMessage('|cffffff00RB player.TargetPtr: "..player.TargetPtr.." |r')")
			--sendMacro("DEFAULT_CHAT_FRAME:AddMessage('|cffffff00RB leader.TargetPtr: "..leader.TargetPtr.." |r')")
			
			if player.Target == leader.Target then
				--sendMacro("DEFAULT_CHAT_FRAME:AddMessage('|cffffff00RB Attacking|r')")
				player:fight()
				yrest(3000)
			end
		end
		
		lootBodies()	
		RoMScript("FollowUnit('party1');"); 	
		player:update()
		leader:update()

	end
	</onLoad>

Re: Party botting

Posted: Wed Jan 05, 2011 7:53 am
by rock5
JackBlonder wrote:Comparing TargetPtr did not work for me.
I think the two pointers point to different memory positions.
But I got it to work by comparing player.Target and leader.Target but I'm not sure if this correct.
As far as I can tell there is no player.Target value so "player.Target == leader.Target" is equivalent to "nil == nil" which will always be true.

I think your problem is, what you are trying to do is not what you want it to do. If you just want to attack your leaders target then just do that. Don't search for a target then compare it with the leaders. Just do

Code: Select all

if leader.TargetPtr ~= 0 then
    player:target(leader.TargetPtr)
    player.TargetPtr = leader.TargetPtr
    etc...

Re: Party botting

Posted: Wed Jan 05, 2011 11:56 am
by JackBlonder
I had the same idea but it didn't work for me.
I'll give it another try when I'm at home.

Re: Party botting

Posted: Wed Jan 05, 2011 8:42 pm
by rock5
JackBlonder wrote:I had the same idea but it didn't work for me.
I'll give it another try when I'm at home.
Ah yes, i think if the leader is botting, it wont work. Which is a really big issue when trying to create an assist bot.

Re: Party botting

Posted: Thu Jan 06, 2011 2:13 am
by JackBlonder
I tried setting player.TargetPtr to leader.TargetPtr again and it didn't work.
The second bot never attacks.

The problem of comparing leader.TargetPtr and player.TargetPtr (after finding an enemy by player:findEnemy)
is that they have different values although it's the same target (second bot attacks same enemy when I ignore comparing player.TargetPtr and leader.TargetPtr)

Code: Select all

			Enemy = player:findEnemy(false,nil,nil)
			player:target(Enemy)
			player.TargetPtr = Enemy.Address
			player:update()
			sendMacro("DEFAULT_CHAT_FRAME:AddMessage('|cffffff00RB player.TargetPtr: "..player.TargetPtr.." |r')")
			sendMacro("DEFAULT_CHAT_FRAME:AddMessage('|cffffff00RB leader.TargetPtr: "..leader.TargetPtr.." |r')")
			
			--if player.TargetPtr == leader.TargetPtr then
				sendMacro("DEFAULT_CHAT_FRAME:AddMessage('|cffffff00RB Attacking: "..player.TargetPtr.." |r')")
				player:fight()
				yrest(3000)
                       --end

Re: Party botting

Posted: Thu Jan 13, 2011 7:30 am
by JackBlonder
I'm still confronted with this issue.
When I use this little script and the leader is botted I noticed that the address of partyleader.Address is the same as partyleader.TargetPtr
Anyone has a good idea to get rid of this problem?

Code: Select all

<?xml version="1.0" encoding="utf-8"?><waypoints>
	<onLoad>
	local partyleaderIndex
	local partyleader
	local partyleaderName
	local partyleaderObj

	if RoMScript("UnitExists('party1')") then
	
		partyleaderIndex = RoMScript("GetPartyLeaderIndex()")
		if partyleaderIndex~=nil then
			printf("Found partyleaderIndex: %d \n",partyleaderIndex)
			partyleaderName = RoMScript("UnitName('party"..partyleaderIndex.."')")
			printf("Partyleader: %s \n",partyleaderName)
			partyleaderObj = player:findNearestNameOrId(partyleaderName)
			partyleader = CPawn(partyleaderObj.Address)
		end
	end

	while(true) do
		player:update()
		if (player.Battling) then --and partymember[i].Target.Ptr~=0
			partyleader:update()
			printf("LeaderPtr: %s\n",partyleader.Address)
			printf("leaderTarget: %s\n",partyleader.TargetPtr)

			player.TargetPtr = partyleader.TargetPtr
			player:getTarget()
			printf("target: %s\n",player.TargetPtr)
		
--			player:fight()

		end

		RoMScript("FollowUnit('party1');");
	end

	</onLoad>
</waypoints>

Re: Party botting

Posted: Thu Jan 13, 2011 8:49 am
by lisa
Had a thought and not sure if it's even possible but is there a way to make the bot actually target the mob physically at the same time it targets it by memory?
It seems to me the bot detects it is being targeted by if it has a physical target itself which is what happens when a mob hits u. If you are just in combat and the mob hasn't hit you in anyway yet then it just says it has agro and is waiting for target.
I could be wrong on that assumption though.

Re: Party botting

Posted: Thu Jan 13, 2011 11:32 am
by rock5
The problem is that when the leader client targets a mob when botting, it correctly changes the memory regions for targeting that mob but doesn't send some unknown vital signal to the server, like normal targeting would, letting it know the new target. So when the second client queries the server for the leaders target, the server doesn't know and send the wrong address.

I did some testing awhile ago and this is what I found.

After doing a player:target(address) on the first client, I tried to see its target from another client. We already know this doesn't work.

I tried then clicking on the target, but it still didn't work.

I tried deselecting the target then clicking it again but it still didn't work.

I had to target something else first before returning to the first target before I was able to see it on the second client.

I conclude from this that that vital info is only sent at the time of changing or aquiring a target. I can't see any way to fix this other than abandoning the memory address targeting and going back to 'TAB' targeting.

Re: Party botting

Posted: Thu Jan 13, 2011 12:06 pm
by lisa
I don't like the idea of going back to TAB targeting, even playing the game and trying to use TAB to target is unreliable.
This problem is beyond me though, that's pretty obvious.

Re: Party botting

Posted: Thu Jan 13, 2011 2:20 pm
by JackBlonder
I can't see any way to fix this other than abandoning the memory address targeting and going back to 'TAB' targeting.
Is there any way I can do that just for my uses.
Something like overwriting the targeting function by my own function?