; 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
}
}