Jump to content

reapler

Elite user
  • Posts

    288
  • Joined

  • Last visited

Posts posted by reapler

  1. 39 minutes ago, Apexx said:
    
    #region Properties 
         public bool GcdActive => DateTime.Now < _unlockTime; 
    #endregion

    Error    1    ; expected
    Error    2    Invalid token ';' in class, struct, or interface member declaration
    Error    3    Syntax error, '>' expected
    Error    4    'Main._unlockTime' is a 'field' but is used like a 'type'
    Error    5    'System.DateTime.Now' is a 'property' but is used like a 'type'

    I forgot to mention that i compiled it with a newer C# version in Vs. For example in C#6 you can import static type members into namespace.

    This version should also work with the older version as ".cs" file:

    Spoiler
    
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Threading;
    using wManager.Plugin;
    using wManager.Wow.Class;
    using wManager.Wow.Enums;
    using wManager.Wow.Helpers;
    using wManager.Wow.ObjectManager;
    using robotManager.Helpful;
    
    public class Main : IPlugin
    {
        #region Variables
    
        private bool _isLaunched;
        private int _msDelay = 150;
        private DateTime _unlockTime = DateTime.Now;
        private readonly HashSet<string> _noGcdSpells = new HashSet<string>
        {
            "Counterspell",
            //...
            //http://wowwiki.wikia.com/wiki/Cooldown => Abilities noted for not affecting nor being affected by the global cooldown:
        };
    
        #endregion
    
    
    
    
        #region Properties
    
            public bool GcdActive
        {
            get
            {
                return DateTime.Now < _unlockTime;
            }
        }
    
        #endregion
    
    
    
    
        #region WRobot Interface
        
        public void Initialize()
        {
            var pGuid = ToWoWGuid(ObjectManager.Me.Guid);
            EventsLuaWithArgs.OnEventsLuaWithArgs += delegate(LuaEventsId id, List<string> args)
            {
                if (
                    id == LuaEventsId.COMBAT_LOG_EVENT_UNFILTERED
                    && args[2] == pGuid
                    && !_noGcdSpells.Contains(args[9])
                    && 
                    (
                        args[1] == "SPELL_CAST_SUCCESS"
                        ||
                        args[1] == "SPELL_HEAL"
                        ||
                        args[1] == "SPELL_DAMAGE"
                    )
                    )
                {
                    Logging.Write("lock");
                    _unlockTime = DateTime.Now.AddMilliseconds(_msDelay);
                }
            };
            _isLaunched = true;
            Logging.Write("Loaded");
            while (_isLaunched)
            {
                try
                {
                    if (Conditions.ProductIsStartedNotInPause)
                    {
                        Pulse();
                    }
                }
                catch (Exception e)
                {
                    Logging.WriteError(e.ToString());
                }
                Thread.Sleep(30);
            }
        }
    
        public void Dispose()
        {
            _isLaunched = false;
        }
        
        public void Settings()
        {
    
        }
    
        #endregion
    
    
    
    
        #region Pulse
    
        public void Pulse()
        {
            var spell = new Spell("Lesser Heal");
            if (!GcdActive 
                && spell.IsSpellUsable
                && !ObjectManager.Me.IsCast
                && ObjectManager.Me.TargetObject.HealthPercent <= 95
                )
            {
                spell.Launch(false, false); //will cast the heal if "_msDelay" was passed
            }
    
            
    
    /*        if (spell.IsSpellUsable
                && !ObjectManager.Me.IsCast
                && ObjectManager.Me.TargetObject.HealthPercent <= 95)
            {
                spell.Launch(false, false); //.IsSpellUsable is true after gcd was passed but the heal itself can delay
                                            //and cause double heal cast if no additional delay is added like above
                                            //so ObjectManager.Me.TargetObject.HealthPercent <= 90 would be true for a short time
            }*/
        }
    
        #endregion
    
    
    
    
        #region Methods
    
        public string ToWoWGuid(ulong guid)
        {
            var wowGuid = ObjectManager.Me.Guid.ToString("x").ToUpper();
            var c = 16 - wowGuid.Length;
            for (var i = 0; i < c; i++)
            {
                wowGuid = "0" + wowGuid;
            }
            return "0x" + wowGuid;
        }
    
        #endregion
        
    }

     

     

  2. 17 minutes ago, Apexx said:

    That's wild! Thank you for the exuberant example. I will need to look this over a few times to try and wrap my head around it.  Why is this sort of thing not already implemented into WRobot? Also, you defined _msDelay. Where does this number come from? 

    It's the wait time after each cast. You may set this to 50ms - 200ms. But i think 50ms should still be ok on low tick speed.

  3. Hello, i've created a small example for this, everything else is explained in the comments:

    using System;
    using System.Collections.Generic;
    using System.Threading;
    using wManager.Plugin;
    using wManager.Wow.Class;
    using wManager.Wow.Enums;
    using wManager.Wow.Helpers;
    using wManager.Wow.ObjectManager;
    using static robotManager.Helpful.Logging;
    
    public class Main : IPlugin
    {
        #region Variables
    
        private bool _isLaunched;
        private int _msDelay = 200;
        private DateTime _unlockTime = DateTime.Now;
        private readonly HashSet<string> _noGcdSpells = new HashSet<string>
        {
            "Counterspell",
            //...
            //http://wowwiki.wikia.com/wiki/Cooldown => Abilities noted for not affecting nor being affected by the global cooldown:
        };
    
        #endregion
    
    
    
    
        #region Properties
    
        public bool GcdActive => DateTime.Now < _unlockTime;
    
        #endregion
    
    
    
    
        #region WRobot Interface
        
        public void Initialize()
        {
            var pGuid = ToWoWGuid(ObjectManager.Me.Guid);
            EventsLuaWithArgs.OnEventsLuaWithArgs += delegate(LuaEventsId id, List<string> args)
            {
                if (
                    id == LuaEventsId.COMBAT_LOG_EVENT_UNFILTERED
                    && args[2] == pGuid
                    && !_noGcdSpells.Contains(args[9])
                    && 
                    (
                        args[1] == "SPELL_CAST_SUCCESS"
                        ||
                        args[1] == "SPELL_HEAL"
                        ||
                        args[1] == "SPELL_DAMAGE"
                    )
                    )
                {
                    Write("lock");
                    _unlockTime = DateTime.Now.AddMilliseconds(_msDelay);
                }
            };
            _isLaunched = true;
            Write("Loaded");
            while (_isLaunched)
            {
                try
                {
                    if (Conditions.ProductIsStartedNotInPause)
                    {
                        Pulse();
                    }
                }
                catch (Exception e)
                {
                    WriteError(e.ToString());
                }
                Thread.Sleep(30);
            }
        }
    
        public void Dispose()
        {
            _isLaunched = false;
        }
        
        public void Settings()
        {
    
        }
    
        #endregion
    
    
    
    
        #region Pulse
    
        public void Pulse()
        {
            var spell = new Spell("Lesser Heal");
            if (!GcdActive 
                && spell.IsSpellUsable
                && !ObjectManager.Me.IsCast
                && ObjectManager.Me.TargetObject.HealthPercent <= 90
                )
            {
                spell.Launch(false, false); //will cast the heal if "_msDelay" was passed
            }
    
    
    /*        if (spell.IsSpellUsable
                && !ObjectManager.Me.IsCast
                && ObjectManager.Me.TargetObject.HealthPercent <= 90)
            {
                spell.Launch(false, false); //.IsSpellUsable is true after gcd was passed but the heal itself can delay
                                            //and cause double heal cast if no additional delay is added like above
                                            //so ObjectManager.Me.TargetObject.HealthPercent <= 90 would be true for a short time
            }*/
        }
    
        #endregion
    
    
    
    
        #region Methods
    
        public string ToWoWGuid(ulong guid)
        {
            var wowGuid = ObjectManager.Me.Guid.ToString("x").ToUpper();
            var c = 16 - wowGuid.Length;
            for (var i = 0; i < c; i++)
            {
                wowGuid = "0" + wowGuid;
            }
            return "0x" + wowGuid;
        }
    
        #endregion
        
    }

    if you are going to lower the tickspeed this will rarer happens, but it can still happen. Instant spells aren't included.

  4. Hello, since you are using vanilla i assume the method doesn't work correctly but i'm not sure("DoString" is obfuscated).

    You also can't use the "/use <item>" it wasn't implemented on vanilla. So you need to iterate the items in your bag with lua.

    I tried this on 3.3.5a but since the used api functions is also present on vanilla, it should also work:

        public void UseItemByName(string name, bool lootItem = true)
        {
            if (lootItem)
            {
                Task.Run(async delegate
                {
                    robotManager.Helpful.Keyboard.DownKey(wManager.Wow.Memory.WowMemory.Memory.WindowHandle,
                        System.Windows.Forms.Keys.ShiftKey);
                    await Task.Delay(2000);
                    robotManager.Helpful.Keyboard.UpKey(wManager.Wow.Memory.WowMemory.Memory.WindowHandle,
                        System.Windows.Forms.Keys.ShiftKey);
                });
            }
            wManager.Wow.Helpers.Lua.LuaDoString(
                @"
                                for b=0,4 do
                                    for s=1,GetContainerNumSlots(b) do
                                        if (string.find(tostring(GetContainerItemLink(b,s) or """"), """+wManager.Wow.Helpers.ItemsManager.GetIdByName(name)+@""" )) then
                                            UseContainerItem(b,s, onSelf);
                                        end
                                    end
                                end
                                "
            );
        }

    Usage:

            UseItemByName("Hearthstone", false);

    or

            UseItemByName("Heavy Crate", true);

     

  5. A small update from me:

    Since i'm almost done with the database, i can continue working on my editor again. But my first design wasn't really good. 

    I'm thinking to use a more simpler solution which doesn't require to assign a "Action parameter" at the sorted quests.

    In the end each action define a step which are selectable on the bar like this:

    Spoiler

    questeditor_gui2.JPG.45884410d5bae23778b0c68d9487342f.JPG

    By the way, if you have a custom pulse like "KillAndLoot",  "Gatherer" or something else which is often used, you are welcome to post it and i can create a seperate setting gui for it.

  6. Hello, @scripterx i really recommend to use c#. Pqr / only lua is limited in many ways.

    According to your posts, i guess you only want to cast specific spells by a button press only if x condition is met.

    So in this case you could do it like this in a plugin(i know it could be better > copy-pasta from my other posts):

    using System;
    using wManager.Plugin;
    using wManager.Wow.Class;
    using wManager.Wow.ObjectManager;
    
    public class Main : IPlugin
    {
        public void Initialize()
        {
            robotManager.Helpful.Logging.Write("Register OnEventsLuaWithArgs");
            wManager.Wow.Helpers.EventsLuaWithArgs.OnEventsLuaWithArgs += delegate (wManager.Wow.Enums.LuaEventsId id, System.Collections.Generic.List<string> args)
            {
                if (id != wManager.Wow.Enums.LuaEventsId.EXECUTE_CHAT_LINE || ObjectManager.Me.IsStunned) return;
                var toCast = new Spell("Riptide");
                if (args[0].ToUpper().Equals(("/cast @target " + toCast.Name).ToUpper())
                    && ObjectManager.Me.TargetObject.HealthPercent <= 90)
                {
                    toCast.Launch(false, false, false, "target");
                }
                if (args[0].ToUpper().Equals(("/cast @player " + toCast.Name).ToUpper())
                    && ObjectManager.Me.HealthPercent <= 95)
                {
                    toCast.Launch(false, false, false, true);
                }
            };
        }
    
        public void Dispose()
        {
    
        }
    
        public void Settings()
        {
    
        }
    }

    In-game you can just create a macro like this:

    #showtooltip Riptide
    /cast @target riptide

    So it will only cast the spell, if target is under 95% health. More related stuff can be found here.

     

    Otherwise you can do it on an automatic way in a rotation:

    using System;
    using System.Threading;
    using System.Windows.Forms;
    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 => 30f;
        private bool _isLaunched;
        public Spell Riptide = new Spell("Riptide");
     
        public void Initialize() // When product started, initialize and launch Fightclass
        {
            _isLaunched = true;
            Logging.Write("[My fightclass] Is initialized.");
            while (_isLaunched)
            {
                try
                {
                    if (!Products.InPause
                        && !ObjectManager.Me.IsDeadMe)
                    {
                        Pulse();
                    }
                }
                catch (Exception e)
                {
                    Logging.WriteError("[My fightclass] ERROR: " + e);
                }
                Thread.Sleep(10); // Pause 10 ms to reduce the CPU usage.
            }
        }
     
        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.");
        }
     
     
        public void Pulse()
        {
            if (ObjectManager.Me.Target != 0
                && Riptide.IsSpellUsable 
                && Riptide.IsDistanceGood 
                && Riptide.KnownSpell 
                && ObjectManager.Me.TargetObject.HealthPercent <= 95)
            {
                Riptide.Launch();
            }
        }
    }

    You can also combine them & use settings for automatic / manual usage and do whatever you want: The possibilities are endless. Using a state engine is also possible.

    More informations can be found here.

     

    If you need help, feel free to ask.

  7. I've looked over the spell class again and found this constructor:

    public Spell(string spellNameEnglish, bool showLog)

    So you need to add "false" on every instance of "Spell":

        public Spell GetActiveStance()
        {
            return new Spell(Lua.LuaDoString<List<string>>(@"local r = {}
                                                for i=1,10 do 
    	                                            local _, n, a = GetShapeshiftFormInfo(i);
    	                                            if a then table.insert(r, tostring(n)); end
                                                end
                                                return unpack(r);").FirstOrDefault() ?? "", false);
        }
    
    	
        public Spell BattleShout = new Spell("Battle Shout", false);
    
        //...

     

    This should hopefully stop the spam.

  8. 15 minutes ago, LilleCarl said:

    2.4.3 DBC (fightclass will create DBC folder in bot root)
    https://mega.nz/#!Fl1nVRyC!w6szGtAhEGUvho1Du5n1ZMB834L28Fg08oFYgOcjU6U

    FightClass that loads Spell DBC files and a child class to Spell where you easily can access this spelldata from https://github.com/Lillecarl/FightClass1

    That's all i've got for now, thanks for your help reapler! :)

    It looks excellent Carl. I'm looking forward that this will be added soon to the WRobot's lib ;)

  9. Hello @LilleCarl, i don't think that's the actual behavior of "new Spell("Regrowth", false).Id" to get the first rank and ".KnownSpell" shouldn't return always true. Maybe @Droidz can look into it.

    On 3.3.5a i have only experienced the second issue.

    But you may try this:

        public List<uint> GetKnownSpellIds(string name)
        {
            return new Spell(name).Ids.Where(SpellManager.KnowSpell).OrderBy(i => i).Distinct().ToList();
        }
        
        public uint GetHighestKnownSpell(string name)
        {
            return new Spell(name).Ids.Where(SpellManager.KnowSpell).OrderByDescending(i => i).FirstOrDefault();
        }

    Usage:

            var s = GetKnownSpellIds("Regrowth");
            for (var i = 0; i < s.Count; i++)
            {
                robotManager.Helpful.Logging.Write("\nId: "+s[i] +"    Rank: "+(i+1));
            }
            
            robotManager.Helpful.Logging.Write("Id: "+GetHighestKnownSpell("Regrowth"));

     

  10. 16 minutes ago, LilleCarl said:

    I've already implemented a C# dbc reader from https://github.com/TrinityCore/SpellWork/tree/0.12/ into my fightclass that reads all the spell DBC, it'll be OpenSource once i've cleaned it up to a non embarrassing level.

    I have already thought about this option at my current project (https://wrobot.eu/forums/topic/6681-extension-wowdb/) but i wanted to be more compact and converted it to SqLite.

    In the end no client actions are needed and i can customize struct definitions (https://github.com/barncastle/WDBXEditor), load it to database and alter it.

    I guess i also need to add spell retrieve methods to my manager aswell more client data to db :)

    But i'm thinking now it's better to use the reader, because all WRobot libraries already have it.

     

    And by the way welcome to WRobot.

     

  11. @Asoter Everything looks fine, checked names and values. For me it works: doesn't matter in "RunCode" or in plugin.

    You may try this snippet:

    using System;
    using System.Linq;
    using robotManager.Helpful;
    using wManager.Plugin;
    
    
    public class Main : IPlugin
    {
            public bool readyIntoDungeon
            {
                get
                {
                    Logging.Write(this.GetType().GetProperties().FirstOrDefault().Name);
                    return Var.GetVar<bool>(this.GetType().GetProperties().FirstOrDefault().Name);
                }
                set
                {
                    Logging.Write(this.GetType().GetProperties().FirstOrDefault().Name);
                    Var.SetVar(this.GetType().GetProperties().FirstOrDefault().Name, value);
                }
            }
        
        public void Initialize()
        {
            Logging.Write(""+readyIntoDungeon);
        }
    
        public void Dispose()
        {
    
        }
        
        public void Settings()
        {
            readyIntoDungeon = true;
        }
    }

    Click on settings button then start bot. If it's not printing "true", then something else could be wrong with your plugin. But without an insight into your code, i can't really define the problem.

  12. So far i can see it correctly detects the debuff. You may need to look-over if you have somewhere else used ".Launch()" for your "Demoralizing Shout",

    because in the snippet it must log "not active" before "[Spell] Cast Demoralizing Shout (Demoralizing Shout)" can appear(it can a bit delay).

    I guess you may also alter the ".Launch()" method aswell the conditions for the spell, since "waitIsCast" has an impact of your rotation:

            var spell = new Spell("Demoralizing Shout");
            if (!ObjectManager.Me.TargetObject.HaveBuff(spell.Ids)
                && spell.IsSpellUsable
                && spell.IsDistanceGood)
            {
                Logging.Write("not active\n=> cast"+spell.Name);
                spell.Launch(false, false);
            }
            else
            {
                Logging.Write(spell.Name+" active");
            }

     

  13. @Asoter Hello, in order to make a variable changeable by quester, you can transform your current variable into an property.

    Let's say you have an quest counter in your plugin defined as int:

    public int QuestCounter = 0;

    So you need to change this into this:

        public int QuestCounter
        {
            get
            {
                return robotManager.Helpful.Var.GetVar<int>(this.GetType().GetProperties().FirstOrDefault()?.Name);
            }
            set
            {
                robotManager.Helpful.Var.SetVar(this.GetType().GetProperties().FirstOrDefault()?.Name, value);
            }
        }

    You can still treat as an normal variable.

     

    And in Quester it looks like this:

    counter.JPG.524a94f1c044d6b265803c6e02f8bd58.JPG

    robotManager.Helpful.Var.SetVar("QuestCounter", 12);

     

  14. 1 hour ago, Apexx said:

    Thanks for the replies. I am still not quite sure how I can check each different id to whichever spell id the player currently has (as per rank and level of training).
    Lower level warriors use spell id 1160, while rank 2 of Demoralizing shout uses 6190. If I run a for loop through each demoralizing shout id that each mob
    might have, I am wondering if this will be very efficient?

    It's pretty fast. For a few ids, there's no need to care about (as i benchmarked, it took about 0,01789ms).

    But if you are going to iterate through thousands of entries, then another solution must be considered.

    You can read more about the performance of .net collections here.

    You might also try this:

            var spell = new Spell("Demoralizing Shout");
            if (!ObjectManager.Me.TargetObject.HaveBuff(spell.Ids))
            {
                Logging.Write("not active");
                spell.Launch();
            }
            else
            {
                Logging.Write("debuff active");
            }

     

  15. Hello, i can't directly test it, but you can try:

                var target = ObjectManager.Me.TargetObject;
                var spell = new Spell("Demoralizing Shout");
                if (!spell.TargetHaveBuff)
                {
                    spell.Launch();
                }

    or you can find the problem by yourself if you lookup spell / target:

    //copy this in your fightclass, and run this with opening settings
        public void ShowConfiguration()
        {
            //effects are also included
            var spellName = "Demoralizing Shout";
            Logging.Write("Get all ids of spell: "+spellName);
            foreach (var id in new Spell(spellName).Ids.Distinct())
            {
                Logging.Write("\n"+id);
            }
            Logging.Write("Done.");
    
    
            Logging.Write("Get all buffs from current target:");
            foreach (var id in ObjectManager.Me.TargetObject.GetAllBuff())
            {
                Logging.Write("\nid: "+id.SpellId+"     name: "+id.GetSpell.Name);
            }
            Logging.Write("Done.");
        }

     

    You can also search for the "HaveBuff()" method with a decompiler, you'll see that some checking are different.

    Usage(with demonstration video) of my prefered decompiler can be found here

×
×
  • Create New...