Checking Aggro with con

Need help with a macro you are writing? Ask here!

Moderator: MacroQuest Developers

User avatar
Fippy
a snow griffon
a snow griffon
Posts: 499
Joined: Tue Jul 16, 2002 10:42 am

Checking Aggro with con

Post by Fippy » Tue Aug 03, 2004 12:27 pm

I am writing myself an advanced Hunting script the aim being to be able to bot a new toon that will either wander around a zone killing mobs or pull to an anchor point and kill. With my second account ill then follow the bot about and keep him healed buffed etc.

At the moment I am fiddling with the movement code basically I am trying to code in some auto avoidance of aggro mobs. What I have right now is something like this.

Code: Select all

Sub CheckPossibleAggro
	/declare NearestMobID int inner
	/varset NearestMobID ${NearestSpawn[npc radius 150 notid ${CurrentTargetID}].ID}
	/if ((${NearestMobID}>0)&&(${NearestMobID}!=${CurrentNearestMobID})) {
		/varset CurrentNearestMobID ${NearestMobID}
		/target npc id ${CurrentNearestMobID}
		/consider
	}
/return
In the main sub theres a declares for CurrentTargetID, and CurrentNearestMobID

What this should do is find the nearest mob that is within 150 units and isnt the mob I am heading to and then con it. To prevent multiple cons each time the sub is called the last target is remebered in CurrentNearestMobID.

Now I want to do something if the mob is going to aggro i.e. scowls. So I set up an event like this.

Code: Select all


#event CheckBadCon "#1#scowls at you, ready to attack#*#"

Sub Event_CheckBadCon(string Line,string MobName)
	/echo ${MobName} Aggro mob detected
/return
What I am after is the best way to get the ID of the mob that scowled at me. It should be in CurrentNearestMobID but that might change before the chat event gets fired which would lead to me avoiding the wrong mob.

Any thought on this or a better way of doing it ?
Fippy

This is my girl. But Rizwank had her first :-)
[img]http://www.btinternet.com/~artanor/images/fairy_bounce09.gif[/img]

Mimatas
a hill giant
a hill giant
Posts: 262
Joined: Wed Mar 10, 2004 4:22 pm

Post by Mimatas » Tue Aug 03, 2004 1:36 pm

Maybe this is a wasteful post (since I don't really know what I'm talking about), but doesn't

Code: Select all

#event CheckBadCon "#1#scowls at you, ready to attack#*#" 
store the text that matches #1#(mob name) in a retrievable location? Once you have the name, you could /target.

The only problem with this that I could see would be if there were multiple mobs with the same name... but then /target would still pick the closest (I think). It could also be safely assumed that any unaggroed mob with the same name will have the same con... so you may end up avoiding a different mob than the one you originally con'd, but it'd still be one you would want to avoid.

User avatar
blueninja
a grimling bloodguard
a grimling bloodguard
Posts: 541
Joined: Thu Aug 28, 2003 7:03 am
Location: Göteborg, Sweden

Post by blueninja » Tue Aug 03, 2004 2:09 pm

The only reliable and easy way I can think of is to set up multiple events for all the possible con messages and setting a flag in the event subs when you recieve a con message. Then you just keep the ID stored until the flag is set by the event.

The not so easy way would be to write a plugin to detour the con function to match the ID to the server response.

Mimatas
a hill giant
a hill giant
Posts: 262
Joined: Wed Mar 10, 2004 4:22 pm

Post by Mimatas » Tue Aug 03, 2004 2:24 pm

still doing research when I've got downtime at work:

#event CheckBadCon "#1#scowls at you, ready to attack#*#"

Sub Event_Consented(string Line, string Name)
/target ${Name}
end sub

Wouldn't this put the mob in your target window.. then (this is likely wrong, but you can get the idea)

${Target.ID}

-----------------------
Looking at your code, It looks to me as though immediately after /consider you could just get the ID from the Target object...

Sub CheckPossibleAggro
/declare ScowlingID int inner
/declare NearestMobID int inner
/varset NearestMobID ${NearestSpawn[npc radius 150 notid ${CurrentTargetID}].ID}
/if ((${NearestMobID}>0)&&(${NearestMobID}!=${CurrentNearestMobID})) {
/varset CurrentNearestMobID ${NearestMobID}
/target npc id ${CurrentNearestMobID}
/consider
/varset ScowlingID ${Target.ID}
}
/return

Again, I know little about this language.. but this may work.

User avatar
Cr4zyb4rd
Plugins Czar
Posts: 1449
Joined: Tue Jul 20, 2004 11:46 am

Post by Cr4zyb4rd » Tue Aug 03, 2004 3:28 pm

Small /doevents "busy loop" inside of your CheckPossibleAggro is the first simple solution that comes to mind. Have your trigger signal somehow (setting an "outer" variable defined in main to Target.ID seems reasonable) that it's been hit, and break the loop when that happens. You'll be wasting time when you could have been doing other things.

Hrm, now that I think about it...you might want to test this, but I'm reasonably certain that even if you spam the hell out of them, the servers will always return the cons in the order you issued them. Sooo...making an array of the mobs you wish to con and walking said array in the event sub would work too. You'd still need a busy loop to wait until the array was fully populated, but events are queued such that they wouldn't race each other, and you could then keep the /doevents loop as part of Sub Main or wherever you're doing it, and use whatever counter variable you used to walk the array as one of the conditions for breaking the loop.

