Jump to content

Cleaner C# for Fight Class (Rotations)


Apexx

Recommended Posts

I consider myself an intermediate programmer, but I haven't even been able to tie Wrobot into Visual Studio.
I read the forums and followed the instructions, but still have had no luck.

I would like to share a piece of code from a rotation I wrote using another bot that no longer exists. The API was beautiful!
Hooking into Visual Studio was easier than ever as well. I am new here, and I am sure after some more time playing around,
I will be able to figure it out eventually. Have a look at this neat fight class approach:

using System.Linq;
using Newtonsoft.Json;
using Botname.API;

namespace Botname {
	[Rotation("Apexx - PvP Beast Mastery [WiP]", "Apexx", WoWClass.Hunter, Specialization.HunterBeastMastery, 40)]
	public class HunterPvPBeastMastery : CombatRotation {
		[JsonProperty("UsePet")]
		public bool UsePet = true;
			
		public HunterPvPBeastMastery() {
			PullSpells = new string[] {
                "Concussive Shot", 
                "Steady Shot"
            };
		}

        private void DebugWrite(string text) {
            API.Print(text);
        }

        // Store Player Focus
        public int myFocus {
            get { return Me.GetPower(WoWPowerType.Focus); }
        }


        // DPS Priority (From Noxxic.com)
        // ############################################################

        // Kill Command [on cooldown]
        private bool KillCommand() {
            string spellname = "Kill Command";
            if (SpellCooldown(spellname) > 0) return false;
            if(!HasSpell(spellname)) return false;
            Cast(spellname, () => Target.HpGreaterThanOrElite(0.4) && (!Target.HasAura("Hunter's Mark") || myFocus >= 60));
            DebugWrite(spellname);
            return true;
        }
        // Kill Shot [when target below 20% Health]
        private bool KillShot() {
            string spellname = "Kill Shot";
            if(SpellCooldown(spellname) > 0) return false;
            if(!HasSpell(spellname)) return false;
            Cast(spellname, () => Me.Target.HealthFraction < 0.2);
            DebugWrite(spellname);
            return true;
        }
        // Focus Fire [with 5 Frenzy stacks]
        private bool FocusFire() {
            string spellname = "Focus Fire";
            if(SpellCooldown(spellname) > 0) return false;
            if(!HasSpell(spellname)) return false;
            if(CastSelf(spellname, () => HasAura("Frenzy") && !HasAura("Focus Fire"))) {
                DebugWrite(spellname);
                return false;
            }
            return false;
        }
        // Arcane Shot [to dump excess Focus (> 60 Focus)]
        private bool ArcaneShot() {
            string spellname = "Arcane Shot";
            if(SpellCooldown(spellname) > 0) return false;
            if(!HasSpell(spellname)) return false;
            Cast(spellname, () => myFocus >= 60);
            DebugWrite(spellname);
            //DebugWrite("My Focus: " + myFocus.ToString());
            return true;
        }
        // Steady Shot [to build Focus (< 60 Focus)]
        private bool SteadyShot() {
            string spellname = "Steady Shot";
            if(SpellCooldown(spellname) > 0) return false;
            if(!HasSpell(spellname)) return false;
            if(Cast(spellname, () => myFocus < 60)) {
                DebugWrite(spellname);
                return true;
            }
            return false;
        }
        // Cobra Shot [to build Focus (< 60 Focus)]
        private bool CobraShot() {
            string spellname = "Cobra Shot";
            if(SpellCooldown(spellname) > 0) return false;
            if(!HasSpell(spellname)) return false;
            Cast(spellname, () => myFocus < 60);
            DebugWrite(spellname);
            return true;
        }


        // AoE Abilities
        // ###########################################################

