Page 1 of 1

Better way to do this?

Posted: Fri May 21, 2004 12:16 pm
by chawk
I'm still fairly new to MQ macros, so perhaps I'm unaware of a better set of commands to help me accomplish what I want. The macro basically scans every spawn in the zone and will echo any spawn that has a capital letter in the name or a pound-sign (a pseudo-named-spawn checker :wink:). It's using the TLO LastSpawn[] to loop through the array till .Name is a null string. It runs rather slow sometimes, and seems to run slower and slower as I use it more or as I'm online longer. I'm not sure if I'm mem leaking or this method sucks in general.

Code: Select all

Sub Main
    /declare i int local 1
    /echo Checking for nameds...
    :loop
        /if (${LastSpawn[${i}].Name.Length}>0) {
            /if (${LastSpawn[${i}].Name.Lower.NotEqualCS[${LastSpawn[${i}].Name}]} || ${LastSpawn[${i}].Name.Count[#]}>0) {
                /if (${LastSpawn[${i}].Type.Equal[NPC]}) {
                    /echo ..${LastSpawn[${i}].CleanName}
                }
            }
            /varcalc i ${i}+1
            /goto :loop
        }
        /echo Done.
/endmacro
I've also thought about somehow writing this in code and adding myself a custom command, but I'd probably crash MQ2. I'm still 100% newb under the hood.

Posted: Fri May 21, 2004 1:07 pm
by Chill
You can get rid of the # code and just do a /who npc # in zones where that works. However, not all zones add # to the named mobs...for the zones that dont your look code looks like a good start.

One obvious problem: your loop will go on forever, or at least until i gets way huge. I would change it into a /for next loop going from 1 up to some value. I have never seen an id with more than 4 digits, so there is probably no need to go above 9999 ever, if even that high. A better way would probably be to do a /who command and parse the number of mobs in the zone with an event, then go through your loop that many times and move from one spawn up to the .Next spawn. The best way would probably be if you can find a variable giving the number of mobs in the zone, and step through only the npcs, but Im not sure if thats possible.

Posted: Fri May 21, 2004 2:32 pm
by s16z
I'd do it a little different.

Code: Select all

/declare MySpawn int inner
/varset MySpawn ${LastSpawn[-1].ID}

:Loop
| do stuff with the spawn, check whatever, etc. I would check that they are NPCs


/varset MySpawn ${Spawn[${MySpawn}].Prev.ID}
/if (${MySpawn}) /goto :Loop

/return

Posted: Fri May 21, 2004 3:49 pm
by chawk
I'm not really sure how to capture text spew from a /who, plus that would kind of spam, I think :wink: Do understand the code works, but I was looking some improvements. The loop doesn't go forever 'cause LastSpawn will return NULL once I get outside valid ID's, and .Name.Length applied to a NULL object returns FALSE apparently, so there's the stopping condition.

I tested the Spawn.Next and Spawn.Prev stuff and it seems a tiny bit faster; I think I might use that :wink: Repeated use of LastSpawn[] might be running unnecessary calculations since I'm simply traversing the spawn list array (well I assume it's array-like).

Thanks.

Posted: Fri May 21, 2004 4:29 pm
by BrainDeath
You should probably put a /return after /endmacro also. That might be part of the problem.

Posted: Fri May 21, 2004 4:46 pm
by Rusty~
spawn.Next and spawn.Prev go by how far away the mob is from you i thought? so if mobs moveit could get the same mob more than once, or skip some of them. another way you could do it is with alerts. for example:

Code: Select all

/clear alert 1
:loop
/if (${Spawn[npc noalert 1].ID}) {
   /alert add 1 id ${Spawn[npc noalert 1].ID}
   | do stuff
   /goto :loop
}
/return