Foraging

SHV126

Lifetimer
Joined
Mar 11, 2006
Messages
129
Reaction score
1
Points
18
Location
St. Paul, Minnesota
I use a foraging macro based on YAFM but lately hasn't been able to trigger the /goto commands, which aren't in this example, moving toons to a different zone so thought I would try to figure it out and came up with the possible problem. I believe it is in the spellcast.inc. I also tried putting is the MQ2Cast_Spell_Routines.inc with the same results.

Code:
|
| SpellCast.inc
|
| Last Modified: 7/29/2005
| This will cast a spell reliably for you...
|
| Usage:
|       /call Cast "spellname|itemname|AA#|AAskillname" [item|activate|gem#] [nocheck|dismount|nodismount]
|
| If no dismount or nodismount is provided it defaults to nodismount.
|
| This would essentially: /cast "Death Peace"
| example: /call Cast "Death Peace"
|
| This would essentially: Check for the spell in your spell slots, if not there mem it to spell
|                         gem slot 7 and then /cast "Death Peace"
| example: /call Cast "Death Peace" gem7
|
| This would essentially: /cast item "White Rope Bridle"
| example: /call Cast "White Rope Bridle" item
|
| This would essentially: /alt activate 169
| example: /call Cast "169" activate
|  or...
| example: /call Cast "Divine Arbitration" activate
|
| This would dismount if your target was lost or dies mid-cast, cast Burn and mem it to spell
| slot 3 if it wasn't already memmed:
| example: /call Cast "Burn" gem3 dismount
|
| This would not dismount but would move you back and forth if your target was lost or dies mid-cast, cast Burn and mem
| it to spell slot 3 if it wasn't already memmed:
| example: /call Cast "Burn" gem3 nodismount
|
| 'nocheck' is the default for the "loss of target/target dying" value.  If nocheck is specified (Or nothing was specified)
| no target checking will be performed and spellcast.inc should act like the spellcast.inc of the past.
|
| It will return the following values:
| CAST_SUCCESS
| CAST_UNKNOWNSPELL
| CAST_OUTOFMANA
| CAST_OUTOFRANGE
| CAST_CANNOTSEE
| CAST_STUNNED
| CAST_RESISTED
| CAST_TOOK2LONG
| CAST_ABILITYNOTREADY
| CAST_IMMUNESLOW
| CAST_LOSTTARGET
|
| New Vars Modification
| Plazmic's no globals needed version
|
| Oct 09, 2003 - Updated to work with new vars and $char(casting) -gf
| Oct 11, 2003 - switched some logic, removed defines -gf
| Oct 15, 2003 - Item support added by -EqMule
| XXX xx, xxxx - Modified to add automeming of spells. -Goofmester1
| Dec 26, 2003 - fd fail 1 added -m0nk
| Jan 01, 2004 - timeout(5s) added to stop "dead-time" -m0nk
| Jan 01, 2004 - switchd fdfail to a standing check. -m0nk
| Jan 01, 2004 - added silence checking as a stun check -m0nk
| Feb 17, 2004 - added AA activate capabilities -ml2517
| Apr 11, 2004 - Updated for new Parm system -ml2517
| Apr 12, 2004 - Will spit out a different message on immune to slows. -ml2517
| Apr 16, 2004 - Removed /sendkeys and replaced with /keypress. -ml2517
| Apr 17, 2004 - Various code enhancements. -Wassup
| Apr 20, 2004 - Updated all of the /if's to have parenthesis. -ml2517
| Apr 25, 2004 - Updated to new variable system. -ml2517
| Apr 29, 2004 - Fixed Item problem -ml2517
| Apr 29, 2004 - Changed the alt ability to use AltAbilityReady instead of an event. -ml2517
| May 02, 2004 - Added the ability to specify a gem slot to mem spells to. -ml2517
| May 10, 2004 - Updated for new event system.
| May 12, 2004 - Added suggestions for loss of target and stun handling change. -ml2517
| May 13, 2004 - Activate now accepts AA skill by name or number. -ml2517
| May 14, 2004 - Added the nocheck value, it is the default. This bypasses the target checking code. -ml2517
| Jul 29, 2005 - Added some delay and hopefully fixed bugged spellbook -fearless
|

#event Fizzle "#*#Your spell fizzles#*#"
#event Interrupt "#*#Your casting has been interrupted#*#"
#event Interrupt "#*#Your spell is interrupted.#*#"
#event Recover "#*#You haven't recovered yet...#*#"
#event Recover "#*#Spell recovery time not yet met.#*#"
#event Resisted "#*#Your target resisted the #*#"
#event OutOfMana "#*#Insufficient Mana to cast this spell!#*#"
#event OutOfRange "#*#Your target is out of range, get closer!#*#"
#event NoLOS "#*#You cannot see your target.#*#"
#event Stunned "#*#You cannot cast while stunned#*#"
#event Stunned "#*#You *CANNOT* cast spells, you have been silenced!#*#"
#event Standing "#*#You must be standing to cast a spell#*#"
#event Standing "#*#has fallen to the ground.#*#"
#event Collapse "#*#Your gate is too unstable, and collapses.#*#"
#event ImmuneSlow "#*#Your target is immune to changes in its attack speed.#*#"
#event Collapses "#*#The portal collapses before you can escape!#*#"


Sub Cast(SpellName,ItemFlag,DismountFlag)
   /declare HaveTarget int local 0
   /declare CastBarTime timer local
   /declare CastCurrLocY float local 0
   /declare CastCurrLocX float local 0
   /varset CastCurrLocY ${Me.Y}
   /varset CastCurrLocX ${Me.X}
   /if (${Target.ID}>0) /varset HaveTarget 1
   /if (!${Defined[CastGiveUpTime]}) /declare CastGiveUpTime timer local
   /if (!${Defined[ItemFlag]}) /declare ItemFlag string local
   /if (!${Defined[DismountFlag]}) {
       /declare DismountFlag string local nocheck
       /if (${ItemFlag.Find["dismount"]}) /varset DismountFlag ${ItemFlag}
   }
   /if (!${Me.Standing} && !${Me.Mount.ID}>0) /stand
   /if (${Me.Moving}) {
       /keypress forward
       /keypress back
       /delay 8
   } else {
       /delay 4
   }
   /if (${ItemFlag.Equal["Item"]} || ${ItemFlag.Equal["Activate"]}) /goto :StartCast

   /if (!${Me.Gem["${SpellName}"]}) {
       /if (${ItemFlag.Find[gem]}) {
           /if (${Int[${ItemFlag.Right[1]}]}>0 && ${Int[${ItemFlag.Right[1]}]}<9) {
               /memspell ${ItemFlag.Right[1]} "${SpellName}"
               /delay 5s ${Me.Gem["${SpellName}"]}
               /if ( ${Window[SpellBookWnd].Open} ) /timed 20 /stand
           } else {
               /goto :GenericMem
           }
       } else {       
           :GenericMem
           /memspell 5 "${SpellName}"
           /delay 5s ${Me.Gem["${SpellName}"]}
           /if ( ${Window[SpellBookWnd].Open} ) /timed 20 /stand
       }

   }
   :StartCast
      /varset CastGiveUpTime 15s
   :CastNow
      /if (${ItemFlag.Equal["Item"]}) {
         /call ClearReturnValue
         /cast item "${SpellName}"
      } else /if (${ItemFlag.Equal["Activate"]}) {
         /call ClearReturnValue
         /if (!${Me.AltAbilityReady[${SpellName}]}) /return CAST_ABILITYNOTREADY
         /alt activate ${Me.AltAbility[${SpellName}].ID}
         /varset CastBarTime ${Me.Casting.CastTime}
      } else {
         /if (!${Me.Gem["${SpellName}"]}) /return CAST_UNKNOWNSPELL
         /call ClearReturnValue
         /if (!${Me.SpellReady["${SpellName}"]}) {
            /if (${CastGiveUpTime}==0) /return CAST_TOOK2LONG
            /delay 1
            /goto :CastNow
         }
         /cast "${SpellName}"
         /varset CastBarTime ${Math.Calc[${Me.Casting.CastTime}*10]}
      }
   :WaitCast
      /if (${Me.Casting.ID}) {
         /if ((!${Target.ID}>0 || ${Target.Type.Equal[CORPSE]}) && !${DismountFlag.Find[nocheck]} && ${HaveTarget}==1) {
             /if (${Me.Mount.ID}>0) {
                 /if (${DismountFlag.Equal[dismount]}) {
                     /dismount
                 } else {
                     /if (!${ItemFlag.Equal["Item"]}) {
                         /if (${CastBarTime}<7) {
                             :Interrupt
                             /keypress FORWARD hold
                             /delay 6
                             /keypress FORWARD
                             /keypress BACK hold
                             /delay 8
                             /keypress BACK
                         } else {
                             :HoldForSpell
                             /delay 1
                             /if (${CastBarTime}<7) /goto :Interrupt
                             /goto :HoldForSpell
                         }
                     } else {
                         /keypress FORWARD hold
                         :Forward
                         /delay 1
                         /if (${Math.Distance[${CastCurrLocY},${CastCurrLocX}]}<6) /goto :Forward
                         /keypress FORWARD
                         /keypress BACK hold
                         :Backward
                         /delay 1
                         /if (${Math.Distance[${CastCurrLocY},${CastCurrLocX}]}>4) /goto :Backward
                         /keypress BACK
                         /if (!${Me.Casting.ID}>0) /goto :DuckTime
                     }
                 }
             }
             :DuckTime
             /keypress FORWARD
             /keypress BACK
             /if (!${Me.Ducking}) /keypress DUCK
             /delay 1
             /if (${Me.Ducking}) /keypress DUCK
             /return CAST_LOSTTARGET
         }
         /delay 1
         /goto :WaitCast
      }
   /delay 1
   /doevents Fizzle
   /doevents Interrupt
   /doevents Interrupt
   /doevents Recover
   /doevents Standing
   /doevents OutOfRange
   /doevents OutOfMana
   /doevents NoLOS
   /doevents Resisted
   /doevents ImmuneSlow
   /doevents Stunned
   /doevents Collapse
   /doevents Collapses
   /if (${Macro.Return.Equal["CAST_RESTART"]}) /goto :StartCast
   /if (!${Macro.Return.Equal["NULL"]}) /return ${Macro.Return}
/return CAST_SUCCESS

Sub ClearReturnValue
/return NULL

Sub Event_Fizzle
/return CAST_RESTART

Sub Event_Interrupt
/return CAST_RESTART

Sub Event_Recover
   /delay 5
/return CAST_RESTART

Sub Event_Standing
   /stand
/return CAST_RESTART

Sub Event_Collapse
/return CAST_RESTART

Sub Event_Collapses
/return CAST_RESTART

Sub Event_OutOfMana
/return CAST_OUTOFMANA

Sub Event_OutOfRange
/return CAST_OUTOFRANGE

Sub Event_NoLOS
/return CAST_CANNOTSEE

Sub Event_Stunned
   /delay 2s !${Me.Stunned}
/return CAST_RESTART

Sub Event_Resisted
/return CAST_RESISTED

Sub Event_ImmuneSlow
/return CAST_IMMUNESLOW

this is a basic version of YAFM that I used to see what was going on and if you were to run this macro it will constantly sit and stand as it just continuously loops through the macro not stopping if the forage ability is not ready.

Code:
|yafm.mac 
| 
|Yet Another Forage Macro 
| 
|Ini File: yafm.ini 
| 
| 0 = destroy 
| x = keep at most x of this item 
| 
|New foraged items are added to the ini file automatically and are kept by default. 

#include spellcast.inc


|||||||||||||||||||| 
| Main 
|||||||||||||||||||| 
sub Main 

    /declare DefaultMaxSave int outer 

    /varset DefaultMaxSave ${Ini[yafm.ini,Default,MaxSave,${NotFound}]} 
    /if (${DefaultMaxSave}==${NotFound}) { 
       /ini "yafm.ini" "Default" "MaxSave" "19" 
        /varset DefaultMaxSave 19 
    } 

   /cleanup 

   | Verify that we have the ability to forage. 
   /if (${Me.Skill[Forage]}==0) { 
      /echo You cannot forage, silly person! 
      /goto :Exit 
   } 

   :Forage 

   | If we can forage then do so. 
   /if (${Me.AbilityReady[Forage]}) { 
      | Stand up.  Can't forage while sitting. 
      /if (${Me.State.NotEqual[STAND]}) { 
         /stand 
         /delay 10 
      } 

      /Call GM
      /call PCCheck
      /delay 1s
      /doability forage 
   } 

   | If we successfully foraged something then take care of it. 
   /if (${Cursor.ID}) { 
      /call HandleItem 

   } 

   /sit


   /goto :Forage

:Exit 
/return 

|||||||||||||||||||| 
| HandleItem 
|||||||||||||||||||| 
sub HandleItem 

   /declare ItemSetting int local 
   /declare NotFound int local 
   /declare ItemsHave int local 

   /varset NotFound -1 

   :LootIt 

   | Look up this item in yafm.ini 
   /varset ItemSetting ${Ini[yafm.ini,ForageList,${Cursor.Name},${NotFound}]} 
   /delay 5 

   | If the item isn't in the .ini file then add it. 
   /if (${ItemSetting}==${NotFound}) { 
       /ini "yafm.ini" "ForageList" "${Cursor.Name}" "${DefaultMaxSave}" 
       /varset ItemSetting ${DefaultMaxSave} 
   } 

   /varset ItemsHave ${FindItemCount[=${Cursor.Name}]}   

   | If we're keeping this item then stash it in our bags. 
   | Otherwise, just destroy it. 
   /if (${ItemSetting}>${ItemsHave}) { 
     /autoinventory 
   } else { 
     /destroy 
   } 

   /delay 5 
   /if (${Cursor.ID}) /goto :LootIt 

/return

   
|--
|##GM Sub for checking
|---------------------
Sub GM
	/if (${Spawn[gm].ID}) {
		/echo GM Detected, Camping to Desktop
                /icamp
		/endmac
	}
/return 

Sub PCCheck
          /if (${SpawnCount[pc radius 50]}==1) /return
          /beep
          /echo PC Detected within range, pausing macro...
          /popup PC Detected within range, pausing macro...
:PCCheck
          /delay 5s
          /if (${SpawnCount[pc radius 100]}>1) /goto :PCCheck
          /echo PC has left the area, resuming macro...
          /popup PC has left the area, resuming macro...
/return

This just started happening this week after the last release that I am aware of. I pretty much am just a copy and paste macro writer so any help in solving the continuous loop would be much appreciated. Thanks
 

Attachments

  • spellcast.inc
    9.6 KB · Views: 3
  • yafm.mac
    2.7 KB · Views: 7
I use a foraging macro based on YAFM but lately hasn't been able to trigger the /goto commands, which aren't in this example, moving toons to a different zone so thought I would try to figure it out and came up with the possible problem. I believe it is in the spellcast.inc. I also tried putting is the MQ2Cast_Spell_Routines.inc with the same results.

Code Redacted~

this is a basic version of YAFM that I used to see what was going on and if you were to run this macro it will constantly sit and stand as it just continuously loops through the macro not stopping if the forage ability is not ready.

Code Redacted~

This just started happening this week after the last release that I am aware of. I pretty much am just a copy and paste macro writer so any help in solving the continuous loop would be much appreciated. Thanks

TLDR ~ Make sure you don't have MQ2NoGoto plugin loaded. /goto and /moveto are not the same thing. One uses MQ2MoveUtils the other jumps from one location to another in code. Third, we can't fix the macro that you aren't showing us if you don't show it to us so I'm not sure why we are discussion theoretic issues. Fourth, I fixed the indents, but I didn't really fix much else other than a couple of case sensitive issues in the macro you aren't using. Fifth, SpellCast.inc isn't needed for this copy of YAFM.mac literally completely unnecessary and can be removed as an include. Sixth, download my files and use them. If you get errors for undeclared variables that should let you know what is wrong perhaps

/goto is used as a way to goto a keyword with : preceding it. IE:

Code:
:MyLabel
/if ( ${Me.Moving} ) /goto :MyLabel
/echo I am no longer moving!

If you're refering to /moveto which is a command for MQ2MoveUtils to cause your character to go to a new location from their current location, then those are two different things.

Also, /goto commands are strictly sub based. IE:

Code:
Sub a
    :MyLabel
    /if ( ${Me.Moving} ) /goto :MyLabel
    /echo I am no longer moving!
/return

Sub b
    :MyLabel
    /if ( ${Me.Moving} ) /goto :MyLabel
    /echo I am no longer moving!
/return

Should work fine because sub a can't call sub b's keyword, and sub b can't call sub a's keyword. They are what is called out of scope. They can't see the keyword of another sub. So I can use :MyLabel in each sub once without it causing any confusion inside the macro.

Be sure you aren't using a plugin like MQ2NoGoto if it is truely a /goto issue.

SpellCast.inc has zero to do with foraging. I check the code in it. I even got a copy with proper indenting now because I'm OCD a little.

With that said.
Code:
/if (${Math.Distance[${CastCurrLocY},${CastCurrLocX}]}<6) /goto :Forward

This happens twice. They make no sense. Perhaps it was intended to do a ${Target.Distance[]}

YAFM.mac ~~

Code:
   | Look up this item in yafm.ini 
   /varset ItemSetting ${Ini[yafm.ini,ForageList,${Cursor.Name},${NotFound}]} 
   /delay 5

Not found is "declared" but never /varset, so it is NULL, thus typically if it has never been assigned a value it may still be considered undefined. Try giving it a default value.

I've added #Warning to the top of the macro, this will let you know if you are encountering an undeclared variable and pause the macro if that is the case.

Undeclared variables are the bane of your existence. :)

