advchant.mac, mq2datavaratized

A forum for you to dump all the macros you create, allowing users to use, modify, and comment on your work.

Moderator: MacroQuest Developers

User avatar
dont_know_at_all
Developer
Developer
Posts: 5450
Joined: Sun Dec 01, 2002 4:15 am
Location: Florida, USA
Contact:

advchant.mac, mq2datavaratized

Post by dont_know_at_all » Tue Apr 27, 2004 7:43 pm

Minamally tested. Killed a couple mobs but I'm not sure about the avoid list. Cleaned up some of the code since running it.

Code: Select all

| - chant.mac - By Raebis
|   - Mob avoidance added by ml2517
|   - MQ2Parmatized by dkaa
|   - MQ2Datatized by dkaa
|   - Obstacle avoidance by dkaa
|
| Version: REV5c(w/ avoidance mod) Jan 10 4:30pm
|
| This mac is used mostly for big open zones with not a lot of
| big hills (cause hills cause pain - unless you have levitate)
|
| Features:------------------------------------------------------------------------
|
| * Automatically selects high light blue, dark blue, or white mob
| * Runs to mob before targeting it (Stealth! No cross-zone targeting!)
| * Aggro/Add Detection: Automatically targets and kites aggroed mobs (adds)
| * Ignores greens and low light blues unless they are aggroed (adds)
| * Caster Detection: Automatically will switch target to aggroed casting mobs
| * Compatible with level 49 and level 6 selos
| * Auto Healing: If health gets low, it will automatically heal
| * Fleeing Mob Catcher: If mob runs away, macro keeps you in range!
| * Detects WMS (Warping Mob Syndrom) and gets a new target if a mob warps away!
| * NEW: Rubber Anchor: kites mobs closest to macro starting point - no wandering!
| * NEW: Mob avoidance by name.  Add/Remove from the list on the fly. (See the description of use below)
| * NEW: Script pausing upon startup or during the script. (See the description of use below)
| ---------------------------------------------------------------------------------
|
| usage: chant.mac <DOTs/LVL6 Selos> <49selo> <radius> [<heal song>] [<pause on startup>]
|
|
| Usage Examples:
|  -Scenario 1: If you are using...
|   ...DOTs in Gems 4, 5, 6, and 7
|   ...Level 49 Selo in Gem 2
|   ...Radius of 55
|   ...Hymn of Restoration in Gem 1
|   ...If you wanted the script to start paused
|   syntax: /mac chant 4567 2 55 1 1
|
|  -Scenario 2: If you are using...
|   ...DOTs in Gems 6 and 7
|   ...Level 6 Selo in gem 3
|   ...Radius of 80
|   ...Hymn of Restoration in gem 8
|   ...If you want the script to start un-paused
|   syntax: /mac chant 673 0 80 8 0
| 
|
| If <heal song> is defined then when health goes below ${Health}Min (default is 70%)
| it will replace the first song in <DOTs> with <heal song> until health is above
| ${Health}Max (default is 85%)
|
| If <pause on startup> is a 1 the script will pause upon startup so that you can add mobs to your avoid list.
| If <pause on startup> is a 0 the script will start immediately and go hunting.
| If you don't define <pause on startup> it assumes you want to immediately start hunting.
|
| If <selo> is 0 then the macro will not try to cast selos every 150 seconds
|
| Note about the rubber anchor:
|   The macro will target the mob closest to the RubberAnchor (your /loc when first
|   starting the macro)
|
| REV5b was Tested in EW for bout an hour
|
| Warning: You may wander from your starting point but after killing a mob, the
|          next mob that the macro targets will be closest to your starting point
|
| Note: Rev information moved to the top
|
| -----------------------------------------------------------------------------------
|
| New Commands:
| -------------
| /echo avoid add mobname 
| /echo avoid remove mobname
| /echo pause
|
| Examples:
| ---------
| /echo avoid add A Large Trout
| /echo avoid remove A Large Trout
| /echo pause
|
| When adding mobs to the avoidance list initially you can use the /echo pause command.
| This will pause the script but still allow you to target and add/remove the mobs you'd
| like to avoid/not avoid.  You can also pause the script upon startup by using the pause parameter.
|
| The best way to use the avoid add command is to use a hotkey with this:
|   /echo avoid add $target(name,clean)
|
| The best way to use the avoid remove command is to use a hotkey with this:
|   /echo avoid remove $target(name,clean)
|
| Then you simply run around the zone targeting mobs that you know you'd like to avoid and add/remove them
| to your avoidance list.  The list is written to an INI file so you won't have to add them to the list
| the next time you play.
|

