Jump to content

How to create an Fight Class (developer only)


Recommended Posts

How to create an Fight Class (developer only)



Fight class using bot API. He is recommanded to use visual studio 12 with framework 4.5 for create an Fight class (add in reference robotManager.dll and wManager.dll).


WRobot supporting C#, Vb.net code, and dll.

Sample C# Fight Class for Hunter: (Finite State Machine (Engine)) ( http://pastebin.com/ywQ2VPGr )

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Threading;
using robotManager;
using robotManager.FiniteStateMachine;
using robotManager.Helpful;
using wManager.Wow.Class;
using wManager.Wow.Helpers;
using wManager.Wow.ObjectManager;
using Timer = robotManager.Helpful.Timer;

public class Main : ICustomClass
{
    public float Range { get { return 36; } }

    private Engine _engine;
    public void Initialize()
    {
        HunterSettings.Load();
        _engine = new Engine(false)
        {
            States = new List<State>
                    {
                         // Pet
                         new PetManager { Priority = 20 },
                         // Defensive
                         new SpellState("Freezing Trap", 13,
                                       context => (ObjectManager.GetUnitAttackPlayer().Count(u => u.GetDistance <= 8) >= 1 && ObjectManager.GetUnitAttackPlayer().Count > 1)),
                         new SpellState("Disengage", 21,
                                       context => (ObjectManager.GetUnitAttackPlayer().Count(u => u.GetDistance <= 8) >= 1)),
                         // Attac multi
                         new SpellState("Multi-Shot", 14,
                                       context => (ObjectManager.GetUnitAttackPlayer().Count() > 1)),
                         new SpellState("Explosive Trap", 14,
                                       context => (ObjectManager.GetUnitAttackPlayer().Count(u => u.GetDistance <= 8) > 1)),
                         // Attac
                         new SpellState("Hunter's Mark", 15,
                                       context => (!ObjectManager.Target.HaveBuff("Hunter's Mark"))),
                         new SpellState("Stampede", 13, context => HunterSettings.CurrentSetting.Stampede),
                         new SpellState("Rapid Fire", 12, context => HunterSettings.CurrentSetting.RapidFire),
                         new SpellState("Kill Shot", 11, context => true),
                         new SpellState("Blink Strike", 10, context => HunterSettings.CurrentSetting.BlinkStrike),
                         new SpellState("Serpent Sting", 9, context => ObjectManager.Me.Focus > 30 && !ObjectManager.Target.HaveBuff("Serpent Sting")),
                         new SpellState("Kill Command", 8, context => ObjectManager.Pet.IsValid && ObjectManager.Pet.IsAlive && ObjectManager.Pet.Position.DistanceTo2D(ObjectManager.Target.Position) < 25),
                         new SpellState("Bestial Wrath", 7, context => true),
                         new SpellState("Dire Beast", 6, context => HunterSettings.CurrentSetting.DireBeast),  
                         new SpellState("Arcane Shot", 5, context => ObjectManager.Me.Focus > 30),
                         new SpellState("Cobra Shot", 4, context =>  ObjectManager.Me.Focus < 25),
                         new SpellState("Readiness", 3, context => HunterSettings.CurrentSetting.Readiness),  
                    }
        };
        _engine.StartEngine(5);
    }

    public void Dispose()
    {
        if (_engine != null)
        {
            _engine.StopEngine();
            _engine.States.Clear();
        }
    }

    public void ShowConfiguration()
    {
        HunterSettings.Load();
        HunterSettings.CurrentSetting.ToForm();
        HunterSettings.CurrentSetting.Save();
    }

    class PetManager : State
    {
        public override int Priority { get; set; }

        public override string DisplayName
        {
            get { return "Pet Manager"; }
        }
        Timer _petTimer = new Timer(-1);
        public override bool NeedToRun
        {
            get
            {
                if (!_petTimer.IsReady)
                    return false;

                if (ObjectManager.Me.IsDeadMe || ObjectManager.Me.IsMounted)
                {
                    _petTimer = new Timer(1000 * 2);
                    return false;
                }
                if (!ObjectManager.Pet.IsValid || ObjectManager.Pet.IsDead)
                    return true;
                return false;
            }
        }

        public override List<State> NextStates
        {
            get { return new List<State>(); }
        }

