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
Overview:
Requirements:
Instructions:
Sample INI information as follows:
Macro code current as follows:
- - - 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.
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.