If you find an undeclared variable, just prior to it's use

/if (!${Defined[NameofVarHere]}) /declare NameofVarHere type scope value


IE:

/if (!${Defined[NotFound]}) /declare NotFound int outer -1

Also I have a copy of YAFM.mac with proper indentation for ease of reading in the future. While you are a copy and paste coder, I'm a coder and it's painful to read code without the assistance of scope lines. So I've attached copies of the properly indented code.

In addition I changed /Call to /call and sub to Sub. Not sure if those are relevant, most coding languages are case sensitive. IE: ${Me.PctHps} is not the same as ${me.pcthps}
 

Attachments

  • SpellCast.inc
    8.5 KB · Views: 0
  • YAFM.mac
    2.6 KB · Views: 5
Last edited:
If I run the updated version that you put up it does the same thing that mine does. It constantly stands and sits which tells me the macro is looping all the time without stopping to wait for the ability to be ready to forage.
E
Also MQ2NoGoTo is not loaded, will post one that shows the working macro. This one is run in Ethernere Tainted West Karana.

Code:
#include common/CommonSubs.inc
#include spellcast.inc


Sub Main

    /declare Filename string outer Ethernere.ini    
    /declare ethernere int outer ${Param0}

   /call ReadINIA ${Filename} "Essence"
    /if (!${Defined[LocArray]}) {
        /echo No Loc Array Created...
        /endmacro
    }


    /if (${Zone.ID}==772) {
    /echo you are already in Ethernere Tainted West Karana
    /face heading 290 nolook
    /popup Dumb Dr00d!
    /call YAFMA
    }

    /memspellset crusadors
    /call Cast "Ring of West Karana
    /delay 10s
    /call Cast "Succor"
    /delay 6s
    /call Cast "Improved Superior Camouflage"
    /call movement 1 2 0
    /delay 2s
    /face heading 290 nolook
    /echo YAFM starting in 5 seconds...
    /memspellset Quellious Places
    /delay 5s
    /call YAFMA