        // Multi-Shot [for Improved Beast Cleave]
        // Will perform Adds.Count check in combat (2+ enemy units)
        private bool MultiShot() {
            string spellname = "Multi-Shot";
            if(SpellCooldown(spellname) > 0) return false;
            if(!HasSpell(spellname)) return false;
            Cast(spellname, () => myFocus >= 40);
            DebugWrite(spellname);
            return true;
        }
        // Explosive Trap [on cooldown]
        // Will perform Adds.Count check in combat (2+ enemy units)
        private bool ExplosiveTrap() {
            string spellname = "Explosive Trap";
            if(SpellCooldown(spellname) > 0) return false;
            if(!HasSpell(spellname)) return false;
            CastOnTerrain(spellname, Me.Target.Position);
            DebugWrite(spellname);
            return true;
        }
        // Ice Trap [for evasive maneuvering]
        private bool IceTrap() {
            string spellname = "Ice Trap";
            if(SpellCooldown(spellname) > 0) return false;
            if(!HasSpell(spellname)) return false;
            CastOnTerrain(spellname, Me.Target.Position);
            DebugWrite(spellname);
            return true;
        }


        // Miscellaneous
        // ###########################################################

        // Dire Beast [should be used as frequently as possible]
        private bool DireBeast() {
            string spellname = "Dire Beast";
            if(SpellCooldown(spellname) > 0) return false;
            if(!HasSpell(spellname)) return false;
            Cast(spellname);
            DebugWrite(spellname);
            return true;
        }
        // Bestial Wrath [Use on cooldown. Let your pet keep Frenzy.]
        private bool BestialWrath() {
            string spellname = "Bestial Wrath";
            if(SpellCooldown(spellname) > 0) return false;
            if(!HasSpell(spellname)) return false;
            Cast(spellname);
            DebugWrite(spellname);
            return true;
        }
        // A Murder of Crows [when target HP < 20% and Focus >= 30]
        private bool MurderofCrows() {
            string spellname = "A Murder of Crows";
            if(SpellCooldown(spellname) > 0) return false;
            if(!HasSpell(spellname)) return false;
            Cast("A Murder of Crows", () => Target.HealthFraction < 0.2 && myFocus >= 30);
            DebugWrite(spellname);
            return true;
        }
        // Concussive Shot [when target does not have debuff]
        private bool ConcussiveShot() {
            string spellname = "Concussive Shot";
            if(SpellCooldown(spellname) > 0) return false;
            if(!HasSpell(spellname)) return false;
            if(Cast(spellname, () => (!Target.HasAura(spellname)))) {
                DebugWrite(spellname);
                return true;
            }
            return false;
        }
        // Last Stand
        private bool LastStand() {
            string spellname = "Last Stand";
            if(SpellCooldown(spellname) > 0) return false;
            if(!HasSpell(spellname)) return false;
            CastSelf(spellname, () => Me.HasAlivePet && Me.Pet.HealthFraction <= 0.5 && Me.Pet.HasAura("Mend Pet"));
            DebugWrite(spellname);
            return true;
        }
        // Disengage [Evasive maneuver used when target(s) are close!]
        private bool Disengage() {
            string spellname = "Disengage";
            if(SpellCooldown(spellname) > 0) return false;
            if(!HasSpell(spellname)) return false;
            if(CastSelfPreventDouble(spellname, () => (Target.DistanceSquared <= 5 * 5))) {
                DebugWrite(spellname);
                return true;
            }
            return false;
        }
        // Tranquilizing Shot [If target has magic aura]
        private bool TranquilizingShot() {
            string spellname = "Tranquilizing Shot";
            if(SpellCooldown(spellname) > 0) return false;
            if(!HasSpell(spellname)) return false;
            Cast(spellname, () => Target.Auras.Any(x => !x.IsDebuff && x.DebuffType == "Magic"));
            DebugWrite(spellname);
            return true;
        }


        // OUT OF COMBAT
        // ###############################################################################

		public override bool OutOfCombat() {
            if (UsePet) {
				if (!Me.HasAlivePet) {
					if (CastSelfPreventDouble("Call Pet 1", null, 2000)) return true;
					if (CastSelfPreventDouble("Revive Pet", null, 2000)) return true;
					return true;
				}
			}
			else if (Me.HasAlivePet) {
				Me.PetDismiss();
			}

            // Check Pet health here
            if(CastSelfPreventDouble("Mend Pet", () => Me.HasAlivePet && Me.Pet.HealthFraction <= 0.8, 9000)) return true;

			if (CastSelf("Trap Launcher", () => !HasAura("Trap Launcher"))) return true;
			return false;
		}