I can spew out some pseudo-code if that came out too complicated...I may have even lost myself :)

Mimatas
a hill giant
a hill giant
Posts: 262
Joined: Wed Mar 10, 2004 4:22 pm

Post by Mimatas » Tue Aug 03, 2004 3:28 pm

That's a good thing to consider... Since con's request info from the server, a fast-moving loop that cons every mob around you may raise flags... if they're checking (they probably aren't... but some are more paranoid than others).

If you've got your higher level toon escorting... why not just charge right through the aggro mobs? Worst case, the higher level toon can step in and regulate.

User avatar
Fippy
a snow griffon
a snow griffon
Posts: 499
Joined: Tue Jul 16, 2002 10:42 am

Post by Fippy » Tue Aug 03, 2004 4:44 pm

Last time i tried something like this was way back in the Original MQ days :) I found then that /target npc "a wolf" didnt reliably pull back the correct mob cause sometimes it would be a mob elsewhere in the zone.

Rapidly conning every mob around me would generate a lot of server traffic from cons and would be above my comfort level.

After looking through the docs on events some more it looks like putting a /doevents CheckBadCon might do the trick if I insert it just after the /consider the chance of switching target is going to be pretty minimal in that time I think. Ill give this a test tonight and let you know if it works.
Fippy

This is my girl. But Rizwank had her first :-)
[img]http://www.btinternet.com/~artanor/images/fairy_bounce09.gif[/img]

User avatar
Fippy
a snow griffon
a snow griffon
Posts: 499
Joined: Tue Jul 16, 2002 10:42 am

Post by Fippy » Tue Aug 03, 2004 6:02 pm

OK this seems to work quite well if anybody is interested.

Code: Select all


Sub Main
	|
	#event CheckBadCon "#1#scowls at you, ready to attack#*#"
	
	/declare CurrentTargetID int outer
	/declare CurrentNearestMobID int outer

	
	:ScanLoop
	                /varset CurrentTargetID ${Target.ID}
		/call CheckPossibleAggro 150
                                /doevents
		/delay 5
	
	/goto :ScanLoop
/return

|---------------------------------------------------------------------------- 
| Name: CheckPossibleAggro
| Description: Sub to consider the nearest mob within the supplied radius
|              that is not the current target. Then check if the 'scowls'
|              con message event has fired
|---------------------------------------------------------------------------- 
Sub CheckPossibleAggro (int AggroRad)
	/declare NearestMobID int inner
	/varset NearestMobID ${NearestSpawn[npc radius ${AggroRad} notid ${CurrentTargetID}].ID}
	/if ((${NearestMobID}>0)&&(${NearestMobID}!=${CurrentNearestMobID})) {
		/varset CurrentNearestMobID ${NearestMobID}
		/target npc id ${CurrentNearestMobID}
		/consider
		/doevents CheckBadCon
	}
/return

|---------------------------------------------------------------------------- 
| Name: Event_CheckBadCon <Chatlog Line> <Mob Name> 
| Description: This event should fire whenever a 'scowls' con message appears 
|              in the chatlog.
|---------------------------------------------------------------------------- 
Sub Event_CheckBadCon(string Line,string MobName)
	/echo ${MobName} Aggro mob detected should be ID ${CurrentNearestMobID} name: ${Spawn[${CurrentNearestMobID}]}
/return
Last edited by Fippy on Wed Aug 04, 2004 6:51 pm, edited 1 time in total.
Fippy

This is my girl. But Rizwank had her first :-)
[img]http://www.btinternet.com/~artanor/images/fairy_bounce09.gif[/img]

User avatar
Cr4zyb4rd
Plugins Czar
Posts: 1449
Joined: Tue Jul 20, 2004 11:46 am

Post by Cr4zyb4rd » Tue Aug 03, 2004 11:13 pm

That won't cut it. You need to loop doevents. The whole point of events is that they are queued and wait patiently until a /doevent matching that trigger is called. You're calling it immediately, at a point when under most situations the server won't have even had a chance to receive your request, let alone answer it...unless my understanding of events is way way off.

User avatar
Fippy
a snow griffon
a snow griffon
Posts: 499
Joined: Tue Jul 16, 2002 10:42 am

Post by Fippy » Wed Aug 04, 2004 6:53 pm

Sorry I accidently deleted the /doevents in the main loop when I deleted a couple of debuging /echos.

I have put it back in :) and it does work as it is now.

I do see your point though I had assumed that /doevents <eventname> would hang about until that event fired when I wrote that code which looking back at it now doesnt make sense.

I havent really tested this with a lot of aggro mobs nearby so it might well start to run into problems then.

maybe we could do with a /delay <eventname> command that waits until a particular event fires.

I suppose I could try setting up an array as a queue for mob ID's conned and then update it with the con they recived iin chatlog events and hope the server sends con messages in the same order they are recived as suggested earlier.
Fippy

This is my girl. But Rizwank had her first :-)
[img]http://www.btinternet.com/~artanor/images/fairy_bounce09.gif[/img]