#event NeedTarget "You must first select a target for this spell!"
#event Exp        "You gain "
#event Died       "You have entered"
#event Caster     " begins to cast a spell."
#event AddAvoid   "[MQ2] avoid add "
#event RemoveAvoid "[MQ2] avoid remove "
#event Pause "[MQ2] pause"
#event Tell       "tells you"

#turbo 40

Sub Main(string DOTs,string Selos,int CRadius,string Health,int Paused)
   /zapvars

   /if (!${Defined[CRadius]}) {
      /echo usage: chant.mac <DOTs, LVL6 Selos> <49selo> <radius> [<heal song>] 
      /return
   }

   /declare PauseFlag int outer

   /if (${Defined[Paused]}) {
       /if (${Paused}) {
           /varset PauseFlag 1
       } else {
           /varset PauseFlag 0
       }
   } else {
       /varset PauseFlag 0
   }

   /declare CirR outer

   /declare Songs[10] int outer
   /declare nSongs int outer
   /declare CurSong int outer
   /declare PrevSong int outer

   /declare Exper int outer
   /declare AAExp int outer

   /declare SongTimer timer outer
   /declare SeloSong int outer

   /declare HealSong int outer
   /declare OrigSong int outer

   /declare HealthMin outer
   /declare HealthMax outer

   /declare DBLevel outer

   /declare TargetUpNext int outer

   /declare RubberX int outer
   /declare RubberY int outer

   /declare AvoidList[50] string outer UNDEFINED-ARRAY-ELEMENT

   /declare MyXLOC float outer
   /declare MyYLOC float outer

   /declare ObstCount int outer
   /declare EachSong int local

   /call AvoidINILoad

   /varset PrevSong 0
   /varset MyXLOC 0.0
   /varset MyYLOC 0.0

   /varset nSongs ${DOTs.Length}
   /echo nSongs ${nSongs}
   /echo DOTs ${DOTs}
   /for EachSong 1 to ${nSongs}
      /varset Songs[${EachSong}] ${DOTs.Mid[${EachSong},1]}
      /echo Song ${EachSong}: ${Me.Gem[${Songs[${EachSong}]}].Name}
   /next EachSong

   /if (${Selos}!=0) {
      /varset SeloSong ${Selos}
      /echo Selo's: ${Me.Gem[${SeloSong}].Name}
   } else {
      /varset SeloSong 0
      /echo Not using level 49 Selos.
   }

   /newif (!${Defined[Health]}) {
      /echo No HealSong. Please watch your health.
      /varset HealSong 0
   } else /if (${Health}!=0) {
      /varset HealSong ${Health}
      /echo Healsong: ${Me.Gem[${HealSong}].Name}
   } else {
      /echo No HealSong. Please watch your health.
      /varset HealSong 0
   }

   /varset CirR ${CRadius}
   /echo Radius: ${CirR}

   /varset OrigSong ${Songs[1]}
   /varset CurSong 1
   /varset Exper ${Me.Exp}
   /varset AAExp ${Me.AAExp}
   /varset SongTimer 1

   |/varset DBLevel $int($calc($calc($char(level)*.75)+1))
   /varset DBLevel 35

   /varset HealthMin 70
   /varset HealthMax 85

   /varset TargetUpNext 0   
 
   /varset RubberX ${Me.X}
   /varset RubberY ${Me.Y}

   /echo Rubber Anchor dropped at ${RubberX},${RubberY}

   /if (${PauseFlag}==1) {
       /echo Script [PAUSED] issue an "/echo pause" to unpause it.
   }

