Example project source code - Wailing Caverns for 5 bots



  • Hello! please find the source code here : Mega Upload Link

    This is the entire project that I used to do repeatable full clears of WC using a team of 5 appropriately leveled bots (I think anything over 16 should work, but you might need to add some extra checks for unlearned spells as I have not back tested the script on low level characters. If you are having trouble with that just add some extra

    local knows_sunfire = IsSpellKnown(93402, false)
    ...
    if (knows_sunfire == true and ...
    

    type checks around the spells you don't have and you should be fine.

    The path manages a full clear of the instance, including jumping off cliffs, talking to the NPC at the end to start the bonus boss and escorting the NPC to the end. It doesn't really know how to stop, however, as the last waypoint is just a patrol for the Merfolk boss, so you will need to stop it manually. I was going to add walking out and resetting the instance, but the group finder just does that for you.

    The only remaining issue is that occasionally a character can get stuck in the water after jumping down from the Elemental boss, I'm not sure why that is but even controlling it manually it is sometimes quite easy to get stuck, I think there is some invisible terrain so I might try and adjust some of the waypoints there.

    I don't think you need any additional in game bot settings to run, except I set the max PvE melee distance for the tank to 8 yards to encourage them to move into position, not sure why but when fighting multiple mobs after killing the first one fine they don't automatically move into melee range for the next one (if they are a caster) so just stand there. Reducing the max melee range seems to fix it.

    In terms of the rotations there are a few kinks still being worked on: I don't do interrupts or taunts yet (but I do do dispels), the healer will spam eat food as I don't have it correctly identifying the refreshment buff yet (but with conjured food it isn't really a problem) and finally the Moonkin will cast two spells while it is empowered instead of only one, as the buff doesn't get removed until the spell lands and by then it is already casting the second one. I will fix this will a global variable for some buff state, but I am trying to do it all stateless so am holding out for a different solution.

    If anyone wants to give it a go feel free, you will need a 5x Minibot subscription which can be a little pricey if you are just doing this for fun, but it works fine with trial accounts (I only upgraded them when I got to lvl 20) as long as you have one that can do the party invites for the dungeon finder.

    In order to work with the paths I have a number of macros that jump to certain points so I can rerun them, but now that it is working I just hit go from the beginning and watch 🙂

    Finally any questions (or suggestions) please feel free to post them here. I'd love some more natural ways of handling some of the things I brute force, or if I am doing things badly please let me know. I am working on SFK at the moment (having already done RFC), but have made some changes to how I organise the paths to save development time, and would love to incorporate any additional suggestions.



  • Really nice work here. Im checking the rotatiosn to see how all works.
    Im more into single rotations and will post once its done and working 🙂

    @MrCeeJ said in Example project source code - Wailing Caverns for 5 bots:

    Hello! please find the source code here : Mega Upload Link

    This is the entire project that I used to do repeatable full clears of WC using a team of 5 appropriately leveled bots (I think anything over 16 should work, but you might need to add some extra checks for unlearned spells as I have not back tested the script on low level characters. If you are having trouble with that just add some extra

    local knows_sunfire = IsSpellKnown(93402, false)
    ...
    if (knows_sunfire == true and ...
    

    type checks around the spells you don't have and you should be fine.

    The path manages a full clear of the instance, including jumping off cliffs, talking to the NPC at the end to start the bonus boss and escorting the NPC to the end. It doesn't really know how to stop, however, as the last waypoint is just a patrol for the Merfolk boss, so you will need to stop it manually. I was going to add walking out and resetting the instance, but the group finder just does that for you.

    The only remaining issue is that occasionally a character can get stuck in the water after jumping down from the Elemental boss, I'm not sure why that is but even controlling it manually it is sometimes quite easy to get stuck, I think there is some invisible terrain so I might try and adjust some of the waypoints there.

    I don't think you need any additional in game bot settings to run, except I set the max PvE melee distance for the tank to 8 yards to encourage them to move into position, not sure why but when fighting multiple mobs after killing the first one fine they don't automatically move into melee range for the next one (if they are a caster) so just stand there. Reducing the max melee range seems to fix it.

    In terms of the rotations there are a few kinks still being worked on: I don't do interrupts or taunts yet (but I do do dispels), the healer will spam eat food as I don't have it correctly identifying the refreshment buff yet (but with conjured food it isn't really a problem) and finally the Moonkin will cast two spells while it is empowered instead of only one, as the buff doesn't get removed until the spell lands and by then it is already casting the second one. I will fix this will a global variable for some buff state, but I am trying to do it all stateless so am holding out for a different solution.

    If anyone wants to give it a go feel free, you will need a 5x Minibot subscription which can be a little pricey if you are just doing this for fun, but it works fine with trial accounts (I only upgraded them when I got to lvl 20) as long as you have one that can do the party invites for the dungeon finder.

    In order to work with the paths I have a number of macros that jump to certain points so I can rerun them, but now that it is working I just hit go from the beginning and watch 🙂

    Finally any questions (or suggestions) please feel free to post them here. I'd love some more natural ways of handling some of the things I brute force, or if I am doing things badly please let me know. I am working on SFK at the moment (having already done RFC), but have made some changes to how I organise the paths to save development time, and would love to incorporate any additional suggestions.



  • This is the code my friend is working on. Its a verry simple one for first timers 🙂 Im open for improvements and other fight rotations for single account. Could need some help so the bot checks my spells before engaging mob, and cast them before even start running. Also go into bearform when more than 3 targets.

    return {
      -- Define rotation.
      rotations = {
        combat = function(env, is_pulling)
    
          local emergency_health = 50
          local ok_health = 75
          local good_health = 50
           -- Do Healing
           local healing = false
           local current_health = UnitHealth("player")
           local max_health = UnitHealthMax("player")
           local life = tonumber(current_health) / tonumber(max_health)
           local hp = env:evaluate_variable("myself.health")
           local form = GetShapeshiftFormID()
           local _,id_Regrowth = GetSpellInfo("Regrowth")
           local have_Regrowth = env:evaluate_variable("myself.buff.Regrowth")
           local have_wild = env:evaluate_variable("myself.buff.Mark of the Wild")
           local have_Thorns = env:evaluate_variable("myself.buff.Thorns")
           local have_rip = env:evaluate_variable("unit.target.debuff.Rip")
           local target_hp = env:evaluate_variable("unit.target.health")
           local min_dot_hp = 90
    
          -- called when a target unit is selected to engage.
    
              if (UnitExists("target")) then
              RunMacroText("/startattack")
    
              if (have_wild <=0) and form ~=1 then
                RunMacroText("/cast Mark of the Wild")
    
              elseif (have_wild ~=0) and (have_Thorns <=0) and form ~=1 then
                RunMacroText("/cast Thorns")
    
              elseif (hp < good_health) and form ~=1 then
                RunMacroText("/cast Regrowth")
    
              elseif (have_Regrowth ~=0) and form ~=1 then
                RunMacroText("/stopcasting")
                RunMacroText("/cast Cat form")
                          
              elseif (have_wild ~=0) and (have_Thorns ~=0) and (hp > good_health) and form ~=1 then
                RunMacroText("/cast Cat form")
    
              elseif (hp < good_health ) and (have_Regrowth <=0) and form ~=0 then
                RunMacroText("/cancelaura Cat form")
    
              elseif GetComboPoints("player","target")>=2 then
    
                RunMacroText("/cast Rip")
    
              elseif (target_hp > min_dot_hp and have_rip == -1) then
    
                RunMacroText("/cast Tiger's Fury")
    
              else
                RunMacroText("/cast Rake")
                
    
              end
    
    
    
          end
         
      
            
    
    
    
    
    
    
        end,
        prepare = function(env)
          -- called to check and run the preparation rotation, such as summon and feeding pets, buffing, conjuring and etc.
          -- Return true if preparation is still ongoing.
          return false;
        end,
      }
    };
    


  • So the checking the spells before you engage is really easy. Just use the prepare function you already have at the bottom of the code, add some conditions and actions just like a rotation. I also use it for eating, healing and buffing and changing druid form, so as soon as I start a script it will take care of all that, and as soon as it drops combat it does it all again.

    Here is my Priest code for the fortitude buff:

    prepare = function(env)
      -- called to check and run the preparation rotation, such as 
      -- summon and feeding pets, buffing, conjuring and etc.
      -- Return true if preparation is still ongoing.
      local in_combat = env:evaluate_variable("myself.is_in_combat") 
      local needs_more_time = false
      if (in_combat) then
        needs_more_time = false
      else
        local has_fortitude = env:evaluate_variable("myself.buff.21562")
        if (has_fortitude == -1) then
          needs_more_time = true
          RunMacroText("/cast Power Word: Fortitude")
        end
        return needs_more_time
      end
    end
    

    The needs_more_time parameter is only there so I can do a number of checks, accross different characters before giving them all the OK at once. You probably don't need it



  • Oh and the enemies check for Bear Form is also simple:

    local enemies = env:evaluate_variable("npcs.all.is_attacking_me")
    -- print ("Enemies attacking me : ", enemies)
    if (enemies > 2) then
      RunMacroText("/cast [noform:1] Bear Form")
    end
    


  • Thanks for that 🙂 ill add and update the rotation. Where do you learn all that ? Or are you old in this game 🙂

    @MrCeeJ said in Example project source code - Wailing Caverns for 5 bots:

    Oh and the enemies check for Bear Form is also simple:

    local enemies = env:evaluate_variable("npcs.all.is_attacking_me")
    -- print ("Enemies attacking me : ", enemies)
    if (enemies > 2) then
      RunMacroText("/cast [noform:1] Bear Form")
    end
    


  • I took a long look on the forums here (there are some examples on the Chinese version of the forum too, you can load the page in google translate to understand how to do a 'Scarlet Graveyard Master single brush (nostalgic version)' - i.e. a clear of SM GY on classic - but the code is easy enough to read, only the printed text is in Chinese and that translates pretty easily. Obviously there is quite a variation in code quality, but if you have been playing WoW since it was in beta, and are a professional developer it is pretty easy to spot the good from the bad and try and copy the good bits 🙂



  • Trying to figure out how the bot will check my mana before it shapeshift from cat to human for healing. Cause sometime it goes out for healing and after that have no mana left for catform 😕

    @MrCeeJ said in Example project source code - Wailing Caverns for 5 bots:

    I took a long look on the forums here (there are some examples on the Chinese version of the forum too, you can load the page in google translate to understand how to do a 'Scarlet Graveyard Master single brush (nostalgic version)' - i.e. a clear of SM GY on classic - but the code is easy enough to read, only the printed text is in Chinese and that translates pretty easily. Obviously there is quite a variation in code quality, but if you have been playing WoW since it was in beta, and are a professional developer it is pretty easy to spot the good from the bad and try and copy the good bits 🙂



  • Here is my eating food code (refactored) which includes checking mana via the WoW LUA API:

    function need_to_eat(env)
                    local food_name = "Conjured Mana Pie" -- Mage foods
                    local food_buff = "167152" -- Replenishment
                    local mana = UnitPower("player", 0)
                    local max_mana = UnitPowerMax("player", 0)
                    local mp = 100 * mana / max_mana
                    local thirsty = false
                    if (max_mana > 0) then
                        if (mp < 90) then
                            thirsty = true
                            local is_drinking = env:evaluate_variable("myself.buff.".. food_buff)
                            if (is_drinking == -1) then
                                RunMacroText("/use " .. food_name)
                            end
                        end
                    end
                    return thirsty
                end
    


  • Just to update, I have now also done Shadow Fang Keep, Straholm (living), Blood Furnace, Hellfire Ramparts, The Steamvault, Shadow Labyrinth. I have added dispelling code, some boss positioning code and debuff tracking and am working on AoE rotations. I am happy to repost my code if anyone is interested in seeing the progress, but also I am cleaning it up quite a lot as I go, and so would rather finish the features and then release it when it is a better example, rather than having some unused-but-not-yet-working methods in the code that might confuse people.



  • thank you for sharing, I can't wait to try



  • I think most here are happy to use it or check for code. 🙃😀😉

    @MrCeeJ said in Example project source code - Wailing Caverns for 5 bots:

    Just to update, I have now also done Shadow Fang Keep, Straholm (living), Blood Furnace, Hellfire Ramparts, The Steamvault, Shadow Labyrinth. I have added dispelling code, some boss positioning code and debuff tracking and am working on AoE rotations. I am happy to repost my code if anyone is interested in seeing the progress, but also I am cleaning it up quite a lot as I go, and so would rather finish the features and then release it when it is a better example, rather than having some unused-but-not-yet-working methods in the code that might confuse people.



  • @MrCeeJ If im in bearform tanking and have aggro . How will i stop the bot to go get more mobs. Since sometimes it gets aggro but still runs away to get more



  • @exstazi I'm not really sure what your problem is here, it sounds more like a pathing / PvE range settings problem than a scripting one.



  • @MrCeeJ said in Example project source code - Wailing Caverns for 5 bots:

    @exstazi I'm not really sure what your problem is here, it sounds more like a pathing / PvE range settings problem than a scripting one.

    i think i need to to find an if code like if have aggro then dont pull more



  • @exstazi But you won't move to the next waypoint until you have killed everything you are in combat with at the current one. It sounds like you have set something up strangely, or are finding targets outside the ones you are already in combat with that would be automatically targeted by the engine.



  • @MrCeeJ said in Example project source code - Wailing Caverns for 5 bots:

    @exstazi But you won't move to the next waypoint until you have killed everything you are in combat with at the current one. It sounds like you have set something up strangely, or are finding targets outside the ones you are already in combat with that would be automatically targeted by the engine.

    Example is when he targets sometjing and is runing towards it. Then gets aggro from something on they way. He doesnt stop and kill it first. He runs towards the one he targeted from the start



  • The PvE Common Property you define has a distance value (defaults to 20 yards), so anything within that will get pulled. If you set it lower it should aggro less things on the way to the waypoint.



  • @MrCeeJ said in Example project source code - Wailing Caverns for 5 bots:

    The PvE Common Property you define has a distance value (defaults to 20 yards), so anything within that will get pulled. If you set it lower it should aggro less things on the way to the waypoint.

    To be exact, the distance is actually the width of the area around the current path, instead of the character. Such design prevents too much deviation of the movement from the path.