objectdef oClass inherits oBase { /**************************************/ /************ VARIABLES ***************/ variable bool SaveShocks = FALSE variable int curePoisonTimer = 0 variable int cureDiseaseTimer = 0 variable int jumpTimer = 0 variable bool RunnerDealtWith = FALSE variable bool Revived = FALSE variable int ReincarnateCount = 0 variable int BackupAttempts = 0 variable string MobDataStorage = "./routines/MobData.xml" variable set MobDataImmunities variable set MobDataRunners variable collection:index:string RandomCast variable collection:int RandomCastCount /**************************************/ /***********Init & Shutdown************/ method Initialize() { LavishSettings:AddSet[MobData] LavishSettings[MobData]:Import[${MobDataStorage}] This:LoadConfig This:InitShamanGUI This:CreateUIErrorStrings This:InitTriggers This.MobDataImmunities:Clear This.MobDataRunners:Clear This:LoadList[MobDataImmunities] This:LoadList[MobDataRunners] Bot:AddPulse["Class","Pulse",10,TRUE,TRUE] UIElement[ClassGUI].FindChild[Console]:Echo["^_^=================================^_^"] UIElement[ClassGUI].FindChild[Console]:Echo[" Swolbyn's Shaman Routine v0.6"] UIElement[ClassGUI].FindChild[Console]:Echo["^_^=================================^_^"] } method Shutdown() { This:SaveConfig This:RemoveTriggers This:ExportList[MobDataImmunities] This:ExportList[MobDataRunners] LavishSettings[MobData]:Export[${MobDataStorage}] } method Pulse() { ExecuteQueued } /**************************************/ /**********UI Error Strings************/ variable collection:string UIErrorMsgStrings method CreateUIErrorStrings() { This.UIErrorMsgStrings:Set["You are facing the wrong way!","backward"] This.UIErrorMsgStrings:Set["Target too close","backward"] This.UIErrorMsgStrings:Set["You are too far away!","forward"] This.UIErrorMsgStrings:Set["Out of range.","forward"] } variable bool needUIHook = TRUE method UIErrorMessage(string Id, string Msg) { if ${This.UIErrorMsgStrings.Element[${Msg}](exists)} && !${Bot.PauseFlag} && ${This.crazyWaitTimer} < ${LavishScript.RunningTime} { if ${Msg.Equal["Target too close"]} || (${Target.Distance} < 5 && ${Me.InCombat}) || ${This.UIErrorMsgStrings.Element[${Msg}].Equal["forward"]} && !${Me.Casting} { This:Debug[${Msg}] This:CustOutput["Moving ${This.UIErrorMsgStrings.Element[${Msg}]} - UI Error: ${Msg}"] Navigator:FaceXYZ[${Target.X},${Target.Y},${Target.Z}] This.attackWaitTimer:Set[${This.InMilliseconds[25]}] This.pullWaitTimer:Set[${This.InMilliseconds[25]}] move ${This.UIErrorMsgStrings.Element[${Msg}]} 1000 wowpress JUMP return } } } /**************************************/ /*********External Mob Data************/ method LoadList(string loadingList) { variable iterator i if !${LavishSettings[MobData].FindSet[${loadingList}](exists)} LavishSettings[MobData]:AddSet[${loadingList}] LavishSettings[MobData].FindSet[${loadingList}]:GetSettingIterator[i] i:First while ${i.IsValid} { ${loadingList}:Add[${i.Key}] i:Next } } method ExportList(string loadingList) { variable iterator i LavishSettings[MobData].FindSet[${loadingList}]:Clear ${loadingList}:GetIterator[i] i:First while ${i.IsValid} { LavishSettings[MobData].FindSet[${loadingList}]:AddSetting[${i.Key},${i.Key}] i:Next } } /**************************************/ /**************Triggers****************/ method InitTriggers() { AddTrigger DetectRunner "[Event:@eventid@:CHAT_MSG_MONSTER_EMOTE](\"%%s attempts to run away in fear!\",\"@Mob@\",@*@" AddTrigger DetectImmune "[Event:@eventid@:CHAT_MSG_SPELL_SELF_DAMAGE](\"Your @FailedSpell@ failed. @Mob*@ is immune.@*@" } method RemoveTriggers() { RemoveTrigger DetectRunner RemoveTrigger DetectImmune } function DetectRunner(string Line, int eventid, string Mob) { if !${This.MobDataRunners.Contains[${Mob}]} { This:CustOutput["Added ${Mob} to the runner list"] This.MobDataRunners:Add[${Mob}] } } function DetectImmune(string Line, int eventid, string FailedSpell, string Mob) { variable string MobId MobId:Set[${Mob}#${FailedSpell}] if !${This.MobDataImmunities.Contains[${MobId}]} { This:CustOutput["Added ${MobId} to the mob immune list"] This.MobDataImmunities:Add[${MobId}] } } /**************************************/ /***********Character States***********/ member isRunner() { if ${This.MobDataRunners.Contains[${Target.Name}]} return TRUE return FALSE } member isImmune(string SpellName) { if ${This.MobDataImmunities.Contains[${Target.Name}#${SpellName}]} return TRUE return FALSE } member isPoisoned() { BuffNum:Set[1] while ${BuffNum} < 16 { BuffNum:Inc if ${Me.Buff[${BuffNum}].DispelType.Equal[Poison]} { return TRUE } } return FALSE } member isDiseased() { BuffNum:Set[1] while ${BuffNum} < 16 { BuffNum:Inc if ${Me.Buff[${BuffNum}].DispelType.Equal[Disease]} { return TRUE } } return FALSE } /**************************************/ /************Reincarnation*************/ member NeedDead() { if !${This.Revived} && ${This.ReincarnateCount} < 10 && (${Me.Dead} || ${Me.Ghost}) { return TRUE } else { return FALSE } } method DeadPulse() { This:Output["Bad Shaman! you died?!"] Bot.RandomPause:Set[25] This.ReincarnateCount:Inc } /**************************************/ /****************Rest******************/ member NeedRest() { if ${This.LootFirst} return FALSE } method RestPulse() { if !${Me.Dead} && !${Me.Ghost} This:Revived:Set[FALSE] if ((${Me.PctMana} >= ${This.StandMP}) && (${Me.PctHPs} >= ${This.StandHP})) && ${Me.Sitting} { Toon:Standup This:Output["Standing."] return } if ${Me.PctMana} < ${This.RestMP} && ${Toon.canCast[Mana Spring Totem]} && !${This.OwnedTotemsCheck[Mana Spring Totem]} && ${This.HasWaterTotem} && !${Consumable.HasDrink} && !${Me.Buff[Drink](exists)} && !${Me.Swimming} && !${Me.InCombat} && !${Me.Casting} { Toon:CastSpell[Mana Spring Totem] This:CustOutput["Casting Mana Spring Totem"] } } /**************************************/ /****************Buff******************/ member NeedBuff() { if ${Me.Swimming} && !${Object[-dead,-range 0-5](exists)} return TRUE if ${Mount.IsMounted} return FALSE if ${Me.Swimming} && ${Toon.canCast[Water Walking]} && ${Item[-inventory,"Fish Oil"](exists)} && !${Me.Buff[Water Walking](exists)} { This:CustOutput["Swimming, need water walking"] return TRUE } if ${Me.Swimming} && !${Me.Race.Find[Undead]} && ${Toon.canCast[Water Breathing]} && ${Item[-inventory,"Shiny Fish Scales"](exists)} && !${Me.Buff[Water Breathing](exists)} { This:CustOutput["Swimming, need water breathing"] return TRUE } if ${Toon.canUseScroll} { This:CustOutput["Need a scroll buff"] return TRUE } } method BuffPulse() { if ${Me.Swimming} { if ${This.jumpTimer} < ${LavishScript.RunningTime} { wowpress JUMP This.jumpTimer:Set[${This.InSeconds[5]}] } if ${Target(exists)} { Toon:ToMelee } return } if ${Me.Swimming} && ${Toon.canCast[Water Walking]} && ${Item[-inventory,"Fish Oil"](exists)} && !${Me.Buff[Water Walking](exists)} { Toon:CastSpell[Water Walking] This:CustOutput["Casting Water Walking"] return } if ${Me.Swimming} && !${Me.Race.Find[Undead]} && ${Toon.canCast[Water Breathing]} && ${Item[-inventory,"Shiny Fish Scales"](exists)} && !${Me.Buff[Water Breathing](exists)} { Toon:CastSpell[Water Breathing] This:CustOutput["Casting Water Breathing"] return } } /**************************************/ /**************************************/ method CombatBuffPulse() { if ${Me.Sitting} Toon:Standup if ${Toon.canCast["Nature's Swiftness"]} { Toon:CastSpell["Nature's Swiftness"] return } } /**************************************/ /****************Pull******************/ method PullPulse() { if ${Me.Sitting} Toon:Standup if ${Target.PctHPs} == 100 { ; Creature is 100% life, assuming new target resetting runner logic This.RunnerDealtWith:Set[FALSE] This.BackupAttempts:Set[0] } } /**************************************/ /***************Attack*****************/ method AttackPulse() { if ${Me.Sitting} Toon:Standup if ${This.HaveAdds} && ${Toon.canCast[War Stomp]} && !${Me.Casting} { Toon:CastSpell[War Stomp] } if ${Target.Distance} < ${Toon.MinMelee} && ${This.BackupAttempts} < 6 && !${Me.Casting} { This:Output["Backing up... wtf"] This.BackupAttempts:Inc Navigator:FaceXYZ[${Target.X},${Target.Y},${Target.Z}] Navigator:MoveBackward[200] return } if ${Target.Distance} > ${Toon.MaxMelee} && !${Me.Casting} { This:Output["Chasing down ${Target.Name}"] Navigator:FaceXYZ[${Target.X},${Target.Y},${Target.Z}] wowpress -hold moveforward return } else { Toon:Stop } if ${Target.Dead} return if !${This.RunnerDealtWith} && ${Target.PctHPs} < 40 && ${This.isRunner} { Navigator:FaceXYZ[${Target.X},${Target.Y},${Target.Z}] if ${Toon.canCast[Frost Shock]} && !${This.isImmune[Frost Shock]} { Toon:CastSpell[Frost Shock] This:CustOutput["Casting Frost Shock on a runner"] This.RunnerDealtWith:Set[TRUE] return } if ${Toon.canCast[Earthbind Totem]} && !${This.OwnedTotemsCheck[Earthbind Totem]} && ${This.HasEarthTotem} { Toon:CastSpell[Earthbind Totem] This:CustOutput["Casting Earthbind Totem to catch a runner"] This.RunnerDealtWith:Set[TRUE] return } } if ${Me.PctHPs} < ${This.HealWave} && ${Toon.canCast[Healing Wave]} && !${Me.Casting} && ${This.healWaitTimer} < ${LavishScript.RunningTime} { Toon:CastSpell[Healing Wave] This:CustOutput["Casting Healing Wave"] This.healWaitTimer:Set[${This.InSeconds[4]}] return } if ${Me.PctHPs} < ${This.LHealWave} && ${Toon.canCast[Lesser Healing Wave]} && !${Me.Casting} && ${This.healWaitTimer} < ${LavishScript.RunningTime} { Toon:CastSpell[Lesser Healing Wave] This:CustOutput["Casting Lesser Healing Wave"] This.healWaitTimer:Set[${This.InSeconds[4]}] return } if ${Target.Dead} return if ${Dangerlvl} >= 1 { if ${Target.PctHPs} > 50 || ${This.HaveAdds} { Navigator:FaceXYZ[${Target.X},${Target.Y},${Target.Z}] if ${This.HaveAdds} && ${Toon.canCast[Stoneclaw Totem]} && !${This.OwnedTotemsCheck[Stoneclaw Totem]} && ${This.HasEarthTotem} { Toon:CastSpell[Stoneclaw Totem] This:CustOutput["Casting Stoneclaw Totem because of Add!"] return } } } if ${Target.Dead} return if ${This.HaveAdds} && ${Toon.canCast[Shamanistic Rage]} { Toon:CastSpell[Shamanistic Rage] This:CustOutput["Casting Shamanistic Rage!!!"] return } Navigator:FaceXYZ[${Target.X},${Target.Y},${Target.Z}] if ${This.HaveAdds} && ${Toon.canCast[Chain Lightning]} && ${Me.PctMana} > ${This.ConserveMana} && !${This.MeleeOnly} && ${This.UseChainLight} { Toon:CastSpell[Chain Lightning] This:CustOutput["Casting Chain Lightning due to an add!"] return } if ${Target.Dead} { WoWScript ClearTarget() return } if !${This.SaveShocks} || (${This.SaveShocks} && ${Me.Buff[Focused](exists)}) { if ${Toon.canCast[Earth Shock]} && !${This.isImmune[Earth Shock]} && ${Target.Buff[Stormstrike](exists)} && ${Target.Distance} < ${This.MaxShockRange} { Toon:CastSpell[Earth Shock] This:CustOutput["Casting Earth Shock on Stormstruck ${Target}!"] return } } } /**************************************/ /**************************************/ /*************Aggro & Adds*************/ member HaveAdds() { variable guidlist AggroList AggroList:Clear AggroList:Search[-units,-nearest,-nopets,-aggro,-alive,-range 0-30] if ${AggroList.Count} >= 2 { return TRUE } else { return FALSE } } /**************************************/ /***********Spells & Casting***********/ method AddRandom(string spellGroup, string spellName) { if !${This.RandomCast.Element[${spellGroup}](exists)} && ${Bot.Started} { This.RandomCast:Set[${spellGroup}] This.RandomCastCount:Set[${spellGroup},0] } This.RandomCast.Element[${spellGroup}]:Insert[${spellName}] This.RandomCastCount.Element[${spellGroup}]:Inc } member CastRandom(string spellGroup, string checkBuff=NULL) { variable int attempts = 0 variable int spellNum = 1 spellNum:Inc[${Math.Rand[${This.RandomCastCount.Element[${spellGroup}]}]}] do { if ${spellNum} > ${This.RandomCastCount.Element[${spellGroup}]} { spellNum:Inc } if ${Toon.canCast[${This.RandomCast.Element[${spellGroup}].Get[${spellNum}]}]} && !${This.isImmune[${This.RandomCast.Element[${spellGroup}].Get[${spellNum}]}]} { if ${checkBuff.Equal[Target]} || ${checkBuff.Equal[Me]} { if !${${checkBuff}.Buff[${This.RandomCast.Element[${spellGroup}].Get[${spellNum}]}](exists)} { Toon:CastSpell[${This.RandomCast.Element[${spellGroup}].Get[${spellNum}]}] This:Output["Casting Random Buff#${spellNum}:${This.RandomCast.Element[${spellGroup}].Get[${spellNum}]}"] return TRUE } } else { Toon:CastSpell[${This.RandomCast.Element[${spellGroup}].Get[${spellNum}]}] This:Output["Casting Random#${spellNum}:${This.RandomCast.Element[${spellGroup}].Get[${spellNum}]}"] return TRUE } } spellNum:Inc } while ${attempts:Inc} <= ${This.RandomCastCount.Element[${spellGroup}]} return FALSE } method CastRandom(string spellGroup, string checkBuff=NULL) { if !${This.CastRandom[${spellGroup},${checkBuff}]} { This:Debug[RandomCast ${spellGroup} failed] } } member LootFirst() { if ${Me.Sitting} || ${Me.Casting} return FALSE if ${Unit[-dead,-lootable,-range 0-10](exists)} return TRUE if ${Toon.HasSkill[Skinning]} { if ${Unit[-dead,-skinnable,-range 0-10](exists)} && ${Item[-inventory,"Skinning Knife"](exists)} return TRUE } if ${LavishScript.RunningTime} <= ${State.LOOTState_Loot_Wait_Until} return TRUE return FALSE } /**************************************/ /*************Other Misc***************/ }