:Loop

   /if (${PauseFlag}==1) {
       /delay 1
       /doevents AddAvoid
       /doevents RemoveAvoid
       /doevents Pause
       /goto :Loop
   }

   /if (${TargetUpNext}<=0) /if (!${Target.ID}) {
      /call GetTarget
      |/delay 2
   }

   /if (${TargetUpNext}>0) /if (${Target.ID}) {
      /echo User Selected Target or Aggroed while running
      /varset TargetUpNext 0
   }

   /if (${Target.Distance}>1000) /if (${Target.PctHPs}<=50) {
      /echo Target Warped... Getting a new target; id was ${Target.ID}
      /cleanup
      /call GetTarget
      /delay 2
   }

   /if (${HealSong}) /if (${Me.PctHPs}<${HealthMin}) {
      /if (${Songs[1]}!=${HealSong}) {
         /echo Healing On - Health: ${Me.PctHPs}% to ${HealthMax}%
         /varset Songs(1) ${HealSong}
      }
   }

   /if (${HealSong}) /if (${Me.PctHPs}>=${HealthMax}) {
      /if (${Songs[1]}!=${OrigSong}) {
         /echo Healing Off
         /varset Songs(1) ${OrigSong}
      }
   }
   |/delay 2
   /if (${SeloSong}) /if (!${Me.Casting.ID}) /if (!${Me.Buff[$Me.Gem[${SeloSong}].Name].Duration}) /varset SongTimer 1
   /if (${SongTimer}>0) /if (!${Me.Casting.ID}) /call SongFailed
   /call Circ
   /delay 1
   /doevents
   |/delay 1
   /goto :Loop
/return

Sub Event_Timer(string TimerName)
   /if (${String[${TimerName}].Equal[SongTimer]}) {
      | ${Me.Buff[${Me.Gem[4]}].ID}
      /if (${SeloSong}) /if (!${Me.Buff[${Me.Gem[${SeloSong}]}].ID}) {
         /echo Selos not up!!!
         /stopsong
         /cast ${SeloSong}
         /varset PrevSong 0
         /varset SongTimer 30
         /call Circ
         /doevents
         /return
      }

      | ${Me.Buff[${Me.Gem[4].Name}].Duration}<=6) {
      /if (${SeloSong}) /if (${Me.Buff[${Me.Gem[${SeloSong}].Name}].Duration}<=6) {
         /echo Selos about to die
         /stopsong
         /cast ${SeloSong}
         /varset PrevSong 0
         /varset SongTimer 30
         /call Circ
         /doevents
         /return
      }

      /delay 2
      /stopsong
      /echo ${CurSong} casting ${Songs[${CurSong}]}
      /cast ${Songs[${CurSong}]}
      /varset PrevSong ${CurSong}
      /varcalc CurSong ${CurSong}+1
      /varset SongTimer 30
      /call Circ
      /doevents
      /if (${CurSong}>${nSongs}) /varset CurSong 1
   }
/return

Sub Circ
   /declare CirX local
   /declare CirY local

   /call CheckObst

   /if (${Target.ID}) {
      /varset CirX ${Target.Y}
      /varset CirY ${Target.X}
   } else {

        /if (${TargetUpNext}!=0) {

            /varset CirX ${Spawn[ID ${TargetUpNext}].Y}
            /varset CirY ${Spawn[ID ${TargetUpNext}].X}

            /if (${Spawn[ID ${TargetUpNext}].Distance}<=${Math.Calc[${CirR}*2]}) {
                /if (${Target.ID}) {
                    /if (${Target.ID}!=${TargetUpNext}) {
                        /target id ${TargetUpNext}
                    }
                } else {
                    /target id ${TargetUpNext}
                }
                /varset TargetUpNext 0
            }
        }
   }

   /if (${Math.Distance[${CirX},${CirY}]}<${Math.Calc[${CirR}/2]}) {
      /face heading ${Math.Calc[${Heading[${CirX},${CirY}].DegreesCCW}+180]}
   } else {
      /face heading ${Math.Calc[${Heading[${CirX},${CirY}].DegreesCCW}+${Math.Calc[90*${CirR}/${Math.Distance[${CirX},${CirY}]}]}]}
   }
/return

