• You've discovered RedGuides 📕 an EverQuest multi-boxing community 🛡️🧙🗡️. We want you to play several EQ characters at once, come join us and say hello! 👋
  • IS THIS SITE UGLY? Change the look. To dismiss this notice, click the X --->
Complete Heal Chain - CHChain.mac

Utility Complete Heal Chain - CHChain.mac 1.5

Download now:  Join us with Level 2 access or earn your way in with  RedCents.
Other Authors
CTaylor22
Server Type
🏢 Live 🏘️ Emu TLP Test
Complete Heal Chain 1.11 beta Updated 08/19/2016

Beta Releases attached at the bottom of page:
* Current Version : CHCHAIN11.mac
* Original 1.0 beta is still attached as CHCHAIN.mac


-by RustyCat and CTaylor22 with friends input and feedback.​

*Note this macro is intend for Redguides community and you do not have permission to share on other websites.


Overview:

Macro is intended to set up a group of healers in a cycling heal chain in normal and patch heal modes. As healers join and leave the chain through events, the chain will shift and adjust accordingly to keep the chain going without heals stopping. They cast their spells with announcements, use mana regen spells assigned and sit to med until it's time repeat the process in normal mode. If a healer fizzles or dies, they announce and their following healer will adjust accordingly with fast heal messages to fill the gap also flagging patcher's to throw a heal out as well on the tank.​
*patch mode is not implemented as of yet.​


Requirements:

Redguides Very Vanilla Compile with default plugins loaded. MQ2EQBCS require with all healer connected to the same EQBCS server/channel.​

Instructions:

