Skygirl779 3 Posted November 16, 2017 Share Posted November 16, 2017 Hello, I want to be able to left click a unit, i.e. target it without beginning to attack it. How can I do this? Thanks Link to comment https://wrobot.eu/forums/topic/7681-left-click-unit/ Share on other sites More sharing options...
Matenia 630 Posted November 16, 2017 Share Posted November 16, 2017 A SPECIFIC unit? You can take a look at (decompile) how Droidz does it in the "Interact" class in the Helper namespace (lots of memory writing). If not, use Lua.LuaDoString(TargetEnemy("name")) (I think) or Lua.RunMaroText("/target name") Skygirl779 1 Link to comment https://wrobot.eu/forums/topic/7681-left-click-unit/#findComment-35095 Share on other sites More sharing options...
Skygirl779 3 Posted November 16, 2017 Author Share Posted November 16, 2017 Just now, Matenia said: A SPECIFIC unit? You can take a look at (decompile) how Droidz does it in the "Interact" class in the Helper namespace (lots of memory writing). If not, use Lua.LuaDoString(TargetEnemy("name")) (I think) or Lua.RunMaroText("/target name") Thank you, but this only lets me target by name and I need to target by guid :( Link to comment https://wrobot.eu/forums/topic/7681-left-click-unit/#findComment-35096 Share on other sites More sharing options...
Matenia 630 Posted November 16, 2017 Share Posted November 16, 2017 (edited) Then you'll have to decompile Interact.InteractGameObject in the wManager.dll. Or just use it and instantly trigger /stopattack right after. If you just want to your spells to target another unit than your current target, there are plenty of threads on how to do this. Edited November 16, 2017 by Matenia Link to comment https://wrobot.eu/forums/topic/7681-left-click-unit/#findComment-35097 Share on other sites More sharing options...
reapler 154 Posted November 16, 2017 Share Posted November 16, 2017 (edited) 1 hour ago, Skygirl779 said: Thank you, but this only lets me target by name and I need to target by guid :( This should gonna do its work: public void Target(ulong guid) { wManager.Wow.Helpers.Lua.RunMacroText("/target "+wManager.Wow.ObjectManager.ObjectManager.GetObjectByGuid(guid)?.Name+""); } Edit: i reconsider my answer, this may not be a ideal solution. If you gonna look at the interact function in WRobot, you'll notice it's a direct function call via asm. So another solution would be to overwrite the guid from the local player's focus and target it via lua: public void Target(WoWObject obj) { var tmp = ObjectManager.Me.FocusGuid; ObjectManager.Me.FocusGuid = obj.Guid; Lua.RunMacroText("/target focus"); ObjectManager.Me.FocusGuid = tmp; } public void Target(ulong guid) { var tmp = ObjectManager.Me.FocusGuid; ObjectManager.Me.FocusGuid = guid; Lua.RunMacroText("/target focus"); ObjectManager.Me.FocusGuid = tmp; } Usage: var firstOrDefault = ObjectManager.GetObjectWoWUnit().OrderBy(i => i.GetDistance).FirstOrDefault(); if (firstOrDefault != null) Target(firstOrDefault.Guid); Edited November 16, 2017 by reapler Skygirl779 1 Link to comment https://wrobot.eu/forums/topic/7681-left-click-unit/#findComment-35099 Share on other sites More sharing options...
Matenia 630 Posted November 16, 2017 Share Posted November 16, 2017 43 minutes ago, reapler said: This should gonna do its work: public void Target(ulong guid) { wManager.Wow.Helpers.Lua.RunMacroText("/target "+wManager.Wow.ObjectManager.ObjectManager.GetObjectByGuid(guid)?.Name+""); } Edit: i reconsider my answer, this may not be a ideal solution. If you gonna look at the interact function in WRobot, you'll notice it's a direct function call via asm. So another solution would be to overwrite the guid from the local player's focus and target it via lua: public void Target(WoWObject obj) { var tmp = ObjectManager.Me.FocusGuid; ObjectManager.Me.FocusGuid = obj.Guid; Lua.RunMacroText("/target focus"); ObjectManager.Me.FocusGuid = tmp; } public void Target(ulong guid) { var tmp = ObjectManager.Me.FocusGuid; ObjectManager.Me.FocusGuid = guid; Lua.RunMacroText("/target focus"); ObjectManager.Me.FocusGuid = tmp; } Usage: var firstOrDefault = ObjectManager.GetObjectWoWUnit().OrderBy(i => i.GetDistance).FirstOrDefault(); if (firstOrDefault != null) Target(firstOrDefault.Guid); For anyone reading this - this will only work in TBC and onwards where "focus" is an existing unit. The direct ASM function call reapler was talking about *might* be your only solution in Vanilla if you want to achieve exactly this. Link to comment https://wrobot.eu/forums/topic/7681-left-click-unit/#findComment-35101 Share on other sites More sharing options...
reapler 154 Posted November 16, 2017 Share Posted November 16, 2017 1 minute ago, Matenia said: For anyone reading this - this will only work in TBC and onwards where "focus" is an existing unit. The direct ASM function call reapler was talking about *might* be your only solution in Vanilla if you want to achieve exactly this. It's also possible to do this on vanilla, but with mouseover guid: public void Target(ulong guid) { if (guid == 0) return; ulong tmp = wManager.Wow.Memory.WowMemory.Memory.ReadUInt64( (uint) wManager.Wow.Memory.WowMemory.Memory.MainModuleAddress + 0x74E2C8); wManager.Wow.Memory.WowMemory.Memory.WriteUInt64( (uint) wManager.Wow.Memory.WowMemory.Memory.MainModuleAddress + 0x74E2C8, guid); wManager.Wow.Helpers.Lua.LuaDoString("TargetUnit('mouseover');"); wManager.Wow.Memory.WowMemory.Memory.WriteUInt64( (uint) wManager.Wow.Memory.WowMemory.Memory.MainModuleAddress + 0x74E2C8, tmp); } Matenia 1 Link to comment https://wrobot.eu/forums/topic/7681-left-click-unit/#findComment-35102 Share on other sites More sharing options...
Matenia 630 Posted November 16, 2017 Share Posted November 16, 2017 23 minutes ago, reapler said: It's also possible to do this on vanilla, but with mouseover guid: public void Target(ulong guid) { if (guid == 0) return; ulong tmp = wManager.Wow.Memory.WowMemory.Memory.ReadUInt64( (uint) wManager.Wow.Memory.WowMemory.Memory.MainModuleAddress + 0x74E2C8); wManager.Wow.Memory.WowMemory.Memory.WriteUInt64( (uint) wManager.Wow.Memory.WowMemory.Memory.MainModuleAddress + 0x74E2C8, guid); wManager.Wow.Helpers.Lua.LuaDoString("TargetUnit('mouseover');"); wManager.Wow.Memory.WowMemory.Memory.WriteUInt64( (uint) wManager.Wow.Memory.WowMemory.Memory.MainModuleAddress + 0x74E2C8, tmp); } This... changes a lot. I had no idea mouseover was a valid unit in Vanilla. Do you happen to know if SpellManager.CastSpellByNameOn(name, unit) works in Vanilla? OP might not have to use that Lua call, if it is possible to cast a spell directly on a Lua unit. Either way, as long as you prevent wRobot from changing target while you manually do it (e.g. pause OnFightLoop, temporarily remove Grinder state from the current product, etc), this should work. That's amazing. Link to comment https://wrobot.eu/forums/topic/7681-left-click-unit/#findComment-35104 Share on other sites More sharing options...
reapler 154 Posted November 16, 2017 Share Posted November 16, 2017 47 minutes ago, Matenia said: Do you happen to know if SpellManager.CastSpellByNameOn(name, unit) works in Vanilla? Yes, in vanilla you need to change the target guid, since the api only allows target or local player as argument. It looks like this: public void CastSpell(string spellName, WoWObject obj) { if (!obj.IsValid) return; ulong tmp = wManager.Wow.Memory.WowMemory.Memory.ReadUInt64( (uint) wManager.Wow.Memory.WowMemory.Memory.MainModuleAddress + 0x74E2D8); wManager.Wow.Memory.WowMemory.Memory.WriteUInt64( (uint) wManager.Wow.Memory.WowMemory.Memory.MainModuleAddress + 0x74E2D8, obj.Guid); Lua.LuaDoString("CastSpellByName('"+spellName+"');"); wManager.Wow.Memory.WowMemory.Memory.WriteUInt64( (uint) wManager.Wow.Memory.WowMemory.Memory.MainModuleAddress + 0x74E2D8, tmp); } Someone may think why not using objectmanager's target property from local player, the reason is the setter has some additional code for actually change the target and some other features. Link to comment https://wrobot.eu/forums/topic/7681-left-click-unit/#findComment-35109 Share on other sites More sharing options...
Matenia 630 Posted November 16, 2017 Share Posted November 16, 2017 (edited) 1 hour ago, reapler said: Yes, in vanilla you need to change the target guid, since the api only allows target or local player as argument. It looks like this: Someone may think why not using objectmanager's target property from local player, the reason is the setter has some additional code for actually change the target and some other features. Plus ObjectManager.Target is marked as readonly (or the GUID is iirc - I tried way back). Edited November 16, 2017 by Matenia Link to comment https://wrobot.eu/forums/topic/7681-left-click-unit/#findComment-35113 Share on other sites More sharing options...
Skygirl779 3 Posted November 16, 2017 Author Share Posted November 16, 2017 7 hours ago, reapler said: This should gonna do its work: public void Target(ulong guid) { wManager.Wow.Helpers.Lua.RunMacroText("/target "+wManager.Wow.ObjectManager.ObjectManager.GetObjectByGuid(guid)?.Name+""); } Edit: i reconsider my answer, this may not be a ideal solution. If you gonna look at the interact function in WRobot, you'll notice it's a direct function call via asm. So another solution would be to overwrite the guid from the local player's focus and target it via lua: public void Target(WoWObject obj) { var tmp = ObjectManager.Me.FocusGuid; ObjectManager.Me.FocusGuid = obj.Guid; Lua.RunMacroText("/target focus"); ObjectManager.Me.FocusGuid = tmp; } public void Target(ulong guid) { var tmp = ObjectManager.Me.FocusGuid; ObjectManager.Me.FocusGuid = guid; Lua.RunMacroText("/target focus"); ObjectManager.Me.FocusGuid = tmp; } Usage: var firstOrDefault = ObjectManager.GetObjectWoWUnit().OrderBy(i => i.GetDistance).FirstOrDefault(); if (firstOrDefault != null) Target(firstOrDefault.Guid); Thank you very much! The focus target is a working solution for me. That said, it's not perfect; is there an API that allows me to safely call WoW functions from wRobot? I have the necessary technical knowledge, I just don't know how to get wRobot to execute asm in WoW's main thread. Link to comment https://wrobot.eu/forums/topic/7681-left-click-unit/#findComment-35124 Share on other sites More sharing options...
reapler 154 Posted November 16, 2017 Share Posted November 16, 2017 8 minutes ago, Skygirl779 said: That said, it's not perfect; is there an API that allows me to safely call WoW functions from wRobot? I have the necessary technical knowledge, I just don't know how to get wRobot to execute asm in WoW's main thread. Yes, you can. For example: //3.3.5a 12340 public void MoveForwardStart() { wManager.Wow.Memory.WowMemory.InjectAndExecute( new [] { //more parameters can be appended by the wrapper wManager.Wow.Memory.WowMemory.CallWrapperCode( (uint)wManager.Wow.Memory.WowMemory.Memory.MainModuleAddress + 0x1FC200), wManager.Wow.Memory.WowMemory.RetnToHookCode, }, true ); } Skygirl779 1 Link to comment https://wrobot.eu/forums/topic/7681-left-click-unit/#findComment-35125 Share on other sites More sharing options...
iMod 99 Posted November 17, 2017 Share Posted November 17, 2017 (edited) Targeting by guid for vanilla (not tested) private static readonly object LockTargeting = new object(); public static void TargetUnit(ulong guid) { // Allocate memory for the target guid uint alloc = Memory.WowMemory.Memory.AllocateMemory(8); // Write guid Memory.WowMemory.Memory.WriteUInt64(alloc, guid); // Create asm string[] asm = new string[] { $"mov ecx, {alloc}", $"call {0x489A40}", Memory.WowMemory.RetnToHookCode }; lock (LockTargeting) { // Execute Memory.WowMemory.InjectAndExecute(asm); } // Free memory Memory.WowMemory.Memory.FreeMemory(alloc); } Edited November 17, 2017 by iMod reapler 1 Link to comment https://wrobot.eu/forums/topic/7681-left-click-unit/#findComment-35199 Share on other sites More sharing options...
Memus 1 Posted February 4, 2019 Share Posted February 4, 2019 On 11/17/2017 at 4:51 PM, iMod said: Targeting by guid for vanilla (not tested) private static readonly object LockTargeting = new object(); public static void TargetUnit(ulong guid) { // Allocate memory for the target guid uint alloc = Memory.WowMemory.Memory.AllocateMemory(8); // Write guid Memory.WowMemory.Memory.WriteUInt64(alloc, guid); // Create asm string[] asm = new string[] { $"mov ecx, {alloc}", $"call {0x489A40}", Memory.WowMemory.RetnToHookCode }; lock (LockTargeting) { // Execute Memory.WowMemory.InjectAndExecute(asm); } // Free memory Memory.WowMemory.Memory.FreeMemory(alloc); } Got a working example of this for 3.3.5a? Changing $"call {0x489A40}" to $"call {0x524BF0}" does not suffice :S Link to comment https://wrobot.eu/forums/topic/7681-left-click-unit/#findComment-51334 Share on other sites More sharing options...
Matenia 630 Posted February 4, 2019 Share Posted February 4, 2019 Because target guid is a static offset in WotLK. ObjectManager.Me.Target = unit.Guid; works, or if you want to set mouseover: private static void SetMouseoverGuid(ulong guid) { switch (Usefuls.WowVersion) { case 5875: Memory.WowMemory.Memory.WriteUInt64((uint)Memory.WowMemory.Memory.MainModuleAddress + 0x74E2C8, guid); break; case 8606: Memory.WowMemory.Memory.WriteUInt64((uint)Memory.WowMemory.Memory.MainModuleAddress + 0x86E950, guid); break; case 12340: Memory.WowMemory.Memory.WriteUInt64((uint) 0x00BD07A0, guid); break; default: throw new Exception("Wow version is not supported!"); } } private static void SetMouseoverUnit(WoWUnit unit) { SetMouseoverGuid(unit.Guid); } public static void Target(WoWUnit unit) { ulong guid = unit.Guid; if (guid == 0) { return; } ulong tmp = Memory.WowMemory.Memory.ReadUInt64((uint)Memory.WowMemory.Memory.MainModuleAddress + 0x74E2C8); SetMouseoverUnit(unit); Lua.LuaDoString(@"TargetUnit(""mouseover"");"); //do something here SetMouseoverUnit(tmp); } Link to comment https://wrobot.eu/forums/topic/7681-left-click-unit/#findComment-51339 Share on other sites More sharing options...
Memus 1 Posted February 4, 2019 Share Posted February 4, 2019 23 minutes ago, Matenia said: Because target guid is a static offset in WotLK. ObjectManager.Me.Target = unit.Guid; works, or if you want to set mouseover: private static void SetMouseoverGuid(ulong guid) { switch (Usefuls.WowVersion) { case 5875: Memory.WowMemory.Memory.WriteUInt64((uint)Memory.WowMemory.Memory.MainModuleAddress + 0x74E2C8, guid); break; case 8606: Memory.WowMemory.Memory.WriteUInt64((uint)Memory.WowMemory.Memory.MainModuleAddress + 0x86E950, guid); break; case 12340: Memory.WowMemory.Memory.WriteUInt64((uint) 0x00BD07A0, guid); break; default: throw new Exception("Wow version is not supported!"); } } private static void SetMouseoverUnit(WoWUnit unit) { SetMouseoverGuid(unit.Guid); } public static void Target(WoWUnit unit) { ulong guid = unit.Guid; if (guid == 0) { return; } ulong tmp = Memory.WowMemory.Memory.ReadUInt64((uint)Memory.WowMemory.Memory.MainModuleAddress + 0x74E2C8); SetMouseoverUnit(unit); Lua.LuaDoString(@"TargetUnit(""mouseover"");"); //do something here SetMouseoverUnit(tmp); } ObjectManager.Me.Target = unit.Guid; Triggers interact/autoattack on hostile/neutral unit which is too annoying to live with. The Mouseover solution is what I'm using right now but I consider that as an workaround. I want a clean solution, as in Vanilla with the inject code. Link to comment https://wrobot.eu/forums/topic/7681-left-click-unit/#findComment-51341 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