iMod 99 Posted April 10, 2017 Share Posted April 10, 2017 (edited) Hello, I was writing a small method that handles casting spells for me and I'm looking for some improvements for it. May you see some issues. /// <summary> /// Cast a spell /// </summary> /// <param name="spell">The spell you want to cast</param> /// <param name="target">The target you want to cast at</param> /// <param name="debuff">The debuff we are looking for</param> /// <param name="buffTimeLeft">Recast if buff time is under the given time</param> /// <param name="stacks">How much stacks you want at the target</param> /// <param name="owner">Flag that determines if we need to be the owner</param> /// <param name="force">Force use the skill and ignore debuffs</param> /// <returns>Returns true if we can cast the spell otherwise false</returns> public static bool CastSpell(Spell spell, WoWUnit target, double buffTimeLeft = 0, int stacks = 0, Spell debuff = null, bool owner = true, bool force = false) { // Check if the spell is known if (!Functions.IsSpellKnown(spell) || target == null) { // Skip return false; } // Check if buff exists bool hasDebuff; if (debuff != null) { hasDebuff = Functions.HasBuff(debuff, target, buffTimeLeft, stacks, owner); } else { hasDebuff = Functions.HasBuff(spell, target, buffTimeLeft, stacks, owner); } // Validate spell if (!ObjectManager.Me.IsStunned && !ObjectManager.Me.IsDead && !ObjectManager.Me.IsCast && !target.IsDead && spell.IsSpellUsable && (ObjectManager.Me.Position.DistanceTo(target.Position) <= spell.MaxRange) && (force || !hasDebuff) && !TraceLine.TraceLineGo(target.Position)) { if (target.Guid == ObjectManager.Me.Guid) { // Cast on self Lua.LuaDoString($"CastSpellByID({spell.Id}, \"player\")"); } else if (ObjectManager.Me.TargetObject.Guid == target.Guid) { // Cast on target Lua.LuaDoString($"CastSpellByID({spell.Id}, \"target\")"); } else if (ObjectManager.Me.TargetObject.Guid != target.Guid) { // Offset 3.3.5a uint mouseOverGUID = 0x00BD07A0; // Set target Memory.WowMemory.Memory.WriteUInt64(mouseOverGUID, target.Guid); // Cast on mouseover Lua.LuaDoString($"CastSpellByID({spell.Id}, \"mouseover\")"); } else { throw new Exception("Something went wrong with the targeting."); } // Log Logging.WriteDebug($"Cast: {spell.NameInGame} at {target.Name}"); // Wait until global cooldown is done Thread.Sleep(SpellManager.GlobalCooldownTimeLeft()); // Return return true; } // Return return false; } Would be glad if someone could overlook it. Thanks in andvance iMod Edited April 12, 2017 by iMod Method update Link to comment Share on other sites More sharing options...
Matenia 627 Posted April 10, 2017 Share Posted April 10, 2017 Should probably also have some smart way of checking whether the spell is off the GCD - like any interrupt. Link to comment Share on other sites More sharing options...
iMod 99 Posted April 10, 2017 Author Share Posted April 10, 2017 41 minutes ago, Schaka said: Should probably also have some smart way of checking whether the spell is off the GCD - like any interrupt. Should be checked by "spell.IsSpellUsable" Link to comment Share on other sites More sharing options...
Matenia 627 Posted April 10, 2017 Share Posted April 10, 2017 No, because you already exit the function, before you get that far. Link to comment Share on other sites More sharing options...
iMod 99 Posted April 10, 2017 Author Share Posted April 10, 2017 49 minutes ago, Schaka said: No, because you already exit the function, before you get that far. True, forgot to remove the lines y.y I'm not checking anymore if the GCD is > 0 since i wait at the bottom. Link to comment Share on other sites More sharing options...
reapler 154 Posted April 10, 2017 Share Posted April 10, 2017 Hello i have also written something similar on another script language. My method was to register the combatlog and set a timer with a boolean value on it when a spell was cast by me(you can add to this latency & some personal preferences to it). I've done this, because (for me) the api function wasn't accurate enough. and you can also add some overloads to your method if you need them for e.g. with list debuffs: public static bool CastSpell(Spell spell, WoWUnit target, double buffTimeLeft = 0, int stacks = 0, List<Spell> debuffs = null, bool owner = true, bool force = false) { //... } or with spellname instead: public static bool CastSpell(string spellname, WoWUnit target, double buffTimeLeft = 0, int stacks = 0, Spell debuff = null, bool owner = true, bool force = false) { //... } Link to comment Share on other sites More sharing options...
iMod 99 Posted April 10, 2017 Author Share Posted April 10, 2017 11 minutes ago, reapler said: Hello i have also written something similar on another script language. My method was to register the combatlog and set a timer with a boolean value on it when a spell was cast by me(you can add to this latency & some personal preferences to it). I've done this, because (for me) the api function wasn't accurate enough. and you can also add some overloads to your method if you need them for e.g. with list debuffs: public static bool CastSpell(Spell spell, WoWUnit target, double buffTimeLeft = 0, int stacks = 0, List<Spell> debuffs = null, bool owner = true, bool force = false) { //... } or with spellname instead: public static bool CastSpell(string spellname, WoWUnit target, double buffTimeLeft = 0, int stacks = 0, Spell debuff = null, bool owner = true, bool force = false) { //... } Thanks, i still had some other overloads but i never used them so they'r gone. So what kind of language are you using for it? I also thought about to use the ingame function instead of lua. I wish i could just use the hook to load my own object manager and own object classes but it seems i have to write my own for it y.y Link to comment Share on other sites More sharing options...
reapler 154 Posted April 10, 2017 Share Posted April 10, 2017 @iMod I've used a more or less modified lua engine from a guy that had written it for 4.3.4 but i got tired with cataclysm and couldn't use the stuff for other Wow expansions(so i came here and learned abit C#) and with objectmanager/hook i'm not sure but i don't think you need to write much or? i mean you can get the base address, pointers and as well other objects and lookup/add descriptors or offsets from the already existing manager. For e.g. i needed something to check a descriptorfield wheter item is soulbound or not(i don't know anymore where exactly i've found it) but i figured out later that the function already exist haha Anyway here is how it looked like: public class Descriptor { private static uint Descriptor_Offset = 0x8; //not in api Can be added later /*public static uint Read(WoWDynamicObject obj, Descriptors.DynamicObjectFields field) { return Read(obj.GetBaseAddress, (uint)field); }*/ public static uint Read(WoWItem obj, Descriptors.ItemFields field) { return Read(obj.GetBaseAddress, (uint) field); } public static uint Read(WoWObject obj, Descriptors.ObjectFields field) { return Read(obj.GetBaseAddress, (uint)field); } public static uint Read(WoWContainer obj, Descriptors.ContainerFields field) { return Read(obj.GetBaseAddress, (uint)field); } public static uint Read(WoWCorpse obj, Descriptors.CorpseFields field) { return Read(obj.GetBaseAddress, (uint)field); } public static uint Read(WoWGameObject obj, Descriptors.GameObjectFields field) { return Read(obj.GetBaseAddress, (uint)field); } public static uint Read(WoWPlayer obj, Descriptors.PlayerFields field) { return Read(obj.GetBaseAddress, (uint)field); } public static uint Read(WoWUnit obj, Descriptors.UnitFields field) { return Read(obj.GetBaseAddress, (uint)field); } public static uint Read(uint obj, uint field ) { try { if (obj != null) { uint address = Memory.WowMemory.Memory.ReadUInt32(obj + Descriptor_Offset); return Memory.WowMemory.Memory.ReadUInt32(address + field); } } catch (Exception ex) { Logging.WriteError("Error: " + ex); return 0; } return 0; } //Add Write } Maybe you also don't need to write for yourself for your goal Link to comment Share on other sites More sharing options...
iMod 99 Posted April 10, 2017 Author Share Posted April 10, 2017 7 minutes ago, reapler said: I've used a more or less modified lua engine from a guy that had wriiten it for 4.3.4 but i got tired with cataclysm and couldn't use the stuff for other Wow expansions(so i came here and learned abit C#) and with objectmanager/hook i'm not sure but i don't think you need to write much or? i mean you can get the base address, pointers and as well other objects and lookup/add descriptors or offsets from the already existing manager. For e.g. i needed something to check a descriptorfield wheter item is soulbound or not(i don't know anymore where exactly i've found it) but i figured out later that the function already exist haha Anyway here is how it looked like: public class Descriptor { private static uint Descriptor_Offset = 0x8; //not in api Can be added later /*public static uint Read(WoWDynamicObject obj, Descriptors.DynamicObjectFields field) { return Read(obj.GetBaseAddress, (uint)field); }*/ public static uint Read(WoWItem obj, Descriptors.ItemFields field) { return Read(obj.GetBaseAddress, (uint) field); } public static uint Read(WoWObject obj, Descriptors.ObjectFields field) { return Read(obj.GetBaseAddress, (uint)field); } public static uint Read(WoWContainer obj, Descriptors.ContainerFields field) { return Read(obj.GetBaseAddress, (uint)field); } public static uint Read(WoWCorpse obj, Descriptors.CorpseFields field) { return Read(obj.GetBaseAddress, (uint)field); } public static uint Read(WoWGameObject obj, Descriptors.GameObjectFields field) { return Read(obj.GetBaseAddress, (uint)field); } public static uint Read(WoWPlayer obj, Descriptors.PlayerFields field) { return Read(obj.GetBaseAddress, (uint)field); } public static uint Read(WoWUnit obj, Descriptors.UnitFields field) { return Read(obj.GetBaseAddress, (uint)field); } public static uint Read(uint obj, uint field ) { try { if (obj != null) { uint address = Memory.WowMemory.Memory.ReadUInt32(obj + Descriptor_Offset); return Memory.WowMemory.Memory.ReadUInt32(address + field); } } catch (Exception ex) { Logging.WriteError("Error: " + ex); return 0; } return 0; } //Add Write } Maybe you also don't need to write for yourself for your goal Thanks dude, i still have all descriptor and offsets i think but my problem atm is that i have some trouble with the asm stuff ^.^ I think i just need to invest some more time in it to get everything nice and clean :) Yeah this bot was way cleaner few years ago =/ now it feels kinda overloaded and slow and this lua memory issue is horrible =/ Link to comment Share on other sites More sharing options...
Mykoplazma 24 Posted April 11, 2017 Share Posted April 11, 2017 Hey reapler do you know haw to cast the spell on guid without targeting ,focusing etc? It was possible on cata (wow+ hack ) to use spell on enemy unit ( like interrupt or something ) without targetting it so you don't loose your focus and target ( very nice for arenas etc ) it was like third focus and when you cast a spell it land on the target and it was in the combat log but there was no targeting the target whatsoever it was working thru simple CastSpellByName("spellname",characterGuid) but I thing there was some kind of internall wraper inside the wow+ or some modification to cast spell by name lua function. Link to comment Share on other sites More sharing options...
iMod 99 Posted April 11, 2017 Author Share Posted April 11, 2017 Hm you could use the internal function at 0x0080DA40 (3.3.5a) CastSpell(SpellID, Guid) Link to comment Share on other sites More sharing options...
Mykoplazma 24 Posted April 11, 2017 Share Posted April 11, 2017 Oh well something new but I don't dig in asm ( :( ) Can you write here how to do it for 5.4.8 pandaria ? Plz ;) I can manage c# but not how to use the internal function from wrobot level. Link to comment Share on other sites More sharing options...
iMod 99 Posted April 11, 2017 Author Share Posted April 11, 2017 2 hours ago, forerun said: Oh well something new but I don't dig in asm ( :( ) Can you write here how to do it for 5.4.8 pandaria ? Plz ;) I can manage c# but not how to use the internal function from wrobot level. Never tried it with wrobot but i will give it a try later. Take a look at "Marshal.GetDelegateForFunctionPointer"[5.4.8 18414] CastSpell = 0x4F9983Update: Some problems with rebase the pointer. Matenia 1 Link to comment Share on other sites More sharing options...
Droidz 2737 Posted April 11, 2017 Share Posted April 11, 2017 Hello, to use descriptor you can use WRobto API like: uint address = wManager.Wow.ObjectManager.ObjectManager.Me.GetDescriptorAddress(wManager.Wow.Patchables.Descriptors.PlayerFields.NextLevelXP); int result = wManager.Wow.Memory.WowMemory.Memory.ReadInt32(address); If you don't want to use focus, you can try to use "mouseover": WoWUnit target; // ... your target uint s_MouseOver = 0x00BD0798; // 3.3.5 http://www.ownedcore.com/forums/world-of-warcraft/world-of-warcraft-bots-programs/wow-memory-editing/298310-3-3-5-offsets.html#post1902575 wManager.Wow.Memory.WowMemory.Memory.WriteUInt64(s_MouseOver, target.Guid); SpellManager.CastSpellByNameOn("Spell Name", "mouseover"); Link to comment Share on other sites More sharing options...
reapler 154 Posted April 11, 2017 Share Posted April 11, 2017 3 hours ago, Droidz said: Hello, to use descriptor you can use WRobto API like: uint address = wManager.Wow.ObjectManager.ObjectManager.Me.GetDescriptorAddress(wManager.Wow.Patchables.Descriptors.PlayerFields.NextLevelXP); int result = wManager.Wow.Memory.WowMemory.Memory.ReadInt32(address); If you don't want to use focus, you can try to use "mouseover": WoWUnit target; // ... your target uint s_MouseOver = 0x00BD0798; // 3.3.5 http://www.ownedcore.com/forums/world-of-warcraft/world-of-warcraft-bots-programs/wow-memory-editing/298310-3-3-5-offsets.html#post1902575 wManager.Wow.Memory.WowMemory.Memory.WriteUInt64(s_MouseOver, target.Guid); SpellManager.CastSpellByNameOn("Spell Name", "mouseover"); I guess that's a brilliant solution to overwrite guid for this purpose :) but it needs the mouseoverguid instead of mouseover for 3.3.5: public void CastSpell(string spellName, WoWUnit unit) { uint MouseOverGUID = 0x00BD07A0; wManager.Wow.Memory.WowMemory.Memory.WriteUInt64(MouseOverGUID, unit.Guid); SpellManager.CastSpellByNameOn(spellName, "mouseover"); } and @forerun i belive you need to search it couldn't find the offset myself currently :/ iMod 1 Link to comment Share on other sites More sharing options...
iMod 99 Posted April 11, 2017 Author Share Posted April 11, 2017 6 hours ago, Droidz said: Hello, to use descriptor you can use WRobto API like: uint address = wManager.Wow.ObjectManager.ObjectManager.Me.GetDescriptorAddress(wManager.Wow.Patchables.Descriptors.PlayerFields.NextLevelXP); int result = wManager.Wow.Memory.WowMemory.Memory.ReadInt32(address); If you don't want to use focus, you can try to use "mouseover": WoWUnit target; // ... your target uint s_MouseOver = 0x00BD0798; // 3.3.5 http://www.ownedcore.com/forums/world-of-warcraft/world-of-warcraft-bots-programs/wow-memory-editing/298310-3-3-5-offsets.html#post1902575 wManager.Wow.Memory.WowMemory.Memory.WriteUInt64(s_MouseOver, target.Guid); SpellManager.CastSpellByNameOn("Spell Name", "mouseover"); Disables my right click and i can't turn my camera anymore for some reasons o.O kinda strange Link to comment Share on other sites More sharing options...
Mykoplazma 24 Posted April 12, 2017 Share Posted April 12, 2017 Ok I get it working 5.4.8 18414 offset. MouseGuid = Wow.exe+D65B28 After that all is ok and you can cast havoc on not current target without changing the current target and spam shadowburn without changing current target - useful thing. And I don't get strange behaviour nothing is blocked etc. I can run around cast shadwoburn and nuke main target in the same time. Matenia 1 Link to comment Share on other sites More sharing options...
iMod 99 Posted April 12, 2017 Author Share Posted April 12, 2017 1 hour ago, forerun said: Ok I get it working 5.4.8 18414 offset. MouseGuid = Wow.exe+D65B28 After that all is ok and you can cast havoc on not current target without changing the current target and spam shadowburn without changing current target - useful thing. And I don't get strange behaviour nothing is blocked etc. I can run around cast shadwoburn and nuke main target in the same time. Sounds good i think i have to test the other pointer that @reapler posted. Hopefully its the solution. Link to comment Share on other sites More sharing options...
Mykoplazma 24 Posted April 12, 2017 Share Posted April 12, 2017 Ok don't wanna be rude but 0x00BD0798 Is static ? If so you need add wow base memory adress to that to work. On panda you need to do that because the base is different each time wow is executed so the final adress will be different. In the code above that thing is not present. iMod 1 Link to comment Share on other sites More sharing options...
iMod 99 Posted April 12, 2017 Author Share Posted April 12, 2017 13 minutes ago, forerun said: Ok don't wanna be rude but 0x00BD0798 Is static ? If so you need add wow base memory adress to that to work. On panda you need to do that because the base is different each time wow is executed so the final adress will be different. In the code above that thing is not present. Thats not rude ;) i'm kinda new to that stuff so i'm glad if i get some infos. I'll try that out later. Link to comment Share on other sites More sharing options...
iMod 99 Posted April 12, 2017 Author Share Posted April 12, 2017 Allright it is working now had some issues in my spell logic. Oh and btw I don't need to add the base. I noticed one issue... sometimes the game switches the target to the mouseover mob.Update: Yey it seems that if the target you have is not attaking you it will target the "mouseover" mob. First post updated. Link to comment Share on other sites More sharing options...
Mykoplazma 24 Posted April 12, 2017 Share Posted April 12, 2017 delete Link to comment Share on other sites More sharing options...
jrouten 1 Posted May 24, 2017 Share Posted May 24, 2017 So, I've tried using this MouseOver cast on Live, and I am not having any luck. I tried @Droidz method above, like this uint s_MouseOverGUID = 0x00F3EDC0; Memory.WowMemory.Memory.WriteInt128(s_MouseOverGUID, target.Guid); SpellManager.CastSpellByNameOn(spell.Name, "mouseover"); This gives me You Have No Target in game unless I actually move the mouse over a target, and it will cast on that target even if the target I'm trying to override mouse-over for is a different target. I got the offset from here: http://www.ownedcore.com/forums/world-of-warcraft/world-of-warcraft-bots-programs/wow-memory-editing/619264-wow-7-2-0-24015-offsets-post3731214.html#post3731214 I tried the LUA method like this: uint s_MouseOverGUID = 0x00F3EDC0; Memory.WowMemory.Memory.WriteInt128(s_MouseOverGUID, target.Guid); Lua.LuaDoString(string.Format("CastSpellByID(\"{0}\", \"mouseover\")", spell.Id.ToString())); And get the same thing. Suggestions? Link to comment Share on other sites More sharing options...
reapler 154 Posted May 24, 2017 Share Posted May 24, 2017 @jrouten I think you should use 'WriteUInt64'. I guess your returned value from memory is also an ulong(=UInt64) variable like your target.guid. I belive they haven't changed it til legion. Otherwise you can check whether the offset is really returning your mouseover guid: At first pick any non moving npc and target it. Try to move your character to a position where the npc is on the left corner on the top of your wow window. Now you need to mouse over the npc(tooltip shouldn't disappear) and get out of the window. As next step you can execute this method to check if the offset is returning the right value: public void checkoffset() { uint MouseOverGUID = 0x00F3EDC0; if (wManager.Wow.Memory.WowMemory.Memory.ReadUInt64(MouseOverGUID) == ObjectManager.Me.Target) { robotManager.Helpful.Logging.Write("offset ok"); } else { robotManager.Helpful.Logging.Write("Got different values:\n" +"Read guid from memory: "+ wManager.Wow.Memory.WowMemory.Memory.ReadUInt64(MouseOverGUID) +"\nNeeded guid: "+ ObjectManager.Me.Target); } } If you've done everything right & it still prints different values you have no choice to search it by yourself ;) You can take for this task a safe memory tool to search for it or searching it with wrobot in a read loop. First option would be better but i don't know if the tools like cheat engine are safe on live. In the end i can't offer more help(i have no live-account) so i wish you good luck Link to comment Share on other sites More sharing options...
jrouten 1 Posted May 24, 2017 Share Posted May 24, 2017 I tried using WriteUInt64, but it generates an error since Target.Guid is an Int128. I was also nervous about using any of the known memory tools with Live, so was hoping to figure this out without having to poke/search. If all else fails, I guess I can create a new account and run it in a VM with proxy Link to comment 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