Errors Help understanding /for loop mechanism
Reply
Help understanding /for loop mechanism
Hello, and thank you if you are able to help!

Recently I tried creating a small macro to memorize spells (I will explain why later). Unfortunately, when I try to loop through my array of spells, I only memorize the last index of the loop...that hasn't already been memorized.

Here is the macro, and I'll provide the example afterwards.

Using EQ client Seeds of Destruction on a Win7 system
Using the MQ2-SoD version available through download from this site.

memspellset.mac
Macro
More +
sub main

/declare PC1 int local ${NearestSpawn[pc JoeBobTheSK].ID}

/declare SpellList[9] string local
/declare SpellNum int local 1
/declare MaxSpells int local 8

  /if (${Me.AltAbility["Mnemonic Retention"]}==3) {
    /varset MaxSpells 9}
  }

/if (${Me.ID}==${PC1}) {
  /echo HELLO
  /varset SpellList[1] "Touch of Innoruuk"
  /varset SpellList[2] "Touch of Volatis"
  /varset SpellList[3] "Voice of Death"
  /varset SpellList[4] "Festering Darkness"
  /varset SpellList[5] "Terror of Thule"
  /varset SpellList[6] "Zevfeer's Bite"
  /varset SpellList[7] "Aura of Pain"
  /varset SpellList[8] "Invoke Death"
  /varset SpellList[9] "Cloak of Luclin"
  /goto :MemSpells
}

:MemSpells
/for SpellNum 1 to ${MaxSpells}
  /delay 3
  /echo ${SpellNum} ${SpellList[${SpellNum}]}
  /memspell ${SpellNum} ${SpellList[${SpellNum}]}
/next SpellNum

/return


JoeBobTheSK does not have Mnemonic Retention, so MaxSpells is 8.

When I run the macro once, the first 8 items of the array are echoed to the MQ window. However, only Invoke Death is memorized (in spell slot 8).
When I run the macro a second time, the 8 items of the array are echoed to the MQ window. This time, only Aura of Pain is memorized.
This continues down the list until item 1, Touch of Innoruuk, is memorized.


Now, some folks will wonder why in the world I wouldn't just use EQ's built in spellset. For some reason, most of my character UI's (using default UI) are borked, such that "newer" implementations of right-click functionality doesn't work. I can loot corpses and open tradeskill containers and such, but I cannot access the chat window menu or memorize spells with right-click. So, I need a macro if I don't want to open the spellbook and find my spells for all my characters.

Also, I'm asking on this forum since this is a rather dated version of MQ2, and if this is a known bug in this version, it would likely have been addressed long ago by the more current MQ2 environment. Searching their forums yielded no obvious reports of this issue, so finding a solution there isn't likely, unless my syntax or logic is incorrect.
Thu May 05, 2011 10:20 am
I'm out at lunch right now, if servant doesn't write up something I'll get you in about an hour.

EDIT: sorvani auto corrected on my phone as servant... a rather unfortunate auto correct, no offense sorvani =)
Last edited by Maudigan on Thu May 05, 2011 11:18 am; edited 1 time in total
Thu May 05, 2011 10:31 am
Project Lead
I just tried putting a "/for testvarthing 1 to 8 ... /next testvarthing" around my initial /for loop just to see if it would memorize all 8 spells if I iterated the loop 8 times, but instead it just echoed the 8 spells 8 times before memorizing Invoke Death. So very odd. I'm not sure if it has something to do with /delay? I tried a /timed replacement, but got junk (NULL) output and no spells memorized.
Thu May 05, 2011 10:35 am
Great, thanks Maudigan. I'll check back in after lunch sometime to see if you can see something.

Another update:

It seems the memspell call isn't happening until after the macro ends, so if I end the macro halfway through the loop, I'll memorize the last item analyzed in the array.
Thu May 05, 2011 10:35 am
It sounds like the delay 3 may not be long enough, and it starts the next memspell before the previous one finishes and ends up halting it... maybe. So first run 1-7 fail, 8 finishes because there is no 9 to interupt it. Next run 1-6 fail, 7 finishes, 8 doesn't interupt because it's already memmed and the memspell function recognizes that and aborts. etc... I'll walk you through a more positive control using conditional delays and event verification. I'm not in front of the game right now, i'm at the office so I can't verify all my syntax is correct.

Macro
More +

