-
Posts
288 -
Joined
-
Last visited
Content Type
Forums
Articles
Bug Tracker
Downloads
Store
Posts posted by reapler
-
-
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.
-
Hello, you may decompile my plugin which uses keyboardhook & gui: https://wrobot.eu/files/file/1213-aoebutton/
I hope it's self-explaining, since it's quite old and can't remember anything ;)
-
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); }
-
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();");
-
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)
-
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);
-
Hello, @Zer you can take a look on:
-
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
-
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));
-
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
-
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.
-
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", });
-
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.
-
Hello, what's your primary goal?
Do you want to send items by item name / id?
Will the code be used in a plugin or quester profile?
-
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.
-
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 ;)
-
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
-
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.
-
Yes, the result is good :) I just added my height + 20:
Thank you.
- BetterSister and Droidz
- 1
- 1
-
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")
-
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.
-
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.
-
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.
-
Hello, i think your goal is to check whether you can disarm?
Plugins and Accept User Keyboard Input
in WRobot for Wow Wrath of the Lich King - Help and support
Posted
I've looked into it, you need to run the hook on its own context via "Application.Run();" to get it working:
So far it worked well.