- Joined
- Dec 15, 2009
- Messages
- 525
- Reaction score
- 31
- Points
- 28
I made this shmbot based on Devestator's Clericbot,so 99% credits should go to Big D.
The main goal of this shmmy bot is
1.slow at the very begining of combat, that means slow MUST cast before 95%,normally I wanna it cast when puller inc(at 98% or so..)---btw,Maskoi's shambot is awesome but i just cant let it slow as I wish no matter how I change the variables.
2.heal like clr..
So here it is,basically changed spell name,and ADD a Sub Slow at the start of mainloop with /call slow
And it will sure load the setting from shmbotsettings_YourCharName.ini
Here is my sham.ini
I've test it some,seems works smooth...Just one problem i need to solve:
It will cast Turgur's Swarm over and over,But I already write
in Sub Slow,Why it will keep cast that? The /if condition ${Target.Buff[Turgur's Swarm].ID}!= 13144 didnt work??
And it also cast WG and Epic2.0 out of combat which i have set the "GroupBuffCombatX=TRUE" ,so need fix that too...other function basically works well.
Any comments would be thankful
The main goal of this shmmy bot is
1.slow at the very begining of combat, that means slow MUST cast before 95%,normally I wanna it cast when puller inc(at 98% or so..)---btw,Maskoi's shambot is awesome but i just cant let it slow as I wish no matter how I change the variables.
2.heal like clr..
So here it is,basically changed spell name,and ADD a Sub Slow at the start of mainloop with /call slow
Code:
| =================================================================================================
| ShmBot v1.31
| Written By: Devestator
|
|
| USAGE: /macro shmBot <IniName>
|
|
| Description:
| This is a bot meant to automate the role of a Shaman in a group. The goal of this bot is to
| be as mana efficient as possible and require little to know input once started.
|
|
| Requirements:
| MQ2Cast_Spell_Routines.inc
| devMovement.inc
| devCommon.inc
| clericBotSettings.ini (you can create custom INIs nameing them clericBotSettings_name.ini
| PLUGIN: MQ2Cast
| PLUGIN: MQ2Debuffs
| PLUGIN: MQ2Exchange
|
| V1.31 Update Notes
| -Added the ability to heal watch list members and their pets
| -Corrected a bug with group heals that would cancel the heal if the target was full on hitpoints
| -Added command healpets, this will turn healing of pets on and off.
| -Added a routine CombatCall, to check for heals while buffing if you have in combat buffs.
| -Corrected a bug that could cause group heals to be cast if there were fewer group members than specified.
|
| V1.30 Update Notes
| -Corrected a parenthesis error in the reztarget function -Thanks Blujahz for pointing it out.
| -Corrected a typo in the LoadSettings routine dealing with AABalance. (Thanks Kombat03)
| -Modified for devCommon.inc v1.80 and devMovement.inc v1.60
| -Added the ability to heal pets. New INI Setting: [General] HealPets=True / False
| -Can now use Debuffs as part of devCommon.inc v1.80
|
| V1.20 Update Notes
| -Added promise and hot tracking for more than one player at a time
| -Added checks to prevent using heal spells that are not memmed and have a long recast time.
| -Added checks to prevent trying to use heal spells that aren't ready and thus taking a while to cast.
| -Added routine to mem heal spells out of combat rather than during combat.
| -Corrected a problem causing an error message when looting was turned on.
| -Corrected a crash bug when receiving a tell from an unsafe pc
| -Turned off debug mode by default that was accidentally left on. Should be less spam in your
| mq2 window now.
|
| V1.10 Update Notes
| -Fixed an error where epicName was not being set properly and thus never used
| -Fixed an error preventing castTimer from ever being set and not allow interrupts to work
| -Moved the hot and promise timers to try and be more accurate about when they will actually expire
| Also added 1 extra second over the normal duration to the timers
|
| ==================================================================================================
#include devCommon.inc
#event oom "Insufficient Mana to cast this spell!"
Sub Main(string iniNameStr)
/declare meVersion float outer 1.31
/squelch /mqlog clear
/call CommonInit
/varset reqCommon 1.80
/varset reqMovement 1.60
/varset debugMode FALSE
/call EchoLog "Shmbot Initialized" true
/call EchoLog "Loading variables..." true
/if (!${Defined[iniNameStr]}) {
/varset iniName shmbotSettings.ini
} else {
/if (!${iniNameStr.Equal[default]}) {
/varset iniName shmbotSettings_${iniNameStr}.ini
} else {
/varset iniName shmbotSettings.ini
}
}
/call LoadSettings
/varset targCount 0
:mainLoop
/call slow
/doevents
/call ClericCombatCheck
/if ((${inCombat} || ${outOfCombatHeal.Equal[NULL]}) && ${doHeals} && !${healCheckTimer}) /call HealCheck
/call CheckForAggro
/if (${iAllowSit} && !${Me.Sitting} && !${sitTimer} && !${Me.Mount.ID} && !${gotAggro} && !${followMode} && !${Me.Casting.ID}) /sit on
/if (!${inCombat}) {
/if (${rezSpell.NotEqual[NULL]} && ${SpawnCount[Corpse radius ${campRadius} los]}) /call RezCheck
/if (${outOfCombatHeal.NotEqual[NULL]} && !${healCheckTimer}) /call RestHealCheck
/if (!${minBuffCheckTimer} && ${Me.PctMana} >= 50) /call buffCheck
/if (!${otherChecksTimer}) {
/call CommonRoutines
/call HealGemCheck
/if (${yaulpSpell.NotEqual[NULL]} && !${Me.Gem[${yaulpSpell}]} && ${yaulpSlot.Find[Gem]}) /memspell ${yaulpSlot.Right[${Math.Calc[${yaulpSlot.Length} - 3]}]} "${yaulpSpell}"
/varset otherChecksTimer 10s
}
} else {
/call CommonCombatRoutines CombatCall
}
/goto :mainLoop
/return
Sub Slow
/assist pigface
/delay 1s
/if ( ${Target.PctHPs}<=98 && ${Me.AltAbilityReady[Turgur's Swarm]} && ${Target.Type.Equal[NPC]} && ${Target.Buff[Turgur's Swarm].ID}!= 13144) {
/gsay AA slow on %t!
/delay 1s
/aa act Turgur's Swarm
/delay 3s
/return
}
/return
Sub AddCleanUp
/if (!${Defined[addTracker]}) /declare addTracker[20] int outer
/declare acLoop int local 0
/declare atLoop int local 0
/declare atInt int local 0
/declare addFound bool local false
/if (!${targCount}) /return
/for acLoop 1 to ${targCount}
/varset addFound false
/varset atInt 0
/for atLoop 1 to 20
/if (${addTracker[${atLoop}]} == ${targArray[${acLoop}]}) {
/varset addFound true
/varset atInt ${atLoop}
}
/if (!${addFound}) /next atLoop
/if (${Spawn[${targArray[${acLoop}]}].Type.NotEqual[Corpse]} && (!${Spawn[${targArray[${acLoop}]}].LineOfSight} || ${Spawn[${targArray[${acLoop}]}].Distance} > ${campRadius})) {
/if (!${Spawn[${targArray[${acLoop}]}].ID}) {
/varset addFound true
/varset atInt ${acLoop}
/if (!${Defined[addCleanUp${atInt}]}) /declare addCleanUp${atInt} timer outer 0s
}
/if (!${addFound}) {
/for atLoop 1 to 20
/if (!${addTracker[${atLoop}]}) {
/varset atInt ${atLoop}
/varset addTracker[${atLoop}] ${targArray[${acLoop}]}
}
/if (!${atInt}) /next atLoop
/if (!${Defined[addCleanUp${atInt}]}) /declare addCleanUp${atInt} timer outer 0s
/varset addCleanUp${atInt} 15s
} else {
/if (!${addCleanUp${atInt}}) {
/call EchoLog "Add removed because it left the camp area, ${Spawn[${targArray[${acLoop}]}].CleanName} | ${targArray[${acLoop}]}" true
/varset targArray[${acLoop}] 0
/varcalc corpseCount ${corpseCount} + 1
/varset corpseArray[${corpseCount}] 0
/varset addTracker[${atInt}] 0
}
}
} else {
/if (${addFound}) /varset addTracker[${atLoop}] 0
}
/next acLoop
/varcalc lTargCount ${targCount} - ${corpseCount}
/if (${lTargCount}<1 && ${minBuffCheckTimer} < 50) /varset minBuffCheckTimer 5s
/return
Sub AfterDeath
/return
Sub CastHeal(int healNum, int healTargID, string hpWatch)
/declare sMaxTry int local ${resistTries}
/if (!${Defined[hpWatch]}) /declare hpWatch string local EmergencyHeal
/if (${Me.Casting.ID} && ${allowInterrupt}) /call Interrupt
/varset currHealID ${Spell[${healSpell[${healNum}]}].ID}
/varset currHealTarg ${healTargID}
/if (${Spell[${currHealID}].MyCastTime} > 5) /varset sMaxTry 1
/squelch /target clear
/squelch /target ID ${healTargID}
/delay 1s ${Target.ID}
/call EchoLog "Attempting to heal ${Target.CleanName} with ${healSpell[${healNum}]} | ${Target.PctHPs}" true
/if (${doAnnounce} && ${healAnnounce[${healNum}].NotEqual[NULL]}) /docommand ${announceChan} ${healAnnounce[${healNum}]}
:tryCast
/varset castStart true
/call MQ2Cast "${healSpell[${healNum}]}" ${healSlot[${healNum}]} 0 ${hpWatch} -targetid|${healTargID} -maxtries|${sMaxTry}
/if (${sMaxTry} == 1 && ${Cast.Result.Equal[CAST_FIZZLE]}) /goto :tryCast
/if (${Cast.Result.Equal[CAST_SUCCESS]}) {
/if (${Spell[${currHealID}].Duration}) {
/if (${Spell[${currHealID}].Name.Find[promised]}) {
/call TrackPromise ${currHealTarg} ${currHealID}
} else {
/if (${healMinGroup[${healNum}]} > 1) {
/varset groupHotTimer ${Math.Calc[${Spell[${currHealID}].Duration.TotalSeconds} + 1]}s
} else {
/call TrackHot ${currHealTarg} ${currHealID}
}
}
}
/call EchoLog "Heal cast successfull" true
/varset healCheckTimer ${healCheckTimerStr}
} else /if (${Cast.Result.Equal[CAST_CANCELLED]}) {
/if (${duckHealNum}) {
/call CastHeal ${duckHealNum} ${duckHealTarg} DuckHeal
} else /if (${duckHealName.NotEqual[NULL]}) {
/if (${duckHealSlot.Equal[Item]} && ${FindItem[${epicName}].InvSlot} != 14) /call ItemSwapCheck "${epicName}"
/varset currHealTarg ${Me.ID}
/varset currHealID 0
/call MQ2Cast "${duckHealName}" ${duckHealSlot} 0 DuckHeal -targetid|${Me.ID} -maxtries|${resistTries}
/if (${Cast.Result.NotEqual[CAST_SUCCESS]}) {
/call EchoLog "${duckHealName} cast failed, reason: ${Cast.Result}" true
} else {
/call EchoLog "${duckHealName} cast succeeded!" true
}
/if (${itemSwapped}) /call ItemSwapCheck
} else {
/call EchoLog "Heal cast failed: ${Cast.Result}" true
}
} else {
/call EchoLog "Heal cast failed: ${Cast.Result}" true
}
/return
Sub ClericCombatCheck
/call CheckForAdds ${campRadius} ${Me.ID} false
/if (${targCount}) /call AddCleanUp
/if (!${inCombat} && (${lTargCount} > 0 || ${Me.CombatState.Equal[Combat]})) {
/varset inCombat true
/varset healCheckTimer 0
}
/if (${inCombat} && ${lTargCount} < 1 && ${Me.CombatState.NotEqual[Combat]}) {
/varset inCombat false
/call AfterCombatRoutines
/varset healCheckTimer 20s
/if (${minBuffCheckTimer} < 150) /varset minBuffCheckTimer 15s
}
/return
Sub Event_oom
/if (${doAnnounce}) /docommand ${announceChan} I am out of mana!
/varset manaLow true
/return
Sub BotCommands(string rFrom,string rMsg)
/declare hMsg string local COMPLETED_NOTFOUND
/declare rFromID int local 0
/varset rFromID ${Spawn[pc ${rFrom}].ID}
| ==========================
| Bot specific commands
| ==========================
/declare paramCount int local
/varcalc paramCount ${rMsg.Count[ ]} + 1
/declare cParams[20] string local
/declare strCommand string local
/varset strCommand ${rMsg.Token[1, ]}
/if (${paramCount}) {
/for nArray 2 to ${paramCount}
/varset cParams[${Math.Calc[${nArray}-1]}] ${rMsg.Token[${nArray}, ]}
/next nArray
}
/if (${strCommand.Equal[heal]}) {
| =======================================
| heal (target) (spell)
| =======================================
/if (${cParams[1].NotEqual[NULL]}) {
/declare healTargName string local ${cParams[1]}
/if (${healTargName.Equal[Me]}) /varset healTargName ${rFrom}
/if (${Spawn[${healTargName}].ID}) {
/squelch /target clear
/squelch /target ${healTargName}
/delay 1s ${Target.ID}
/if (${Target.ID}) {
/if (${cParams[2].Length}) {
/declare healName string local
/for nArray 2 to 20
/if (${cParams[${nArray}].Length}) /varset healName ${healName} ${cParams[${nArray}]}
/if (${cParams[${nArray}].Length}) /next nArray
/call EchoLog "Attempting to cast ${healName} on ${Target.CleanName} | ${Target.PctHPs}"
/call MQ2Cast "${healName}"
/if (${Cast.Result.Equal[CAST_SUCCESS]}) {
/varset hMsg \agHeal cast successfully
} else {
/varset hMsg \arFailed to cast heal, reason: \ag${Cast.Result}
}
} else {
/if (${healCount}) {
/varset hMsg NULL
/for nArray 1 to ${healCount}
/if (${healMinGroup[${nArray}]}) /next nArray
/if (${Target.Distance} < ${Spell[${healSpell[${nArray}]}].Range}) {
/if (${Target.Type.NotEqual[Corpse]}) {
/if (${healClasses[${nArray}].Find[${Target.Class.ShortName}]}) {
/if (${Target.PctHPs} >= ${healMinHP[${nArray}]} && ${Target.PctHPs} <= ${healMaxHP[${nArray}]}) {
/call EchoLog "Attempting to cast ${healSpell[${nArray}]} on ${Target.CleanName} | ${Target.PctHPs}" true
/call MQ2Cast "${healSpell[${nArray}]}" ${healSlot[${nArray}]}
/if (${Cast.Result.Equal[CAST_SUCCESS]}) {
/varset hMsg \agHeal cast successfully
} else {
/varset hMsg \arFailed to cast heal, reason: \ag${Cast.Result}
}
}
}
}
}
/if (${hMsg.Equal[NULL]}) /next nArray
/if (${hMsg.Equal[NULL]}) /varset hMsg \ayCould not Find A heal to cast on the specified Target.
} else {
/varset hMsg \ayNo heal spells set, cannot heal.
}
}
} else {
/varset hMsg \ag${healTargName} \aocould not be found to heal.
}
} else {
/varset hMsg No heal Target given
}
} else {
/if (${doHeals}) {
/varset doHeals false
/varset hMsg No longer healing
} else {
/varset doHeals true
/varset hMsg I will now heal
}
}
} else /if (${strCommand.Equal[healpets]}) {
/if (${healPets}) {
/varset healPets FALSE
/varset hMsg No longer healing pets
} else {
/varset healPets TRUE
/varset hMsg I will now heal pets
}
} else /if (${strCommand.Equal[NULL]}) {
/varset hMsg \ayCommand not recognized
}
/return ${hMsg}
Sub CombatCall
/call HealCheck TRUE
/return
Sub HealGemCheck
/declare gCheck int local
/for gCheck 1 to ${healCount}
/if (${healSlot[${gCheck}].Find[Gem]} && !${Me.Gem[${healSpell[${gCheck}]}]}) {
/memspell ${spellSlot.Right[${Math.Calc[${spellSlot.Length} - 3]}]} "${healSpell[${gCheck}]}"
}
/call ClericCombatCheck
/if (!${inCombat}) /next gCheck
/return
Sub HealCheck(bool secondaryCall)
/if (!${Defined[secondaryCall]}) /declare secondaryCall bool local FALSE
/declare hInt int local 0
/declare groupAvgHP int local 0
/declare avgCount int local 0
/declare lowHP int local 100
/declare pHeal bool local false
/declare hHeal bool local false
/declare gPets bool local false
/declare grpArray int local 0
/declare targVariable string local Target
/if (${healCount}) {
/for hInt 1 to ${healCount}
/if (${Spell[${healSpell[${hInt}]}].Duration}) {
/if (${healSpell[${hInt}].Find[promised]}) {
/varset pHeal true
/varset hHeal false
} else {
/if (${groupHotTimer}) /next hInt
/varset hHeal true
/varset pHeal false
}
} else {
/varset hHeal false
/varset pHeal false
}
/if (${healSlot[${hInt}].Equal[Item]} && ${FindItem[${healSpell[${hInt}]}].Timer}) /next hInt
/if (${healSlot[${hInt}].Equal[alt]} && !${Me.AltAbilityReady[${healSpell[${hInt}]}]}) /next hInt
/if (${healSlot[${hInt}].Find[Gem]} && !${Me.Gem[${healSpell[${hInt}]}]} && ${Spell[${healSpell[${hInt}]}].RecastTime} > 2) /next hInt
/if (${healSlot[${hInt}].Find[Gem]} && ${Me.Gem[${healSpell[${hInt}]}]} && !${Me.SpellReady[${healSpell[${hInt}]}]}) /next hInt
/if (${Me.CurrentMana} > ${Spell[${healSpell[${hInt}]}].Mana}) {
/if (${healMinGroup[${hInt}]}>1) {
/if (${Group.GroupSize} >= ${healMinGroup[${hInt}]}) {
/if (${hHeal} && ${groupHotTimer}) /next hInt
/varset avgCount 0
/varset groupAvgHP 0
/for nArray 0 to ${Group.Members}
/if (${Group.Member[${nArray}].Type.Equal[Corpse]} || !${Group.Member[${nArray}].ID}) /next nArray
/varcalc groupAvgHP ${groupAvgHP} + ${Group.Member[${nArray}].PctHPs}
/varcalc avgCount ${avgCount} + 1
/if (${Group.Member[${nArray}].PctHPs} < 50 && ${hInt} < ${healCount}) /next hInt
/next nArray
/if (${avgCount} == 0) /return
/varcalc groupAvgHP ${groupAvgHP} / ${avgCount}
/if (${groupAvgHP} <= ${healMaxHP[${hInt}]} && ${groupAvgHP} >= ${healMinHP[${hInt}]}) {
/call EchoLog "Attempting to cast group heal ${healSpell[${nArray}]}, group avg: ${groupAvgHP}" true
/call CastHeal ${hInt} ${Me.ID}
/return
}
}
} else {
/for nArray 0 to ${Group.Members}
/if (${Group.Member[${nArray}].Pet.ID} && !${Group.Member[${nArray}].Pet.Name.Find[familiar]}) /varset gPets TRUE
/if (${pHeal} || ${hHeal}) {
/if (${pHeal}) /call TrackPromise ${Group.Member[${nArray}].ID}
/if (${hHeal}) /call TrackHot ${Group.Member[${nArray}].ID}
/if (${Macro.Return.Equal[FALSE]}) /next nArray
}
/if (${Group.Member[${nArray}].Distance} > ${Spell[${healSpell[${hInt}]}].Range}) /next nArray
/if (${Group.Member[${nArray}].Type.Equal[Corpse]} || !${Group.Member[${nArray}].ID}) /next nArray
/if (${Group.Member[${nArray}].CleanName.Equal[${pullerName}]} && (!${Group.Member[${nArray}].LineOfSight} || ${Group.Member[${nArray}].Distance} > ${campRadius})) /next nArray
/if (${healClasses[${hInt}].Find[${Group.Member[${nArray}].Class.ShortName}]} || ${healClasses[${hInt}].Find[${Group.Member[${nArray}].Class.Name}]} || ${healClasses[${hInt}].Find[${Group.Member[${nArray}].CleanName}]} || ((${healClasses[${hInt}].Find[mt]} || ${healClasses[${hInt}].Find[maintank]}) && ${Group.Member[${nArray}].CleanName.Equal[${mainTank}]})) {
/if (${Group.Member[${nArray}].PctHPs} >= ${healMinHP[${hInt}]} && ${Group.Member[${nArray}].PctHPs} <= ${healMaxHP[${hInt}]}) {
/call CastHeal ${hInt} ${Group.Member[${nArray}].ID}
/return
}
}
/next nArray
}
}
/next hInt
/if (${gPets} && ${healPets}) {
/for hInt 1 to ${healCount}
/if (${Spell[${healSpell[${hInt}]}].Duration}) {
/if (${healSpell[${hInt}].Find[promised]}) {
/varset pHeal true
/varset hHeal false
} else {
/varset hHeal true
/varset pHeal false
}
} else {
/varset hHeal false
/varset pHeal false
}
/if (${healMinGroup[${hInt}]}>1) /next hInt
/if (${healSlot[${hInt}].Equal[Item]} && ${FindItem[${healSpell[${hInt}]}].Timer}) /next hInt
/if (${healSlot[${hInt}].Equal[alt]} && !${Me.AltAbilityReady[${healSpell[${hInt}]}]}) /next hInt
| /if (${healSlot[${hInt}].Find[Gem]} && !${Me.SpellReady[${healSpell[${hInt}]}]} && ${Spell[${healSpell[${hInt}]}].RecastTime} > 3) /next hInt
/if (${Defined[healRecastTimer${hInt}]} && ${healRecastTimer${hInt}}) /next hInt
/if (${Me.CurrentMana} > ${Spell[${healSpell[${hInt}]}].Mana}) {
/for grpArray 0 to ${Group.Members}
/if (${Group.Member[${grpArray}].Pet.ID} && !${Group.Member[${grpArray}].Pet.Name.Find[familiar]}) {
/if (${pHeal} || ${hHeal}) {
/if (${pHeal}) /call TrackPromise ${Group.Member[${grpArray}].Pet.ID}
/if (${hHeal}) /call TrackHot ${Group.Member[${grpArray}].Pet.ID}
/if (${Macro.Return.Equal[FALSE]}) /next grpArray
}
/if (${Group.Member[${grpArray}].Pet.Distance} > ${Spell[${healSpell[${hInt}]}].Range}) /next grpArray
/if (${healClasses[${hInt}].Find[${Group.Member[${grpArray}].Class.ShortName}-Pet]} || ${healClasses[${hInt}].Find[${Group.Member[${grpArray}].Class.Name}-Pet]} || ${healClasses[${hInt}].Find[${Group.Member[${grpArray}].CleanName}-Pet]} || ${healClasses[${hInt}].Find[Pet]}) {
/if (${Group.Member[${grpArray}].Pet.PctHPs} >= ${healMinHP[${hInt}]} && ${Group.Member[${grpArray}].Pet.PctHPs} <= ${healMaxHP[${hInt}]}) {
/call CastHeal ${hInt} ${Group.Member[${grpArray}].Pet.ID}
/return
}
}
}
/next grpArray
}
/next hInt
}
/if (${watchCount}) {
/varset gPets false
/for hInt 1 to ${healCount}
/if (${Spell[${healSpell[${hInt}]}].Duration}) {
/if (${healSpell[${hInt}].Find[promised]}) {
/varset pHeal true
/varset hHeal false
} else {
/varset hHeal true
/varset pHeal false
}
} else {
/varset hHeal false
/varset pHeal false
}
/if (${healMinGroup[${hInt}]}>1) /next hInt
/if (${healSlot[${hInt}].Equal[Item]} && ${FindItem[${healSpell[${hInt}]}].Timer}) /next hInt
/if (${healSlot[${hInt}].Equal[alt]} && !${Me.AltAbilityReady[${healSpell[${hInt}]}]}) /next hInt
| /if (${healSlot[${hInt}].Find[Gem]} && !${Me.SpellReady[${healSpell[${hInt}]}]} && ${Spell[${healSpell[${hInt}]}].RecastTime} > 3) /next hInt
/if (${Defined[healRecastTimer${hInt}]} && ${healRecastTimer${hInt}}) /next hInt
/if (${Me.CurrentMana} > ${Spell[${healSpell[${hInt}]}].Mana}) {
/for grpArray 1 to ${watchCount}
/if (${Spawn[${watchList[${grpArray}]}].Pet.ID}) /varset gPets true
/if (${pHeal} || ${hHeal}) {
/if (${pHeal}) /call TrackPromise ${Spawn[${watchList[${grpArray}]}].ID}
/if (${hHeal}) /call TrackHot ${Spawn[${watchList[${grpArray}]}].ID}
/if (${Macro.Return.Equal[FALSE]}) /next grpArray
}
/if (${Spawn[${watchList[${grpArray}]}].Distance} > ${Spell[${healSpell[${hInt}]}].Range}) /next grpArray
/if (${Spawn[${watchList[${grpArray}]}].Type.Equal[Corpse]} || !${Spawn[${watchList[${grpArray}]}].ID}) /next grpArray
/if (${Spawn[${watchList[${grpArray}]}].CleanName.Equal[${pullerName}]} && (!${Spawn[${watchList[${grpArray}]}].LineOfSight} || ${Spawn[${watchList[${grpArray}]}].Distance} > ${campRadius})) /next grpArray
/if (${healClasses[${hInt}].Find[${Spawn[${watchList[${grpArray}]}].Class.ShortName}]} || ${healClasses[${hInt}].Find[${Spawn[${watchList[${grpArray}]}].Class.Name}]} || ${healClasses[${hInt}].Find[${Spawn[${watchList[${grpArray}]}].CleanName}]} || ((${healClasses[${hInt}].Find[mt]} || ${healClasses[${hInt}].Find[maintank]}) && ${Spawn[${watchList[${grpArray}]}].CleanName.Equal[${mainTank}]})) {
/if (${useEQBC} && ${NetBots[${watchList[${grpArray}]}].Zone}) {
/varset targVariable NetBots[${watchList[${grpArray}]}]
} else {
/squelch /target id ${Spawn[${watchList[${grpArray}]}].ID}
/delay 1s ${Target.ID}==${Spawn[${watchList[${grpArray}]}].ID}
/delay 2
/varset targVariable Target
}
/if (${${targVariable}.PctHPs} >= ${healMinHP[${hInt}]} && ${${targVariable}.PctHPs} <= ${healMaxHP[${hInt}]}) {
/call CastHeal ${hInt} ${Spawn[${watchList[${grpArray}]}].ID}
/return
}
}
/next grpArray
}
/next hInt
/if (${gPets} && ${healPets}) {
/for hInt 1 to ${healCount}
/if (${Spell[${healSpell[${hInt}]}].Duration}) {
/if (${healSpell[${hInt}].Find[promised]}) {
/varset pHeal true
/varset hHeal false
} else {
/varset hHeal true
/varset pHeal false
}
} else {
/varset hHeal false
/varset pHeal false
}
/if (${healMinGroup[${hInt}]}>1) /next hInt
/if (${healSlot[${hInt}].Equal[Item]} && ${FindItem[${healSpell[${hInt}]}].Timer}) /next hInt
/if (${healSlot[${hInt}].Equal[alt]} && !${Me.AltAbilityReady[${healSpell[${hInt}]}]}) /next hInt
| /if (${healSlot[${hInt}].Find[Gem]} && !${Me.SpellReady[${healSpell[${hInt}]}]} && ${Spell[${healSpell[${hInt}]}].RecastTime} > 3) /next hInt
/if (${Defined[healRecastTimer${hInt}]} && ${healRecastTimer${hInt}}) /next hInt
/if (${Me.CurrentMana} > ${Spell[${healSpell[${hInt}]}].Mana}) {
/for grpArray 1 to ${watchCount}
/if (${Spawn[${watchList[${grpArray}]}].Pet.ID}) {
/if (${pHeal} || ${hHeal}) {
/if (${pHeal}) /call TrackPromise ${Spawn[${watchList[${grpArray}]}].Pet.ID}
/if (${hHeal}) /call TrackHot ${Spawn[${watchList[${grpArray}]}].Pet.ID}
/if (${Macro.Return.Equal[FALSE]}) /next grpArray
}
/if (${Spawn[${watchList[${grpArray}]}].Pet.Distance} > ${Spell[${healSpell[${hInt}]}].Range}) /next grpArray
/if (${healClasses[${hInt}].Find[${Spawn[${watchList[${grpArray}]}].Class.ShortName}-Pet]} || ${healClasses[${hInt}].Find[${Spawn[${watchList[${grpArray}]}].Class.Name}-Pet]} || ${healClasses[${hInt}].Find[${Spawn[${watchList[${grpArray}]}].CleanName}-Pet]} || ${healClasses[${hInt}].Find[Pet]}) {
/if (${useEQBC} && ${NetBots[${watchList[${grpArray}]}].Zone}) {
/varset targVariable NetBots[${watchList[${grpArray}]}].PetHP
} else {
/squelch /target id ${Spawn[${watchList[${grpArray}]}].Pet.ID}
/delay 1s ${Target.ID}==${Spawn[${watchList[${grpArray}]}].Pet.ID}
/delay 2
/varset targVariable Target.PctHPs
}
/if (${${targVariable}} >= ${healMinHP[${hInt}]} && ${${targVariable}} <= ${healMaxHP[${hInt}]}) {
/call CastHeal ${hInt} ${Spawn[${watchList[${grpArray}]}].Pet.ID}
/return
}
}
}
/next grpArray
}
/next hInt
}
}
:exitHealLoop
}
/if (${yaulpSpell.NotEqual[null]} && !${Me.Mount.ID} && ${inCombat} && !${Me.Buff[${yaulpSpell}].ID} && ${Me.SpellReady[${yaulpSpell}]} && !${secondaryCall}) {
/for nArray 0 to ${Group.Members}
/if (${Group.Member[${nArray}].Type.Equal[Corpse]} || !${Group.Member[${nArray}].ID}) /next nArray
/if (${Group.Member[${nArray}].PctHPs} < ${lowHP}) /varset lowHP ${Group.Member[${nArray}].PctHPs}
/if (${lowHP} > 60) /next nArray
/if (${lowHP} > 60) {
/call EchoLog "Attempting to use ${yaulpSpell}" true
/call MQ2Cast "${yaulpSpell}" ${yaulpSlot}
/if (${Cast.Result.NotEqual[CAST_SUCCESS]}) /call EchoLog "Yaulp failed, reason: ${Cast.Result}" true
}
}
/return
Sub EmergencyHeal
/declare lowHP int local 100
/declare lowID int local 0
/declare eLoop int local
/declare cGroupAvg int local 100
/declare cAvgCount int local 0
/if (${castStart}) {
/varset castTimer ${Spell[${currHealID}].MyCastTime}s
/varset castStart false
}
/if (!${allowInterrupt}) /return
/if (!${Me.Casting.ID}) /return
/varset duckHealNum 0
/varset duckHealTarg 0
/varset duckHealName NULL
/varset duckHealSlot NULL
/if (((${Spawn[${currHealTarg}].PctHPs} >= 98 && ${castTimer} > 5) || ${Spawn[${currHealTarg}].Type.Equal[Corpse]} || !${Spawn[${currHealTarg}].ID}) && ${allowInterrupt} && !${Spell[${currHealID}].AERange}) {
/call EchoLog "The target being healed is either already healed, dead, or not in the zone, canceling heal" true
/call Interrupt
/return
}
/for eLoop 0 to ${Group.Members}
/if (${Group.Member[${eLoop}].Type.NotEqual[Corpse]} && ${Group.Member[${eLoop}].ID}) {
/varcalc cAvgCount ${cAvgCount} + 1
/varcalc cGroupAvg ${cGroupAvg} + ${Group.Member[${eLoop}].PctHPs}
/if (${classList.Find[${Group.Member[${eLoop}].Class.ShortName}]} && ${Group.Member[${eLoop}].PctHPs} < ${lowHP}) {
/varset lowHP ${Group.Member[${eLoop}].PctHPs}
/varset lowID ${Group.Member[${eLoop}].ID}
}
}
/next eLoop
/if (${cAvgCount}) /varcalc cGroupAvg ${cGroupAvg} / ${cAvgCount}
/if (${lowHP} < ${emergencyHP} && ${castTimer} > 10 && (${useEpicBalance} || ${useAABalance}) && ${cGroupAvg} > 50) {
/if (${useEpicBalance} && !${FindItem[${epicName}].Timer}) {
/call EchoLog "Attempting to use ${epicName} epic click" true
/call Interrupt
/varset duckHealName ${epicName}
/varset duckHealSlot Item
/return
}
/if (${useAABalance} && ${Me.AltAbilityReady[Divine Arbitration]}) {
/call EchoLog "Attempting to use AA Divine Arbitration" true
/call Interrupt
/varset duckHealName Divine Arbitration
/varset duckHealSlot alt
/return
}
}
/if (${lowID} != ${currHealTarg} && ${Target.PctHPs} > 50 && ${lowHP} < ${emergencyHP} && ${castTimer}>${Math.Calc[${Spell[${currHealID}].MyCastTime} * 5]} && (${Spawn[${currHealTarg}].CleanName.NotEqual[${mainTank}]} || ${lowID} == ${Me.ID} || ${lowID} == ${Spawn[${mainTank}].ID})) {
/call EchoLog "4"
/if (${Me.Gem[${healSpell[${fastestHealNum}]}]}) {
/call EchoLog "Canceling heal to heal someone that is about to die" true
/call Interrupt
/call CastHeal ${fastestHealNum} ${lowID} DuckHeal
/return
} else {
/for eLoop 1 to ${healCount}
/if (${Spell[${heallSpell[${eLoop}]}].Duration}) /next eLoop
/if (!${Me.Gem[${healSpell[${eLoop}]}]}) /next eLoop
/if (${Spell[${healSpell[${eLoop}]}].MyCastTime} > 2) /next eLoop
/if (${healMinGroup[${eLoop}]}>1) /next eLoop
/if (${healClasses[${eLoop}].Find[${Spawn[${lowID}].Class.ShortName}]}) {
/call EchoLog "Canceling heal to heal someone that is about to die" true
/call Interrupt
/varset duckHealNum ${eLoop}
/varset duckHealTarg ${lowID}
/return
}
/next eLoop
}
} else {
/if (${Target.PctHPs} < ${emergencyHP}) {
/if (${fastestCastTime} < ${Math.Calc[${castTimer} + 2.5]} && ${Me.Gem[${healSpell[${fastestHealNum}]}]}) {
/call EchoLog "Canceling heal to use a faster heal spell" true
/call Interrupt
/varset duckHealNum ${fastestHealNum}
/varset duckHealTarg ${Target.ID}
/return
} else {
/for eLoop 1 to ${healCount}
/if (!${Me.Gem[${healSpell[${eLoop}]}]}) /next eLoop
/if (${healMinGroup[${eLoop}]}>1) /next eLoop
/if (${Spell[${heallSpell[${eLoop}]}].Duration}) /next eLoop
/if (${Math.Calc[${Spell[${healSpell[${eLoop}]}].MyCastTime} * 10]} < ${Math.Calc[${castTimer} + 2.5]}) {
/if (${healClasses[${eLoop}].Find[${Spawn[${currHealTarg}].Class.ShortName}]}) {
/call EchoLog "Canceling heal to use a faster heal spell" true
/call Interrupt
/varset duckHealNum ${fastestHealNum}
/varset duckHealTarg ${Target.ID}
/return
}
}
}
/next eLoop
}
}
/return
Sub DuckHeal
| If needed in the future this is what is called when an emergency heal is being cast.
/if (${Spawn[${currHealTarg}].Type.Equal[Corpse]} || !${Spawn[${currHealTarg}].ID}) {
/call Interrupt
}
/return
Sub LoadSettings
| ====================
| Load Heals
| ====================
/declare healCount int outer
/varset healCount ${Ini[${iniName},Heals,Value]}
/call EchoLog "Loading heals: ${healCount} heal spell(s)" true
/declare healSpell[${healCount}] string outer
/declare healSlot[${healCount}] string outer
/declare healMinGroup[${healCount}] int outer
/declare healMinHP[${healCount}] int outer
/declare healMaxHP[${healCount}] int outer
/declare healClasses[${healCount}] string outer
/declare healType[${healCount}] string outer
/declare healAnnounce[${healCount}] string outer
/declare classList string outer
/declare outOfCombatHeal string outer
/declare outOfCombatSlot string outer
/declare outOfCombatHP int outer
/declare fastestHealNum int outer
/declare fastestCastTime float outer 20.0
/varset outOfCombatHeal ${Ini[${iniName},Heals,OutOfCombatHeal]}
/varset outOfCombatSlot ${Ini[${iniName},Heals,OutOfCombatSlot]}
/varset outOfCombatHP ${Ini[${iniName},Heals,OutOfCombatHP]}
/if (${healCount}) {
/for nArray 1 to ${healCount}
/varset healSpell[${nArray}] ${Ini[${iniName},Heals,HealName${nArray}]}
/varset healSlot[${nArray}] ${Ini[${iniName},Heals,HealSlot${nArray}]}
/varset healMinGroup[${nArray}] ${Ini[${iniName},Heals,HealMinGroup${nArray}]}
/varset healMinHP[${nArray}] ${Ini[${iniName},Heals,HealMinHP${nArray}]}
/varset healMaxHP[${nArray}] ${Ini[${iniName},Heals,HealMaxHP${nArray}]}
/varset healClasses[${nArray}] ${Ini[${iniName},Heals,HealClasses${nArray}]}
/varset healType[${nArray}] ${Ini[${iniName},Heals,HealType${nArray}]}
/varset healAnnounce[${nArray}] ${Ini[${iniName},Heals,HealAnnounce${nArray}]}
/if (${healType[${nArray}].Equal[NULL]}) /varset healType[${nArray}] ALL
/call EchoLog " ${nArray} - NAME: ${healSpell[${nArray}]} SLOT: ${healSlot[${nArray}]} MINGROUP: ${healMinGroup[${nArray}]} MINHP: ${healMinHP[${nArray}]} MAXHP: ${healMaxHP[${nArray}]} TYPE: ${healType[${nArray}]} CLASSES: ${healClasses[${nArray}]}" true
/varset classList ${classList}${healClasses[${nArray}]}
/if (${Spell[${healSpell[${nArray}]}].MyCastTime} < ${fastestCastTime} && !${Spell[${healSpell[${nArray}]}].Duration}) {
/varset fastestHealNum ${nArray}
/varset fastestCastTime ${Math.Calc[${Spell[${healSpell[${nArray}]}].MyCastTime} * 10]}
}
/next nArray
}
| ====================
| Load General Settings
| ====================
/declare pauseTimer timer outer
| /declare campAfterGate bool outer
/declare pauseActions bool outer false
/declare doHeals bool outer true
/declare healCheckTimerStr string outer 5s
/declare healCheckTimer timer outer 0s
/declare iAllowSit bool outer true
/declare rezSpell string outer
/declare rezSlot string outer
/declare rezAnnounce string outer NULL
/declare rezTracker[100] int outer
/declare rezTimerStr string outer 2m
/declare otherChecksTimer timer outer 10s
/declare hotTimer timer outer 0s
/declare promiseTimer timer outer 0s
/declare yaulpSpell string outer
/declare yaulpSlot string outer
/declare emergencyHP int outer 35
/declare useEpicBalance bool outer false
/declare useAABalance bool outer false
/declare epicBalanceName string outer NULL
/declare duckHealNum int outer 0
/declare duckHealTarg int outer 0
/declare duckHealName string outer
/declare duckHealSlot string outer
/declare castStart bool outer false
/declare epicName string outer
/declare healPets bool outer false
/call EchoLog "Loading general settings" true
/varset healCheckTimerStr ${Ini[${iniName},General,HealCheckTime]}
/varset doHeals ${Ini[${iniName},General,HealAtStart]}
/varset outOfCombatSit ${Ini[${iniName},General,OutOfCombatSit]}
/varset iAllowSit ${Ini[${iniName},General,AllowSit]}
/varset rezSpell ${Ini[${iniName},General,RezSpell]}
/varset rezSlot ${Ini[${iniName},General,RezSlot]}
/varset rezAnnounce ${Ini[${iniName},General,RezAnnounce]}
/varset yaulpSpell ${Ini[${iniName},General,YaulpSpell]}
/varset yaulpSlot ${Ini[${iniName},General,YaulpSlot]}
/varset emergencyHP ${Ini[${iniName},General,EmergencyHealHP]}
/varset useEpicBalance ${Ini[${iniName},General,UseEpicBalance]}
/varset useAABalance ${Ini[${iniName},General,UseAABalance]}
/varset healPets ${Ini[${iniName},General,HealPets]}
/if (${Ini[${iniName},General,CampAfterGate].NotEqual[NULL]}) {
/varset campAfterGate ${Ini[${iniName},General,CampAfterGate]}
} else {
/varset campAfterGate true
}
/if (${unsafePCAction.Equal[NULL]}) /varset unsafePCAction pause
/if (${useEpicBalance}) {
/if (${FindItem[Harmony of the Soul].InvSlot}) /varset epicName Harmony of the Soul
/if (${FindItem[Aegis of Superior Divinity].InvSlot}) /varset epicName Aegis of Superior Divinity
/if (${epicName.Equal[NULL]}) /varset useEpicBalance false
}
/if (${useAABalance}) {
/if (!${Me.AltAbility[Divine Arbitration]}) /varset useAABalance false
}
/call EchoLog " MinSafeDistance: ${minSafeDistance}" true
/call EchoLog " Camping after gate: ${campAfterGate}" true
/call EchoLog " Unsafe PC action: ${unsafePCAction}" true
| ====================
| Finish Loading
| ====================
/varset homeX ${Me.X}
/varset homeY ${Me.Y}
/varset maxLoc 1
/varset LocArray[1] ${homeY},${homeX}
| ====================
| Final var setup
| ====================
/declare oTargID int outer
/declare manaLow bool outer false
/declare currHealID int outer
/declare currHealTarg int outer
/declare castTimer timer outer 0s
/declare promiseTrack[20] int outer
/declare hotTrack[20] int outer
/declare groupHotTimer timer outer 0s
/varset targID 0
/varset startZone ${Zone.ShortName}
/varset movVar 1
/varset minBuffCheckTimer 0s
/varset curLoc 1
/varset lTargCount 0
/call CommonLoad
/call resetTimers
/tgb on
/call EchoLog "ClericBot \agv${meVersion}\ao, written by \awDevestator\ao, initiated"
/call EchoLog "Looting Corpses: \ag${lootCorpses}"
/call EchoLog "Main Tank: \ag${mainTank}"
/call EchoLog "Main Assist: \ag${mainAssist}"
/call EchoLog "Puller: \ag${pullerName}"
/call EchoLog "INI FileName: \ag${iniName}"
/call EchoLog "Healing: \ag${doHeals}"
/call EchoLog "Debuffing: \ag${doDebuffs}"
/call EchoLog "Group Buffing: \ag${doGroupBuffs}"
/if (${doGroupBuffs}) /call EchoLog "Minimum Check Time: \ag${minBuffCheckTimerStr}"
/call EchoLog "Self Buffing: \ag${doSelfBuffs}"
/if (${doAnnounce}) {
/call EchoLog "Announcements: \ag${announceChan}"
} else {
/call EchoLog "Announcements: \agOFF"
}
/delay 1s
/doevents
/return
Sub ResetTimers
/varset globalCooldown 0s
/if (${csCount}>0) {
/for nArray 1 to ${csCount}
/varset csTimer${nArray} 0s
/next nArray
}
/return
Sub RestHealCheck
/declare rhLoop int local
/if (${Me.PctMana} < 50) /return
/for rhLoop 0 to ${Group.Members}
/if (${Group.Member[${rhLoop}].ID} && ${Group.Member[${rhLoop}].PctHPs} < ${outOfCombatHP} && ${Group.Member[${rhLoop}].Type.NotEqual[Corpse]} && ${Group.Member[${rhLoop}].Distance} < ${Spell[${outOfCombatHeal}].Range}) {
/if (${Group.Member[${rhLoop}].CleanName.Equal[${pullerName}]} && (!${Group.Member[${rhLoop}].LineOfSight} || ${Group.Member[${rhLoop}].Distance} > ${campRadius})) /next rhLoop
/squelch /target clear
/squelch /target ID ${Group.Member[${rhLoop}].ID}
/delay 1s ${Target.ID}
/call EchoLog "Casting out of combat heal: ${outOfCombatHeal} on ${Target.CleanName}" true
/if (${doAnnounce}) /docommand ${announceChan} ${outOfCombatHeal} on %t
/call MQ2Cast "${outOfCombatHeal}" ${outOfCombatSlot} 0 CheckForAggro -targetid|${Target.ID} -maxtries|${resistTries}
/if (${Cast.Result.NotEqual[CAST_SUCCESS]}) /call EchoLog "Heal failed, reason: ${Cast.Result} | Aggro: ${gotAggro}" true
}
/call ClericCombatCheck
/if (${Me.PctMana} < 50) /return
/if (!${gotAggro} && ${Me.CombatState.NotEqual[Combat]} && !${inCombat}) /next rhLoop
/if (!${gotAggro} && ${Me.CombatState.NotEqual[Combat]} && !${inCombat}) /varset healCheckTimer 10s
/return
Sub RezCheck
/declare corpseID int local
/declare corpseNum int local
/if (${rezSpell.Equal[Null]}) /return
/varset corpseNum 0
:nextcorpse
/if (${rezSlot.Find[Gem]} && ${Me.CurrentMana} < ${Math.Calc[${Spell[${rezSpell}].Mana} + 100]}) /return
/varcalc corpseNum ${corpseNum} + 1
/varset corpseID ${Me.NearestSpawn[${corpseNum},Corpse radius ${campRadius}].ID}
/if (${corpseID}) {
/if (${Spawn[${corpseID}].Deity.ID}) {
/call SafePC ${Spawn[${corpseID}].DisplayName}
/if (${Macro.Return.Equal[true]}) {
:tryRez
/call RezTarget ${corpseID}
/if (${Macro.Return.Equal[COMPLETED_FAIL]}) /goto :tryRez
/if (${Macro.Return.Equal[ABORT_AGGRO]}) /return
}
}
/goto :nextcorpse
}
/return
Sub RezTarget(int rezTargID)
/if (${rezSpell.Equal[Null]}) /return ABORT_NOSPELL
/if (${rezSlot.Find[Gem]} && ${Me.CurrentMana} < ${Spell[${rezSpell}].Mana}) /return ABORT_MANA
/if (${rezSlot.Find[Gem]} && !${Me.SpellReady[${rezSpell}]}) /return ABORT_NOTREADY
/if (${rezSlot.Equal[Item]} && ${FindItem[${rezSpell}].Timer}) /return ABORT_NOTREADY
/if (${rezSlot.Equal[alt]} && !${Me.AltAbilityReady[${rezSpell}]}) /return ABORT_NOTREADY
/if (!${Spawn[${rezTargID}].ID} || ${Spawn[${rezTargID}].Type.NotEqual[Corpse]} || !${Spawn[${rezTargID}].Deity.ID}) /return ABORT_NOCORPSE
/if (!${Spawn[${rezTargID}].LineOfSight}) /return ABORT_CANNOTSEE
/if (${Spawn[${rezTargID}].Distance} > ${campRadius}) /return ABORT_DISTANCE
/if (!${Defined[lastRezID]}) /declare lastRezID int outer
/call OkToRez ${rezTargID}
/if (${Macro.Return.Equal[false]}) /return ABORT_REZTIMER
/squelch /target clear
/squelch /target ID ${rezTargID}
/delay 1s ${Target.ID}
/if (${Target.ID}) {
/call EchoLog "Attempting to rez ${Target.CleanName}" true
/if (${rezSlot.Equal[Item]}) /call ItemSwapCheck ${rezSpell}
/if (${rezAnnounce.NotEqual[NULL]} && ${doAnnounce}) /docommand ${announceChan} ${rezAnnounce}
/call MQ2Cast "${rezSpell}" ${rezSlot} 0 CheckForAggro -targetid|${corpseID}
/if (${itemSwapped}) /call ItemSwapCheck
/doevents
/if (${gotAggro}) /return ABORT_AGGRO
/if (${Cast.Result.Equal[CAST_SUCCESS]}) {
/call AddRezTracker ${Target.ID}
/return COMPLETED_SUCCESS
} else {
/call EchoLog "Rez Failed, Reason: ${Cast.Result}" true
/return COMPLETED_FAIL
}
}
/return UNKNOWN
Sub AddRezTracker(int rezTrackID)
/declare rtLoop int local 0
/declare rtInt int local 0
/call CleanRezTracker
/for rtLoop 1 to 60
/if (!${rezTracker[${rtLoop}]}) /varset rtInt ${rtLoop}
/if (!${rtInt}) /next rtLoop
/if (!${rtInt}) {
/call EchoLog "\ayThere are currently 60 corpses being tracked, no more can be tracked at this time."
} else {
/call EchoLog "Tracking ${Spawn[${rezTrackID}].CleanName}, number ${rtInt}" true
/if (!${Defined[rezTimer${rtInt}]}) /declare rezTimer${rtInt} timer outer
/varset rezTimer${rtInt} ${rezTimerStr}
/varset rezTracker[${rtInt}] ${rezTrackID}
}
/return
Sub OkToRez(int rezCheckID)
/declare retValue bool local true
/declare rtLoop int local 0
/declare rtFound bool local false
/for rtLoop 1 to 60
/if (${rezTracker[${rtLoop}]} == ${rezCheckID}) {
/varset rtFound true
/if (${rezTimer${rtLoop}}) {
/varset retValue false
} else {
/varset retValue true
/varset rezTracker[${rtLoop}] 0
}
}
/if (!${rtFound}) /next rtLoop
/if (!${rtFound}) /varset retValue true
/return ${retValue}
Sub CleanRezTracker
/declare rtLoop int local
/for rtLoop 1 to 60
/if (${rezTracker[${rtLoop}]}) {
/if (!${Spawn[${rezTracker[${rtLoop}]}].ID} || ${Spawn[${rezTracker[${rtLoop}]}].Type.NotEqual[Corpse]}) /varset rezTracker[${rtLoop}] 0
}
/next rtLoop
/return
Sub TrackPromise(int playerID, int SpellID)
/if (!${Defined[playerID]}) /return
/declare pLoop int local 0
/declare pInt int local 0
/for pLoop 1 to 20
/if (${promiseTrack[${pLoop}]} == ${playerID}) /varset pInt ${pLoop}
/if (!${pInt}) /next pLoop
/if (${pInt}) {
/if (${promiseTrackTimer${pInt}}) {
/return FALSE
} else {
/varset promiseTrack[${pInt}] 0
/return TRUE
}
} else {
/if (${Defined[SpellID]}) {
/varset pInt 0
/for pLoop 1 to 20
/if (!${promiseTrack[${pLoop}]}) {
/varset pInt ${pLoop}
/varset promiseTrack[${pLoop}] ${playerID}
/if (!${Defined[promiseTrackTimer${pLoop}]}) /declare promiseTrackTimer${pLoop} timer outer
/varset promiseTrackTimer${pLoop} ${Math.Calc[${Spell[${SpellID}].Duration} * 6 + 1]}s
}
/if (!${pInt}) /next pLoop
} else {
/return TRUE
}
}
/return FALSE
Sub TrackHoT(int playerID, int SpellID)
/if (!${Defined[playerID]}) /return
/declare pLoop int local 0
/declare pInt int local 0
/for pLoop 1 to 20
/if (${hotTrack[${pLoop}]} == ${playerID}) /varset pInt ${pLoop}
/if (!${pInt}) /next pLoop
/if (${pInt}) {
/if (${hotTrackTimer${pInt}}) {
/return FALSE
} else {
/varset hotTrack[${pInt}] 0
/return TRUE
}
} else {
/if (${Defined[SpellID]}) {
/varset pInt 0
/for pLoop 1 to 20
/if (!${hotTrack[${pLoop}]}) {
/varset pInt ${pLoop}
/varset hotTrack[${pLoop}] ${playerID}
/if (!${Defined[hotTrackTimer${pLoop}]}) /declare hotTrackTimer${pLoop} timer outer
/varset hotTrackTimer${pLoop} ${Math.Calc[${Spell[${SpellID}].Duration} * 6 + 1]}s
}
/if (!${pInt}) /next pLoop
} else {
/return TRUE
}
}
/return FALSE
And it will sure load the setting from shmbotsettings_YourCharName.ini
Here is my sham.ini
Code:
[General]
MinSafeDistance=5
CampRadius=60
ResistTries=3
TimeToSitAfterCast=3s
ReplyToTells=false
LootCorpses=false
UnsafePCAction=continue
AllowInterrupt=true
AllowSit=true
PullerName=group
MainAssist=group
MainTank=group
GroupBuffAtStart=true
SelfBuffAtStart=true
HealAtStart=true
DebuffAtStart=true
HealPets=true
MinBuffCheckTimer=1m
HealCheckTime=0s
Announcements=true
AnnounceChan=/g
RezSpell=Null
RezSlot=Null
RezAnnounce=Reviviscence (96% rez) in on %t
YaulpSpell=
YaulpSlot=
EmergencyHealHP=30
UseEpicBalance=false
UseAABalance=False
[SelfBuffs]
Value=0
SelfBuffName1=Cryostasis Fragment Ring
SelfBuffText1=Knowledge of the Past V
SelfBuffSlot1=item
SelfBuffName2=Grlax's Belt
SelfBuffText2=Expanding Mind II
SelfBuffSlot2=item
SelfBuffName3=Slagstone
SelfBuffText3=Prismatic Ward III
SelfBuffSlot3=item
SelfBuffName4=Merciless Visage of Discord
SelfBuffText4=Form of Endurance VII
SelfBuffSlot4=item
[GroupBuffs]
Value=6
GroupBuffGroup1=Talisman of Unity Rk. II
GroupBuffGroupDisplayName1=Talisman of Unity Rk. II
GroupBuffSingle1=Talisman of Unity Rk. II
GroupBuffSingleDisplayName1=Talisman of Unity Rk. II
GroupBuffAlias1=Shielding
GroupBuffTargets1=WAR|SHD|PAL|RNG|MNK|ROG|BRD|BST|BER|SHM|CLR|DRU|WIZ|MAG|ENC|NEC
GroupBuffSlot1=gem6
GroupBuffCombat1=false
GroupBuffGroupAnnounce1=Unity inc on group
GroupBuffSingleAnnounce1=Unity inc on %t
GroupBuffAuto1=TRUE
GroupBuffGroupMin1=1
GroupBuffGroup2=Talisman of Celerity
GroupBuffGroupDisplayName2=Talisman of Celerity
GroupBuffSingle2=Talisman of Celerity
GroupBuffSingleDisplayName2=Talisman of Celerity
GroupBuffAlias2=Haste
GroupBuffTargets2=WAR|SHD|PAL|RNG|MNK|ROG|BRD|BST|BER|SHM|CLR|DRU|WIZ|MAG|ENC|NEC
GroupBuffSlot2=gem7
GroupBuffCombat2=false
GroupBuffGroupAnnounce2=Haste inc
GroupBuffSingleAnnounce2=Haste inc on %t
GroupBuffAuto2=TRUE
GroupBuffGroupMin2=1
GroupBuffGroup3=Champion
GroupBuffGroupDisplayName3=Champion
GroupBuffSingle3=Champion
GroupBuffSingleDisplayName3=Champion
GroupBuffAlias3=Champion
GroupBuffTargets3=WAR|SHD|PAL|RNG|MNK|ROG|BRD|BST|BER|SHM|CLR|DRU|WIZ|MAG|ENC|NEC
GroupBuffSlot3=gem8
GroupBuffCombat3=false
GroupBuffGroupAnnounce3=Champion inc
GroupBuffSingleAnnounce3=Champion inc %t
GroupBuffAuto3=TRUE
GroupBuffGroupMin3=1
GroupBuffGroup4=Null
GroupBuffGroupDisplayName4=Null
GroupBuffSingle4=Wild Growth Rk. II
GroupBuffSingleDisplayName4=Wild Growth Rk. II
GroupBuffAlias4=hp
GroupBuffTargets4=MT
GroupBuffSlot4=gem10
GroupBuffCombat4=False
GroupBuffGroupAnnounce4=WG inc
GroupBuffSingleAnnounce4=WG inc on %t
GroupBuffAuto4=TRUE
GroupBuffGroupMin4=1
GroupBuffGroup5=Talisman of the Lynx Rk. II
GroupBuffGroupDisplayName5=Talisman of the Lynx Rk. II
GroupBuffSingle5=Null
GroupBuffSingleDisplayName5=Null
GroupBuffAlias5=Proc
GroupBuffTargets5=MT
GroupBuffSlot5=Null
GroupBuffCombat5=TRUE
GroupBuffGroupAnnounce5=Lynx inc on group
GroupBuffSingleAnnounce5=Lynx inc on %t
GroupBuffAuto5=TRUE
GroupBuffGroupMin5=1
GroupBuffGroup6=Blessed Spiritstaff of the Heyokah
GroupBuffGroupDisplayName6=Prophet's Gift of the Ruchu
GroupBuffSingle6=Null
GroupBuffSingleDisplayName6=Null
GroupBuffAlias6=ep2.0
GroupBuffTargets6=WAR|SHD|PAL|RNG|MNK|ROG|BRD|BST|BER
GroupBuffSlot6=item
GroupBuffCombat6=TRUE
GroupBuffGroupAnnounce6=Ep2.0 inc
GroupBuffSingleAnnounce6=Ep2.0 inc on %t
GroupBuffAuto6=TRUE
GroupBuffGroupMin6=1
[SafePCs]
Value=0
PCName1=
[LeaveLoot]
LootNoDrop=true
LeaveUnknown=true
Value=0
LootItem1=pearl
LootAlert1=f:\kungfu.mp3
[WantedLoot]
Value=2
LootItem1=pearl
LootAlert1=f:\kungfu.mp3
LootItem2=spell
[DestroyLoot]
DestroyUnknown=false
Value=0
LootItem1=
[IgnoreMobs]
Value=0
MobName1=
[Debuffs]
DebuffAdds=false
Value=0
DebuffSpell1=Healing Counterbias
DebuffMinMana1=1
DebuffMinHPs1=10
DebuffMaxHPs1=99
DebuffMaxMobs1=100
DebuffMinMobs1=1
DebuffSpellSlot1=gem4
DebuffRecastDly1=400s
DebuffAnnounce1=HC SLOW on %t
[Heals]
OutOfCombatHeal=Halcyon Whisper Rk. II
OutOfCombatSlot=gem1
OutOfCombatHP=80
Value=2
HealName1=Dannal's Mending Rk. II
HealSlot1=gem2
HealMinGroup1=1
HealMinHP1=31
HealMaxHP1=80
HealClasses1=WAR|SHD|PAL|RNG|MNK|ROG|BRD|BST|BER|SHM|CLR|DRU|WIZ|MAG|ENC|NEC
HealAnnounce1=Dannal's Mending on %t
HealName2=Antecedent's Intervention Rk. II
HealSlot2=gem3
HealMinGroup2=1
HealMinHP2=1
HealMaxHP2=30
HealClasses2=WAR|SHD|PAL|RNG|MNK|ROG|BRD|BST|BER|SHM|CLR|DRU|WIZ|MAG|ENC|NEC
HealAnnounce2=Emergency Group heal inc, Save your life!
[Alerts]
AlertDeathAudioFile=null
AlertEvac=null
Value=0
AlertMobName1=null
AlertAudioFile1=null
I've test it some,seems works smooth...Just one problem i need to solve:
It will cast Turgur's Swarm over and over,But I already write
Code:
/if ( ${Target.PctHPs}<=98 && ${Me.AltAbilityReady[Turgur's Swarm]} && ${Target.Type.Equal[NPC]} && ${Target.Buff[Turgur's Swarm].ID}!= 13144) {
/gsay AA slow on %t!
/delay 1s
/aa act Turgur's Swarm
in Sub Slow,Why it will keep cast that? The /if condition ${Target.Buff[Turgur's Swarm].ID}!= 13144 didnt work??
And it also cast WG and Epic2.0 out of combat which i have set the "GroupBuffCombatX=TRUE" ,so need fix that too...other function basically works well.
Any comments would be thankful
Last edited: