Droidz 2742 Posted December 17, 2012 Share Posted December 17, 2012 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 More sharing options...
GRB 6 Posted December 21, 2012 Share Posted December 21, 2012 Why not implement the usage of lua intstead of C# && VB? Something like PQR, It have some downsides tho, you cant count enemy players around you, but other then that, is a much more powerfull way to create profiles. Link to comment https://wrobot.eu/forums/topic/12-how-to-create-an-fight-class-developer-only/#findComment-51 Share on other sites More sharing options...
Shadow 100 Posted December 22, 2012 Share Posted December 22, 2012 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. Link to comment https://wrobot.eu/forums/topic/12-how-to-create-an-fight-class-developer-only/#findComment-54 Share on other sites More sharing options...
GRB 6 Posted December 22, 2012 Share Posted December 22, 2012 Not even need to implement prq profiles, just the same concept for lua usage. Profiles in lua are much easyer to create. Link to comment https://wrobot.eu/forums/topic/12-how-to-create-an-fight-class-developer-only/#findComment-55 Share on other sites More sharing options...
Droidz 2742 Posted December 23, 2012 Author Share Posted December 23, 2012 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. Link to comment https://wrobot.eu/forums/topic/12-how-to-create-an-fight-class-developer-only/#findComment-57 Share on other sites More sharing options...
Droidz 2742 Posted March 15, 2014 Author Share Posted March 15, 2014 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; } } } } Link to comment https://wrobot.eu/forums/topic/12-how-to-create-an-fight-class-developer-only/#findComment-6778 Share on other sites More sharing options...
Droidz 2742 Posted January 26, 2016 Author Share Posted January 26, 2016 Samples: Monk - Brewmaster.cs Monk - Windwalker.cs Link to comment https://wrobot.eu/forums/topic/12-how-to-create-an-fight-class-developer-only/#findComment-12063 Share on other sites More sharing options...
trusislv1 0 Posted February 25, 2016 Share Posted February 25, 2016 Hi where i can download these robotManager.dll and wManager.dll packages? Link to comment https://wrobot.eu/forums/topic/12-how-to-create-an-fight-class-developer-only/#findComment-12614 Share on other sites More sharing options...
Brian 10 Posted February 25, 2016 Share Posted February 25, 2016 2 hours ago, trusislv1 said: Hi where i can download these robotManager.dll and wManager.dll packages? already in wrobot bin folder trusislv1 1 Link to comment https://wrobot.eu/forums/topic/12-how-to-create-an-fight-class-developer-only/#findComment-12615 Share on other sites More sharing options...
RonSwanson 2 Posted January 24, 2017 Share Posted January 24, 2017 Quote Does this way still work or is it obsolete now? Link to comment https://wrobot.eu/forums/topic/12-how-to-create-an-fight-class-developer-only/#findComment-22262 Share on other sites More sharing options...
Droidz 2742 Posted January 24, 2017 Author Share Posted January 24, 2017 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 Link to comment https://wrobot.eu/forums/topic/12-how-to-create-an-fight-class-developer-only/#findComment-22281 Share on other sites More sharing options...
RonSwanson 2 Posted January 24, 2017 Share Posted January 24, 2017 6 hours ago, Droidz said: Hello, I have fixed code http://wrobot.eu/forums/topic/12-how-to-create-an-fight-class-developer-only/?do=findComment&comment=6778 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. Link to comment https://wrobot.eu/forums/topic/12-how-to-create-an-fight-class-developer-only/#findComment-22309 Share on other sites More sharing options...
Droidz 2742 Posted January 24, 2017 Author Share Posted January 24, 2017 35 minutes ago, Doobie 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. Yes you can Link to comment https://wrobot.eu/forums/topic/12-how-to-create-an-fight-class-developer-only/#findComment-22317 Share on other sites More sharing options...
kpeno 1 Posted February 6, 2017 Share Posted February 6, 2017 All this now working for 1.12.1? right? Link to comment https://wrobot.eu/forums/topic/12-how-to-create-an-fight-class-developer-only/#findComment-23218 Share on other sites More sharing options...
Droidz 2742 Posted February 7, 2017 Author Share Posted February 7, 2017 12 hours ago, kpeno said: All this now working for 1.12.1? right? Yes, only change is before WoD, wow GUID in int64 (or long, ulong, uint64), since WoD wow GUID is Int128 Link to comment https://wrobot.eu/forums/topic/12-how-to-create-an-fight-class-developer-only/#findComment-23247 Share on other sites More sharing options...
Enraged 25 Posted March 13, 2018 Share Posted March 13, 2018 @Droidz Just a heads up, you forgot to include "using wManager.Wow.Bot.States;" in the first example of C# fight class with Finite State Machine. Link to comment https://wrobot.eu/forums/topic/12-how-to-create-an-fight-class-developer-only/#findComment-41240 Share on other sites More sharing options...
Genifikius 1 Posted August 2, 2018 Share Posted August 2, 2018 Could you upload a documentation of the bot API or link it if its already uploaded somewhere? Link to comment https://wrobot.eu/forums/topic/12-how-to-create-an-fight-class-developer-only/#findComment-46298 Share on other sites More sharing options...
Marsbar 228 Posted August 2, 2018 Share Posted August 2, 2018 (edited) 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 August 2, 2018 by Marsbar Link to comment https://wrobot.eu/forums/topic/12-how-to-create-an-fight-class-developer-only/#findComment-46299 Share on other sites More sharing options...
Genifikius 1 Posted August 2, 2018 Share Posted August 2, 2018 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? Link to comment https://wrobot.eu/forums/topic/12-how-to-create-an-fight-class-developer-only/#findComment-46300 Share on other sites More sharing options...
Marsbar 228 Posted August 2, 2018 Share Posted August 2, 2018 managed, c# Link to comment https://wrobot.eu/forums/topic/12-how-to-create-an-fight-class-developer-only/#findComment-46301 Share on other sites More sharing options...
Genifikius 1 Posted August 2, 2018 Share Posted August 2, 2018 didn't get lucky finding a proper decompiler do you guys recommand any? Link to comment https://wrobot.eu/forums/topic/12-how-to-create-an-fight-class-developer-only/#findComment-46302 Share on other sites More sharing options...
Marsbar 228 Posted August 2, 2018 Share Posted August 2, 2018 (edited) Jetbrains dotPeek is quite simple and free Gotta say tho I find it easier going through the object browser in VS example: Edited August 2, 2018 by Marsbar morris79 and Genifikius 1 1 Link to comment https://wrobot.eu/forums/topic/12-how-to-create-an-fight-class-developer-only/#findComment-46303 Share on other sites More sharing options...
Genifikius 1 Posted August 3, 2018 Share Posted August 3, 2018 I'm not having trouble going through C# code, probably gonna use both thank you so much, what a powerful tool. ? Link to comment https://wrobot.eu/forums/topic/12-how-to-create-an-fight-class-developer-only/#findComment-46331 Share on other sites More sharing options...
nfx 1 Posted August 4, 2018 Share Posted August 4, 2018 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? Link to comment https://wrobot.eu/forums/topic/12-how-to-create-an-fight-class-developer-only/#findComment-46366 Share on other sites More sharing options...
Marsbar 228 Posted August 4, 2018 Share Posted August 4, 2018 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. Link to comment https://wrobot.eu/forums/topic/12-how-to-create-an-fight-class-developer-only/#findComment-46370 Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now