sub YAFMA

    /declare DefaultMaxSave10 int outer 
    /declare Cnt int Local
    /declare NotFound int Local

    /varset NotFound -1


    /varset DefaultMaxSave10 ${Ini[yafm.ini,Default,MaxSave,${NotFound}]} 
    /if (${DefaultMaxSave10}==${NotFound}) { 
       /ini "yafm.ini" "Default" "MaxSave" "19" 
        /varset DefaultMaxSave1 19 
    } 

   /cleanup 

    /itemnotify pack8 rightmouseup
    /itemnotify pack3 rightmouseup
   | Verify that we have the ability to forage. 
   /if (${Me.Skill[Forage]}==0) { 
      /echo You cannot forage, silly person! 
      /goto :Exit 
   } 
   
   :Forage

   | If we can forage then do so. 
   /if (${Me.AbilityReady[Forage]}) { 
      | Stand up.  Can't forage while sitting. 
      /if (${Me.State.NotEqual[STAND]}) { 
         /stand 
         /delay 5 
      } 

      /call GM
      /call PCCheck
      /delay 1s
      /doability forage 
   } 

   | If we successfully foraged something then take care of it. 
   /if (${Cursor.ID}) { 
      /call HandleItem 

   /if (${FindItemCount[=Ethernere Essence]}>=${ethernere}) /call juice

   }
   
   /goto :Forage1
   
   :Forage1

   | If we can forage then do so. 
   /if (${Me.AbilityReady[Forage]}) { 
      | Stand up.  Can't forage while sitting. 
      /if (${Me.State.NotEqual[STAND]}) { 
         /stand 
         /delay 5 
      } 

      /call GM
      /call PCCheck
      /delay 1s
      /doability forage 
   } 

   | If we successfully foraged something then take care of it. 
   /if (${Cursor.ID}) { 
      /call HandleItem 

   }

   /goto :Forage