|using this to clean up the readability
|of the spell name in question
/declare sName string local


:MemSpells
/for SpellNum 1 to ${MaxSpells}
  |this doesn't effect the logic, it
  |just makes the code more readable
  |by converting the indexed array variable
  |into a normal var
  /varset sName ${SpellList[${SpellNum}]}

  |start the memorize first
  /memspell ${SpellNum} ${sName}

  |delay for 10 seconds OR until
  |the memorize is succesfull whichever
  |is shortest
  /delay 10s ${Me.Gem[${SpellNum}].Name.Equal[${sName}]}

  |now we need to determine if we got here
  |by waiting the 10 seconds or by being
  |succesfull
  /if (${Me.Gem[${SpellNum}].Name.Equal[${sName}]}) {
      /echo SUCCESS - ${SpellNum} ${SpellList[${SpellNum}]}
  }
  else {
      /echo FAILED - ${SpellNum} ${SpellList[${SpellNum}]}
  }
/next SpellNum

|and same thing without comments:


/declare sName string local

:MemSpells
/for SpellNum 1 to ${MaxSpells}  
  /varset sName ${SpellList[${SpellNum}]}

  /memspell ${SpellNum} ${sName}

  /delay 10s ${Me.Gem[${SpellNum}].Name.Equal[${sName}]}

  /if (${Me.Gem[${SpellNum}].Name.Equal[${sName}]}) {
      /echo SUCCESS - ${SpellNum} ${SpellList[${SpellNum}]}
  }
  else {
      /echo FAILED - ${SpellNum} ${SpellList[${SpellNum}]}
  }
/next SpellNum


if you run that and you get a spam of "SUCCESS", but it still didn't really memorize the spell then start going through manually. I'm not all that familiar with /memspell, it's possible if you start a new memspell when the old spell is still cooling down from being memorized that it screws it up... but it's doubtfull.
Thu May 05, 2011 11:42 am
Project Lead
That seems to work. I had thought /memspell queued them up, but I guess it's not that smart. Thank you very much!
Thu May 05, 2011 12:26 pm
No problem, unfortunately most of it is fairly crude. That conditional delay then the if for confirmation makes reliable code that is pretty easy to produce, more-so when the chunk of code has a bunch of steps that are all dependant on the previous step working. I.E.

/step 1
/delay 10s ${Step1Worked}
/if (!${Step1Worked}) /return

/step 2
/delay 10s ${Step2Worked}
/if (!${Step2Worked}) /return

/step 3
/delay 10s ${Step3Worked}
/if (!${Step3Worked}) /return
Thu May 05, 2011 12:35 pm
Project Lead
- Maudigan
EDIT: sorvani auto corrected on my phone as servant... a rather unfortunate auto correct, no offense sorvani =)

Owning an iPhone myself, I am familiar with that auto correct. A pain in the ass when signing in to sites on my phone until I added it to the dictionary.

- vfinger
Now, some folks will wonder why in the world I wouldn't just use EQ's built in spellset. For some reason, most of my character UI's (using default UI) are borked, such that "newer" implementations of right-click functionality doesn't work. I can loot corpses and open tradeskill containers and such, but I cannot access the chat window menu or memorize spells with right-click. So, I need a macro if I don't want to open the spellbook and find my spells for all my characters.

You know there is a setting in game for "Allow Context Menus" and it kills all of that if you turn it off.
_________________
Sorvani
Thu May 05, 2011 8:41 pm
Senior Project Member
MQ2Cast has built in functionality to do this. Admittedly I've never tried to use it. From http://www.macroquest2.com/wiki/index.php/MQ2Cast#.2Fsss


/sss
Spell Set Save - This will save your any number of your currently memmed spells into a spell set.

Syntax:
/sss "name" [gems]
Name is what you want your spell set to be called. If no gems are specified, all your gems are saved (ie. 123456789). You can specify a smaller subset if needed.
/sss dps 1238
/sss wunshi 5
[edit]

/ssm
Spell Set Memorize - This will memorize a previously saved spell set.
/ssm dps
[edit]

/ssl
Spell Set List - This will list all spell sets that have been saved.
/ssl
[edit]

/ssd
Spell Set Delete - This will delete a spell set from the ini file.
/ssd wunshi
[edit]
Fri May 06, 2011 4:49 pm
Errors Help understanding /for loop mechanism
Reply