Jump to content

reapler

Elite user
  • Posts

    288
  • Joined

  • Last visited

Posts posted by reapler

  1. I've looked into it, you need to run the hook on its own context via "Application.Run();" to get it working:

    using System;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using robotManager.Helpful;
    using wManager.Plugin;
    
    public class Main : IPlugin
    {
        public void Initialize()
        {
            KeyBoardHook.Initialize();
            KeyBoardHook.OnKeyDown += KeyDown;
        }
        
        public void Dispose()
        {
            KeyBoardHook.OnKeyDown -= KeyDown;
            KeyBoardHook.Dispose();
        }
    
        public void Settings()
        {
        }
        
        private static void KeyDown(object sender, KeyBoardHook.KeyArgs keyArgs)
        {
            Logging.Write(keyArgs.Key.ToString());
        }
    
    
        public class KeyBoardHook
        {
            private const int WH_KEYBOARD_LL = 13;
            private const int WM_KEYDOWN = 0x0100;
            private const int WM_KEYUP = 0x101;
            private static readonly LowLevelKeyboardProc Proc = HookCallback;
            private static IntPtr _hookId = IntPtr.Zero;
            private static Keys _lastKeyDown = Keys.None;
            public delegate void KeyBoardHookEventHandler(object sender, KeyArgs e);
            public static event KeyBoardHookEventHandler OnKeyDown = delegate{};
            public static event KeyBoardHookEventHandler OnKeyUp = delegate{};
    
            internal static void Initialize()
            {
                Task.Factory.StartNew(() =>//avoid thread blocking from Application.Run();
                {
                    _hookId = SetHook(Proc);
                    Application.Run(); //important! need to run in its own "context"
                });
            }
    
            internal static void Dispose()
            {
                UnhookWindowsHookEx(_hookId);
                Application.Exit();
            }
            
            private static IntPtr SetHook(LowLevelKeyboardProc proc)
            {
                using (var curProcess = Process.GetCurrentProcess())
                using (var curModule = curProcess.MainModule)
                {
                    return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
                }
            }
            
            private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
            
            private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
            {
                if (nCode < 0)
                    return CallNextHookEx(_hookId, nCode, wParam, lParam);
                if (wParam == (IntPtr) WM_KEYDOWN)
                {
                    var vkCode = (Keys) Marshal.ReadInt32(lParam);
                    if (_lastKeyDown == vkCode)
                        return CallNextHookEx(_hookId, nCode, wParam, lParam);
                    OnKeyDown(null, new KeyArgs(vkCode));
                    _lastKeyDown = vkCode;
                }
                else if (wParam == (IntPtr) WM_KEYUP)
                {
                    var vkCode = (Keys) Marshal.ReadInt32(lParam);
                    OnKeyUp(null, new KeyArgs(vkCode));
                    if (_lastKeyDown == vkCode)
                        _lastKeyDown = Keys.None;
                }
                return CallNextHookEx(_hookId, nCode, wParam, lParam);
            }
            
            [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
            
            [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            private static extern bool UnhookWindowsHookEx(IntPtr hhk);
            
            [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
            
            [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            private static extern IntPtr GetModuleHandle(string lpModuleName);
    
            public class KeyArgs : EventArgs 
            {
                public Keys Key { get; private set; }
    
                public KeyArgs(Keys key) 
                {
                    this.Key = key;
                }
            }
        }
    }

    So far it worked well.

  2. 19 minutes ago, Apexx said:

    I looked into the code and it seems you had used your own form events handling. I am using the WRobot's settings window from inside the class itself.
    I don't think the InputHook catches anything while the game window has focus. I guess I am trying to catch the even from WRobot directly.

    I initially implemented it, because sometimes i had a bug from WRobot's keyboard class which didn't hooked my keys, dunno if it's fully working now.

  3. Hello, you can subscribe your method to the event on initialize and unsubscribe on dispose:

        public void Initialize()
        {
            Radar3D.Pulse();
            Radar3D.OnDrawEvent += Radar3DOnDrawEvent;
        }
        
        public void Dispose()
        {
            Radar3D.OnDrawEvent -= Radar3DOnDrawEvent;
            Radar3D.Stop();
        }
        
        private static void Radar3DOnDrawEvent()
        {
            if (ObjectManager.Target.IsValid)
                Radar3D.DrawLine(ObjectManager.Me.Position, ObjectManager.Target.Position, Color.Chocolate);
            Radar3D.DrawCircle(ObjectManager.Me.Position, 5, Color.Chocolate);
        }

     

  4. 16 minutes ago, sowelu said:

    Dont work in my code, so , is there  no way to inplement swift rotation from code ? Key rotation  too slow. 

    I forgot to illustrate the other method more detailed. You can actually write your radians to rotation property at the player class (like you did), but after the write it is needed to update the rotation via a nudge:

                ObjectManager.Me.Rotation = 1.1f;
                //or use robotmanager's keyboard class
                Lua.LuaDoString("TurnLeftStart();");
                Lua.LuaDoString("TurnLeftStop();");

     

  5. I assume you are using the "Rotation" property from your playerclass to change the rotation, but this should be only used to get rotation values.

    This behavior occures because you are only changing your client-side rotation but not your actual rotation on the server.

    It can be fixed either using the mentioned "Face();" method in my previous posts (dunno if it works on vanilla)

    or by a nudge turn via keypress / lua (http://wowwiki.wikia.com/wiki/API_TurnLeftStart & http://wowwiki.wikia.com/wiki/API_TurnLeftStop)

  6. This should finally do the desired work while the other method was just for calculating :)

        /// <summary>
        /// Used to get the facing from two positions based on the origin rotation.
        /// </summary>
        /// <param name="from">The 1. position.</param>
        /// <param name="to">The 2. position.</param>
        /// <param name="originRotation">The origin rotation.</param>
        /// <returns>Negative radian on the right; positive on the left.</returns>
        public float FacingCenter(Vector3 from, Vector3 to, float originRotation)
        {
            var face = NormalizeRadian(Atan2Rotation(from, to) - originRotation);
            if (face < System.Math.PI)
                return -face;
            return NormalizeRadian(originRotation-Atan2Rotation(from, to));
        }
    
        /// <summary>
        /// Used to normalize the input radian.
        /// </summary>
        /// <param name="radian">The radians to normalize.</param>
        public float NormalizeRadian(float radian)
        {
            if (radian < 0.0)
                return (float) (-(- radian % (2.0 * System.Math.PI)) + 2.0 * System.Math.PI);
            return radian % 6.283185f;
        }
        
        /// <summary>
        /// Used to calculate atan2 of to positions.
        /// </summary>
        /// <param name="from">The 1. position.</param>
        /// <param name="to">The 2. position.</param>
        /// <param name="addRadian">Radians to add.</param>
        /// <returns></returns>
        public float Atan2Rotation(Vector3 from, Vector3 to, float addRadian = 0)
        {
            return (float) System.Math.Atan2(to.Y - from.Y, to.X - from.X) + addRadian;
        }

     

    Usage:

                        var rot = FacingCenter(ObjectManager.Me.Position, ObjectManager.Target.Position, ObjectManager.Me.Rotation);
                        if (rot < 0)
                            Logging.Write("Facing to right: "+rot);
                        Logging.Write("Facing to left: "+rot);

     

  7. Hello, this should work:

            private static double ActualRotation(double value, double min, double max)
            {
                if (value < min)
                    return min;
                return value > max ? max : value;
            }
    
            public static double CalculateFacingCenter(Vector3 source, float playerRotation, Vector3 destination)
            {
                Vector3 v2 = destination - source;
                v2.Z = 0.0f;
                Vector3 v1 = new Vector3((float) Math.Cos(playerRotation), (float) Math.Sin(playerRotation), 0.0f);
                return Math.Acos(ActualRotation(Vector3.Dot(ref v1, ref v2) / (v2.Magnitude() * (double) v1.Magnitude()), -1.0, 1.0));
            }

    And additional snippets which could help you:

        /// <summary>
        /// Used to calculate new position by parameter.
        /// </summary>
        /// <param name="from">The position to calculate from.</param>
        /// <param name="rotation">The rotation of the object in radians.</param>
        /// <param name="radius">The radius to add.</param>
        /// <returns></returns>
        public Vector3 CalculatePosition(Vector3 from, float rotation, float radius)
        {
            return new Vector3(System.Math.Sin(rotation) * radius + from.X, System.Math.Cos(rotation) * radius + from.Y, from.Z);
        }
    
        /// <summary>
        /// Used to calculate atan2 of to positions.
        /// </summary>
        /// <param name="from">Position 1.</param>
        /// <param name="to">Position 2.</param>
        /// <param name="addRadian">Radians to add.</param>
        /// <returns></returns>
        public float Atan2Rotation(Vector3 from, Vector3 to, float addRadian = 0)
        {
            return (float) System.Math.Atan2(to.Y - from.Y, to.X - from.X) + addRadian;
        }
    
        /// <summary>
        /// Used to face to the desired position.
        /// </summary>
        /// <param name="to">The position to face.</param>
        /// <param name="addRadian">Radians to add from the position.</param>
        public static void Face(Vector3 to, float addRadian = 0)
        {
            wManager.Wow.Helpers.ClickToMove.CGPlayer_C__ClickToMove(0, 0, 0, wManager.Wow.ObjectManager.ObjectManager.Me.Guid, 2, (float)System.Math.Atan2(to.Y - wManager.Wow.ObjectManager.ObjectManager.Me.Position.Y, to.X - wManager.Wow.ObjectManager.ObjectManager.Me.Position.X)+addRadian);
        }

    Usage for second block(i guess first one should be understandable)

            //turn 180°
            Face(ObjectManager.Target.Position, (float)System.Math.PI);
    
            //turn left
            Face(ObjectManager.Target.Position, 1.53589f);//88° = 1.53589 rad
    
            //turn right
            Face(ObjectManager.Target.Position, -1.53589f);//88° = 1.53589 rad

     

  8. Hello,  this might help you:

        /// <summary>
        /// Used to get the cooldown of an inventory item.
        /// </summary>
        /// <param name="slotId">The slot to get from.</param>
        /// <returns>The left cooldown of the item.</returns>
        public int GetInventoryCooldown(WoWInventorySlot slotId)
        {
            return Lua.LuaDoString<int>(
                @"
                local start, duration, enable = GetInventoryItemCooldown(""player"", "+(int)slotId+@")
                local coolDown = duration-(GetTime()-start);
                if (coolDown < 0) then 
                    return 0;
                end
                return coolDown;
                ");
        }

     

    Usage:

            Logging.Write("Cooldown of Trinket1: "+GetInventoryCooldown(WoWInventorySlot.Trinket1));

     

  9. Hello, you can try the following examples to either run a macro or using "Keyboard" class to press a button:

     

    Run wow macro(only work on tbc and above): open worldmap by click.xml

    Press button for 2 seconds: move forward by keyboard button press.xml  Available keys to press: https://msdn.microsoft.com/en-us/library/system.windows.forms.keys(v=vs.71).aspx

     

  10. 7 hours ago, sowelu said:

    Can it be rewritten for full bags disenchant? ( no mater which item is).  Unfortunately I dont understand well what is going on in code above :(

    Yes, it's also possible. You need to change ""local _, stackCount = GetContainerItemInfo(b, s)\t" +" with GetItemInfo, add your conditions and return a list with a struct of the bag position & its slot.

     

    The struct:

        public struct BagInfo
        {
            public int Bag;
    
            public int Slot;
    
            public BagInfo(int bag, int slot)
            {
                Bag = bag;
                Slot = slot;
            }
    
            public override string ToString()
            {
                return "Bag = " + Bag + " ; Slot = " + Slot;
            }
        }

     

    The disenchant list:

        /// <summary>
        /// Used to get a list of all disenchantable items as bag and slot position.
        /// </summary>
        /// <param name="maxItemLevel">The maximum item level.</param>
        /// <param name="interactions">The amount of interactions.</param>
        /// <returns></returns>
        public static List<BagInfo> DisenchantList(int maxItemLevel = int.MaxValue, int interactions = int.MaxValue)//parameter list can be extended
        {
            var execute =
                "local counter = 0; " +
                "local leftStacks = 0; " +
                "local bs = {}" +
                "for b=0,4 do " +
                "if GetBagName(b) then " +
                "for s=1, GetContainerNumSlots(b) do " +
                "local itemLink = GetContainerItemLink(b, s) " +
                "if itemLink then " +
                "local itemName, itemLink, itemRarity, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, itemTexture, itemSellPrice = GetItemInfo(itemLink) \t" +
                "if itemRarity > 1 and itemRarity < 5 " +
                "and itemLevel <= " + maxItemLevel + " " +
                "and (itemType == 'Armor' or itemType == 'Weapon') ";
            execute = execute + 
                      "then " +
                      "if (counter < "+interactions+") then " +
                      "table.insert(bs, b); " +
                      "table.insert(bs, s); " +
                      "counter = counter + 1; " +
                      "else " +
                      "leftStacks = leftStacks + 1;" +
                      "end " +
                      "\tend\tend\tend end end return unpack(bs);";
            var bs = Lua.LuaDoString<List<int>>(execute);
            var list = new List<BagInfo>();
            for (var i = 0; i < bs.Count; i += 2)
            {
                list.Add(new BagInfo(bs[i], bs[i+1]));
            }
            return list;
        }

     

    The final method to execute:

        /// <summary>
        /// Disenchant all items depend on the itemLevel.
        /// </summary>
        /// <param name="maxItemLevel">The maximum item level.</param>
        /// <remarks>AutoLoot must be enabled to work properly.</remarks>
        public void Disenchant(int maxItemLevel = int.MaxValue)
        {
            var disenchant = new Spell("Disenchant");
            foreach (var bagInfo in DisenchantList())
            {
                disenchant.Launch();
                Thread.Sleep(100);
                Lua.LuaDoString("UseContainerItem("+bagInfo.Bag+", "+bagInfo.Slot+");");
                Thread.Sleep((int)disenchant.CastTime+800);
            }
        }

    Not fully tested, but it should work.

     

    And

    9 hours ago, sowelu said:

    Works fine as charm, hell thanks. Dont know why but i had to replace .

    
    Lua.LuaDoString($"SendMail(\"{recipient}\",\"{subject}\",\" \");");

    to 

    
    Lua.LuaDoString("SendMail(\"" + recipient + "\", \"" + subject + "\")");

    I think you let it compile by WRobot or using a lower framework version, so new additions over the course of the years like this example doesn't support it.

  11. In my other post, i've written a method to interact with the items: https://wrobot.eu/forums/topic/7064-check-distance/?tab=comments#comment-32142

    You can also use this to right clicking your items to the mail attachment.

    I've rewritten abit, so it returns the left stacks:

        /// <summary>
        /// Interact with all listed item names.
        /// </summary>
        /// <param name="itemNames">The itemNames to interact with.</param>
        /// <param name="interactions">The amount of interactions.</param>
        /// <returns>The amount of itemNames / stacks blocked by "interactions".</returns>
        /// <remarks>Bug at links with "-"</remarks>
        public static int InteractItems(List<string> itemNames, int interactions = int.MaxValue)
        {
            if (!itemNames.Any())
                return -1;
            var execute = 
                "local counter = 0; " +
                "local leftStacks = 0; " +
                "for b=0,4 do " +
                "if GetBagName(b) then " +
                "for s=1, GetContainerNumSlots(b) do " +
                "local itemLink = GetContainerItemLink(b, s) " +
                "if itemLink then " +
                "local _, stackCount = GetContainerItemInfo(b, s)\t" +
                "if string.find(itemLink, \""+ itemNames.FirstOrDefault() + "\") ";
            if (itemNames.Count > 1)
            {
                execute = itemNames.Where(obj => itemNames.FirstOrDefault() != obj).Aggregate(execute, (current, obj) => current + "or string.find(itemLink, \"" + obj + "\") ");
            }
            execute = execute + 
                      "then " +
                      "if (counter < "+interactions+") then " +
                      "UseContainerItem(b, s); " +
                      "counter = counter + 1; " +
                      "else " +
                      "leftStacks = leftStacks + 1;" +
                      "end " +
                      "\tend\tend\tend end end return leftStacks;";
            return Lua.LuaDoString<int>(execute);
        }
    
        /// <summary>
        /// Sends a mail to a recipient.
        /// </summary>
        /// <param name="recipient">The recipient.</param>
        /// <param name="subject">The subject.</param>
        /// <param name="itemNames">The items to send as names.</param>
        /// <returns>true if successful ; false if no mailbox available or stacks are left.</returns>
        public bool SendItems(string recipient, string subject, List<string> itemNames)
        {
            var mailBox = ObjectManager.GetObjectWoWGameObject().FirstOrDefault(i => i.IsMailbox && i.GetDistance <= 5);
            if (mailBox == null || string.IsNullOrWhiteSpace(recipient))
                return false;
            if (subject.Length == 0)
                subject = "-";
            if (mailBox)
            {
                const int delayMs = 800;
                var timeOut = DateTime.Now.AddSeconds(40);
                Interact.InteractGameObject(mailBox.GetBaseAddress);
                Thread.Sleep(delayMs);
                Lua.LuaDoString("RunMacroText('/click MailFrameTab2');");
                Thread.Sleep(delayMs);
    
                var leftStack = InteractItems(itemNames, 12);
                Thread.Sleep(delayMs);
                Lua.LuaDoString($"SendMail(\"{recipient}\",\"{subject}\",\" \");");
                Thread.Sleep(delayMs*3);
    
                while (leftStack != 0 && DateTime.Now < timeOut)
                {
                    leftStack = InteractItems(itemNames, 12);
                    Thread.Sleep(delayMs);
                    Lua.LuaDoString($"SendMail(\"{recipient}\",\"{subject}\",\" \");");
                    Thread.Sleep(delayMs*3);
                }
    
                Lua.LuaDoString("CloseMail();");
                if (leftStack != 0)
                    return false;
            }
            return true;
        }

     

    Usage:

            SendItems("Reapler", "items for you", 
                new List<string>
                {
                    "Super Healing Potion",
                    "Heavy Netherweave Bandage",
                    "Super Mana Potion",
                });

     

  12. Hello, for example you can do the following for "COMBAT_LOG_EVENT_UNFILTERED":

        public void Initialize()
        {
            wManager.Wow.Helpers.EventsLuaWithArgs.OnEventsLuaWithArgs += delegate(LuaEventsId id, List<string> args)
            {
                if (id == LuaEventsId.COMBAT_LOG_EVENT_UNFILTERED)
                {
                    for (var i = 0; i < args.Count; i++)
                    {
                        robotManager.Helpful.Logging.Write($"args[{i}]: {args[i]}");
                    }
                }
            };
        }

    To get a list of all "LuaEventsId", i recommend to decompile "wManager.dll" in "WRobot\Bin\" and search for the desired value.

  13. 12 hours ago, Apexx said:

    I have since scrapped the project as trying to write healbots using WRobot was just too much for my skill of keeping things organized and maybe too many checks.
    Here is the snippet that did seem to work, but using the check for my warrior fight class, it would continuously crash WRobot before logging the actual error.

    
    // Buff Friendly Targets
    if (PriestSettings.CurrentSetting.BuffFriendlyTargets)
    {
    	if (_powerWordFortitude.KnownSpell
    		&& _powerWordFortitude.IsSpellUsable
    		&& target.Faction == player.Faction
    		&& target.IsAlive
    		&& target.IsValid
    		&& target.GetDistance <= _powerWordFortitude.MaxRange
    		&& !TraceLine.TraceLineGo(target.Position)
    		&& !target.HaveBuff(_powerWordFortitude.Ids))
    	{
    		Logging.WriteDebug(target.Name + " is missing Power Word: Fortitude.");
    		_powerWordFortitude.Launch();
    		Thread.Sleep(SpellManager.GetSpellCooldownTimeLeft(_powerWordFortitude.Id));
    	}
    }

     

    If this happens you should consider to use try and catch to log the error:

            try
            {
                // Buff Friendly Targets
                if (PriestSettings.CurrentSetting.BuffFriendlyTargets)
                {
                    if (_powerWordFortitude.KnownSpell
                        && _powerWordFortitude.IsSpellUsable
                        && target.Faction == player.Faction
                        && target.IsAlive
                        && target.IsValid
                        && target.GetDistance <= _powerWordFortitude.MaxRange
                        && !TraceLine.TraceLineGo(target.Position)
                        && !target.HaveBuff(_powerWordFortitude.Ids))
                    {
                        Logging.WriteDebug(target.Name + " is missing Power Word: Fortitude.");
                        _powerWordFortitude.Launch();
                        Thread.Sleep(SpellManager.GetSpellCooldownTimeLeft(_powerWordFortitude.Id));
                    }
                }
            }
            catch (Exception e)
            {
                Logging.WriteError(e.ToString());
            }

    For example you haven't initialized "PriestSettings.CurrentSetting", so this would result in null and throw an exception.

  14. 12 hours ago, sowelu said:

    Can I somehow receive some data from another instance of bot like value of variable in plugin? It would be cool to send a message to another instance.

    If you run the instances of WRobot on the same pc, you can checkout my CacheManager here.

    1 hour ago, sowelu said:

    1. Can I record path and force character to move  by C#  ?

    Yes, i recommend to use the "Quester" product and add a quest with "FollowPath" in "Quests Editor" window. It also supports C#.

    1 hour ago, sowelu said:

    2. How to use distract on the ground?

    I think, you know how to calculate the position, so you could use this:

            //replace "new Vector3()" with your desired position
            SpellManager.CastSpellByIDAndPosition(1725, new Vector3()); 

     

    1 hour ago, sowelu said:

    3 How to open trade, put items, and push it

    To open trade with current target:

            Lua.LuaDoString("RunMacroText('/trade');");

     

    Put items to the trade window(another solution, forgot the exact reason why it was in some ways better then the WRobot's method):

        /// <summary>
        /// Interact with all listed item names.
        /// </summary>
        /// <param name="items">Item list</param>
        /// <remarks>Bug at links with "-"</remarks>
        public static void InteractItems(List<string> items)
        {
            if (!items.Any())
                return;
            var execute = "for b=0,4 do " +
                          "if GetBagName(b) then " +
                          "for s=1, GetContainerNumSlots(b) do " +
                          "local itemLink = GetContainerItemLink(b, s) " +
                          "if itemLink then " +
                          "local _, stackCount = GetContainerItemInfo(b, s)\t" +
                          "if string.find(itemLink, \""+ items.FirstOrDefault() + "\")";
            if (items.Count > 1)
            {
                execute = items.Where(obj => items.FirstOrDefault() != obj).Aggregate(execute, (current, obj) => current + "or string.find(itemLink, \"" + obj + "\") ");
            }
            execute = execute + "then UseContainerItem(b, s)\tend\tend\tend end end";
            Lua.LuaDoString(execute);
        }

     

    To press the trade button:

            Lua.LuaDoString("RunMacroText('/click TradeFrameTradeButton');");

    Take also a look at https://wrobot.eu/forums/topic/6826-frame-stack-on-wow-tbc-243/ or type "/fstack" in Wow if you have wotlk or above, to get other related frame stuff.

     

    And If you mention a new topic, just open a new thread ;)

     

  15. Hello, ".PlayerFaction" should do its job:

            if (ObjectManager.Me.PlayerFaction == ((WoWPlayer) ObjectManager.Target).PlayerFaction)
            {
                Logging.Write("target same faction");
            }
    
            if (ObjectManager.Me.PlayerFaction != ((WoWPlayer) ObjectManager.Target).PlayerFaction)
            {
                Logging.Write("target hostile faction");
            }

    To check if target is a player:

    ObjectManager.Target.PlayerControlled

  16. I also noticed that the event with gcd lock sometimes react slow. But this works fine for me:

        public void Pulse()//pulse every 50ms
        {
            if (Target.HealthPercent <= 95)
            {
                new Spell("Flash of Light").Launch();//waitIsCast is true => no pulse while casting
                Logging.Write("cast done\nwait 5 seconds");
                Thread.Sleep(5000);
                Logging.Write("let it pulse again");
            }
            Logging.Write("pulse");
        }

    or if you don't want to block pulse and only want to lock the spell cast:

        private bool _folCast;
        public void Pulse()
        {
            if (Target.HealthPercent <= 95 && !_folCast)
            {
                _folCast = true;
                Task.Run(delegate
                {
                    new Spell("Flash of Light").Launch();//waitIsCast is true => the task have to wait while casting
                    Logging.Write("cast done\nset _folCast to false in 5 seconds");
                    Thread.Sleep(5000);
                    _folCast = false;
                    Logging.Write("_folCast is set to false");
                });
            }
            Logging.Write("pulse");
        }

    Of course it needs more checks to the cast, but you get the basic idea.

     

    The used initialize method:

        public void Initialize()
        {
            _isLaunched = true;
            Logging.Write("Loaded");
            while (_isLaunched)
            {
                try
                {
                    if (Conditions.ProductIsStartedNotInPause)
                    {
                        Pulse();
                    }
                }
                catch (Exception e)
                {
                    Logging.WriteError(e.ToString());
                }
                Thread.Sleep(50);//lower values will cause rather double casts
            }
        }

     

    If you use Task.Run for other stuff, ensure it won't trigger multiple times in a loop.

    If it's still double cast in your fightclass, you should check your routine flow while running.

     

  17. Hello, i'm developing currently on a click to move tool for the wow map. But i noticed that the .FindZ(); method isn't able to retrieve the height of dalaran, it returns the height of Crystalsong Forest.

    Yes it's working, no doubt, but is it possible to get the z position on dalaran instead of Crystalsong Forest? (the clicked position on the map is on "The Underbelly")

  18. I've altered your second snippet, because it threw some errors:

                if (GetCVar("HuntersMarkDisabled") == nil) then
                    RegisterCVar("HuntersMarkDisabled", "default")
                end
                if (GetCVarBool("HuntersMarkDisabled")) then
                     SetCVar("HuntersMarkDisabled", 0 );
                     DEFAULT_CHAT_FRAME:AddMessage("enabled frame: HuntersMark");
                else
                     SetCVar( "HuntersMarkDisabled", 1 );
                     DEFAULT_CHAT_FRAME:AddMessage("disabled frame: HuntersMark");
                end

    But since you are using only lua, i think there's a better solution but lua is not my favorite language ;) Maybe someone else can other offer a better answer.

  19. Hello, i think you would like to also connect to C#? So you can use this:

            Lua.LuaDoString(@"
                if (GetCVar(""frameDisabled"") == nil) then
                    RegisterCVar(""frameDisabled"", ""default"")
                end
                if (GetCVarBool(""frameDisabled"")) then
                     SetCVar(""frameDisabled"", 0 );
                     DEFAULT_CHAT_FRAME:AddMessage(""enabled frame"");
                else
                     SetCVar( ""frameDisabled"", 1 );
                     DEFAULT_CHAT_FRAME:AddMessage(""disabled frame"");
                end
            ");

    After each call it will be changed. And the returned values can be used by a fightclass.

    In lua just replace the double quote to one quote and add your code.

  20. Well, you can use these methods to check your unit:

        /// <summary>
        /// Used to get the main hand weapon of an unit.
        /// </summary>
        /// <remarks>Using 3.3.5a(12340) offsets.</remarks>
        /// <param name="unit">The unit.</param>
        public int MainHandId(WoWUnit unit)
        {
            if (unit.PlayerControlled)
                return wManager.Wow.Memory.WowMemory.Memory.ReadInt32(unit.GetDescriptorAddress(0x4E4));
            return wManager.Wow.Memory.WowMemory.Memory.ReadInt32(unit.GetDescriptorAddress(0xE0));
        }
        
        public bool IsDisarmed(WoWUnit unit)
        {
            return unit.UnitFlags.HasFlag(UnitFlags.Disarmed);
        }
    
        public bool IsHumanoid(WoWUnit unit)
        {
            return unit.CreatureTypeTarget == "Humanoid";
        }

    As you can see you need for the main hand id different offsets, which are for wotlk(maybe it works for other expansions).

    Please note that the id will still be returned for player characters even when shapeshifted or disarmed. If a npc / player doesn't carry a weapon, it will be zero.

    I think it should suffice to build a properly check for disarm.

×
×
  • Create New...