:Exit
/return

|||||||||||||||||||| 
| HandleItem 
|||||||||||||||||||| 
sub HandleItem 

   /declare ItemSetting int local 
   /declare NotFound int local 
   /declare ItemsHave int local 

   /varset NotFound -1 

   :LootIt 

   | Look up this item in yafm.ini 
   /varset ItemSetting ${Ini[yafm.ini,ForageList,${Cursor.Name},${NotFound}]} 
   /delay 5 

   | If the item isn't in the .ini file then add it. 
   /if (${ItemSetting}==${NotFound}) { 
       /ini "yafm.ini" "ForageList" "${Cursor.Name}" "${DefaultMaxSave}" 
       /varset ItemSetting ${DefaultMaxSave} 
   } 

   /varset ItemsHave ${FindItemCount[=${Cursor.Name}]} 

   | If we're keeping this item then stash it in our bags. 
   | Otherwise, just destroy it. 
   /if (${ItemSetting}>${ItemsHave}) { 
     /autoinventory 
   } else { 
     /destroy 
   } 

   /delay 5 
   /if (${Cursor.ID}) /goto :LootIt 

/return

Sub GM
	/if (${Spawn[gm].ID}) {
		/echo GM Detected, Camping To Desktop!
                /camp desktop
		/endmac
	}
/return 

Sub PCCheck
          /if (${SpawnCount[pc radius 50]}==1) /return
          /beep
          /echo PC Detected within range, pausing macro...
          /popup PC Detected within range, pausing macro...
:PCCheck
          /delay 5s
          /if (${SpawnCount[pc radius 100]}>1) /goto :PCCheck
          /echo PC has left the area, resuming macro...
          /popup PC has left the area, resuming macro...
/return

Sub juice
   
    /delay 5s
    /keypress 7

/return



 

/return
 
Last edited:
If I run the updated version that you put up it does the same thing that mine does. It constantly stands and sits which tells me the macro is looping all the time without stopping to wait for the ability to be ready to forage.


So no mention of undeclared variables??

Cuz I'm here to tell you that on the 3rd line of Sub Main you have an undeclared variable......
 
That isn't the problem though. If you were to correct the /declare NotFound int Local and /varset NotFound -1 you would be able to see that the toon will constantly stand up and sit down until the forage ability is ready, forage and continue to stand up and sit down until the next forage ability is ready.
 
Last edited: