using System; using InnerSpaceAPI; using LavishScriptAPI; using PRModuleInterface; using PRCoreInterface; namespace PRModuleLibrary { // Main Code public partial class PRModule : IPlugin { //my delcares string WhichManaGem; bool UseFireWard; bool UseFrostWard; bool NeedBuffs; bool CheckedBuffs; string MyManaGem; CombatPrepStates CombatPrepStateSwitch = new CombatPrepStates(); RoutineStates RoutineStateSwitch = new RoutineStates(); PullingStates PullingStateSwitch = new PullingStates(); SingleTargetCombat SingleTargetCombatSwitch = new SingleTargetCombat(); DoubleTargetCombat DoubleTargetCombatSwitch = new DoubleTargetCombat(); MultiTargetCombat MultiTargetCombatSwitch = new MultiTargetCombat(); BuffStates BuffStateSwitch = new BuffStates(); public enum RoutineStates { CombatPrep, //Speaks for itself Pulling, //Speaks for itself Combat //The actual killing } public enum CombatPrepStates //apparently checking health is not needed { Buffing, //May just make this part of the CheckingBuffs. CheckingManaGem, //Speaks for itself PreCombatWards //I'll implement it if I have to. Do any pre-combat fire/frost wards on fire/frost damage dealers } public enum PullingStates { Advancing, //Get close if the mob wandered out of range for some reason. If it did, your pull range is probably too high Casting //the actual pulling } public enum SingleTargetCombat { Nuking, //our good 'ole spec-optimized nukes. PreFlee, //Mana-shield, snares, etc, while running from mobs SwapToDoubleTargetCombat //Escalate to doubletarget combat if a mob aggros, essentially just start the CC } public enum DoubleTargetCombat { Nuking, //Will be same as singletarget nuking, because it's really the same CrowdControl, //Snare mobs if possible, get away, sheep lower priority mob SwapToMultiTargetCobmat, //Switch to multi target combat if needed, not sure how well it'd work mostly because there's a good chance you'll be lowhp with adds. Flee? PreFlee //same as above } public enum MultiTargetCombat { AoENuking, //Fancy blizzarding, blast waving, etc. should really be a frostie for this... EmergencyCrowdControl, //snares and flares to get away if needed, probably be merged with preflee PreFlee //same as above } public enum BuffStates //kinda like sub-substates for buffing. It'll do my own downtime if I need to. { CheckingBuffs, //I'm going to have this here anyway because of waltz's current buff implementation CheckMana, //..... CastBuffs //Spec-optimized buffing. } private void GetCombatPrepState() { if (!CheckedBuffs) return CombatPrepStates.CheckingBuffs; if (!Requiem.Character.Buff("Arcane Intellect").IsValid || (!Requiem.Character.Buff("Molten Armor").IsValid && !Requiem.Character.Buff("Ice Armor").IsValid && !Requiem.Character.Buff("Frost Armor").IsValid)) return CombatPrepStates.Buffing; //currently lacking Dampen Magic if (MyManaGem == null || !Requiem.Inventory.GetItem(MyManaGem)) return CombatPrepStates.CheckingManaGem; if ((UseFireWard && !Requiem.Character.Buff("Fire Ward").IsValid) || (UseFrostWard && !Requiem.Character.Buff("Frost Ward").IsValid)) return CombatPrepStates.PreCombatWards; } private void CheckBuffs() { if (!Requiem.Character.Buff("Arcane Intellect")) { NeedArcInt = true; } if (!Requiem.Character.Buff("Ice Armor") && !Requiem.Character.Buff("Frost Armor") && !Requiem.Character.Buff("Molten Armor")) { NeedArmorSpell = true; } if (Requiem.Character.TargetList.Unit(0).Mana > 0 || UseFireWard || UseFrostWard) { NeedDampen = true; } } private void Buffs() { if (NeedArcInt) { Requiem.Character.Cast("Arcane Intellect", Requiem.Character.GUID); } if (NeedArmorSpell) { if (!Requiem.Character.Cast("Molten Armor")) { if (!Requiem.Character.Cast("Ice Armor")) { if (!Requiem.Character.Cast("Frost Armor")) { } } } } if (NeedDampen) { Requiem.Character.Cast("Dampen Magaic", Requiem.Character.GUID); } } private void CheckManaGem() { if (!Requiem.Inventory.GetItem("Mana Agate") && !Requiem.Inventory.GetItem("Mana Jade") && !Requiem.Inventory.GetItem("Mana Citrine") && !Requiem.Inventory.GetItem("Mana Ruby") && !Requiem.Inventory.GetItem("Mana Emerald")) { if (!Requiem.Character.Cast("Conjure Mana Emerald")) { if (!Requiem.Character.Cast("Conjure Mana Ruby")) { if (!Requiem.Character.Cast("Conjure Mana Citrine")) { if (!Requiem.Character.Cast("Conjure Mana Jade")) { if (!Requiem.Character.Cast("Conjure Mana Agate")) { } } } } } } } private void PreCombatWards() { if (UseFireWard) { Requiem.Character.Cast("Fire Ward", Requiem.Character.GUID); } if (UseFrostWard) { Requiem.Character.Cast("Frost Ward", Requiem.Character.GUID); } } //pull-related variables private void Pull() { if (PullWithPyroblast && !MobIsFireImmune)//Placeholder { if (GetPullState()) CastOnTarget("Pyroblast"); } if (PullWithFrostbolt && !MobIsFrostImmune) //Placeholder { if (GetPullState()) CastOnTarget("Frostbolt"); } if (!PullWithFrostbolt && !PullWithPyroblast && !MobIsFireImmune) { if (GetPullState()) CastOnTarget("Fireball"); } if ((PullWithPyroblast || !PullWithFrostbolt) && MobIsFireImmune) { if (GetPullState()) CastOnTarget("Frostbolt"); } if (PullWithFrostbolt && MobIsFrostImmune) { if (GetPullState()) CastOnTarget("Fireball"); } } bool PullWithPyroblast; bool PullWithFrostbolt; bool MobIsFireImmune; bool MobIsFrostImmune; bool NukeWithFireball; bool NukeWithFrostbolt; //Will have the GUI ask whether or not to use these for now //In the future, would like to autodetect talents bool UsePresenceOfMind; bool UseArcanePower; bool IHaveImpArcMissiles; bool UseConeOfCold; bool UseDragonsBreath; private void SingleTargetCombatFunction() { if (TargetIsTooClose()) GetAwayFromTarget(); if (TargetIsInRange()) NukeTarget("Single"); } private void DoubleTargetCombatFunction() { if (TargetIsTooClose() && !CanSheepSomething().Equals(0)) GetAwayFromTarget(); if (TargetIsInRange()) { if (CanSheepSomething().Equals(1)) { Requiem.Character.Target(1); // rough guess on how targeting goes CastOnTarget("Polymorph"); Requiem.Character.Target(2); NukeTarget(); } if (CanSheepSomething().Equals(2)) { Requiem.Character.Target(2); CastOnTarget("Polymorph"); Requiem.Character.Target(1); NukeTarget(); } } } //Am I a Frost mage? bool ImAFrostMage; private void MultiTargetCombatFunction() { if (!ImAFrostMage || Requiem.Character.Level <= 40) // don't want to aoe grind if I don't have the levels for talents... { PreFlee();// do any pre-flee steps, unless I'm AoEgrinding there's no reason to try doing three mobs at once. } // and if I can't aoe grind... better run. } private int CanSheepSomething() { if (Requiem.Character.PriorityList.Unit(2).Type.Equals("Beast") || Requiem.Character.PriorityList.Unit(2).Type.Equals("Humanoid")) return 2; if (Requiem.Character.PriorityList.Unit(1).Type.Equals("Beast") || Requiem.Character.PriorityList.Unit(1).Type.Equals("Humanoid")) return 1; return 0; } private void NukeTarget() { if (TargetIsInRange()) { if (Requiem.Character.GetUnit().IsCasting()) //Probably not correct, but Iw ant to check if the mob's casting CastOnTarget("Counterspell"); if (!MobIsFireImmune && true && true) //Need a way to check mob's health without isxwow, true1 = high hp, 2 = low CastOnTarget("Scorch"); if (true && true && true) //Same situation as above, but lower health, need to check for wand existing Requiem.Character.Cast("Shoot"); if (CanCast("Fire Blast") && !MobIsFireImmune) //Will add range check later CastOnTarget("Fire Blast"); if (CanCast("Dragon's Breath") && !MobIsFireImmune && UseDragonsBreath) //Will add range check later Requiem.Character.Cast("Dragon's Breath"); if (CanCast("Cone of Cold") && !MobIsFrostImmune && UseConeOfCold) //Will add range check later { if (Requiem.Navigation.ShouldFace(Requiem.Character.CurrentTarget.Location.X, Requiem.Character.CurrentTarget.Location.Y)) { Requiem.Navigation.Face(Requiem.Character.CurrentTarget.Location.X, Requiem.Character.CurrentTarget.Location.Y); } Requiem.Character.CurrentTarget.Cast("Cone of Cold"); } if (CanCast("Blast Wave") && !MobIsFireImmune && UseBlastWave) //Will add range check later Requiem.Character.Cast("Blast Wave"); if (UsePresenceOfMind && CanCast("Presence of Mind")) Requiem.Character.Cast("Presence of Mind"); if (UseArcanePower && CanCast("Arcane Power") && Requiem.Character.ManaPercent >= 50) Requiem.Character.Cast("Arcane Power"); if (CanCast("Ice Lance") && !MobIsFrostImmune && (Requiem.Character.CurrentTarget.Buff("Frozen").IsValid() || Requiem.Character.CurrentTarget.Buff("Chilled").IsValid())) CastOnTarget("Ice Lance"); if (Requiem.Character.Buff("Presence of Min").IsValid() && !MobIsFireImmune && CanCast("Pyroblast")) CastOnTarget("Pyroblast"); if ((IHaveImpArcMissiles && Requiem.Character.Buff("Clearcasting").IsValid() && CanCast("Arcane Missiles")) || (MobIsFrostImmune && MobIsFireImmune)) CastOnTarget("Arcane Missiles"); if (NukeWithFireball && !MobIsFireImmune) CastOnTarget("Fireball"); else if (MobIsFireImmune) CastOnTarget("Frostbolt"); if (NukeWithFrostbolt && !MobIsFrostImmune) CastOnTarget("Frostbolt"); else if (MobIsFrostImmune) CastOnTarget("Fireball"); } } private bool CanGetAwayFromTarget() { if (CanUseSpell("Blink") && CanUseSpell("Frost Nova") && !MobIsFrostImmune && GetSafeSpot(Requiem.Character.Heading)) return true; return false; } private void GetAwayFromTarget() { if (TargetIsTooClose())//Eventually going to modify this to make sure I'm not running through mobs { //or doing something otherwise retarded. Might need an ipo check. if (CanUseSpell("Blink") && CanUseSpell("Frost Nova") && !MobIsFrostImmune && GetSafeSpot(100)) { Requiem.Character.Cast("Frost Nova"); Requiem.Navigation.Face(SafeX, SafeY); Requiem.Character.Cast("Blink"); Requiem.Navigation.Face(Requiem.Character.CurrentTarget.Location.X, Requiem.Character.CurrentTarget.Location.Y); } else if (CanUseSpell("Frost Nova") && !CanUseSpell("Blink") && !MobIsFrostImmune) { Requiem.Character.Cast("Frost Nova"); Requiem.Navigation.StrafeRight(20); //Could really use this added. Strafe right for two seconds, 20 deciseconds Requiem.Character.Face(Requiem.Character.CurrentTarget.Location.X, Requiem.Character.CurrentTarget.Location.Y); } } } //GetSafeSpot vars, will require cleanup float TestX; float TestY; double SafeX; double SafeY; int FailCount; private void GetSafeSpot(float MyAngle) { // Need a way to get how many mobs there are within aggro radius of a certain point // isn't requiem supposed to have something like this? // do all my math... if (FailCount > 8) return false; if (FailCount <= 8) return true; } private bool CanCast(string Spell) { if (true) // Need a way to get whether or not a spell exists and can be used, without resorting ISXWoW { return true; } } private void CastOnTarget(string Spell) // could really use a way to get the mana cost of a spell { Requiem.Character.Cast(Spell, Requiem.Character.CurrentTarget); } private bool TargetIsInRange() { if (Requiem.Character.Location.Distance(Requiem.Character.CurrentTarget.Location.X, Requiem.Character.CurrentTarget.Location.Y, Requiem.Character.CurrentTarget.Location.Z) <= PullingRange) { return true; } } private bool TargetIsTooClose() { if (Requiem.Character.Location.Distance(Requiem.Character.CurrentTarget.Location.X, Requiem.Character.CurrentTarget.Location.Y, Requiem.Character.CurrentTarget.Location.Z) <= 6) { return true; } } private void ManaUp() { if (!Requiem.Inventory.ItemCount(Requiem.Inventory.BestDrink) < 6) { ConjureMyWater(); //May or may not end up being handled by requiem, so who knows } Requiem.Inventory.Use(Requiem.Inventory.BestDrink); if (Requiem.Character.ManaPercent < 95) { do { } while (Requiem.Character.Buff("Drink").IsValid); } } private void ConjureMyWater() { if (Requiem.Character.ManaPercent >= 7.5) { Requiem.Character.Cast("Conjure Water"); } else { Requiem.Character.Sit(); if (Requiem.Character.ManaPercent >= 7.5) break; } } private bool GetPullState() { if (Requiem.Character.Location.Distance(Requiem.Character.CurrentTarget.Location.X, Requiem.Character.CurrentTarget.Location.Y, Requiem.Character.CurrentTarget.Location.Z)) { Requiem.Navigation.Face(Requiem.Character.CurrentTarget.Location.X, Requiem.Character.CurrentTarget.Location.Y); do { Requiem.Navigation.MoveForward(); } while (Requiem.Character.Location.Distance(Requiem.Character.CurrentTarget.Location.X, Requiem.Character.CurrentTarget.Location.Y, Requiem.Character.CurrentTarget.Location.Z) > (PullingRange - 3)); } return true; } private bool GetBuffState() { if (!CheckedBuffs) return BuffStates.CheckingBuffs; if (Requiem.Character.ManaPercent <= 25) return BuffStates.CheckMana; if (NeedBuffs) return BuffStates.CastBuffs; } int PullingRange; string CombatState; // This function is called every frame. public void Pulse() { RoutineStateSwitch = GetRoutineState(); switch (RoutineStateSwitch) { case RoutineStates.CombatPrep: CombatPrepStateSwitch = GetCombatPrepState(); switch (CombatPrepCurrentState) { case CombatPrepStates.Buffing: BuffStateSwitch = GetBuffState(); switch (BuffStateSwitch) { case BuffStates.CheckingBuffs: CheckBuffs(); break; case BuffStates.CheckMana: ManaUp(); break; case BuffStates.CastBuffs: Buffs(); break; } break; case CombatPrepStates.CheckingManaGem: CheckManaGem(); break; case CombatPrepStates.PreCombatWards: PreCombatWards(); break; } break; case RoutineStates.Pulling: if (GetPullState()) Pull(); break; case RoutineStates.Combat: //Will come back to this. break; } } // This function is executed when the plugin is loaded. public void OnLoad() { } // This function is executed when the plugin is unloaded. public void OnUnload() { } } }