Sub SongFailed
   /if (!${PrevSong}) {
      /varset SongTimer 1
      /return
   }
   /varset CurSong ${PrevSong}
   /varset SongTimer 1
/return

Sub Event_NeedTarget
   /if (${TargetUpNext}<=0) /call GetTarget
/return

Sub Event_Died
   /delay 10
   /sit
   /delay 10
   /camp desktop
/return

Sub Event_Exp
   /varset AAExp ${Math.Calc[${Me.AAExp}-${AAExp}]}
   /varset Exper ${Math.Calc[${Me.Exp}-${Exper}]}

   /echo EXP: ${Exper}:${Me.PctExp}% - AAXP: ${AAExp}:${Me.AAExp}% - ${Math.Calc[${Macro.RunTime}/60]} minutes

   /varset Exper ${Me.Exp}
   /varset AAExp ${Me.AAExp}

   /if (${TargetUpNext}==0) /if (${Target.ID}==0) /call GetTarget
/return

Sub GetTarget
   /declare LastMobID int local 0
   /declare FirstMobID int local 0
   /declare MobID int local 0
   /declare SRadius int local


   /varset MobID ${Spawn[npc radius ${Math.Calc[${CirR}*2]}].ID}
   /varset FirstMobID ${MobID}
   /echo MobID ${MobID}

   :CheckAggrodMobs
   /if (${MobID}!=0) {
       /if (${Spawn[ID ${MobID}].Speed}>100) {
          /call AvoidTargets ${MobID}
          /if (${Macro.Return}==1) {
             /target id ${MobID}
             /echo Kiting aggro'd mob: ${Target.CleanName}
             /return
          }
       }
       /varset LastMobID ${MobID}
       /varset MobID ${Spawn[npc id ${LastMobID} radius ${Math.Calc[${CirR}*2]} next].ID}
       /if (${FirstMobID}==${MobID}) {
           /goto :NoAggrodMobs
       }
       /goto :CheckAggrodMobs
       :NoAggrodMobs
   }

   /varset MobID 0
   /varset FirstMobID 0
   /varset LastMobID 0
   /for SRadius 0 to 10000 step 100
      /if (${MobID}==0) {
          /varset MobID ${Spawn[npc range ${DBLevel} ${Me.Level} loc ${RubberX} ${RubberY} radius ${SRadius}].ID}
          /varset FirstMobID ${MobID}
      } else {
          /varset LastMobID ${MobID}
          /varset MobID ${Spawn[npc range ${DBLevel} ${Me.Level} loc ${RubberX} ${RubberY} radius ${SRadius} next].ID}
          /if (${FirstMobID}==${MobID}) {
              /next SRadius
          }
      }
      /if (${MobID}!=0) {
         /call AvoidTargets ${MobID}
         /if (${Macro.Return}==1) {
            /goto :Done
         }
      }
   /next SRadius

   /varset MobID ${Spawn[npc]} 
   /echo No mobs found, action required!
   /beep
   /beep
   /beep
   /beep
:Done
   /varset TargetUpNext ${MobID}
   /echo Next: ${Spawn[ID ${MobID}].Level} ${Spawn[ID ${MobID}].CleanName} - Distance: ${Spawn[ID ${MobID}].Distance}
/return 



|#############################################################################


Sub AvoidTargets(int TempMobID)
    /declare Element int local 1

:AvoidCheckLoop

    /if (${AvoidList[${Element}].Equal[UNDEFINED-ARRAY-ELEMENT]}) {
        /return 1
    }

    /if (${AvoidList[${Element}].Equal[${Spawn[ID ${TempMobID}].CleanName}]}) {
        /return 0
    }
    /varcalc Element ${Element}+1
/goto :AvoidCheckLoop
/return 1


|#############################################################################


Sub AvoidINIRemove(string RemoveName)
/declare TempElements local 0
/declare TempVar int local 0
/declare TempItem string local