        public override List<State> BeforeStates
        {
            get { return new List<State>(); }
        }

        private readonly Spell _revivePet = new Spell("Revive Pet");
        private readonly Spell _callPet = new Spell("Call Pet 1");

        public override void Run()
        {
            if (!ObjectManager.Pet.IsValid)
            {
                _callPet.Launch(true);
                Thread.Sleep(Usefuls.Latency + 1000);
            }
            if (!ObjectManager.Pet.IsValid || ObjectManager.Pet.IsDead)
                _revivePet.Launch(true);

            _petTimer = new Timer(1000 * 2);
        }
    }
}

[Serializable]
public class HunterSettings : Settings
{
    [Setting]
    [DefaultValue(false)]
    [Category("Beast Mastery")]
    [DisplayName("Rapid Fire")]
    [Description("Use Rapid Fire")]
    public bool RapidFire { get; set; }

    [Setting]
    [DefaultValue(false)]
    [Category("Beast Mastery")]
    [DisplayName("Stampede")]
    [Description("Use Stampede")]
    public bool Stampede { get; set; }

    [Setting]
    [DefaultValue(false)]
    [Category("Beast Mastery")]
    [DisplayName("Dire Beast")]
    [Description("Use Dire Beast")]
    public bool DireBeast { get; set; }

    [Setting]
    [DefaultValue(false)]
    [Category("Beast Mastery")]
    [DisplayName("Readiness")]
    [Description("Use Readiness")]
    public bool Readiness { get; set; }

    [Setting]
    [DefaultValue(false)]
    [Category("Beast Mastery")]
    [DisplayName("Blink Strike")]
    [Description("Use Blink Strike")]
    public bool BlinkStrike { get; set; }

    private HunterSettings()
    {
        ConfigWinForm(new System.Drawing.Point(400, 400), "Hunter " + Translate.Get("Settings"));
    }

    public static HunterSettings CurrentSetting { get; set; }

    public bool Save()
    {
        try
        {
            return Save(AdviserFilePathAndName("CustomClass-Hunter", ObjectManager.Me.Name + "." + Usefuls.RealmName));
        }
        catch (Exception e)
        {
            Logging.WriteError("HunterSettings > Save(): " + e);
            return false;
        }
    }

    public static bool Load()
    {
        try
        {
            if (File.Exists(AdviserFilePathAndName("CustomClass-Hunter", ObjectManager.Me.Name + "." + Usefuls.RealmName)))
            {
                CurrentSetting =
                    Load<HunterSettings>(AdviserFilePathAndName("CustomClass-Hunter",
                                                                 ObjectManager.Me.Name + "." + Usefuls.RealmName));
                return true;
            }
            CurrentSetting = new HunterSettings();
        }
        catch (Exception e)
        {
            Logging.WriteError("HunterSettings > Load(): " + e);
        }
        return false;
    }
}
 
Another C# Fight Class structure: http://pastebin.com/krBv3QCD )
using System;
using System.Threading;
using System.Windows.Forms;
using robotManager.Helpful;
using robotManager.Products;
using wManager.Wow.Class;
using wManager.Wow.Enums;
using wManager.Wow.Helpers;
using wManager.Wow.ObjectManager;
using Timer = robotManager.Helpful.Timer;
 
public class Main : ICustomClass
{
    public float Range { get { return 4.5f; } }
 
    private bool _isLaunched;
    private ulong _lastTarget;
 
    public void Initialize() // When product started, initialize and launch Fightclass
    {
        _isLaunched = true;
        Logging.Write("[My fightclass] Is initialized.");
        Rotation();
    }
 
    public void Dispose() // When product stopped
    {
        _isLaunched = false;
        Logging.Write("[My fightclass] Stop in progress.");
    }
 
    public void ShowConfiguration() // When use click on Fight class settings
    {
        MessageBox.Show("[My fightclass] No setting for this Fight Class.");
    }
 
 
    // SPELLS:
    // Buff:
    public Spell DeadlyPoison = new Spell("Deadly Poison");
    public Spell Sprint = new Spell("Sprint");
    // Pull:
    public Spell Stealth = new Spell("Stealth");
    // Combat:
    public Spell Garrote = new Spell("Garrote");
    public Spell SliceandDice = new Spell("Slice and Dice");
    public Spell Eviscerate = new Spell("Eviscerate");
    public Timer SliceandDiceTimer = new Timer(); // Timer
 