        // IN COMBAT
        // ###############################################################################
		public override void Combat() {
			if (Me.HasAlivePet) {
				UnitObject add = Adds.FirstOrDefault(x => x.Target == Me);
				if (add != null)
					Me.PetAttack(add);
			}
			else if (!Me.HasAlivePet) {
				if (CastSelf("Heart of the Phoenix")) return;
				if (CastSelfPreventDouble("Revive Pet", null, 10000)) return;
			}

            int addsWithinMultiRange = 0;
            if(Adds.Count > 0) {
                foreach(var aggro in Adds.Where(x => x.DistanceSquared < SpellMaxRangeSq("Arcane Shot"))) {
                    UnitObject add = aggro;
                    if(Cast("Serpent Sting", () => !add.HasAura("Serpent Sting", true), add)) {
                        DebugWrite("Serpent Sting");
                        return;
                    }
                }
                
                //  Add.Count +1 to offset 0
                addsWithinMultiRange = 1 + Adds.Count(x => x.DistanceSquaredTo(Target) < 40 * 40);
                //DebugWrite("Adds in range: " + addsWithinMultiRange);

                // Check Pet health here
                if(CastSelfPreventDouble("Mend Pet", () => Me.HasAlivePet && Me.Pet.HealthFraction <= 0.8, 9000)) return;

                // AoE if more than one enemy unit
                if(addsWithinMultiRange >= 2) {
                    if(ExplosiveTrap()) return;
                    //if(IceTrap()) return;
                    //if(MultiShot()) return;
                }
            }


            // Begin Rotation

            if(Target.HealthFraction < 0.2) {
                API.ExecuteMacro("/stopcasting");
                if(KillShot()) return;
            }

            //if(DireBeast()) return;
            //if(BestialWrath()) return;
            if(ConcussiveShot()) return;
            if(FocusFire()) return;
            if(ArcaneShot()) return;
            if(SteadyShot()) return;
            if(CobraShot()) return;
            if(LastStand()) return;
            if(MurderofCrows()) return;
            if(KillCommand()) return;

            if(Target.HealthFraction < 0.2) {
                API.ExecuteMacro("/stopcasting");
                if(KillShot()) return;
            }

            if(Target.IsCastingAndInterruptible() && SpellCooldown("Counter Shot") <= 0) {
                API.ExecuteMacro("/stopcasting");
                Cast("Counter Shot");
                DebugWrite("Counter Shot");
            }

            if(Disengage()) return;

            if(TranquilizingShot()) return;
            if(Cast("Barrage")) return;
            if(Cast("Glaive Toss")) return;

            // Check Player health here
            // Feign Dealth when HP at 20%
            if(CastSelfPreventDouble("Feign Death", () => Me.HealthFraction <= 0.2)) return;

			if (CastSelfPreventDouble("Feign Death", () => Me.HasAlivePet && Target.Target == Me.Pet && Adds.Any(x => x.Target == Me))) return;
		}
	}
}

I will keep searching the forums to better educate myself here. I like writing fight classes and grinder/questing profiles.
 

Link to comment
Share on other sites

I followed the forum here:

I managed to get the same Pinvoke error as described, and disabled the PInvokeStackImbalance error check to get Wrobot to load from Debug. I guess my question is, what's next?

Let's say I want to write a starter Protection warrior fight class...

Link to comment
Share on other sites

Quote

Let's say I want to write a starter Protection warrior fight class...

1. Create a new C# class.
2. Add refrences to the bot libs you want to work with
3. Implement the ICustomClass interface into your new class
4. Implement the interface methods (just take a look at the samples floating around)
5. Make instances of your spells like Spell spellName = new Spell("SpellName");
6. Well and now the creative part comes... you need to validate and pulse your actions you want to do

At the end compile the stuff and put the dll into your FightClass folder.

That should be the basic stuff.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...