:RemCheckLoop
    /varset TempItem ${Ini[AvoidList.ini,Avoid,${TempVar},NOTFOUND]}
    /if (${TempItem.Equal[NULL]}) {
        | no file
        /goto :RemFoundInArray
    }
    /if (${TempItem.Equal[NOTFOUND]}) {
        /echo ${RemoveName} not in AvoidList.ini
        /goto :RemFoundInArray
    }

    /if ${RemoveName.Equal[${TempItem}]} {
        /varset AvoidList[${Math.Calc[${TempVar}+1]}] Empty  
        /echo ${RemoveName} removed from AvoidList.ini
        /ini AvoidList.ini Avoid ${TempVar} Empty
    :VerifyRemoval
        /if (!${Ini[AvoidList.ini,Avoid,${TempVar},NOTFOUND].Equal[Empty]}) {
            /echo verify removal unsuccessful
            /goto :VerifyRemoval
        }
        /goto :RemFoundInArray
    }
    /varcalc TempVar ${TempVar}+1
    /goto :RemCheckLoop
:RemFoundInArray
/return


|#############################################################################


Sub AvoidINIAdd(string AddName)
/declare TempElements int local 0
/declare TempVar int local 1
/declare TempItem string local

:AddCheckLoop
    /varset TempItem ${Ini[AvoidList.ini,Avoid,${TempVar},NOTFOUND]}

    /if (${TempItem.Equal[NULL]}) {
        | no file
        /goto :FoundInArray
    }

    /if (${TempItem.Equal[NOTFOUND]}) {
        /varset AvoidList[${Math.Calc[${TempVar}+1]}] ${AddName}
        /goto :AddItem
    }

    /if (${TempItem.Equal[${AddName}]}) {
        /echo ${AddName} already in AvoidList.ini
        /goto :FoundInArray
    }

    /if (${TempItem.Equal[Empty]}) {
        /varset AvoidList[${Math.Calc[${TempVar}+1]}] ${AddName}
        /goto :AddItem
    }

    /varcalc TempVar ${TempVar}+1
    /goto :AddCheckLoop

:AddItem

    /ini AvoidList.ini Avoid "${TempVar} ${AddName}

:VerifyAdd
    /if (!${Ini[AvoidList.ini,Avoid,${TempVar},NOTFOUND].Equal[${AddName}]}) {
        /echo verify addition unsuccessful
        /goto :VerifyAdd
    }

/echo ${AddName} added to AvoidList.ini

:FoundInArray
/return


|#############################################################################


Sub AvoidINILoad
/declare TempItem string local
/declare AvoidItemNum int local 0

:LoadAvoidLoop

    /varset TempItem ${Ini[AvoidList.ini,Avoid,${AvoidItemNum},NOTFOUND]}
    /if (${TempItem.Equal[NULL]}) {
        /goto :DoneLoading
    }
    /if (${TempItem.Equal[NOTFOUND]}) {
        /goto :DoneLoading
    }
    | note: indexing starts at 1 not 0
    /echo adding ${TempItem} to avoid list
    /varset AvoidList[${Math.Calc[${AvoidIndex}+1]}] ${TempItem}
    /varcalc AvoidItemNum ${AvoidItemNum}+1
    /goto :LoadAvoidLoop
:DoneLoading
/return


|#############################################################################


Sub Event_AddAvoid(string EvtText)
/if (${EvtText.Mid[6,10].Equal[avoid add ]}) {
    /call AvoidINIAdd "${EvtText.Mid[16,${Math.Calc[${EvtText.Length}-16]}]}"
}
/return

Sub Event_RemoveAvoid(EvtText)
/if (${EvtText.Mid[6,13].Equal[avoid remove ]}) {
    /call AvoidINIRemove "${EvtText.Mid[19,${Math.Calc[${EvtText.Length}-19]}]}"
}
/return

Sub Event_Pause(string EvtText)
/echo Sub Event_Pause(EvtText) ${EvtText}
/if (${EvtText.Mid[6,5)].Equal[pause]}) {
    /if n ${PauseFlag}==0 {
        /echo Script [PAUSED]
        /varset PauseFlag 1   
    } else {
        /echo Script [UNPAUSED]
        /varset PauseFlag 0
    }
}
/return

