; Immolator's OpenBot Frost Mage Routine ; ; History: ; Legend: E = Enhancement, F = Fix, C = Change ; v1.0.0 ; E: First version, put up a skeleton for all the necessary functions ; E: Faces mob while casting ; E: Eats, drinks and buffs ; E: Combat added, pulls and fights ; E: Uses Ice Barrier ; E: Uses Evocation ; E: Uses Water Elemental ; v1.0.1 ; F: Fixed constant unnecessary downtime ; F: Removed an unused variable ; F: Fixed major bug in alpha version that made routine unusable ; E: Rewrote rest routine (stability/intelligence) ; E: Rewrote combat routine (stability/intelligence) ; E: Rewrote pull routine (stability/intelligence) ; v1.0.2 ; E: Added Counterspell support ; E: Improved Water Elemental support ; E: Simplified a whole bunch of code whilst maintaining functionality ; E: Added mana gem support ; v1.0.3 ; E: Commented a lot more of the code ; F: Fixed a bug with the water elemental ; F: Fixed Evocation (Large bug) ; ; Todo: ; Better combat sequence ; Bandages ; Potions ; Scrolls ; Polymorph ; Better Water Elemental ; Better Evocation ; Fix buggy downtime sequence ; Wards ; Immunity detection ; Mana shield on panic ; Trinkets ; Racials objectdef oClass inherits oBase { ; Customize these variables to suit your needs: variable int PullRange = 35 ; The spell used to pull mobs variable string PullSpell = "Frostbolt" ; The armour spell used (Ice Armour, Frost Armour, Mage Armour) variable string ArmourBuff = "Ice Armor" ; Whether to use Dampen Magic or not variable bool UseDampen = TRUE ; Whether to use Polymorph or not - Not used yet variable bool UsePoly = TRUE ; Whether to use spell wards (Fire/Frost) - Not used yet variable bool UseWards = TRUE ; Rest when at this amount of mana variable int MinMana = 70 ; Stop resting when at this amount of mana variable int MaxMana = 90 ; Rest when at this amount of health variable int MinHealth = 70 ; Stop resting when at this amount of health variable int MaxHealth = 90 ; Do not change the variables below this line, they are set by the routine variable string ManaGem = NULL variable bool UseFireWard = FALSE variable bool UseFrostWard = FALSE variable bool ImmuneFrost = FALSE variable bool ImmuneFire = FALSE variable bool NeedRegen = FALSE method Initialize() { ; Get the latest mana gem and store it for later use This.ManaGem:Set[${This.GetManaGem}] } method CastingPulse() { ; Make sure we're facing our target when casting if ${Target.GUID.NotEqual[${Me.GUID}]} && ${Target(exists)} { Navigator:FaceXYZ[${Target.X},${Target.Y},${Target.Z}] } } method RestPulse() { ; Don't try to do other actions while casting if ${Me.Casting} { return } ; Stop moving so we can cast Move -stop ; Stand up when we're full, so we can cast if (${Me.PctMana} > ${This.MaxMana}) && (${Me.PctHPs} > ${This.MaxHealth}) { Toon:Standup } ; Don't attempt to do anything while eating/drinking if ${Me.Buff[Drink](exists)} || ${Me.Buff[Eat](exists)} { return } ; Check if we have water, if we don't, and we have free bag slots, then conjure some if !${Consumable.HasDrink} && (${Inventory.GetBagsInfo[RETRIEVE_FREESLOTS,"normal"]} > 0 ) && ${Toon.CastSpellGUID[${Me.GUID},Conjure Water]} { return } ; Check if we have food, if we don't, and we have free bag slots, then conjure some if !${Consumable.HasFood} && (${Inventory.GetBagsInfo[RETRIEVE_FREESLOTS,"normal"]} > 0 ) && ${Toon.CastSpellGUID[${Me.GUID},Conjure Food]} { return } ; Check if we have the highest available mana gem, if we don't, and we have free bag slots, then conjure one if !${Item[${This.ManaGem}](exists)} && (${Inventory.GetBagsInfo[RETRIEVE_FREESLOTS,"normal"]} > 0 ) && ${Toon.CastSpellGUID[${Me.GUID},Conjure ${This.ManaGem}]} { return } ; Make sure we our the desired armour buff if ${Toon.EnsureBuff[${Me.GUID},${This.ArmourBuff}]} { return } ; Make sure we have AI if ${Toon.EnsureBuff[${Me.GUID},Arcane Intellect]} { return } ; If we want to use dampen magic, then make sure we're using it if ${This.UseDampen} && ${Toon.EnsureBuff[${Me.GUID},Dampen Magic]} { return } if (${Consumable.HasDrink} && !${Me.Buff[Drink](exists)} && (${Me.PctMana} < ${This.MaxMana})) || (${Consumable.HasFood} && !${Me.Buff[Food](exists)} && (${Me.PctHPs} < ${This.MaxHealth})) { ; Drink if we need to if ${Consumable.HasDrink} && !${Me.Buff[Drink](exists)} && (${Me.PctMana} < ${This.MaxMana}) { Consumable:useDrink } ; Eat if we need to if ${Consumable.HasFood} && !${Me.Buff[Food](exists)} && (${Me.PctHPs} < ${This.MaxHealth}) { Consumable:useFood } return } } member NeedRest() { ; Don't rest if we're in combat if ${Me.InCombat} { return FALSE } ; Rest if we don't have any drinks, and we have a conjure spell if !${Consumable.HasDrink} && ${Spell[Conjure Water](exists)} { return TRUE } ; Rest if we don't have any food, and we have a conjure spell if !${Consumable.HasFood} && ${Spell[Conjure Food](exists)} { return TRUE } ; Rest if we don't have a mana gem, and we have a conjure spell if !${Item[${This.ManaGem}](exists)} && ${This.CheckSpell[Conjure ${This.ManaGem}]} { return TRUE } ; Rest if we need our desired armour buff if ${Toon.NeedBuff[${Me.GUID},${This.ArmourBuff}]} { return TRUE } ; Rest if we need AI if ${Toon.NeedBuff[${Me.GUID},Arcane Intellect]} { return TRUE } ; Rest if we want to use dampen, and we need it if ${This.UseDampen} && ${Toon.NeedBuff[${Me.GUID},Dampen Magic]} { return TRUE } ; Rest if we're below the desired health/mana threshold if (${Me.PctMana} < ${This.MaxMana}) || (${Me.PctHPs} < ${This.MaxHealth}) { return TRUE } ; If we get to here then we don't need to rest, so we can return false return FALSE } method PullPulse() { ; Stop moving before pull Move -stop ; Make sure we have Ice Barrier on pull if ${Toon.CastSpellGUID[${Target.GUID},Ice Barrier]} { return } ; Make sure we have our Water Elemental on pull if ${Toon.CastSpellGUID[${Target.GUID},Summon Water Elemental]} { return } ; Cast our pull spell on the target if ${Toon.CastSpellGUID[${Targeting.TargetCollection.Get[1]},${PullSpell}]} { return } if ${Me.Pet(exists)} && !${Me.Pet.Aggro} && !${Me.Pet.Casting(exists)} { WoWScript PetAttack() return } } method AttackPulse() { ; If our target is casting, then try to Counterspell it if ${Target.Casting(exists)} && ${Toon.CastSpellGUID[${Target.GUID},Counterspell]} { return } ; If we have Water Elemental out, then tell it to attack if ${Me.Pet(exists)} && !${Me.Pet.Aggro} && !${Me.Pet.Casting(exists)} { WoWScript PetAttack() } ; If we're out of mana, and Frost Nova and Evocation are ready, then attempt to Nova, back up, and Evocate if (${Target.Distance} < 10) && (${Me.PctMana} < 5) && ${This.CheckSpell[Frost Nova] } && ${This.CheckSpell[Evocation]} { if ${Toon.CastSpellGUID[${Target.GUID},Frost Nova]} { if ${Target.Distance} < 10 { Move Backward if ${Toon.CastSpellGUID[${Target.GUID},Evocation]} { return } return } return } return } ; If we're close enough to our target, then Frost Nova it if (${Target.Distance} < 10) && ${Toon.CastSpellGUID[${Target.GUID},"Frost Nova"]} { return } ; If we're out of range of our main nuke, then face our target get in range if (${Target.Distance} > 34) { Navigator:FaceXYZ[${Target.X},${Target.Y},${Target.Z}] Move Forward return } ; If the mob is frozen (by Nova or Frostbite) and we're close to it, then back up if (${Target.Buff[Frost Nova](exists)} || ${Target.Buff[Frostbite](exists)}) && (${Target.Distance} < 10) { Move Backward return } ; If we don't have Ice Barrier up then try to cast it if !${Me.Buff[Ice Barrier](exists)} && ${Toon.CastSpellGUID[${Target.GUID},Ice Barrier]} { return } ; If we're low on mana and we have a usable gem, then use it if ${Me.PctMana}<5 && ${Item[${This.ManaGem}].Usable} { Item[${This.ManaGem}]:Use return } ; If we're low on mana or the mob is low on health then Wand it if ${Me.PctMana}<5 || ${Target.PctHPs}<10 { Move -stop if ${Toon.CastSpellGUID[${Target.GUID},Shoot]} { return } } ; If we're in range then use Cone of Cold if (${Target.Distance} < 8) && ${Toon.CastSpellGUID[${Target.GUID},Cone of Cold]} { return } ; If we're in range then use Fire Blast if (${Target.Distance} < 20) && ${Toon.CastSpellGUID[${Target.GUID},Fire Blast]} { return } ; If everything else has been done then use Frostbolt if ${Toon.CastSpellGUID[${Target.GUID},Frostbolt]} { return } } ; +-----------------------------------------------------------------------------------------------------+ ; | Name: CheckSpell | ; | Arguments: String (Spell to check) | ; | Returns: Bool(If spell is ready or not) | ; | Description: Checks if a spell is ready for casting. | ; +-----------------------------------------------------------------------------------------------------+ member CheckSpell(string spellname) { ; Check if the spell exists, is not on cooldown, we have the required mana, and the spell is usable. If so, then return true. if ${Spell[${spellname}](exists)} && !${Spell[${spellname}].Cooldown} && (${Me.CurrentMana} >= ${Spell[${SpellName}].Mana}) && ${Spell[${spellname}].Action.Usable} { return TRUE } ; If any of the above return false, then the spell isn't ready for one or more reasons, so return false return FALSE } ; +-----------------------------------------------------------------------------------------------------+ ; | Name: GetManaGem | ; | Arguments: None | ; | Returns: String (Mana Gem name) | ; | Description: Finds highest available mana gem. | ; +-----------------------------------------------------------------------------------------------------+ member GetManaGem() { if ${Spell[Conjure Mana Emerald](exists)} { return "Mana Emerald" } if ${Spell[Conjure Mana Ruby](exists)} { return "Mana Ruby" } if ${Spell[Conjure Mana Citrine](exists)} { return "Mana Citrine" } if ${Spell[Conjure Mana Jade](exists)} { return "Mana Jade" } if ${Spell[Conjure Mana Agate](exists)} { return "Mana Agate" } ; If we don't have any mana gem spells available, then just return NULL return NULL } }