Target healer you intend to follow in your heal chain line up and type /mac CHChain <mode> <delay> <startingtank> (optional param's in works)​

IE. /mac CHChain normal 5 MightyWarrior​



After you got all the healers in the chain and you want to start them casting their heals. Create a hotkey /bc Start the chain with ${Target.CleanName}. Then Target one of the healers in the chain and press the hotkey​

Healers will have a custom INI file that maintains the characters specific heal spells and settings. If they are missing required spells, the macro will notify to correct and end.​

This macro uses Spell Gems 1 - 5. If a spell in the ini file is not memed the macro will mem the spell.​

Sample INI information as follows:
Rich (BB code):
[General]
Version=1.0
ChainRole=
ChainDelay=
RaidTarget=
ManaRegenOn=
Tank1=
Tank2=
Tank3=
Tank4=
Tank5=
[Spells]
BigHealSpell=
FastHealSpell=
HoTHealSpell=
PatchHealSpell=
ManaRegenSpell=



|* Example of current completion
----------------------------------------------------------
[General]
Version=1.0
ChainRole=normal         (normal/patch options, only normal implemented currently)
ChainDelay=3            (seconds of delay between starting big heal casts)
RaidTarget=                (future usage)
ManaRegenOn=1            (1/0 to use or not use mana regen spell before sitting)
Tank1=MightyWarrior        (First tank name, also assigned on macro start)
Tank2=NotAsMightyWarrior(Back up tanks here down in line up)
Tank3=NotMightyWarrior
Tank4=WeakWarrior
Tank5=Maskoi
[Spells]
BigHealSpell=Complete Heal
FastHealSpell=Ethereal Light
HoTHealSpell=Celestial Healing
PatchHealSpell=Remedy
ManaRegenSpell=Yaulp V
-----------------------------------------------------------
*|

Macro code current as follows:
Rich (BB code):
|
| CHChain.mac 1.11 beta Dated 08/19/16 by Rustycat and CTaylor22 (still being developed)
| ***Macro under development means, use at your own risk and test before you die to dragons!
|
| Current Paramaters that can be passed:
|     /CHChain.mac role delay big fast hot patch regen ini
|
| Requires healers to be logged into the same EQBC server to communication.
| Useage: Set up character specific INI with spell list to be used in heal chain.
| Target the healer you will be following in chain order and launch marco.
|
| Features: Healers in chain key off their chain assist when started and follows announcements
| for their turn to heal. If they fizzle, they cast their fast patch and the next healer
| keys in to start their heal right away to help close the hole made. Patch healers can now
| be configured to use Promise and HoT's as well as using their normal patches. Patch healers
| will look for low health players within range to try and patch heal the non-raidtank. All
| healers will look for all forms of mod rods within their inventory as mana levels trigger.
| If configured, healers can use mana regen spells such as Cleric Yaulps after casting
| their heal spells. Heal chain follows tank line up if the raidtank goes down automatically
| to the next configured tank.
|__________________________________________________________________________________________

#turbo

#Event  CastBigHeal "#*#::#1#:: casting chain heal #*# on #*#"
#Event  CastBigHeal "#*#::#1#:: I fizzled, casting fast patch instead."
#Event  CastBigHeal "#*#::#1#:: casting fast heal #*# on #*#"
#Event  SpellFizzle "Your spell fizzles!"
#Event  Idied       "You died."
#Event  Idied       "You have been slain by#*#"
#Event  ImOutAdjustment "#*#::#1#:: I'm out, adjust chain, I was after #2#"
#Event  JoinAdjustment  "#*#::#1#:: I'm joining the chain, assisting off #2#"
#Event  StartChain  "#*#Start the chain with #1#"
#Event  ChangeSettings "#*#::#1#:: Chain Gang Update Settings: #2# #3#"
#Event  RollCall "#*#::#1#:: Chain Gang Start Roll Call #2#"
#Event  RollCall "#*#::#1#:: Roll Call I Go After #2#"
#Event  SlashCMDs "[MQ2] SetCMD #1# #2#"
#Event  Timer       Timer1


Sub Main

    /declare TargetAssisted string outer ${Target.CleanName}
    /if (!${Target.ID} || ${Spawn[${Target.ID}].Type.NotEqual[pc]} || ${Target.ID}==${Me.ID}) {
       /echo You didn't target a PC. Target someone and restart.
       /end
    }
    /if (!${EQBC.Connected}) {
       /echo This macro requires a Connection to EQBC. Please check your settings and try again.
       /end      
    }
    /declare Pline               string outer      
    /declare TempInt             int    outer 0
    /declare TempStr             string outer
    /while (${Defined[Param${TempInt}]}) {
       /varset Pline ${Pline}|${Param${TempInt}}
       /varcalc TempInt ${TempInt}+1
    }



    /declare IniFileName         string outer null
    /call Parse_SingleParam "ini" "IniFileName"
    /if (${IniFileName.Equal[null]}) /varset IniFileName CHChain_${Me.CleanName}.ini

    |______________________________________________________________________________________________
    /declare Tank[5]                     string outer null
    /call LoadIni General Tank           string null Tank
   
    /call LoadIni General ChainRole      string normal
    /call LoadIni General ChainDelay     int    6
    /call LoadIni General RaidTarget     string
    /call LoadIni General ManaRegenOn    int    0
    |______________________________________________________________________________________________
    /call LoadIni Spells BigHealSpell    string null
    /call LoadIni Spells FastHealSpell   string null
    /call LoadIni Spells PatchHealSpell  string null
    /call LoadIni Spells HotHealSpell    string null
    /call LoadIni Spells PromiseHealSpell string null  
    /call LoadIni Spells ManaRegenSpell  string null
    /call LoadIni Spells HealLocalPct    string null
    |______________________________________________________________________________________________
    /squelch /alias /setrole      /echo SetCMD role
    /squelch /alias /setdelay     /echo SetCMD delay
    /squelch /alias /setbig       /echo SetCMD big
    /squelch /alias /setfast      /echo SetCMD fast
    /squelch /alias /sethot       /echo SetCMD hot
    /squelch /alias /setpromise   /echo SetCMD promise
    /squelch /alias /setpatch     /echo SetCMD patch
    /squelch /alias /setHealLocalPct     /echo SetCMD patch
    /squelch /alias /setregen     /echo SetCMD regen
    /squelch /alias /settank1     /echo SetCMD tank1
    /squelch /alias /settank2     /echo SetCMD tank2
    /squelch /alias /settank3     /echo SetCMD tank3
    /squelch /alias /chainstart   /echo SetCMD cstart
    /squelch /alias /chainpause   /echo SetCMD cpause
    /squelch /alias /saveini      /echo SetCMD saveini
    /squelch /alias /loadini      /echo SetCMD loadini
    |______________________________________________________________________________________________
    /declare CurrentTank         string outer
    /declare WhosCasting         string outer
    /declare CheckCasting        string outer
    /declare WhosCastingBefore   string outer
    /declare CastingWhat         string outer
    /declare ModRodToUse         string outer
    /declare BigHealTimer        timer  outer 0
    /declare ModRodCheckTimer    timer  outer 0
    /declare ii                  int    outer 0
    /declare jj                  int    outer 0
    /declare kk                  int    outer 0
    /declare TankSwitched        int    outer 0
    /declare ChainPaused         int    outer 1
    /declare bcManaCOL           int    outer 60
    /declare bcManaCOLInc        int    outer 10
    /declare lastManaLevel       int    outer
    /declare Medding             int    outer 0
    /declare Fizzled             int    outer 0
    /declare TriedCount          int    outer 0
    /declare FastHealRange  int outer   0
    /declare NearestPC  string  outer
   
    /call Parse_CommandLine
    /call INICheck
    /if (${ChainRole.NotEqual[patch]}) /bc ::${Me.CleanName}:: I'm joining the chain, assisting off ${TargetAssisted}
   
    :loop
    /call CheckCasting
    /if (${Window[RespawnWnd]}) /call Event_Idied
    /if (${Me.Standing} && !${Me.Mount.ID}) /sit
   
    /doevents
    |/delay 1s
    /call CheckTarget ${Target.ID} 0
    /call CheckMana
    /if (${TankSwitched}==1) {
   
        /if (${ChainRole.Equal[patch]}) {
            |This will have patch heals throw fast heals on the raid targets target, maybe it saves a ranger.... or not.
            /assist ${RaidTarget}
            /delay 5s ${Me.AssistComplete}==TRUE
            /call CastThis "${FastHealSpell}"
            |/cast "${FastHealSpell}"
        }
       | Maybe Checked whoCasting and cast a fast heal if your next in line?
       | funny thing is with the change to the /bc and including the ${Me.CleanName} you can trigger the heal for yourself
       | /bc ${TargetAssisted} The rest of the event message here.
        /rs Heads up, tank changed! Heal incoming on ${Target}!!!
    }
    /if (${ChainRole.Equal[patch]}) {
        /if (!${HoTHealSpell.Equal[NULL]}) /call CheckHot
        /if (!${PromiseHealSpell.Equal[NULL]}) /call CheckPromise
        /call HealLocals
    }
    /goto :loop
/return
:OnExit
   /if (${ChainRole.Equal[patch]}) {
        /bc I'm out, you're one patcher down!
    } else {
        /bc ::${Me.CleanName}:: I'm out, adjust chain, I was after ${TargetAssisted}   
    }
/return
|______________________________________________________________________________________________
Sub Event_RollCall(Line,SenderName,AssistName)
   /if (!${ChainPaused} || ${SenderName.Equal[${Me.CleanName}]}) /return
   /if (${AssistName.Equal[${Me.CleanName}]} && ${Line.Find[start roll call]}) {
      /bc +w+Starting Chain Roll Call:+x+
      /bc ::${Me.CleanName}:: Roll Call I Go After ${TargetAssisted}
      /varset TempInt 1
   }
   /if (${SenderName.Equal[${TargetAssisted}]}) {
      /if (!${TempInt}) {
         /bc ::${Me.CleanName}:: Roll Call I Go After ${TargetAssisted}
      } else {
         /varset TempInt 0
      }
   }
/return
|______________________________________________________________________________________________
Sub CheckMana
    /if (${Cursor.ID}>0) /autoinv
    /if (${Me.PctMana}>=80) /return
    /if (${Me.PctMana}<80 && ${Me.PctHPs}>25 && !${ModRodCheckTimer}) {
            /call UseRod
            /delay 5
            /return
        }
    /if (${Me.PctMana}<=${bcManaCOL} && ((${Me.PctMana}<${lastManaLevel} && ${Math.Calc[${lastManaLevel}-${Me.PctMana}]}>=${bcManaCOLInc}) || (${Me.PctMana}>${lastManaLevel} && ${Math.Calc[${Me.PctMana}-${lastManaLevel}]}>=${bcManaCOLInc}))) {
        /bc ::${Me.CleanName}:: Need some Luvin Current Mana at ${Me.PctMana}
        /rs Give me luvin, current Mana at ${Me.PctMana}
        /varset lastManaLevel ${Me.PctMana}
    }
    /if (${Me.PctMana}<${Math.Calc[${Spell[${BigHealSpell}].Mana}*2]}) {
        /varset Medding 1
        /bc ::${Me.CleanName}:: I'm out, adjust chain, I was after ${TargetAssisted}
        /bc I'm out of mana, medding up to 90%.
        :medloop
        /if (${Me.Standing} && !${Me.Mount.ID}) /sit
        /doevents ChangeSettings
        /doevents SlashCMDs
        /doevents ImOutAdjustment
        /if (${Me.PctMana}<80 && ${Me.PctHPs}>25 && !${ModRodCheckTimer}) {
            /if (${Cursor.ID}>0) /autoinv
            /call UseRod
            /delay 5
        }
        /if (${Me.PctMana}>90 && ${Medding}==1) {
            /target ${TargetAssisted}
            /doevents flush
            /bc ::${Me.CleanName}:: I'm joining the chain, assisting off ${TargetAssisted}
            /varset Medding 0
            /return
        } else {
            /delay 5
            /goto :medloop
        }
    }
/return
|______________________________________________________________________________________________
Sub CheckTarget(int cID, int Force)
   /if (!${Force} && ${cID} && ${Spawn[pc ${CurrentTank}].ID} && ${cID}==${Spawn[pc ${CurrentTank}].ID} && ${Target.Type.NotEqual[corpse]}) /return
   /for ii 1 to ${Tank.Size}
      /if (${CurrentTank.Equal[${Tank[${ii}]}]}) {
         | Check from Current Tanks position forward for next tank
         /varcalc jj ${ii}+1
         /for kk ${jj} to ${Tank.Size}
            /if (${jj}<=${Tank.Size} && ${Tank[${kk}].NotEqual[null]} && ${Spawn[pc ${Tank[${kk}]}].ID} && ${Spawn[pc ${Tank[${kk}]}].Type.NotEqual[corpse]}) {
               /target ${Tank[${jj}]}
               /varset CurrentTank ${Tank[${jj}]}
               /varset TankSwitched 1              
               /return
            }
         /next kk
         | We could not find a next tank in the lineup so lets start from the beginning.
         /varset jj ${ii}-1
         /for kk 1 to ${jj}
            /if (${jj}>0 && ${Tank[${kk}].NotEqual[null]} && ${Spawn[pc ${Tank[${kk}]}].ID} && ${Spawn[pc ${Tank[${kk}]}].Type.NotEqual[corpse]}) {
               /target ${Tank[${jj}]}
               /varset CurrentTank ${Tank[${jj}]}
               /varset TankSwitched 1              
               /return
            }
         /next kk
         | We are in deep shit! There was NO Tank in the lineup that was ready. Just bend over and kiss your ass good bye.
         /varset TankSwitched 2
      }
      /next
/return
|______________________________________________________________________________________________
Sub Event_CastBigHeal(Line,CasterName)
    |/echo ${Line} ${CasterName} ${TargetAssisted}
    /if (${Medding}==1) /return
    /if (${ChainRole.Equal[patch]} && ${Line.Find[fast]}) {
        /target ${CurrentTank}
        /delay 5
        /call CastThis "${PatchHealSpell}"
        |/cast "${PatchHealSpell}"
        /return
    }
    /if (${WhosCasting.NotEqual[${CasterName}]}) /vardata CheckCasting WhosCasting
    /vardata WhosCasting CasterName
    /if (${CasterName.NotEqual[${TargetAssisted}]}) /return
    |/echo I am setting cast timer because of ${TargetAssisted}
    /if (${ChainPaused}) /varset ChainPaused 0
    /if (${Line.Find[fizzled]}) {
       /varset BigHealTimer 1
    } else {
       /varset BigHealTimer ${ChainDelay}s
    }
    /vardata WhosCastingBefore CheckCasting
    |/echo Cast Timer set to ${ChainDelay}
/return
|______________________________________________________________________________________________
Sub HealLocals
   | NearestSpawn[1,pc] will always be you, so start at 2.
   /varset NearestPC 2
   /varset FastHealRange ${FastHealSpell}.Range
   | Using variable to set the patch heal radius based on the range of the fastheal they're going to cast.
   /varset TempInt ${NearestSpawn[2,pc radius ${FastHealRange}].ID}
   |Do this as long as we have a spawn ID.
   /while (${TempInt}) {
      | If you just finished casting something. You need to wait for Global cool down to expire.
      | If you don't add this, you will most likely only heal the first character needing a heal and skip the rest'
      | Added coolDown check in the CastThis routine
      | check if the spawn is not a corpse and their HP's are less than healchecklevel(??) needs to be determined and it is NOT the current tank.'
      /if (${Spawn[id ${TempInt}].Type.NotEqual[corpse]} && ${Spawn[id ${TempInt}].PctHPs}<${HealLocalPct} && ${Spawn[${CurrentTank}].ID}!=${TempInt}) {
         /target id ${TempInt}
         /delay 5
         /if (${Me.SpellReady[${FastHealSpell}]}) {
            /call CastThis ${FastHealSpell}
            |/cast ${FastHealSpell}
            /rs Tossing a heal on ${Target}
         }
      }
      | get the next spawn in the list TempInt will be null or 0 when getting past the end of the spawn list.     
      /varcalc NearestPC ${NearestPC}+1
      /varset TempInt ${NearestSpawn[${NearestPC},pc radius ${FastHealRange}].ID}
   }
/return
|______________________________________________________________________________________________
Sub Event_ChangeSettings(Line,SenderName,varName,varData)
   |May want to a check the SenderName to make sure someone isn't trying to screw with us.
   /if (!${varName.Length}) /return
   /if (${Defined[${varName}]}) /varset ${varName} ${varData}
/return
|______________________________________________________________________________________________
Sub Event_SpellFizzle
    /varset Fizzled 1
    /if (${CastingWhat.NotEqual[${BigHealSpell}]}) /return
    |/cast "${FastHealSpell}"
    /bc ::${Me.CleanName}:: I fizzled, casting fast patch instead.
    /rs Next tank be ready if heal misses!
    /varset Fizzled 2
/return
|______________________________________________________________________________________________
Sub UseRod
    /if (${FindItem[Summoned: Modulating Rod].InvSlot} && ${FindItem[Summoned: Modulating Rod].TimerReady} == 0) {
        /varset ModRodToUse Summoned: Modulating Rod
    } else /if (${FindItem[Rod of Mystical Transvergence].InvSlot} && ${FindItem[Rod of Mystical Transvergence].TimerReady} == 0) {
        /varset ModRodToUse Rod of Mystical Transvergence
    } else /if (${FindItem[Wand of Elemental Transvergence].InvSlot} && ${FindItem[Wand of Elemental Transvergence].TimerReady} == 0) {
        /varset ModRodToUse Wand of Elemental Transvergence
    } else /if (${FindItem[Rod of Prime Transvergence].InvSlot} && ${FindItem[Rod of Prime Transvergence].TimerReady} == 0) {
        /varset ModRodToUse Rod of Prime Transvergence
    } else /if (${FindItem[Rod of Ethereal Transvergence].InvSlot} && ${FindItem[Rod of Ethereal Transvergence].TimerReady} == 0) {
        /varset ModRodToUse Rod of Ethereal Transvergence
    } else /if (${FindItem[Rod of Spectral Transvergence].InvSlot} && ${FindItem[Rod of Spectral Transvergence].TimerReady} == 0) {
        /varset ModRodToUse Rod of Spectral Transvergence
    } else /if (${FindItem[Rod of Arcane Transvergence].InvSlot} && ${FindItem[Rod of Arcane Transvergence].TimerReady} == 0) {
        /varset ModRodToUse Rod of Arcane Transvergence
    } else /if (${FindItem[Summoned: Large Modulation Shard].InvSlot} && ${FindItem[Summoned: Large Modulation Shard].TimerReady} == 0) {
        /varset ModRodToUse Summoned: Large Modulation Shard
    } else /if (${FindItem[Summoned: Medium Modulation Shard].InvSlot} && ${FindItem[Summoned: Medium Modulation Shard].TimerReady} == 0) {
        /varset ModRodToUse Summoned: Medium Modulation Shard
    } else /if (${FindItem[Summoned: Small Modulation Shard].InvSlot} && ${FindItem[Summoned: Small Modulation Shard].TimerReady} == 0) {
        /varset ModRodToUse Summoned: Small Modulation Shard
    } else /if (${FindItem[Summoned: Giant Modulation Shard].InvSlot} && ${FindItem[Summoned: Giant Modulation Shard].TimerReady} == 0) {
        /varset ModRodToUse Summoned: Giant Modulation Shard
    } else /if (${FindItem[Wand of Pelagic Modulation].InvSlot} && ${FindItem[Wand of Pelagic Modulation].TimerReady} == 0) {
        /varset ModRodToUse Wand of Pelagic Modulation
    } else /if (${FindItem[Wand of Palegic Transvergence].InvSlot} && ${FindItem[Wand of Palegic Transvergence].TimerReady} == 0) {
        /varset ModRodToUse Wand of Palegic Transvergence
    } else {
        /varset ModRodToUse
        /varset ModRodCheckTimer 5s
    }
    /if (${ModRodToUse.Length}) {
        /call CheckStance
        /nomodkey /itemnotify "${ModRodToUse}" rightmouseup
    }
   
/return
|______________________________________________________________________________________________
Sub CheckHoT
   | Check for timer and if timer has expired
   /if (${Defined[HOT${Target.ID}]} && ${HOT${Target.ID}}) /return
   /call CastThis ${HotHealSpell}
   |/cast ${HotHealSpell}
   /delay 5
   | Create a timer variable for each character you cast a HOT on.
   /if (!${Defined[HOT${Target.ID}]}) /declare HOT${Target.ID} timer outer 0
   /varcalc HOT${Target.ID} ${Spell[${TempStr}].Duration.TotalSeconds}*10
/return
|______________________________________________________________________________________________
Sub CheckPromise
    | If no second arg then
    /if (!${PromiseHealSpell.Arg[2|].Length}) {
       /varset TempStr ${PromiseHealSpell}
    } else {
    | if there was a second arg then
       /varset TempStr ${PromiseHealSpell.Arg[2,|]}
    }
    /if (${Target.Buff[${TempStr}].ID}) /return
    /call CastThis "${PromiseHealSpell.Arg[1,|]}"
    |/cast ${PromiseHealSpell.Arg[1,|]}
/return
|______________________________________________________________________________________________
Sub Event_Timer(Timer, OriginalValue)
   /if (${Timer.Equal[BigHealTimer]}) {
      /if (${Me.Sitting} && !${Me.Mount.ID}) /stand
      |/if (${ChainPaused}) /varset ChainPaused 0
      /if (!${TankSwitched}) {
         /if (!${ChainPaused}) /bc ::${Me.CleanName}:: casting chain heal spell ${BigHealSpell} on ${Target.Name}
         /call CastThis "${BigHealSpell}"
         |/cast "${BigHealSpell}"
      } else /if (${TankSwitched}==1) {
         | may not need To check TankSwitched for fast healing, just including code here for now.
         /if (!${ChainPaused}) /bc casting fast heal spell ${FastHealSpell} on ${Target.Name}
         /call CastThis "${FastHealSpell}"
         |/cast "${FastHealSpell}"
         /varset TankSwitched 0
      }
      /if (${Math.Calc[${Spell[${BigHealSpell}].Range}*.90]}<=${Target.Distance}) {
         /bc Target ${Target.Name} is close too or OOR. Big Spell Range: ${Spell[${BigHealSpell}].Range} Target Distance: ${Target.Distance}
         /rs Target ${Target.Name} is close too or OOR. Big Spell Range: ${Spell[${BigHealSpell}].Range} Target Distance: ${Target.Distance}
      }
      /if (${Math.Calc[${Spell[${FastHealSpell}].Range}*.90]}<=${Target.Distance}) {
         /bc Target ${Target.Name} is close too or OOR. Fast Spell Range: ${Spell[${FastHealSpell}].Range} Target Distance: ${Target.Distance}
         /rs Target ${Target.Name} is close too or OOR. Fast Spell Range: ${Spell[${FastHealSpell}].Range} Target Distance: ${Target.Distance}
      }
    }
/return
|______________________________________________________________________________________________
Sub Event_Idied
    /if (${ChainRole.NotEqual[patch]}) /bc ::${Me.CleanName}:: I'm out, adjust chain, I was after ${TargetAssisted}
    /rs I died, chain adjusting
    /end
/return
|______________________________________________________________________________________________
Sub Event_ImOutAdjustment(Announcement,ChainAdjuster,NewAssist)
    /if (${ChainAdjuster.Equal[${TargetAssisted}]}) {
        /varset TargetAssisted ${NewAssist}
        /echo Assisting off ${TargetAssisted} now.
        /if (${Medding}) /return
        /if (${WhosCasting.Equal[${NewAssist}]}) {
           /if (${Me.Sitting} && !${Me.Mount.ID}) /stand
           /bc ::${Me.CleanName}:: casting fast heal ${FastHealSpell} on ${Target.Name}
           /call CastThis "${FastHealSpell}"
           |/cast "${FastHealSpell}"
        }
        /return
    }
   
    /echo Still assisting off ${TargetAssisted}
/return
|______________________________________________________________________________________________
Sub Event_Joinadjustment(Announcement,NewAssist,ChainAdjuster)
    /if (${NewAssist.Equal[${Me.Name}]}) /return
    /if (${ChainAdjuster.Equal[${TargetAssisted}]}) {
        /varset TargetAssisted ${NewAssist}
        /echo Assisting off ${TargetAssisted} now.
        /return
        }
    /echo Still assisting off ${TargetAssisted}
/return
|______________________________________________________________________________________________
Sub Event_StartChain(Announcement,ChainStarter)
    /if (${ChainStarter.NotEqual[${Me.Name}]} || !${ChainPaused}) /return
        /if (${Me.Sitting} && !${Me.Mount.ID}) /stand
        /bc ::${Me.CleanName}:: casting chain heal ${BigHealSpell} on ${Target.Name}
        /call CastThis "${BigHealSpell}"
        |/cast "${BigHealSpell}"
        /varset ChainPaused 0
/return
|______________________________________________________________________________________________
Sub Event_SlashCMDs(Line,varName,varData)

    /if (!${varName.Length} || !${varData.Length}) /return
    /echo past point 1
    /if (${varName.Equal[role]}) {
      /varset ChainRole ${varData}
   } else /if (${varName.Equal[delay]}) {
      /varset ChainDelay ${varData}
   } else /if (${varName.Equal[big]}) {
      /varset BigHealSpell ${varData}
   } else /if (${varName.Equal[fast]}) {
      /varset FastHealSpell ${varData}
   } else /if (${varName.Equal[hot]}) {
      /varset HotHealSpell ${varData}
   } else /if (${varName.Equal[patch]}) {
      /varset PatchHealSpell ${varData}
   } else /if (${varName.Equal[regen]}) {
      /varset ManaRegenSpell ${varData}
   } else /if (${varName.Equal[tank1]}) {
      /varset Tank[1] ${varData}
      /varset CurrentTank ${Tank[1]}
      /echo CurrentTank is now ${Tank[1]}
   } else /if (${varName.Equal[tank2]}) {
      /varset Tank[2] ${varData}
   } else /if (${varName.Equal[tank3]}) {
      /varset Tank[3] ${varData}
   } else /if (${varName.Equal[cstart]}) {
      /if (${ChainPause}) {
         /bc ::${Me.CleanName}:: Chain Gang Update Settings: ChainPause 0
         /delay 1s
         /doevents Event_ChangeSettings
         /bc ::${Me.CleanName}:: casting chain heal spell ${BigHealSpell} on ${Target.Name}
         /call CastThis "${BigHealSpell}"
         |/cast "${BigHealSpell}"
      }
   } else /if (${varName.Equal[cpause]}) {
      /if (${ChainPause}) {
         /bc ::${Me.CleanName}:: Chain Gang Update Settings: ChainPause 1
         /delay 1s
         /doevents Event_ChangeSettings
      }
   } else /if (${varName.Equal[saveini]}) {
      /call INIWrite
   } else /if (${varName.Equal[loadini]}) {
      /target ${TargetAssisted}
      /mac CHChain
   }
/return
|______________________________________________________________________________________________
Sub INICheck
    /varset CurrentTank ${Tank[1]}
    /echo My starting tank is ${CurrentTank}
    /target ${CurrentTank}
    /delay 5s ${Target.BuffsPopulated}==TRUE
    /if (!${Target.ID} || ${Spawn[${Target.ID}].Type.NotEqual[pc]} || ${Spawn[${Target.ID}].Type.Equal[corpse]} || ${Target.ID}==${Me.ID}) {
            /echo Can't target your tank, make sure it's correct.
            /endmacro
        }

    /echo Chain heal spell is ${BigHealSpell}
    /if (${BigHealSpell.Equal[NULL]} || !${Me.Book[${BigHealSpell}]}) {
        /echo Invalid BigHealSpell Heal. Please check ini file or command line param.
        /endmacro
        }
    /call MemSpells 1 "${BigHealSpell}"
    /echo Fast heal spell is ${FastHealSpell}
    /if (${FastHealSpell.Equal[NULL]} || !${Me.Book[${FastHealSpell}]}) {
        /echo Invalid FastHealSpell Heal. Please check ini file or command line param.
        /endmacro
        }  
    /call MemSpells 2 "${FastHealSpell}"
    /echo HoT heal spell is ${HoTHealSpell}
    /if (${HoTHealSpell.Equal[NULL]} || !${Me.Book[${HotHealSpell}]}) {
        /echo No HoT Heal assigned. If you intend to have one, please check ini file or command line param.
        }
    /call MemSpells 3 "${HotHealSpell}"
    /echo Patch heal spell is ${PatchHealSpell}
    /if (${PatchHealSpell.NotEqual[NULL]} && !${Me.Book[${PatchHealSpell}]}) {
        /echo Invalid PatchHealSpell Heal. Please check ini file or command line param.
        /endmacro
    }
    /call MemSpells 4 "${PatchHealSpell}"
    /echo Promise heal spell is ${PromiseHealSpell}
    /if (${PromiseHealSpell.NotEqual[NULL]} && !${Me.Book[${PatchHealSpell}]}) {
        /echo No Promise Heal assigned. If you intend to have one, please check ini file or command line param.
        /endmacro
    }
    /call MemSpells 5 "${PromiseHealSpell}"
    /echo ManaRegen spell is ${ManaRegenSpell}
    /if (${ManaRegenOn} && ${ManaRegenSpell.NotEqual[NULL]} && (${Me.Book[${ManaRegenSpell}]} || ${Me.AltAbility[${ManaRegenSpell}].ID})) {
       /call MemSpells 6 "${ManaRegenSpell}"
    }
/return
|______________________________________________________________________________________________
Sub LoadIni(string sectionName, string varName, string varType, string varValue, string varArray, string FileName)
    /echo Loading your current INI settings.
    | Assign ini name to default ini if not defined
    /if (${FileName.Length}==0) {
        /declare FileName string local
        /varset FileName ${IniFileName}
    }
    | Check if ini value is asking for an array.
    /if (${${varArray}.Size}>0) {
       /declare ii int local
       /for ii 1 to ${${varArray}.Size}
          /if (!${Ini[${FileName},${sectionName},${varArray}${ii}].Length}) /ini "${FileName}" "${sectionName}" "${varArray}${ii}" "${varValue}"
          /if (${Ini[${FileName},${sectionName},${varArray}${ii}].Length}) /varset ${varArray}[${ii}]  ${Ini[${FileName},${sectionName},${varArray}${ii}]}
          /if (${${varArray}[${ii}].NotEqual[null]}) {
             | find out if there is a Rank and fix spell name.
             /if (${varType.Equal[string]} && ${Int[${${varArray}[${ii}].Left[1]}]}==0 ) {
                /if (${Me.Book[${${varArray}[${ii}]}]} || ${Me.Book[${Spell[${${varArray}[${ii}]}].RankName}]}) {
                   /varset ${varArray}[${ii}] ${Spell[${${varArray}[${ii}]}].RankName}
                }
             }
          }
       /next ii
       /return
    } else {
       /if (!${Defined[${varName}]} && ${Defined[varType]}) /declare ${varName} ${varType} outer
       /if (!${Ini[${FileName},${sectionName},${varName}].Length}) {
          /if (${varValue.Length}) {
             /ini "${FileName}" "${sectionName}" "${varName}" "${varValue}"
             /varset ${varName} ${varValue}
          }
       } else {
          /varset ${varName} ${Ini[${FileName},${sectionName},${varName}]}
       }
       | find out if there is a Rank and fix spell name.
       /varset TempStr ${varName}
       /echo ${TempStr} ${varName} ${${varName}}
       /if (${varType.Equal[string]} && ${Int[${TempStr.Left[1]}]}==0 && !${varName.Find[Help]}) {
          /if (${Me.Book[${TempStr}].ID} || ${Me.Book[${TempStr}].Spell.RankName}) {
             /varset ${varName} ${Me.Book[${TempStr}].Spell.RankName}
          }
       }
       |/echo ${varName} - ${${varName}}
    }
/return
|______________________________________________________________________________________________
| /CHChain.mac role delay big fast hot promise regen ini
Sub Parse_CommandLine
   /varset TempInt 1
   /if (${Select[${Pline.Arg[${TempInt},|]},role,delay,ini]}) {
      /while (${Int[${Pline.Arg[${TempInt},|].Length}]}) {
         /if (${Pline.Arg[${TempInt},|].Equal[role]}) {
            /varset ChainRole ${Pline.Arg[${TempInt}+1,|]}
         } else /if (${Pline.Arg[${TempInt},|].Equal[delay]}) {
            /varset ChainDelay ${Pline.Arg[${TempInt}+1,|]}
         } else /if (${Pline.Arg[${TempInt},|].Equal[tank]}) {
            /varset Tank[1] ${Pline.Arg[${TempInt}+1,|]}
         } else /if (${Pline.Arg[${TempInt},|].Equal[ini]}) {
            /varset IniFileName ${Pline.Arg[${TempInt}+1,|]}
         }
         /varcalc TempInt ${TempInt}+2
      }
   } else {
      /if (${Pline.Arg[1,|].NotEqual[null]}) /varset ChainRole ${Pline.Arg[1,|]}
      /if (${Pline.Arg[2,|].NotEqual[null]}) /varset ChainDelay ${Pline.Arg[2,|]}
      /if (${Pline.Arg[3,|].NotEqual[null]}) /varset Tank[1] ${Pline.Arg[3,|]}
      /if (${Pline.Arg[4,|].NotEqual[null]}) /varset IniFileName ${Pline.Arg[4,|]}
   }
/return
|______________________________________________________________________________________________
Sub Parse_SingleParam(string pToFind, string varName)
   /if (!${Pline.Find[${pToFind}|]}) {
      /if (${pToFind.Equal[role|]} && ${Pline.Arg[1,|].NotEqual[null]}) /varset ChainRole ${Pline.Arg[1,|]}
      /if (${pToFind.Equal[delay|]} && ${Pline.Arg[2,|].NotEqual[null]}) /varset ChainDelay ${Pline.Arg[2,|]}
      /if (${pToFind.Equal[tank|]} && ${Pline.Arg[3,|].NotEqual[null]}) /varset Tank[1] ${Pline.Arg[3,|]}
      /if (${pToFind.Equal[ini|]} && ${Pline.Arg[4,|].NotEqual[null]}) /varset IniFileName ${Pline.Arg[4,|]}
      /return
   }
   /varset TempInt 1
   /if (${Int[${pToFind.Length}]} && ${Int[${varName.Length}]}) {
      /while (${Int[${Pline.Arg[${TempInt},|].Length}]}) {
         /if (${Pline.Arg[${TempInt},|].Equal[${pToFind}]}) /varset ${varName} ${Pline.Arg[${TempInt}+1,|]}
         /varcalc TempInt ${TempInt}+2
      }
      /return
   }
/return
|______________________________________________________________________________________________
Sub MemSpells(int i, pGem)
/echo ${i} ${pGem} ${Int[${Me.Gem[${pGem}]}]} ${Int[${Me.Gem[${i}].ID}]} ${Spell[${pGem}].ID}
   /if (${Int[${Me.Gem[${pGem}]}]}==${i} || ${Int[${Me.Gem[${pGem}]}]}>5) /return
   /if (${pGem.Length} && ${pGem.NotEqual[null]}) {
      /while (${Int[${Me.Gem[${i}].ID}]}!=${Spell[${pGem}].ID}) {
         /memorize "${pGem}" gem${i}
         /delay 10 ${Int[${Me.Gem[${i}].ID}]}==${Spell[${pGem}].ID}
      }
   }
/return
|__________________________________________________________________________________________
Sub INIWrite

    /ini IniFileName General ChainRole ${ChainRole}
    /ini IniFileName General ChainDelay ${ChainDelay}
    /ini IniFileName General RaidTarget ${RaidTarget}
    /ini IniFileName General ManaRegenOn ${ManaRegenOn}
    /ini IniFileName General Tank1 ${Tank[1]}
    /ini IniFileName General Tank2 ${Tank[2]}
    /ini IniFileName General Tank3 ${Tank[3]}
   
    /ini IniFileName Spells BigHealSpell ${BigHealSpell}
    /ini IniFileName Spells FastHealSpell ${FastHealSpell}
    /ini IniFileName Spells HoTHealSpell ${HoTHealSpell}
    /ini IniFileName Spells PatchHealSpell ${PatchHealSpell}
    /ini IniFileName Spells PromiseHealSpell ${PromiseHealSpell}
    /ini IniFileName Spells ManaRegenSpell ${ManaRegenOn}
    /ini IniFileName Spells HealLocalPct ${PatchHealSpell}
   
/return
|__________________________________________________________________________________________
Sub CheckCoolDown
   /while (${Me.SpellInCooldown}) {
      /delay 3
   }
/return
|__________________________________________________________________________________________
Sub CheckCasting
   | Can add code to check and see if we need to /stopcast to help on saving mana.
   /while (${Me.Casting.ID}) {
      /delay 3
   }
/return
|__________________________________________________________________________________________
Sub CastThis(cSpell)
   | Can add code to check and see if we need to /stopcast to help on saving mana.
   /if (!${cSpell.Length}) /return
   /varset CastingWhat ${cSpell}
   /varset Fizzled 1
   /varset TriedCount 0
   /call CheckCoolDown
   /while (${Fizzled} && ${TriedCount}<2) {
      /varset Fizzled 0
      /cast "${CastingWhat}"
      /call CheckCasting
      /doevents SpellFizzle
      /if (${Fizzled}==2) {
         /varset CastingWhat ${FastHealSpell}
         /varset TriedCount -1
         /call CheckCoolDown
      } else /if (${Fizzled}==1) {
         /delay 2s ${Me.SpellReady[${CastingWhat}]}
      }
      /varcalc TriedCount ${TriedCount}+1
   }
/return
|__________________________________________________________________________________________
Sub CheckStance
    /if (${Me.Sitting} && !${Me.Mount.ID}) {
       /stand
       /delay 1s ${Me.Standing}
    }
/return

- - - Updated - - -

I went and made some major changes to the assist code to help with when all the tanks go down, but there is still some character trying to tank the mob. Also changed the use mod rods to check if class and level usable, can also modify the mod rods list you want to check. I have had no chance to test this code, so would appreciate if someone would at least load it up and try it and report what problems you find. ChainHeal_15.mac

* reserved for possible later use.
Author
Rustycat
First release
Last update
Rating
0.00 star(s) 0 ratings

More resources from Rustycat

Share this resource

Latest updates

  1. Fixed a few syntax errors in the Loadini routine

    This should fix some of the loadini syntax errors.
Back
Top