#define TOON_NONE 0 #define TOON_ATTACK 1 #define TOON_ENGAGE 2 #define TOON_BACKUP 3 #define TOON_CASTING 4 #define TOON_SPELLTARGET 5 #define TOON_FACING 6 #define TOON_LOOT 7 #define TOON_SHIFT 8 #define TOON_UNSHIFT 9 #define TOON_WAIT 10 #define TOON_NEEDFACE 11 #define TOON_CLEARTARGET 12 #define TOON_STOPMOVE 13 #define STAT_ATP 1 #define STAT_HPS 2 #define STAT_AGI 3 #define STAT_STR 4 #define STAT_INT 5 #define STAT_SPI 6 #define STAT_STA 7 objectdef oToonBase inherits oBase { /* * Public var */ variable int MinCombatRange = 1 variable int MaxCombatRange = 5 variable int RepairPct = 20 variable int KeepFreeSlots = 3 variable int MountDistance = 400 variable bool Loot = TRUE variable int CorpseCampLimit = 2 variable int ExitOnStuck = 0 variable settingsetref ToonConfig variable int PrimaryStat = STAT_AGI variable int SecondaryStat = STAT_STA variable bool AutoEquip = FALSE /* * Private var */ variable int WaitUntil = 0 variable bool Herbalist = FALSE variable bool Miner = FALSE /* * Target selection */ member WantTarget(string GUID) { /* * Keep aggro related first! */ if ${Unit[${GUID}].Target.Name.Equal[${Me.Name}]} { return TRUE } if ${Object[${GUID}].Tapped} { return FALSE } if ${Math.Distance[${Me.Z},${Object[${GUID}].Z}]} > 4 { return FALSE } if ${Unit[${GUID}].Level} < ${Math.Calc[${Me.Level} - 5]} { return FALSE } if ${Unit[${GUID}].Level} > ${Math.Calc[${Me.Level} + 2]} { return FALSE } if ${Object[${GUID}].FactionGroup.Equal[${Me.FactionGroup}]} { return FALSE } if !${Grind.InRoamRange[${GUID}]} { return FALSE } return TRUE } member TargetPriority(string GUID, int BasePriority) { variable objectref Data variable int Priority Data:Set[${GUID}] Priority:Set[${BasePriority}] if ${Data.Aggro} || ${Environment.ImTheTarget[${GUID}]} { Priority:Dec[40] } switch ${Data.ReactionLevel} { case 3 Priority:Dec[20] break case 4 Priority:Inc[20] break } Priority:Inc[${Data.Distance}] return ${Priority} } /* * Pull */ member NeedPull() { return FALSE } method PullPulse() { } /* * Buff */ member NeedBuff() { return FALSE } method BuffPulse() { } /* * Sit & stand */ method Sit() { if !${Me.Sitting} { wowpress sitorstand } } method Stand() { if ${Me.Sitting} { wowpress sitorstand } } /* * Rest */ member NeedRest() { if ${Me.PctHPs} < 50 { return TRUE } return FALSE } method RestPulse() { } /* * Gathering */ member IsSkinner() { if ${Item[-inventory,"Skinning Knife"](exists)} { return TRUE } return FALSE } member IsHerbalist() { return ${This.Herbalist} } member IsMiner() { if ${This.Miner} && ${Item["Mining Pick"](exists)} { return TRUE } return FALSE } /* * Casting */ member CanCast(string SpellName) { if !${Spell["${SpellName}"](exists)} { return FALSE } if ${Spell["${SpellName}"].Cooldown} { return FALSE } return TRUE } method CastSpell(string SpellName) { if !${This.CanCast[${SpellName}]} { return } if ${Navigator.HaveDestination} { Navigator:ResetDestination } Cast "${SpellName}" } method CastInstantSpell(string SpellName) { if !${This.CanCast[${SpellName}]} { return } Cast "${SpellName}" This:Wait[100] } /* * Routine */ method Routine() { if !${Me.Attacking} { WoWScript AttackTarget() } } /* * Attack */ method DropOutOfCombat() { Environment:ClearTarget() } member AttackState() { if !${This.DoneWaiting} { return TOON_WAIT } if ${WoWScript[SpellIsTargeting()]} { return TOON_SPELLTARGET } if ${Math.Abs[${Me.Heading}-${Me.HeadingTo[${Target.X},${Target.Y}]}]} > 10 && ${Target.Distance} < ${This.MaxCombatRange} { return TOON_NEEDFACE } if ${Me.Casting} { return TOON_CASTING } if ${Target.Dead} { return TOON_CLEARTARGET } if ${Target.Distance} >= ${This.MaxCombatRange} { return TOON_ENGAGE } if ${Target.Distance} < ${This.MinCombatRange} { return TOON_BACKUP } if ${Target.Distance} > ${This.MinCombatRange} && ${Target.Distance} < ${This.MaxCombatRange} && ${Movement.Moving} { return TOON_STOPMOVE } if ${ISXWoW.Facing} { return TOON_FACING } return TOON_ATTACK } method AttackPulse() { This.CurrentState:Set[${This.AttackState}] switch ${This.CurrentState} { case TOON_CASTING break case TOON_NEEDFACE Navigator:FaceXYZ[${Target.X},${Target.Y},${Target.Z}] break case TOON_FACING break case TOON_BACKUP break case TOON_SPELLTARGET SpellTarget ${Target.GUID} if ${WoWScript[SpellIsTargeting()]} { WoWScript SpellStopTargeting() } break case TOON_ENGAGE if !${Navigator.MovingToObject[${Target.GUID}]} { Navigator:MoveTo[${Target.X}, ${Target.Y}, ${Target.Z}] } break case TOON_ATTACK This:Routine break case TOON_STOPMOVE Navigator:ResetDestination move -stop break case TOON_CLEARTARGET WoWScript ClearTarget() break case TOON_WAIT break } } /* * Subscribed events */ method SpellCastSucceeded() { This:Wait[${Math.Calc[10 + ${This.Lag}]}] } method ErrorMessage(int EventID, string EventString, string Message) { if ${Message.Equal["You cannot attack that target."]} { Environment:BlackListGUID["${Target.GUID}"] Environment:ClearTarget } } /* * */ method Wait(int MiliSeconds) { This.WaitUntil:Set[${Math.Calc[${LavishScript.RunningTime} + ${MiliSeconds}]}] } member DoneWaiting() { if ${This.WaitUntil} < ${LavishScript.RunningTime} { return TRUE } return FALSE } /* * Misc */ member Lag() { return ${WoWScript[GetNetStats(),3]} } member GotSkill(string SkillName) { variable int Idx = 1 do { WoWScript ExpandSkillHeader(${Idx}) if ${WoWScript[GetSkillLineInfo(${Idx})].Equal["${SkillName}"]} { return TRUE } } while ${WoWScript[GetSkillLineInfo(${Idx:Inc})](exists)} return FALSE } /* * GUI */ method ToonGUIVisible(bool Show) { LavishSettings["ByteBot"].FindSet["GUI"]:AddSetting["Toon",${Show}] if ${Show} { UIElement[ToonGUI]:Show } else { UIElement[ToonGUI]:Hide } } /* * Config */ method LoadConfig() { This.MinCombatRange:Set[${This.ToonConfig.FindSetting["MinCombatRange",1]}] This.MaxCombatRange:Set[${This.ToonConfig.FindSetting["MaxCombatRange",5]}] This.RepairPct:Set[${This.ToonConfig.FindSetting["RepairPct",20]}] This.KeepFreeSlots:Set[${This.ToonConfig.FindSetting["KeepFreeSlots",3]}] This.MountDistance:Set[${This.ToonConfig.FindSetting["MountDistance",400]}] This.Loot:Set[${This.ToonConfig.FindSetting["Loot",TRUE]}] This.CorpseCampLimit:Set[${This.ToonConfig.FindSetting["CorpseCampLimit",2]}] This.ExitOnStuck:Set[${This.ToonConfig.FindSetting["ExitOnStuck",0]}] This.PrimaryStat:Set[${This.ToonConfig.FindSetting["PrimaryStat",STAT_AGI]}] This.SecondaryStat:Set[${This.ToonConfig.FindSetting["SecondaryStat",STAT_STA]}] This.AutoEquip:Set[${This.ToonConfig.FindSetting["AutoEquip",FALSE]}] } /* * */ method InitToon() { } method Plugin() { ui -load "class/${Me.Class}.xml" This:ToonGUIVisible[${LavishSettings["ByteBot"].FindSet["GUI"].FindSetting["Toon",TRUE]}] LavishScript:RegisterEvent[TOON_GUI_VISIBLE] LavishSettings:AddSet["Class"] LavishSettings["Class"]:Clear LavishSettings["Class"]:Import["etc/class.xml"] This.ToonConfig:Set[${LavishSettings["Class"].FindSet["${Me.Class}"]}] if !${ToonConfig} { LavishSettings["Class"]:AddSet["${Me.Class}"] This.ToonConfig:Set[${LavishSettings["Class"].FindSet["${Me.Class}"]}] } This:LoadConfig Event[UI_ERROR_MESSAGE]:AttachAtom[${This.ObjectName}:ErrorMessage] Event[UNIT_SPELLCAST_SUCCEEDED]:AttachAtom[${This.ObjectName}:SpellCastSucceeded] Event[TOON_GUI_VISIBLE]:AttachAtom[${This.ObjectName}:ToonGUIVisible] This.Herbalist:Set[${This.GotSkill["Herbalism"]}] if ${This.Herbalist} { This:Echo["I am gay and I like to pick flowers."] } This.Miner:Set[${This.GotSkill["Mining"]}] if ${This.Miner} { This:Echo["I am a miner."] } This:InitToon } method Shutdown() { LavishSettings["Class"]:Export["etc/class.xml"] Event[UI_ERROR_MESSAGE]:DetachAtom[${This.ObjectName}:ErrorMessage] Event[UNIT_SPELLCAST_SUCCEEDED]:DetachAtom[${This.ObjectName}:SpellCastSucceeded] Event[TOON_GUI_VISIBLE]:Unregister ui -unload "class/${Me.Class}.xml" } }