    internal void Rotation()
    {
        Logging.Write("[My fightclass] Is started.");
        while (_isLaunched)
        {
            try
            {
                if (!Products.InPause)
                {
                    if (!ObjectManager.Me.IsDeadMe)
                    {
                        BuffRotation();
 
                        if (Fight.InFight && ObjectManager.Me.Target > 0)
                        {
                            Pull();
                            CombatRotation();
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Logging.WriteError("[My fightclass] ERROR: " + e);
            }
 
            Thread.Sleep(10); // Pause 10 ms to reduce the CPU usage.
        }
        Logging.Write("[My fightclass] Is now stopped.");
    }
 
    internal void BuffRotation()
    {
        if (ObjectManager.Me.IsMounted)
            return;
 
        // Deadly Poison:
        if (DeadlyPoison.KnownSpell && !DeadlyPoison.HaveBuff && DeadlyPoison.IsSpellUsable && !ObjectManager.Me.GetMove)
        {
            DeadlyPoison.Launch();
            return;
        }
        // Sprint
        if (Sprint.KnownSpell && !ObjectManager.Me.InCombat && ObjectManager.Me.GetMove && Sprint.IsSpellUsable)
        {
            Sprint.Launch();
            return;
        }
    }
    internal void Pull()
    {
        if (ObjectManager.Me.Target == _lastTarget)
            return;
 
        // Stealth:
        if (Stealth.KnownSpell && Stealth.IsSpellUsable && !Stealth.HaveBuff && ObjectManager.Target.Target != ObjectManager.Me.Guid)
        {
            Stealth.Launch();
            _lastTarget = ObjectManager.Me.Target;
        }
    }
 
    internal void CombatRotation()
    {
        // Garrote:
        if (Garrote.IsSpellUsable && Garrote.IsDistanceGood && Garrote.KnownSpell && ObjectManager.Me.HaveBuff(115192))
        {
            Garrote.Launch();
            return;
        }
        // Eviscerate:
        if (Eviscerate.KnownSpell && Eviscerate.IsSpellUsable && Eviscerate.IsDistanceGood && (ObjectManager.Me.ComboPoint > 4 || (SliceandDice.HaveBuff && SliceandDiceTimer.IsReady)))
        {
            Eviscerate.Launch();
            if (SliceandDice.HaveBuff)
                SliceandDiceTimer = new Timer(1000 * 36);
            return;
        }
    }
}

 

Sample Vb.net Fight Class base: ( http://pastebin.com/EETxYYi3 )

Imports System.Collections.Generic
Imports System.Linq
Imports System.Threading
Imports robotManager.FiniteStateMachine
Imports robotManager.Helpful
Imports wManager.Wow.Class
Imports wManager.Wow.Helpers
Imports wManager.Wow.ObjectManager

Public Class Main
    Implements ICustomClass
    
    Public ReadOnly Property Range As Single Implements ICustomClass.Range
        Get
            Return 5
        End Get
    End Property


    Public Sub Initialize() Implements ICustomClass.Initialize

    End Sub

    Public Sub Dispose() Implements ICustomClass.Dispose

    End Sub

    Public Sub ShowConfiguration() Implements ICustomClass.ShowConfiguration

    End Sub
End Class

Sample DLL:
Only create class Main (implement ICustomClass) without namespace in your dll.

Link to comment
https://wrobot.eu/forums/topic/12-how-to-create-an-fight-class-developer-only/
Share on other sites

What Ive actually been doing, (until i can hammer out my loc profile, and more classes become available) is using the default fight class (which basically /attack(s) and run PQR with WRobot, then WRobot handels the paths and interaction, and PQR does the actual rotation for fighting once your toon is in combat.  I do realize this completely defeats the purpose of fight classes, but it loops back to my origional suggestion of implementing pqr profiles.

You can launch lua script:

 

string money = Lua.LuaDoString("money  = GetMoney()", "money");

 

 

And you can use others structs: (sample of tnb customclass: http://pastebin.com/vqjFFJEE )
 
 
For create product (grinder, gatherer, ...) I use api of robotManager.dll and wManager.dll (like for fights class), you have acces at a lot of informations for create fights class.
  • 1 year later...

Sample to use shortcut to activate/deactivate spells (look "_hookKeybindingsSpells"):

Before WoD

using System;
using System.Threading;
using System.Windows.Forms;
using robotManager.Helpful;
using robotManager.Products;
using wManager.Wow.Class;
using wManager.Wow.Enums;
using wManager.Wow.Helpers;
using wManager.Wow.ObjectManager;
using Timer = robotManager.Helpful.Timer;

public class Main : ICustomClass
{
    public float Range { get { return 20; } }

    private bool _isLaunched;
    private ulong _lastTarget;
    readonly KeyboardHook _hookKeybindingsSpells = new KeyboardHook();
    private bool _spellsActivated = false;

    public void Initialize() // When product started, initialize and launch Fightclass
    {
        _isLaunched = true;

        _hookKeybindingsSpells.KeyPressed += HookSpellsKeyPressed;
        _hookKeybindingsSpells.RegisterHotKey(ModifierKeys.Alt, Keys.Q);

        Logging.Write("[My fightclass] Is initialized.");
        Rotation();
    }

    private void HookSpellsKeyPressed(object sender, KeyPressedEventArgs e)
    {
        _spellsActivated = !_spellsActivated;
        if (_spellsActivated)
            Logging.Write("[My fightclass] Spells is activated.");
        else
            Logging.Write("[My fightclass] Spells is desactivated.");
    }

    public void Dispose() // When product stopped
    {
        _isLaunched = false;

        _hookKeybindingsSpells.Dispose();

        Logging.Write("[My fightclass] Stop in progress.");
    }

    public void ShowConfiguration() // When use click on Fight class settings
    {
        MessageBox.Show("[My fightclass] No setting for this Fight Class.");
    }

    // SPELLS:
    public Spell SteadyShot = new Spell("Steady Shot"); // or "Arcane Shot"

    internal void Rotation()
    {
        if (!SteadyShot.KnownSpell)
            SteadyShot = new Spell("Arcane Shot");

        Logging.Write("[My fightclass] Is started.");
        while (_isLaunched)
        {
            try
            {
                if (!Products.InPause)
                {
                    if (!ObjectManager.Me.IsDeadMe)
                    {
                        BuffRotation();

                        if (Fight.InFight && ObjectManager.Me.Target > 0)
                        {
                            Pull();
                            CombatRotation();
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Logging.WriteError("[My fightclass] ERROR: " + e);
            }

            Thread.Sleep(10); // Pause 10 ms to reduce the CPU usage.
        }
        Logging.Write("[My fightclass] Is now stopped.");
    }

    internal void BuffRotation()
    {
        if (ObjectManager.Me.IsMounted)
            return;

    }

    internal void Pull()
    {
        if (ObjectManager.Me.Target == _lastTarget)
            return;

        if (ObjectManager.Target.Target != ObjectManager.Me.Guid)
        {

            _lastTarget = ObjectManager.Me.Target;
        }
    }

    internal void CombatRotation()
    {
        // Steady Shot or Arcane Shot
        if (_spellsActivated) // Alt-Q
        {
            if (SteadyShot.IsSpellUsable && SteadyShot.IsDistanceGood && SteadyShot.KnownSpell)
            {
                SteadyShot.Launch(false);
                return;
            }
        }
    }
}

Since WoD:

using System;
using System.Threading;
using System.Windows.Forms;
using MemoryRobot;
using robotManager.Helpful;
using robotManager.Products;
using wManager.Wow.Class;
using wManager.Wow.Helpers;
using wManager.Wow.ObjectManager;

public class Main : ICustomClass
{
    public float Range { get { return 20; } }

    private bool _isLaunched;
    private Int128 _lastTarget;
    readonly KeyboardHook _hookKeybindingsSpells = new KeyboardHook();
    private bool _spellsActivated = false;

    public void Initialize() // When product started, initialize and launch Fightclass
    {
        _isLaunched = true;

        _hookKeybindingsSpells.KeyPressed += HookSpellsKeyPressed;
        _hookKeybindingsSpells.RegisterHotKey(ModifierKeys.Alt, Keys.Q);

        Logging.Write("[My fightclass] Is initialized.");
        Rotation();
    }

    private void HookSpellsKeyPressed(object sender, KeyPressedEventArgs e)
    {
        _spellsActivated = !_spellsActivated;
        if (_spellsActivated)
            Logging.Write("[My fightclass] Spells is activated.");
        else
            Logging.Write("[My fightclass] Spells is desactivated.");
    }

    public void Dispose() // When product stopped
    {
        _isLaunched = false;

        _hookKeybindingsSpells.Dispose();

        Logging.Write("[My fightclass] Stop in progress.");
    }

    public void ShowConfiguration() // When use click on Fight class settings
    {
        MessageBox.Show("[My fightclass] No setting for this Fight Class.");
    }

    // SPELLS:
    public Spell SteadyShot = new Spell("Steady Shot"); // or "Arcane Shot"

    internal void Rotation()
    {
        if (!SteadyShot.KnownSpell)
            SteadyShot = new Spell("Arcane Shot");

        Logging.Write("[My fightclass] Is started.");
        while (_isLaunched)
        {
            try
            {
                if (!Products.InPause)
                {
                    if (!ObjectManager.Me.IsDeadMe)
                    {
                        BuffRotation();

                        if (Fight.InFight && ObjectManager.Me.Target.IsNotZero())
                        {
                            Pull();
                            CombatRotation();
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Logging.WriteError("[My fightclass] ERROR: " + e);
            }

            Thread.Sleep(10); // Pause 10 ms to reduce the CPU usage.
        }
        Logging.Write("[My fightclass] Is now stopped.");
    }

    internal void BuffRotation()
    {
        if (ObjectManager.Me.IsMounted)
            return;

    }

    internal void Pull()
    {
        if (ObjectManager.Me.Target == _lastTarget)
            return;

        if (ObjectManager.Target.Target != ObjectManager.Me.Guid)
        {

            _lastTarget = ObjectManager.Me.Target;
        }
    }

    internal void CombatRotation()
    {
        // Steady Shot or Arcane Shot
        if (_spellsActivated) // Alt-Q
        {
            if (SteadyShot.IsSpellUsable && SteadyShot.IsDistanceGood && SteadyShot.KnownSpell)
            {
                SteadyShot.Launch(false);
                return;
            }
        }
    }
}

 

  • 1 year later...
  • 5 weeks later...
  • 10 months later...
8 hours ago, Doobie said:

Does this way still work or is it obsolete now?

Hello, I have fixed code http://wrobot.eu/forums/topic/12-how-to-create-an-fight-class-developer-only/?do=findComment&comment=6778

6 hours ago, Droidz said:

Okay I am using it for vanilla is the API the same? Like can I use the Before WOD structure for a vanilla fight class.

  • 2 weeks later...
  • 1 year later...
  • 4 months later...
2 minutes ago, Genifikius said:

Could you upload a documentation of the bot API or link it if its already uploaded somewhere?

There isn't one. Best things you can do is either decompile the DLLs or reference it in something like Visual Studio and then look through the functions in the Object Browser. The main DLL you'd be interested in is wManager

Edited by Marsbar
1 minute ago, Marsbar said:

There isn't one. Best things you can do is either decompile the DLLs or reference it in something like Visual Studio and then look through the functions in the Object Browser. The main DLL you'd be interested in is wManager

Are these DLLs managed or unmanaged?

Jetbrains dotPeek is quite simple and free
Gotta say tho I find it easier going through the object browser in VS

example:

f7b8056265aa7095de6a7972279f64de.png

Edited by Marsbar

Is the this: Another C# Fight Class structure: http://pastebin.com/krBv3QCD )

still usable? Because i tried to use it and it shows:

[E] 11:44:51 - Fight Class Loading error.

What is the best way to debug a fightclass?

 

1 hour ago, nfx said:

Is the this: Another C# Fight Class structure: http://pastebin.com/krBv3QCD )

still usable? Because i tried to use it and it shows:

[E] 11:44:51 - Fight Class Loading error.

What is the best way to debug a fightclass?

 

Yeah, should still work.
A few different ways, I'd say either add loads of logging or do a Debugger.Launch() in the initialize (make sure to ref System.Diagnostics), that will prompt a JIT debugger and you can then step through it in VS.

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...