Work Continues On Healbot AI 2 menu

Shout-Out

User Tag List

Page 1 of 3 123 LastLast
Results 1 to 15 of 38
  1. #1
    cloud_wizard's Avatar Member
    Reputation
    5
    Join Date
    Dec 2008
    Posts
    44
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Work Continues On Healbot AI 2



    Hiya. Work on Healbot AI 2 is progressing nicely. The UI is DONE, the healing AI is about 75% done. But none of it is any good if I can't convince you guys to help me with this next part.

    I need to implement some code that will get the health values for the entire raid. This is outside of my area of expertise. I humbly ask for your help here. Everyone who contributes something that moves me in that direction will get a copy of the bot when it's finished.

    When it's finished you will be able to use it with multiple instances of WoW on one computer. You can select one (possibly more, haven't decided) as the healer, and choose whether or not to run the healer instance(s) as minimized. In another instance, you could be playing another toon. The bot will follow you around, keeping a safe distance (configurable), healing you and your group members / pets (fully configurable). The bot will take talent point allocation into consideration. It will take agro into consideration, giving healing priority to targets with agro while in aggressive healing mode. It will take spell pushback into consideration. It will take hot timers, buffs, and debuffs into consideration. It will take lag into consideration. It will take bonus healing and target health deficit into consideration and guesstimate overhealing based on spell choice. It will give high priority to avoiding overhealing when in conservative healing mode.

    There's really a lot of features going into this... Many many more than I have listed here. These are just some of the juicy ones.

    I'm also taking feature requests.


    Work Continues On Healbot AI 2
  2. #2
    Gamer's Avatar Active Member
    Reputation
    239
    Join Date
    Jan 2007
    Posts
    198
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Errm, not sure why the double thread, but heres my answer again.

    Ok, if you assume that every player around you is in your raid (eg. in an instance) you can simply loop through the object list looking for player objects, then read their health.

    Sample:

    Code:
    
    
            Dim ClientConnectionOffset As UInt32 = &H11CA260
            Dim ObjectManagerOffset As UInteger = &H2864
            System.Diagnostics.Process.EnterDebugMode()
                WoW.OpenProcessAndThread(SProcess.GetProcessFromProcessName("wow"))
                g_ClientConnection = WoW.ReadUInt(ClientConnectionOffset)
                s_curMgr = WoW.ReadUInt(g_ClientConnection + ObjectManagerOffset)
    
    
             Dim CurObj As UInteger = MagicWoW.ReadUInt(s_curMgr + &HAC)
            Dim NextObj As UInteger = CurObj
             Dim ObjType As Integer
           
    
            While Not CurObj = 0
          
                                ObjType = Wow.ReadUInt(CurObj + &H14)
    
                   
    
                        If (ObjType = 4) Then
    
                Dim UnitFields as Uint32 = WoW.ReadUInt(localObj + &H8)
                          
                Dim HP As UInt32 = WoW.ReadUInt(UnitFields + (&H17 * 4))
                Dim MaxHP as Uint32 = WoW.ReadUInt(UnitFields + (&H1F * 4))
                        
    
    If (HP/MAXHP) < 0.1 Then
    healz.
    End If
    
                
             
                    NextObj = MagicWoW.ReadUInt(CurObj + &H3C)
    
            
    
                If NextObj = CurObj Then
                    Exit While
                Else
                    CurObj = NextObj
                End If
    
            End While
    PS: The &H is equivalent to 0x.
    Last edited by Gamer; 12-29-2008 at 10:37 AM.

  3. #3
    cloud_wizard's Avatar Member
    Reputation
    5
    Join Date
    Dec 2008
    Posts
    44
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Gamer View Post
    Errm, not sure why the double thread, but heres my answer again.

    Ok, if you assume that every player around you is in your raid (eg. in an instance) you can simply loop through the object list looking for player objects, then read their health.

    Sample:

    Code:
    
    
            Dim ClientConnectionOffset As UInt32 = &H11CA260
            Dim ObjectManagerOffset As UInteger = &H2864
            System.Diagnostics.Process.EnterDebugMode()
                WoW.OpenProcessAndThread(SProcess.GetProcessFromProcessName("wow"))
                g_ClientConnection = WoW.ReadUInt(ClientConnectionOffset)
                s_curMgr = WoW.ReadUInt(g_ClientConnection + ObjectManagerOffset)
    
    
             Dim CurObj As UInteger = MagicWoW.ReadUInt(s_curMgr + &HAC)
            Dim NextObj As UInteger = CurObj
             Dim ObjType As Integer
           
    
            While Not CurObj = 0
          
                                ObjType = Wow.ReadUInt(CurObj + &H14)
    
                   
    
                        If (ObjType = 4) Then
    
                Dim UnitFields as Uint32 = WoW.ReadUInt(localObj + &H8)
                          
                Dim HP As UInt32 = WoW.ReadUInt(UnitFields + (&H17 * 4))
                Dim MaxHP as Uint32 = WoW.ReadUInt(UnitFields + (&H1F * 4))
                        
    
    If (HP/MAXHP) < 0.1 Then
    healz.
    End If
    
                
             
                    NextObj = MagicWoW.ReadUInt(CurObj + &H3C)
    
            
    
                If NextObj = CurObj Then
                    Exit While
                Else
                    CurObj = NextObj
                End If
    
            End While
    PS: The &H is equivalent to 0x.
    The double thread because the first one isn't mine. The guy who originally started this project made that thread, went crazy, had a breakdown, and abandoned the project. He sent me his source code when he left. Your guess is as good as mine as to why, though.

    I read the thread. I understand the looping through the objects in the area. However, is there a way to distinguish one object from another? By Unit ID perhaps? Spells in WoW are cast at a Unit ID.

    UnitID can be anything from player, playerpet, focus, target, targettarget, targettargettarget, party1 thru party4, party1pet thru party4pet, raid1 thru raid40, raid1pet thru raid40pet, focustarget, raid20target, etc.

    In order for the looping method to be give me the information I need, I need to be able to directly associate a health value with a UnitID.

    I don't want to have to assume that every player around me is in my group. The bot will be doing some healing outside of instances.

    Also, I should probably mention that I'm writing this in Managed C++. That's what the project was started in when I inherited it, I don't see any point in changing it.

    I looked at Cyphers sticky. is GUID the same thing as UnitID? If so, this method may very well work. If not, I may be able to make this work if I just have the Unit Name... But Unit ID is GREATLY preferred.

  4. #4
    Gamer's Avatar Active Member
    Reputation
    239
    Join Date
    Jan 2007
    Posts
    198
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I was referring to http://www.mmowned.com/forums/wow-me...tire-raid.html.

    And I'm not sure that UnitID and GUID are the same.

  5. #5
    cloud_wizard's Avatar Member
    Reputation
    5
    Join Date
    Dec 2008
    Posts
    44
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    WTF? That thread was an accidental post. Sorry, I will edit it out immediately. Please continue the discussion here, not there.

    Edit: I re-checked Cyphers post for more information. One of the descriptors (not necessarily in this list) has to contain the UnitID information. It's stored client side just like everything else. These are a few possibilities (only possible because I don't know what they are).

    [07:14:50]: OBJECT_FIELD_GUID = 0x0
    [07:14:50]: UNIT_VIRTUAL_ITEM_SLOT_ID = 0x37
    [07:14:50]: UNIT_FIELD_DISPLAYID = 0x42
    [07:14:50]: UNIT_FIELD_NATIVEDISPLAYID = 0x43
    [07:14:51]: GAMEOBJECT_DISPLAYID = 0x8
    UnitID has to be somewhere...
    Last edited by cloud_wizard; 12-29-2008 at 11:42 AM.

  6. #6
    luciferc's Avatar Contributor
    Reputation
    90
    Join Date
    Jul 2008
    Posts
    373
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Okay heres some basic's

    Guid = Is always Unique

    The Baseaddr sometimes changes for a Person so Always Call/Store by GUID.


    To see who you have Selected you do this.

    UInt64 target_GUID = Memory.ReadUInt64(hProcess, 0x010A58B;

    It will return the GUID of the guy.

    So to change your Target you write to that Location (0x010A58B with the GUID of the guy u want to heal.

    And then you press Keys.

    I dunno where u got the Idea that you can use UnitId but if you looked @ the post more carefully you would notice that GUIDs are the shit and that theres Fields for it as well.
    Last edited by luciferc; 12-29-2008 at 12:49 PM.

  7. #7
    luciferc's Avatar Contributor
    Reputation
    90
    Join Date
    Jul 2008
    Posts
    373
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    --After you get there Base (by Looping with this If Statement)
    Code:
    BaseAddress Getter
    if (target_GUID == WowObjects[q].OBJECT_FIELD_GUID)
    {
    //Wow Objects Is a Struct that stores it.
    Code:
    Get Targets HP Percent
    int cur_hp = Memory.ReadInt(hProcess, (Memory.ReadUInt(hProcess, targetbase + 0x08)) + 0x17 * 4);
    int max_hp = Memory.ReadInt(hProcess, (Memory.ReadUInt(hProcess, targetbase + 0x08)) + 0x1F * 4);
    target_hp_percent = (double)cur_hp / (double)max_hp;
    Code:
    Thats How to get there Coordinates
    myinfo.tx = Memory.ReadFloat(hProcess, targetbase + 0x7d0); //x
    myinfo.ty = Memory.ReadFloat(hProcess, targetbase + 0x7d4); //y
    myinfo.tz = Memory.ReadFloat(hProcess, targetbase + 0x7d8); //z
    Code:
    My Wow Object Struct (Cut down a lil)
    public struct Object
            {
                public UInt64 OBJECT_FIELD_GUID;
                public int OBJECT_FIELD_TYPE;
                public uint OBJECT_FIELD_BASEADRESS;
                public string OBJECT_FIELD_NAME;
                public int OBJECT_FIELD_DISPLAY_ID;
                public float OBJECT_X;
                public float OBJECT_Y;
                public float OBJECT_Z;
                public int OBJECT_FIELD_LEVEL;
            }
    Last edited by luciferc; 12-29-2008 at 12:57 PM.

  8. #8
    cloud_wizard's Avatar Member
    Reputation
    5
    Join Date
    Dec 2008
    Posts
    44
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Sorry for being stuck on UnitIDs. Looking at the code of the original healbot, I can see that he used UnitIDs to do all his dirty work.

    He had the bot start by indexing all the UnitIDs in an array. He'd go through a while loop that would step his UnitID as he checked health. He'd check for ppl with <20% health, stepping UnitID to max, resetting unit ID, stepping health to <40%, stepping unit ID to max, resetting unit ID, stepping health to <60%, etc...

    If the bot ever stopped on a unit that needed healing, it would pass the Unit ID and it's current health value to another function which would do some stuff, decide how best to heal, pass the data again to the heal function where (And this is the cool part) the bot would type a slash command in game that used the unit ID from the original function in the heal command. It would look something like this.

    /cast [target=UnitID] Greater Heal

    Where UnitID is obviously the UnitID.

    Quite genius IMO...


    Yours is very helpful information, Thank you. Now... is there a way to tell if a unit is in my group or not?

  9. #9
    Nesox's Avatar ★ Elder ★
    Reputation
    1280
    Join Date
    Mar 2007
    Posts
    1,238
    Thanks G/R
    0/3
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I have a suggestion, if your rading with a guild you could make it dump evryone in the guild that is near
    Code:
    [07:14:50]: PLAYER_GUILDID = 0x97
    and use that as an index for reading the health if it's below 20% and then just throw them a heal

  10. #10
    schlumpf's Avatar Retired Noggit Developer

    Reputation
    755
    Join Date
    Nov 2006
    Posts
    2,759
    Thanks G/R
    0/3
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Nesox: Nice addition, but most raids are random. You may use that with a toggle in the bot's config. But else..

  11. #11
    Shynd's Avatar Contributor
    Reputation
    97
    Join Date
    May 2008
    Posts
    393
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Here's how I would do it:
    • 1. Write a LUA function that parses through each UnitID (party1, party2..raid40) until it finds who to heal (check for, as you said, less than 20% first, 40%, 60%, etc, all making sure they're in range of whatever your class' main heal is). Put this function in an AddOn, which makes it available globally to WoW's embedded LUA.
    • 2. Write a DLL in C/whatever that will be injected into WoW.exe. This DLL should detour one of the DirectX render functions that is called every frame (EndScene would probably be the one I'd do). Inside the EndScene detour, use CGameLua__DoString, using WoW's lua_State (0x012E87EC in WoW.3.0.3), to call the LUA function you wrote in step 1, which should return either the player name to be healed or the UnitID. Use lua_ToString to pop the UnitID/name off of the LUA stack.
    • 3a. (Non-optimal) Just modify the original handler program to accept this data and type its /cast whatever command as normal. The original author said, I believe, that it was the data-gathering process that was clunky (reading pixels, etc.) and that the casting of the heals was fine. If it's not broke and you don't want to improve on it, you don't need to change it.
    • 3b. (Recommended) Add a shared memory segment to the injected DLL, allowing you to set conditions from your external handler program. You'd have variables like BOOL IsRunning and BOOL ShouldHealPets and float AlertHealthLevel and float LowHealthLevel and float ModerateHealthLevel. When your program starts up, the DLL should be injected and IsRunning should initialize as false, so that it just idly loops without doing anything. As your program is configured by the user, set your conditions within the DLL's shared memory segment (AlertHealthLevel = 20%, LowHealthLevel = 40%, etc.). When the Start button is hit, IsRunning should be set to true, allowing the DLL to start healing / following / whatever. All actions are taken inside WoW's context, allowing for the best speed and the most robust repertoire of possible actions.
    • 3c. (Advanced) Your DLL is all you need, period. It creates an in-game GUI, ala WoWX, by hooking DirectX and overlaying information / gathering user input / etc. Everything is configured in-game and all healing / following / buffing / whatever actions are done in the WoW context, much like in step 3b. This is the best of the options, but also would cause a lot of problems because you would probably be tempted to copy+paste code from WoWX or somewhere else without actually learning the code theory in question, causing you to run into a lot of problems you wouldn't know how to solve. That's just a guess, but I'd bet it's a pretty safe one.

  12. #12
    cloud_wizard's Avatar Member
    Reputation
    5
    Join Date
    Dec 2008
    Posts
    44
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    This.



    This is what I need. This is an excellent post with tons of valuable information.

    1. Write a LUA function that parses through each UnitID (party1, party2..raid40) until it finds who to heal (check for, as you said, less than 20% first, 40%, 60%, etc, all making sure they're in range of whatever your class' main heal is). Put this function in an AddOn, which makes it available globally to WoW's embedded LUA.
    The LUA addon for use in WOW: Easy. I can do that. Hell, the one that came with the original healbot is nice as is. I'll add a few things to it, like agro detection, etc.

    2. Write a DLL in C/whatever that will be injected into WoW.exe. This DLL should detour one of the DirectX render functions that is called every frame (EndScene would probably be the one I'd do). Inside the EndScene detour, use CGameLua__DoString, using WoW's lua_State (0x012E87EC in WoW.3.0.3), to call the LUA function you wrote in step 1, which should return either the player name to be healed or the UnitID. Use lua_ToString to pop the UnitID/name off of the LUA stack.
    Er... That could be a little tricky. Several questions on this. How do you "inject" a dll? Is that detectable? I'm not familiar with DirectX *at all*. I'm probably going to have to get your help with this step.

    Er, wait... You said all I should be getting from the addon is a Unit Name / Unit ID? I don't want the addon doing the thinking on this... I was asked to keep the decision making code (the AI) more or less a secret. Although now that I've seen some of the things you guys can do to these poor programs, I don't think it'll stand much chance against any of you... but it's still not going in an addon. I realize that limits my options... But maybe there's another way. I could write the addon to just be a data gatherer of sorts... And I'd use the same method of calling the LUA functions to get the data... but for the amount of data that I'd need to move, doing it after every frame is a little too often. I was thinking 10x a second would be a little better. Maybe lower still would be better.

    3a. (Non-optimal) Just modify the original handler program to accept this data and type its /cast whatever command as normal. The original author said, I believe, that it was the data-gathering process that was clunky (reading pixels, etc.) and that the casting of the heals was fine. If it's not broke and you don't want to improve on it, you don't need to change it.
    That's not gonna work. The original healbot AI was written to run in the background while WoW was in the foreground (in order to send the cast commands). It had to type them, much like I'm typing this message right now. Character by character. It would sometimes make typos if you told it to type too fast. (missing characters that didn't register).

    I want this bot to be able to cast without needing WoW to be the active window.

    3b. (Recommended) Add a shared memory segment to the injected DLL, allowing you to set conditions from your external handler program. You'd have variables like BOOL IsRunning and BOOL ShouldHealPets and float AlertHealthLevel and float LowHealthLevel and float ModerateHealthLevel. When your program starts up, the DLL should be injected and IsRunning should initialize as false, so that it just idly loops without doing anything. As your program is configured by the user, set your conditions within the DLL's shared memory segment (AlertHealthLevel = 20%, LowHealthLevel = 40%, etc.). When the Start button is hit, IsRunning should be set to true, allowing the DLL to start healing / following / whatever. All actions are taken inside WoW's context, allowing for the best speed and the most robust repertoire of possible actions.
    The only thing I really want the DLL to do is get the information from the addon for me. I'd like to have my main program do all the thinking. I already have an idea of how I'd like to do it. There's a timer on the main form that'll hit 10x a second (100ms intervals). Basically when this timer is hit, It'll do all the thinking, checking health values and other relevant information for everyone in the raid. If it decides to heal someone based on the information it has, it'll go into the function that decides which spell to cast, based on the current health of the target. When it decides which spell to cast, it casts it (Though I haven't decided how, yet).

    I'm not even gonna touch 3c. Heh. That's a little (a lot) beyond my capabilities.

    All in all, This is an excellent contribution to my project. Would you mind adding me on yahoo? My ID is the same on yahoo as it is here. I'd really like to get your involvement in the rest of the project.

    Thank you, Shynd.


  13. #13
    Cypher's Avatar Kynox's Sister's Pimp
    Reputation
    1358
    Join Date
    Apr 2006
    Posts
    5,368
    Thanks G/R
    0/6
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    3c is what I do, its much nicer to use and code with than the alternatives. CEGUI is fairly nice and easy to pick up.

    An alternative to 3b would to be use a named pipe to communicate with your external app. I believe this is a better alternative than shared data. As far as I'm aware if you're using shared data you can bot ONLY ONE copy of WoW. WoW!Sharp had that limitation because of its use of shared mem.

    But in any case you definitely want to get function calls happening one way or another in your bot. You COULD implement your bot pretty much entirely in LUA, but you'd have to hack the LUA addon check to make it think all calls are coming from the Blizzard UI (I could show you how to do that).

  14. #14
    Nesox's Avatar ★ Elder ★
    Reputation
    1280
    Join Date
    Mar 2007
    Posts
    1,238
    Thanks G/R
    0/3
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Sending messages is very poor your better off using castspellbyid.. so you can run it in the background, and doing what Shynd suggested by writing a addon would greatley increase performance of your bot as reading a whole raids hp would waste alot of resources, why do it yourself when you can let wow do the dirtywork for you!

  15. #15
    cloud_wizard's Avatar Member
    Reputation
    5
    Join Date
    Dec 2008
    Posts
    44
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I like the function calls idea. I'm definitely gonna go that route.

    I'd like to only base as much of the bot on LUA as is necessary for several reasons. One is that I don't want to share the code. I'll share the bot, just not the code. Another is that if I share the code via addon, blizz can more easily see how it works and put a stop to it. Also, I remember reading something about 'banned' addons... That WoW Refuses to let load?

    The next steps are writing the DLL and the injector. The injector is actually going to be part of my main program (unless that will cause conflicts?). And since this is not something I'm familiar with, can I bug one of you for help with that? Yahoo IM is really the way to reach me outside these forums. My ID is the same as here on the forums.


Page 1 of 3 123 LastLast

Similar Threads

  1. Work orders continue if you replace the building.
    By Mercarcher in forum World of Warcraft Exploits
    Replies: 6
    Last Post: 11-19-2014, 12:21 AM
  2. [Compieling] Continue the work?
    By LordExeon in forum WoW EMU Questions & Requests
    Replies: 3
    Last Post: 04-26-2010, 09:41 AM
  3. Working WoW Glider! 0.6.2
    By Matt in forum World of Warcraft Bots and Programs
    Replies: 15
    Last Post: 03-31-2006, 09:22 AM
  4. BWH 1.9 Working (no trial)
    By Matt in forum World of Warcraft Bots and Programs
    Replies: 2
    Last Post: 03-23-2006, 07:04 PM
  5. World of Warcraft Bot (GetALifeBot) 0.57 working with 1.9.4
    By Matt in forum World of Warcraft Bots and Programs
    Replies: 7
    Last Post: 03-07-2006, 09:43 PM
All times are GMT -5. The time now is 02:30 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search