Sub Event_Caster(string CastText)
   /declare CasterID int local
   /varset CasterID ${Spawn[${CastText.Left[${Math.Calc[${String[${CastText}].Length}-24]}]}].ID}
   /if (!${Spawn[ID ${CasterID}].Type.Equal[NPC]}) /return
   /if (${Target.ID}==${CasterID}) /return
   /if (${Spawn[ID ${CasterID}].Distance}<=${Math.Calc[${CirR}*2]}) {
      /target id ${CasterID}
      /echo Targeting Caster: ${Target.CleanName}
   }
/return 

Sub Event_Tell
   /beep
   /mp3 play
   /doevents
/return

sub CheckObst
    /if (${MyXLOC}==${Me.X}) /if (${MyYLOC}==${Me.Y}) {
        /echo STUCK!!!
        /call HitObst 2
    }
    /varset MyXLOC ${Me.X}
    /varset MyYLOC ${Me.Y}
/return

sub HitObst
   /keypress up
   /keypress down hold
   /if (${Math.Rand[99]}>50) {

      /delay 2
      /keypress down 
      /keypress Right hold
      /delay 2
      /delay ${Param0}
      /keypress Right
   } else {
      /delay 2
      /keypress down 
      /keypress Left hold
      /delay 2
      /delay ${Param0}
      /keypress Left
   }
   /keypress down
   /keypress Right
   /keypress Left
   /keypress up
   /keypress num_lock
/return


GuardianX99
a lesser mummy
a lesser mummy
Posts: 43
Joined: Tue Dec 31, 2002 6:31 pm
Contact:

Post by GuardianX99 » Tue Apr 27, 2004 8:36 pm

I hate and love you in the same thought. I was changing this as well but I suckj at the new code system ATM

MrSmallie
a hill giant
a hill giant
Posts: 167
Joined: Fri Oct 11, 2002 11:18 am

Post by MrSmallie » Wed Apr 28, 2004 12:25 pm

I love disclaimers that say I tested it, it worked, then I changed some stuff. :lol:
Me
[img]http://home.comcast.net/~mrsmallie/ches.JPG[/img]

User avatar
dont_know_at_all
Developer
Developer
Posts: 5450
Joined: Sun Dec 01, 2002 4:15 am
Location: Florida, USA
Contact:

Post by dont_know_at_all » Wed Apr 28, 2004 1:02 pm

Well, i ran it again -- no problems.

Jerle69
a hill giant
a hill giant
Posts: 263
Joined: Wed Apr 28, 2004 3:26 pm

Really?

Post by Jerle69 » Wed Apr 28, 2004 3:33 pm

I have the April 27th code release of MQ2 compiled on my system and I tried this macro out last night. Two "bad things" occurred:

1) When I invoked the macro, it spat out the syntax help. I figured I missed a parameter or something. Doublechecked my invocation and found that I did, in fact, include the pause/nopause value on the end, even though the syntax help doesn't mention it (it is in the remarks at the beginning of the macro, though). Either way the code looked fine, even though it wasn't in the syntax help. Well, double checking and trying it two more times never would let me get past this point, so I commented out the ${Definined[Paused]} code in Sub Main because, well it WAS defined, and it never would get past it.

2) After forcing it to accept any parameters I gave it, it bombed on another problem: the declares:

Code: Select all

/declare PauseFlag int outer 
... it expected global or local or array or array2 or whathaveyou. I never did find anything about declaring variables with a particular datatype (such as int) nor did I find support for "outer" or "inner" (just global and local).

You said this works on your MQ2? How?

Thanks,
Jerle
--Jerle

User avatar
dont_know_at_all
Developer
Developer
Posts: 5450
Joined: Sun Dec 01, 2002 4:15 am
Location: Florida, USA
Contact:

Post by dont_know_at_all » Wed Apr 28, 2004 6:39 pm

Search for mq2datavars or
Scan the announcements or
Wait for Saturday.

Jerle69
a hill giant
a hill giant
Posts: 263
Joined: Wed Apr 28, 2004 3:26 pm

Thanks

Post by Jerle69 » Wed Apr 28, 2004 6:51 pm

Read about the MQ2DataVarization... Makes more sense now. Lax changes things faster than I keep up with the changes, I spose. I'll wait til the old /declare is depracated instead of activating datavarization in the distribution.

Thanks for coding ahead ;)
--Jerle