I haven't been successful in locating what I'm after so heres what I'm thinking. Have a quest bot go to the soil spots, till the soil, plant lets say carrot seeds, cure what ever ailment it may have, destroy it with a shovel, and start over until a "Bursting" one comes a long, harvest that, and rinse and repeat. Its horrifically slow BUT at least you can in theory save several days of dailies by doing this.
Profile for another BoT . I am not sure how to make it work for HB I hope some one can convert this in to a HB farm profile Tilling = {} ------- Configuration section ------- -- set to 1 for more verbose logging Tilling.DebugLevel = 1; -- Grind out reputation for pandaria factions using the farm. Tilling.PandariaRepGrindMode = 0; -- which seed to plant when not rep grinding Tilling.PlantSeedId = 89233; -- 89233 = "Songbell" seed Tilling.BeforeTillersReveredSeedId = 80590; -- 80590 = "Juicycrunch Carrot" seed -- buy seed bags if available (starting at revered tillers reputation) Tilling.BuySeedBags = 1; -- which pandaria faction to grind reputation for -- can be one of: "auto", "dominance_offensive", "operation_shieldwall", "golden_lotus", "shado_pan", "august_celestials", "klaxxi" -- "auto" will grind reputation for all factions you are not 999/999 exalted with yet starting with those you have the most rep with already Tilling.PandariaRepGrindModeFaction = "auto"; -- do work order dailies even if exalted with the pandaria factions Tilling.ForceRepGrindMode = 0; -- Force grind Tillers rep? This mode will harvest bursting crops, destroy all normal growing -- crops and repeat Tilling.TillersEndlessMode = 0; ------- End of configuration section ------- Tilling.DoneLanes = {} Tilling.PlantSeedIds = {}; Tilling.TotalPlots = 0; Tilling.RepGrindFactions = { ["dominance_offensive"] = { ["name"] = "Dominance Offensive", ["player_faction"] = 0, ["faction_id"] = 1375, ["seed_id"] = 80593, ["step_1_quest"] = 32642, ["step_2_quest"] = 32643 }, ["operation_shieldwall"] = { ["name"] = "Operation Shieldwall", ["player_faction"] = 1, ["faction_id"] = 1376, ["seed_id"] = 89326, ["step_1_quest"] = 32645, ["step_2_quest"] = 32646 }, ["golden_lotus"] = { ["name"] = "Golden Lotus", ["faction_id"] = 1269, ["seed_id"] = 80595, ["step_1_quest"] = 32647, ["step_2_quest"] = 32648 }, ["shado_pan"] = { ["name"] = "Shado-Pan", ["faction_id"] = 1270, ["seed_id"] = 79102, ["step_1_quest"] = 32649, ["step_2_quest"] = 32650 }, ["august_celestials"] = { ["name"] = "The August Celestials", ["faction_id"] = 1341, ["seed_id"] = 89329, ["step_1_quest"] = 32653, ["step_2_quest"] = 32657 }, ["klaxxi"] = { ["name"] = "The Klaxxi", ["faction_id"] = 1337, ["seed_id"] = 80592, ["step_1_quest"] = 32658, ["step_2_quest"] = 32659 } } Tilling.YoonQuests = { [31672] = 80592, [31942] = 89329, [31673] = 80593, [31941] = 89328, [31670] = 80590, [31669] = 79102, [31674] = 80594, [31675] = 80595, [31943] = 89326, [31671] = 80591 } Tilling.SeedVendor = { ["name"] = "Merchant Greenfield", ["id"] = 58718, ["waypoint"] = {-234.487,587.89,167.643}, ["walk_to"] = {-268.316,603.411,167.548} } Tilling.GardeningTools = { { ["name"] = "Vintage Bug Sprayer", ["item_id"] = 80513, ["object_id"] = 211331, ["skip"] = function() if Tilling.TotalPlots == 1 or (Tilling.TotalPlots == 2 and GetObjectByID(Tilling.BulkGardeningTools.repellers[1]) == 0) or Tilling.TotalPlots == 3 or (Tilling.TotalPlots == 4 and GetObjectByID(Tilling.BulkGardeningTools.repellers[2]) == 0) then return 0 else return 1 end end }, { ["name"] = "Rusty Watering Can", ["item_id"] = 79104, ["object_id"] = 211330, ["skip"] = function() if Tilling.TotalPlots == 1 or (Tilling.TotalPlots == 2 and GetObjectByID(Tilling.BulkGardeningTools.sprinklers[1]) == 0) or Tilling.TotalPlots == 3 or (Tilling.TotalPlots == 4 and GetObjectByID(Tilling.BulkGardeningTools.sprinklers[2]) == 0) then return 0 else return 1 end end }, { ["name"] = "Dented Shovel", ["item_id"] = 89880, ["object_id"] = 215719, ["skip"] = function() if Tilling.TillersEndlessMode == 1 then return 0 else return 1 end end }, { ["name"] = "Master Plower", ["item_id"] = 89815, ["object_id"] = 215698, ["skip"] = function() if Tilling.TotalPlots == 4 then return 0 else return 1 end end } } Tilling.SeedBagPositions = { {-169.389;639.76;165.41}, {-169.674;648.307;165.41}, {-154.178;649.213;165.41}, {-153.214;640.603;165.41} } Tilling.PlowPositions = { {-171.428;633.416;165.409;1}, {-166.731,653.804,165.409;1}, {-155.77,635.865,165.409;1}, {-151.725,653.482,165.409;1} } Tilling.BulkGardeningTools = { ["repellers"] = {215162,215163}, ["sprinklers"] = {215135,215137} } Tilling.CropLocations = { -- first patch { {-172.036,637.776,165.409}, {-166.274,637.094,165.409}, {-166.781,641.316,165.409}, {-172.022,642.157,165.409} }, -- second patch { {-171.902,646.503,165.409}, {-166.631,645.583,165.409}, {-166.712,649.865,165.409}, {-172.751,650.672,165.409} }, -- third patch { {-157.057,651.572,165.409}, {-150.850,650.656,165.409}, {-150.979,646.145,165.409}, {-156.996,647.659,165.409} }, -- fourth patch { {-156.133,643.073,165.409}, {-150.537,642.583,165.409}, {-150.857,638.232,165.409}, {-156.468,638.921,165.409} } } Tilling.SeedBags = { -- Green Cabbage [79102] = 80809, -- Juicycrunch [80590] = 84782, -- Scallion [80591] = 84783, -- Mogu Pumpkin [80592] = 85153, -- Red Blossom Leek [80593] = 85158, -- Pink Turnip [80594] = 85162, -- White Turnip [80595] = 85163, -- Jade Squash [89328] = 89848, -- Witchberry [89326] = 89847, -- Striped Melon [89329] = 89849, -- Enigma [85216] = 95449, -- Magebulb [85217] = 95451, -- Raptorleaf [89202] = 95457, -- Snakeroot [85215] = 95447, -- Windshear Cactus [89197] = 95454, -- Songbell [89233] = 95445 } function Tilling.LogMsg(text) if (Tilling.DebugLevel > 0) then _Log(text); end end function Tilling.RepRequired(faction_id) WowLuaDoString(string.format('_,_,_,_,_,rep,_,_,_,_,_,_,_=GetFactionInfoByID(%d)', faction_id)); local currentrep = tonumber(WowGetLuaValue("rep")); return 42999 - currentrep; -- return 43000 - currentrep; end function Tilling.DoFightWith(obj, sleep, id, is_npc, cancel_shapeshift) Tilling.LogMsg("starting DoFightWith"); Tilling.DoInteractWith(obj, sleep, -1, is_npc, cancel_shapeshift); local TargetGUID = 0; local targetobj = 0; repeat WowLuaDoString("creatureID=0 TargetNearestEnemy(false) if (UnitExists('target')) then guid = UnitGUID('target') creatureID = tonumber('0x'..strsub(guid,7,10)) end"); TargetGUID = tonumber(WowGetLuaValue("creatureID")); targetobj = GetObjectByID(TargetGUID); Sleep(200); until TargetGUID ~= 0 and targetobj ~= 0 and Tilling.Distance(GetUnitPos(GetPlayer()), GetUnitPos(targetobj)) <= 5; Tilling.LogMsg("Target GUID: ".. TargetGUID); Tilling.LogMsg("Target object address: ".. targetobj); Tilling.LogMsg("Target object location: "); Tilling.LogBotPos(GetUnitPos(targetobj)); Tilling.LogMsg("handing over control to bot KillMob()"); -- Sleep(sleep); KillMob(targetobj); -- FightCheck(); Tilling.LogMsg("received control back from bot"); Tilling.WaitForDespawn(obj, id); Tilling.LogMsg("ending DoFightWith"); end function Tilling.DoWrestleWith(obj, sleep, id, is_npc, cancel_shapeshift, spellid) Tilling.LogMsg("starting DoWrestleWith"); Tilling.DoInteractWith(obj, sleep, -1, is_npc, cancel_shapeshift); while Tilling.InVehicle() ~= 1 do Sleep(200) end; while Tilling.InVehicle() == 1 do -- Tilling.LogMsg("in vehicle"); CastSpellByID(spellid, nil, true); end Tilling.WaitForDespawn(obj, id); Tilling.LogMsg("ending DoWrestleWith"); end function Tilling.DoSnapWith(obj, sleep, id) Tilling.LogMsg("starting DoSnapWith"); Tilling.DoInteractWith(obj, sleep); Tilling.WalkTo({-191.029,625.291,165.768}); Tilling.WalkTo(Tilling.CropLocations[1][1]); Tilling.WaitForDespawn(obj, id); Tilling.LogMsg("ending DoSnapWith"); end function Tilling.DoTillSoil(obj, sleep, id, is_npc, cancel_shapeshift) Tilling.LogMsg("starting DoTillSoil"); local pos = GetUnitPos(obj); local lane = Tilling.PosIsLane({pos[0], pos[1], pos[2]}); Tilling.LogMsg("found lane: " .. lane); if Tilling.HasNumItems(89815) == 0 or Tilling.DoneLanes[lane] == 1 then -- no master plower Tilling.DoInteractWith(obj, sleep, id, is_npc, cancel_shapeshift); else Tilling.DoneLanes[lane] = 1; -- SetTarget(obj); Tilling.WalkTo(Tilling.PlowPositions[lane]); local face_target = function() local should_patch; if lane == 1 then should_patch = {1,4}; elseif lane == 2 then should_patch = {1,2}; elseif lane == 3 then should_patch = {3,1}; elseif lane == 4 then should_patch = {4,3}; else error("Invalid lane."); end local object_list = GetObjectList(); for _, object in ipairs(object_list) do if GetObjectType(object) == 3 then local unit_pos = GetUnitPos(object); local exact_patch = Tilling.PosIsExactPatch({unit_pos[0], unit_pos[1], unit_pos[2]}); if exact_patch ~= nil and exact_patch[1] == should_patch[1] and exact_patch[2] == should_patch[2] then FaceTarget(object); break; end end end end face_target(); WowLuaDoString("UseItemByName(89815)"); Sleep(5000); local mob = GetObjectByID(70447); if mob ~= 0 then if lane <= 2 then Tilling.WalkTo({-169.502;643.547;165.409}); else Tilling.WalkTo({-154.01;644.72;165.409}); end KillMob(mob); while Tilling.InCombat() == true do mob = GetObjectByID(70447); if mob ~= 0 and IsUnitAlive(mob) == true then KillMob(mob); else --FightCheck(); Sleep(500); end end else Sleep(sleep); end end Tilling.LogMsg("ending DoTillSoil"); end function Tilling.InCombat(target) if target == nil then target = "player" end; WowLuaDoString("combat=UnitAffectingCombat('" .. target .. "')"); if WowGetLuaValue("combat") == "1" then return true; else return false; end end function Tilling.DoInteractWith(obj, sleep, id, is_npc, cancel_shapeshift) Tilling.LogMsg("starting DoInteractWith"); if sleep == nil then sleep = 0 end; if is_npc == nil then is_npc = 1 end; if id == nil then id = -1 end; local pos; if is_npc == 1 then pos = GetUnitPos(obj); else pos = GetObjectPos(obj); end Tilling.LogMsg("starting to walk to " .. obj); Tilling.WalkTo({ pos[0], pos[1], pos[2] }); Tilling.LogMsg("finished walking"); if cancel_shapeshift == 1 then WowLuaDoString("index = GetShapeshiftForm()"); if tonumber(WowGetLuaValue("index")) > 0 then Tilling.LogMsg("cancelling shapeshift"); WowLuaDoString("CancelShapeshiftForm()"); end end Tilling.LogMsg("interacting with " .. obj); InteractWith(obj); Sleep(sleep); Tilling.LogMsg("ending DoInteractWith"); end function Tilling.DoPlantSeed(obj, sleep, id, is_npc, cancel_shapeshift) for _, seed in ipairs(Tilling.PlantSeedIds) do if seed.count > 0 then if Tilling.HasNumItems(seed.id) > 0 then SetTarget(obj); Tilling.DoInteractWith(obj); Tilling.UseItemByID(seed.id); seed.count = seed.count - 1; elseif Tilling.HasNumItems(Tilling.SeedBags[seed.id]) > 0 then if Tilling.Distance(GetUnitPos(GetPlayer()), Tilling.CropLocations[1][1], 0, 1) > 2 then Tilling.WalkTo(Tilling.CropLocations[1][1]); end local pos = GetUnitPos(obj); local patch = Tilling.PosIsPatch({pos[0],pos[1],pos[2]}); if patch == nil then error("invalid patch") end; local target = Tilling.SeedBagPositions[patch]; Tilling.UseItemByID(Tilling.SeedBags[seed.id]); DoTerrainClick(target[1], target[2], target[3]); seed.count = seed.count - 4; else error("Ran out of seeds. Shouldn't have happpened."); end break; end end Sleep(3000); end function Tilling.DoWaterWith(obj, sleep, id) local sprinkler = 0; local pos = GetUnitPos(obj); local posispatch = Tilling.PosIsPatch({pos[0],pos[1],pos[2]}); if posispatch ~= nil and posispatch <= 2 then sprinkler = GetObjectByID(Tilling.BulkGardeningTools.sprinklers[1]); elseif posispatch ~= nil and posispatch >= 3 then sprinkler = GetObjectByID(Tilling.BulkGardeningTools.sprinklers[2]); end if sprinkler ~= 0 then Tilling.DoInteractWith(sprinkler, sleep, -1, 0); Sleep(3000); else Tilling.DoInteractWith(obj, sleep); Tilling.UseItemByID(79104); Tilling.WaitForDespawn(obj, id); end end function Tilling.DoBugSprayWith(obj, sleep, id) local repeller = 0; local pos = GetUnitPos(obj); local posispatch = Tilling.PosIsPatch({pos[0],pos[1],pos[2]}); if posispatch ~= nil and posispatch <= 2 then repeller = GetObjectByID(Tilling.BulkGardeningTools.repellers[1]); elseif posispatch ~= nil and posispatch >= 3 then repeller = GetObjectByID(Tilling.BulkGardeningTools.repellers[2]); end if repeller ~= 0 then Tilling.DoInteractWith(repeller, sleep, -1, 0); Sleep(3000); else Tilling.DoInteractWith(obj, sleep); Tilling.UseItemByID(80513); Tilling.WaitForDespawn(obj, id); end end function Tilling.DoJumpWith(obj, sleep, id) Tilling.DoInteractWith(obj, sleep); WowLuaDoString('JumpOrAscendStart()'); Tilling.WaitForDespawn(obj, id); end function Tilling.DoRazeWith(obj, sleep, id) SetTarget(obj); Tilling.DoInteractWith(obj, sleep); Tilling.UseItemByID(89880); Tilling.WaitForDespawn(obj, id); end Tilling.Crops = { { ["name"] = "Green Cabbage", ["alluring"] = 60070, ["bursting"] = 63157, ["growing"] = 58566, ["infested"] = 60026, ["parched"] = 58565, ["plump"] = 60113, ["ripe"] = 58567, ["runty"] = 60218, ["smothered"] = 60181, ["tangled"] = 60270, ["wiggling"] = 60029, ["wild"] = 60207 }, { ["name"] = "Juicycrunch Carrot", ["alluring"] = 63147, ["bursting"] = 63158, ["growing"] = 63153, ["infested"] = 63145, ["parched"] = 63144, ["plump"] = 63156, ["ripe"] = 63154, ["runty"] = 63150, ["smothered"] = 63148, ["tangled"] = 63151, ["wiggling"] = 63146, ["wild"] = 63149 }, { ["name"] = "Scallions", ["alluring"] = 63159, ["bursting"] = 63160, ["growing"] = 63161, ["infested"] = 63162, ["parched"] = 63163, ["plump"] = 63164, ["ripe"] = 63165, ["runty"] = 63166, ["smothered"] = 63167, ["tangled"] = 63168, ["wiggling"] = 63169, ["wild"] = 63170 }, { ["name"] = "Mogu Pumpkin", ["alluring"] = 63178, ["bursting"] = 63180, ["growing"] = 63181, ["infested"] = 63182, ["parched"] = 63183, ["plump"] = 63184, ["ripe"] = 63185, ["runty"] = 63186, ["smothered"] = 63187, ["tangled"] = 63188, ["wiggling"] = 63189, ["wild"] = 63190 }, { ["name"] = "Red Blossom Leek", ["alluring"] = 63222, ["bursting"] = 63223, ["growing"] = 63224, ["infested"] = 63226, ["parched"] = 63227, ["plump"] = 63228, ["ripe"] = 63229, ["runty"] = 63230, ["smothered"] = 63231, ["tangled"] = 63232, ["wiggling"] = 63233, ["wild"] = 63234 }, { ["name"] = "Pink Turnip", ["alluring"] = 63243, ["bursting"] = 63245, ["growing"] = 63246, ["infested"] = 63247, ["parched"] = 63248, ["plump"] = 63249, ["ripe"] = 63250, ["runty"] = 63251, ["smothered"] = 63252, ["tangled"] = 63253, ["wiggling"] = 63254, ["wild"] = 63255 }, { ["name"] = "White Turnip", ["alluring"] = 63259, ["bursting"] = 63260, ["growing"] = 63261, ["infested"] = 63262, ["parched"] = 63263, ["plump"] = 63264, ["ripe"] = 63265, ["runty"] = 63267, ["smothered"] = 63268, ["tangled"] = 63269, ["wiggling"] = 63270, ["wild"] = 63271 }, { ["name"] = "Jade Squash", ["alluring"] = 66107, ["bursting"] = 66108, ["growing"] = 66109, ["infested"] = 66110, ["parched"] = 66111, ["plump"] = 66112, ["ripe"] = 66113, ["runty"] = 66114, ["smothered"] = 66115, ["tangled"] = 66116, ["wiggling"] = 66117, ["wild"] = 66118 }, { ["name"] = "Witchberries", ["alluring"] = 66079, ["bursting"] = 66080, ["growing"] = 66081, ["infested"] = 66082, ["parched"] = 66083, ["plump"] = 66084, ["ripe"] = 66085, ["runty"] = 66086, ["smothered"] = 66087, ["tangled"] = 66088, ["wiggling"] = 66089, ["wild"] = 66090 }, { ["name"] = "Striped Melon", ["alluring"] = 66122, ["bursting"] = 66123, ["growing"] = 66124, ["infested"] = 66125, ["parched"] = 66127, ["plump"] = 66128, ["ripe"] = 66129, ["runty"] = 66130, ["smothered"] = 66131, ["tangled"] = 66132, ["wiggling"] = 66133, ["wild"] = 66134 }, { ["name"] = "Autumn Blossom", ["growing"] = 66172, ["ripe"] = 66175 }, { ["name"] = "Spring Blossom", ["growing"] = 66189, ["ripe"] = 66192 }, { ["name"] = "Winter Blossom", ["growing"] = 66171, ["ripe"] = 66173 }, { ["name"] = "Enigma", ["alluring"] = 65913, ["growing"] = 65916, ["infested"] = 65918, ["parched"] = 65919, ["ripe"] = { 65929, 65930, 65931, 65932, 65933, 65938 }, ["runty"] = 65920, ["smothered"] = 65921, ["tangled"] = 65922, ["wiggling"] = 65924, ["wild"] = 65925 }, { ["name"] = "Magebulb", ["alluring"] = 65985, ["growing"] = 65986, ["infested"] = 65987, ["parched"] = 65988, ["ripe"] = 65989, ["runty"] = 65990, ["smothered"] = 65991, ["tangled"] = 65992, ["wiggling"] = 65993, ["wild"] = 65994 }, { ["name"] = "Raptorleaf", ["alluring"] = 66012, ["growing"] = 66013, ["infested"] = 66014, ["parched"] = 66015, ["ripe"] = 66016, ["runty"] = 66017, ["smothered"] = 66018, ["tangled"] = 66019, ["wiggling"] = 66020, ["wild"] = 66021 }, { ["name"] = "Snakeroot", ["alluring"] = 65964, ["growing"] = 65965, ["infested"] = 65966, ["parched"] = 65967, ["ripe"] = 65973, ["runty"] = 65968, ["smothered"] = 65969, ["tangled"] = 65970, ["wiggling"] = 65971, ["wild"] = 65972 }, { ["name"] = "Windshear Cactus", ["alluring"] = 66002, ["growing"] = 66003, ["infested"] = 66004, ["parched"] = 66005, ["ripe"] = 66006, ["runty"] = 66007, ["smothered"] = 66008, ["tangled"] = 66009, ["wiggling"] = 66010, ["wild"] = 66011 }, { ["name"] = "Songbell", ["alluring"] = 66039, ["growing"] = 66040, ["infested"] = 66041, ["parched"] = 66042, ["ripe"] = 66043, ["runty"] = 66044, ["smothered"] = 66045, ["tangled"] = 66046, ["wiggling"] = 66047, ["wild"] = 66048 }, { ["name"] = "Portal Shard", ["unstable"] = 67446, ["growing"] = 67482, ["stable"] = 67486 } } Tilling.Soils = { { ["name"] = "Stubborn Weed", ["id"] = 60153, ["action"] = Tilling.DoWrestleWith, ["sleep"] = 500, ["spellid"] = 115857 }, { ["name"] = "Untilled Soil", ["id"] = 58562, ["action"] = Tilling.DoTillSoil, ["sleep"] = 3000, ["unshift"] = 1 }, { ["name"] = "Occupied Soil", ["id"] = 60172, ["action"] = Tilling.DoFightWith, ["sleep"] = 3000 }, { ["name"] = "Untilled Soil", ["id"] = 58562, ["action"] = Tilling.DoInteractWith, ["sleep"] = 3000, ["unshift"] = 1 }, { ["name"] = "Tilled Soil", ["id"] = 58563, ["action"] = Tilling.DoPlantSeed, ["sleep"] = 500 } } Tilling.CropFixes = { { ["name"] = "wiggling", ["action"] = Tilling.DoFightWith, ["sleep"] = 3000 }, { ["name"] = "alluring", ["action"] = Tilling.DoFightWith, ["sleep"] = 3000 }, { ["name"] = "unstable", ["action"] = Tilling.DoFightWith, ["sleep"] = 3000 }, { ["name"] = "infested", ["action"] = Tilling.DoBugSprayWith, ["sleep"] = 500 }, { ["name"] = "parched", ["action"] = Tilling.DoWaterWith, ["sleep"] = 500 }, { ["name"] = "runty", ["action"] = Tilling.DoJumpWith, ["sleep"] = 3000 }, { ["name"] = "wild", ["action"] = Tilling.DoWrestleWith, ["sleep"] = 500, ["spellid"] = 116073 }, { ["name"] = "tangled", ["action"] = Tilling.DoSnapWith, ["sleep"] = 1000 } } Tilling.CropDestructions = { { ["name"] = "growing", ["action"] = Tilling.DoRazeWith, ["sleep"] = 500 } }
2nd 1/2 function Tilling.GetGardeningTools() for _, Tool in ipairs(Tilling.GardeningTools) do if Tool.skip ~= nil and Tool.skip() == 1 then Tilling.LogMsg(string.format("skipping %q", Tool.name)); else Tilling.LogMsg(string.format("picking up %q if not already in inventory", Tool.name)); local obj = 0; repeat obj = GetObjectByID(Tool.object_id); if obj ~= 0 then Tilling.LogMsg("picking it up"); Tilling.DoInteractWith(obj, 500); end until obj == 0; end end end function Tilling.NumOfPatches() local obj; obj = GetObjectByID(210444); -- Weed if (obj ~= 0) then local pos = GetObjectPos(obj); if Tilling.PosIsPatch({pos[0], pos[1], pos[2]}) == 2 then _Log("You have 1 x 4 available patches."); return 1; end end obj = GetObjectByID(210451); -- Broken Cart if (obj ~= 0) then _Log("You have 2 x 4 available patches."); return 2; end obj = GetObjectByID(209572); -- Giant Rock if (obj ~= 0) then _Log("You have 3 x 4 available patches."); return 3; end _Log("You have 4 x 4 available patches."); return 4; end function Tilling.MountDown() DisMount(); Sleep(500); end function Tilling.MountUp() DoMount(); Sleep(500); end function Tilling.FlyTo(pos) Tilling.MountUp(); GlobalFlyingNavigate( pos[1], pos[2], pos[3], pos[4] or 5); Tilling.MountDown(); end function Tilling.WalkTo(pos) local helperwaypoints = { {-160.891,634.021,165.409}, {-162.538,656.035,165.059} } local _playerpos = GetUnitPos(GetPlayer()); local playerpos = {_playerpos[0], _playerpos[1], _playerpos[2]}; Tilling.LogMsg("walking to:"); Tilling.LogPos(pos); local startpatch = Tilling.PosIsPatch(playerpos); local endpatch = Tilling.PosIsPatch(pos); if (startpatch == nil and endpatch ~= nil and endpatch >= 3) or (endpatch == nil and startpatch ~= nil and startpatch >= 3) or (startpatch ~= nil and endpatch ~= nil and ((startpatch <= 2 and endpatch >= 3) or (startpatch >= 3 and endpatch <= 2))) then Tilling.LogMsg("crossover detected, using helper waypoint to avoid scarecrow"); local wp; if Tilling.Distance(playerpos, helperwaypoints[1], 1, 1) < Tilling.Distance(playerpos, helperwaypoints[2], 1, 1) then wp = helperwaypoints[1]; else wp = helperwaypoints[2]; end NavigateTo(wp[1], wp[2], wp[3], wp[4] or 3); end NavigateTo(pos[1], pos[2], pos[3], pos[4] or 3); Sleep(500); end function Tilling.PosIsPatch(pos) for i = 1,4 do for j = 1,4 do if Tilling.Distance(Tilling.CropLocations[j], pos, 1, 1) < 3 then return i; end end end return nil; end function Tilling.PosIsExactPatch(pos) for i = 1,4 do for j = 1,4 do if Tilling.Distance(Tilling.CropLocations[j], pos, 1, 1) < 3 then return {i, j}; end end end return nil; end function Tilling.PosIsLane(pos) for i = 1,4 do for j = 1,4 do if Tilling.Distance(Tilling.CropLocations[j], pos, 1, 1) < 3 then if i <= 2 then if (j == 1 or j == 4) then return 1; else return 2; end else if (j == 1 or j == 4) then return 3; else return 4; end end end end end return nil; end function Tilling.Distance (pos1, pos2, arrayoffset1, arrayoffset2) if (arrayoffset1 == nil) then arrayoffset1 = 0 end; if (arrayoffset2 == nil) then arrayoffset2 = 0 end; -- Tilling.LogMsg("distance between x1: " .. pos1[arrayoffset1] .. " y1: " .. pos1[arrayoffset1+1] .. " z1: " .. pos1[arrayoffset1+2] .. " x2: " .. pos2[arrayoffset2] .. " y2: " .. pos2[arrayoffset2+1] .. " z2: " .. pos2[arrayoffset2+2]); local distance = math.sqrt(math.pow(pos1[arrayoffset1] - pos2[arrayoffset2],2) + math.pow(pos1[arrayoffset1+1] - pos2[arrayoffset2+1],2) + math.pow(pos1[arrayoffset1+2] - pos2[arrayoffset2+2],2)); -- Tilling.LogMsg("is " .. distance); return distance; end function Tilling.LogPos(pos) Tilling.LogMsg("x: " .. pos[1] .. " y: " .. pos[2] .. " z: " .. pos[3]); end function Tilling.LogBotPos(pos) Tilling.LogMsg("x: " .. pos[0] .. " y: " .. pos[1] .. " z: " .. pos[2]); end function Tilling.UseItemByID(id) if tonumber(id) == nil then return end; WowLuaDoString("local name = GetItemInfo("..tonumber(id)..") UseItemByName(name)"); end function Tilling.HasNumItems(item_id) if tonumber(item_id) == nil then return 0 end; WowLuaDoString(string.format("itemcount=GetItemCount(%d)", tonumber(item_id))) return tonumber(WowGetLuaValue("itemcount")); end function Tilling.HasNumCharges(item_id) if tonumber(item_id) == nil then return 0 end; WowLuaDoString(string.format("chargecount=GetItemCount(%d, false, true)", tonumber(item_id))) return tonumber(WowGetLuaValue("chargecount")); end function Tilling.HasNumSeeds(seed_id) if tonumber(seed_id) == nil then return 0 end; local seed_num = Tilling.HasNumItems(seed_id) + ( Tilling.HasNumCharges(Tilling.SeedBags[seed_id]) * 4 ); Tilling.LogMsg("you have " .. seed_num .. " seeds of type " .. seed_id .. " including seed bag charges"); return seed_num; end function Tilling.HasNumFreeBagSlots() WowLuaDoString("freeslots = 0; for bag=0,4 do local num_free,bag_type = GetContainerNumFreeSlots(bag); if bag_type == 0 then freeslots = freeslots + num_free; end end"); return tonumber(WowGetLuaValue("freeslots")); end function Tilling.BuySeeds() local seeds = Tilling.PlantSeedIds; local bought_seeds = false; for _, seed in ipairs(Tilling.PlantSeedIds) do local itemsbefore = Tilling.HasNumSeeds(seed.id); local itemsrequired = seed.count - itemsbefore; if itemsrequired > 0 then bought_seeds = true; _Log("Buying " .. itemsrequired .. " seeds of type " .. seed.id); if Tilling.Distance(GetUnitPos(GetPlayer()), Tilling.SeedVendor.walk_to, 0, 1) > 3 then Tilling.WalkTo(Tilling.CropLocations[1][1]); Tilling.WalkTo(Tilling.SeedVendor.waypoint); Tilling.WalkTo(Tilling.SeedVendor.walk_to); end local vendor = GetObjectByID(Tilling.SeedVendor.id); -- |cffffffff|Hitem:79102:0:0:0:0:0:0:0:90:0:0|h[Green Cabbage Seeds]|h|r while Tilling.HasNumSeeds(seed.id) < itemsbefore + itemsrequired do InteractWith(vendor); Sleep(1000); WowLuaDoString('if GetNumGossipOptions() > 0 then SelectGossipOption(1) end'); Sleep(1000); WowLuaDoString('for i=1,3 do MerchantNextPageButton:Click() end'); local buy_seed_id = seed.id; local buy_seed_count = itemsrequired; -- need to be revered for seed bags if Tilling.BuySeedBags == 1 and buy_seed_count >= 4 and Tilling.SeedBags[buy_seed_id] ~= nil and Tilling.RepRequired(1272) <= 21999 then if buy_seed_id == 79102 or buy_seed_id == 80590 or buy_seed_id == 80591 or buy_seed_id == 80592 or buy_seed_id == 80593 or buy_seed_id == 80594 or buy_seed_id == 80595 or buy_seed_id == 89328 or buy_seed_id == 89326 or buy_seed_id == 89329 or Tilling.RepRequired(1272) <= 999 then buy_seed_id = Tilling.SeedBags[buy_seed_id]; buy_seed_count = 1; end end WowLuaDoString('num=0; for i = 1,GetMerchantNumItems() do if GetMerchantItemLink(i) == nil then break end; if string.find(GetMerchantItemLink(i), "item:' .. buy_seed_id .. ':") ~= nil then num=i; break; end end'); local merchantslot = tonumber(WowGetLuaValue("num")); Tilling.LogMsg("Trying to buy " .. itemsrequired .. " seeds of type " .. buy_seed_id .. " from merchant"); if merchantslot ~= nil and merchantslot ~= 0 then Tilling.LogMsg("Found merchant slot " .. merchantslot); WowLuaDoString("BuyMerchantItem(" .. merchantslot .. "," .. buy_seed_count .. ")"); Sleep(3000); else Tilling.LogMsg("No merchant slot found, retrying."); WowLuaDoString("CloseMerchant()"); end end end end if bought_seeds == true then Tilling.WalkTo(Tilling.SeedVendor.waypoint); Tilling.GetReady(); end end function Tilling.InVehicle() WowLuaDoString("v = CanExitVehicle()"); return tonumber(WowGetLuaValue("v")); end function Tilling.Harvest() for _, Crop in ipairs(Tilling.Crops) do for _, state in { "ripe", "bursting", "plump", "stable" } do if Crop[state] ~= nil then local crop_ids = Crop[state]; -- Enigmas have several object ids if type(crop_ids) ~= "table" then crop_ids = { crop_ids }; end for _,crop_id in ipairs(crop_ids) do local obj = GetObjectByID(crop_id); while obj ~= 0 do _Log ("Found " .. state .. " \"" .. Crop.name .. "\", harvesting it."); Tilling.DoInteractWith(obj); Tilling.WaitForDespawn(obj, crop_id); obj = GetObjectByID(crop_id); end end end end end end function Tilling.Till() for _, Soil in ipairs(Tilling.Soils) do local obj = GetObjectByID(Soil.id); while obj ~= 0 do _Log("Found \"" .. Soil.name .. "\", tending to it."); Soil.action(obj, Soil.sleep, Soil.id, 1, Soil.unshift, Soil.spellid); Tilling.WaitForDespawn(obj, Soil.id); obj = GetObjectByID(Soil.id); end end end function Tilling.FixCrops() for _, CropFix in ipairs(Tilling.CropFixes) do for _, Crop in ipairs(Tilling.Crops) do local state = CropFix.name; if Crop[state] ~= nil then local obj = GetObjectByID(Crop[state]); while obj ~= 0 do _Log ("Found " .. state .. " \"" .. Crop.name .. "\", fixing it."); CropFix.action(obj, CropFix.sleep, Crop[state], 1, nil, CropFix.spellid); obj = GetObjectByID(Crop[state]); end end end end local obj = GetObjectByID(60185); while obj ~= 0 do _Log("Found \"Encroaching Weed\", pulling it."); Tilling.DoWrestleWith(obj, 500, 60185, nil, nil, 115857); obj = GetObjectByID(60185); end end function Tilling.DestroyCrops() for _, CropDestruction in ipairs(Tilling.CropDestructions) do for _, Crop in ipairs(Tilling.Crops) do local state = CropDestruction.name; if Crop[state] ~= nil then local obj = GetObjectByID(Crop[state]); while obj ~= 0 do _Log ("Found " .. state .. " \"" .. Crop.name .. "\", destroying it."); CropDestruction.action(obj, CropDestruction.sleep, Crop[state]); obj = GetObjectByID(Crop[state]); end end end end end function Tilling.WaitForDespawn(oldobj, id, timeout) if oldobj == 0 then return end; if timeout == nil then timeout = 10000 end; local newobj = oldobj; Tilling.LogMsg("start waiting for despawn. id:" .. id .. " obj:" .. oldobj); local totalsleep = 0; while oldobj == newobj do -- Tilling.LogMsg("... still waiting. old:" .. oldobj .. " new:" .. newobj); newobj = GetObjectByID(id); Sleep(200); totalsleep = totalsleep + 200; if totalsleep > timeout then Tilling.LogMsg("despawn timeout"); break; end end end function Tilling.numKeys(assoc_array) local count = 0; for key, value in pairs(assoc_array) do if key ~= nil then count = count + 1 end; end return count; end function Tilling.GetPlayerFaction() WowLuaDoString('playerfaction = UnitFactionGroup("player")'); local faction = WowGetLuaValue("playerfaction"); if faction == 'Alliance' then return 1; elseif faction == 'Horde' then return 0; else error("Unknown faction: " .. faction); end end function Tilling.WorkOrderSeeds() local result = {}; if Tilling.PandariaRepGrindModeFaction ~= "auto" then local faction = Tilling.RepGrindFactions[Tilling.PandariaRepGrindModeFaction]; if faction == nil then error "invalid Tilling.PandariaRepGrindModeFaction specified"; else result = { { ["id"] = faction.seed_id, ["count"] = 8 }, { ["id"] = Tilling.GetActualSeed(), ["count"] = 8 } } Tilling.RepGrindFactions = { faction }; end else for key, faction in pairs(Tilling.RepGrindFactions) do if Tilling.ForceRepGrindMode == 0 then if ((faction.player_faction ~= nil and faction.player_faction ~= Tilling.GetPlayerFaction())) or (Tilling.RepRequired(faction.faction_id) == 0) or (Tilling.RepRequired(faction.faction_id) == 42999) then Tilling.LogMsg(string.format("Skipping faction %q for rep grind.", faction.name)); Tilling.RepGrindFactions[key]= nil; end else if (faction.player_faction ~= nil) and (faction.player_faction ~= Tilling.GetPlayerFaction()) then Tilling.LogMsg(string.format("Skipping faction %q for rep grind.", faction.name)); Tilling.RepGrindFactions[key]= nil; end end end if Tilling.numKeys(Tilling.RepGrindFactions) > 0 then if Tilling.numKeys(Tilling.RepGrindFactions) == 1 then for key, faction in pairs(Tilling.RepGrindFactions) do table.insert(result, {["id"] = faction.seed_id, ["count"] = 8}); end table.insert(result, {["id"] = Tilling.GetActualSeed(), ["count"] = 8}); else local rep_required = {}; for key, value in pairs(Tilling.RepGrindFactions) do table.insert(rep_required, { ["required_rep"] = Tilling.RepRequired(value.faction_id), ["faction"] = key }); end table.sort(rep_required, function(a,b) return a["required_rep"] < b["required_rep"] end); local rep_grind_factions = {}; local count = 0; for key, value in pairs(rep_required) do if count >= 2 then break end; table.insert(rep_grind_factions, Tilling.RepGrindFactions[value.faction]); count = count + 1; end Tilling.RepGrindFactions = rep_grind_factions; local i = 0; for key, faction in pairs(Tilling.RepGrindFactions) do i = i + 1; if i <= 2 then table.insert(result, {["id"] = faction.seed_id, ["count"] = 8}); else Tilling.RepGrindFactions[key] = nil; end end end else _Log("you don't need any reputations"); Tilling.RepGrindFactions = {}; result = { { ["id"] = Tilling.GetActualSeed(), ["count"] = Tilling.TotalPlots * 4 } } end end return result; end function Tilling.GetReady() if GetObjectByID(215705) == 0 then _Log("Not near Farm, so flying there."); SetMount(1); Tilling.FlyTo(Tilling.CropLocations[1][1]); else Tilling.MountDown(); Tilling.WalkTo(Tilling.CropLocations[1][1]); end Tilling.TotalPlots = Tilling.NumOfPatches(); end function Tilling.AutoCompleteQuests() WowLuaDoString("for i=1,GetNumQuestLogEntries() do if GetQuestLogIsAutoComplete(i) == true then ShowQuestComplete(i); break; end; end"); Sleep(1000); WowLuaDoString("QuestFrameCompleteQuestButton:Click()"); Sleep(1000); WowLuaDoString("if QuestFrameAcceptQuestButton ~= nil then QuestFrameAcceptQuestButton:Click() end"); Sleep(1000); end function Tilling.YoonDailyStart() local need_seed = nil; _Log("Accepting Yoon's farming daily"); Tilling.WalkTo({-180.239;629.81;165.409}); for quest_id, seed_id in pairs(Tilling.YoonQuests) do _Log("Trying to accept quest id " .. quest_id); AcceptQuestByID(40248, quest_id); if IsQuestInLog(quest_id) == true then need_seed = seed_id; break; else WowLuaDoString("CloseGossip()"); Sleep(1000); end end return need_seed; end function Tilling.YoonDailyEnd() for quest_id, seed_id in pairs(Tilling.YoonQuests) do if IsQuestInLog(quest_id) == true and IsQuestStepDone(quest_id, 1) == true then Tilling.WalkTo({-180.239;629.81;165.409}); Sleep(1000); _Log("Turning in Yoon's farming daily " .. quest_id); TurnInQuestByID(40248, quest_id); if IsQuestInLog(quest_id) == true then _Log("working around bot bug"); -- accept quest: workaround for bot bug WowLuaDoString("CloseGossip()"); Sleep(1000); AcceptQuestByID(40248, quest_id); TurnInQuestByID(40248, quest_id); end break; end end end function Tilling.GetActualSeed() local actual_seed = nil; if Tilling.RepRequired(1272) > 21999 then actual_seed = Tilling.BeforeTillersReveredSeedId; else actual_seed = Tilling.PlantSeedId; end return actual_seed; end -- main function Tilling.Main() Tilling.GetReady(); if Tilling.TillersEndlessMode == 1 then Tilling.GetGardeningTools(); Tilling.PlantSeedIds = { { ["id"] = Tilling.GetActualSeed(), ["count"] = Tilling.TotalPlots * 4 } } -- while Tilling.HasNumFreeBagSlots() >= 2 and Tilling.RepRequired(1272) > 0 do while Tilling.HasNumFreeBagSlots() >= 2 do Tilling.DoneLanes = {}; Tilling.Harvest(); Tilling.BuySeeds(); Tilling.Till(); Tilling.FixCrops(); Tilling.DestroyCrops(); end error("Done. Your bags are full."); else local pandaria_quest_rep_grind_active = 0; local has_yoon_quest = 0; if Tilling.PandariaRepGrindMode == 1 and Tilling.RepRequired(1272) > 999 then local actual_seed = Tilling.GetActualSeed(); local yoon_seed = Tilling.YoonDailyStart(); if yoon_seed ~= nil then has_yoon_quest = 1; if yoon_seed == actual_seed then Tilling.PlantSeedIds = { { ["id"] = actual_seed, ["count"] = Tilling.TotalPlots * 4 } } else Tilling.PlantSeedIds = { { ["id"] = actual_seed, ["count"] = (Tilling.TotalPlots * 4) - 1 }, { ["id"] = yoon_seed, ["count"] = 1 } } end else _Log("failed to pick up Yoon quest"); Tilling.PlantSeedIds = { { ["id"] = actual_seed, ["count"] = Tilling.TotalPlots * 4 } } end elseif Tilling.PandariaRepGrindMode == 1 and WasQuestDone(32682) == true then pandaria_quest_rep_grind_active = 1; Tilling.PlantSeedIds = Tilling.WorkOrderSeeds(); else if Tilling.PandariaRepGrindMode == 1 and Tilling.RepRequired(1272) <= 999 then _Log("Must complete this quest first for rep grinding: http://www.wowhead.com/quest=32682"); _Log("Not doing any rep quests."); end Tilling.PlantSeedIds = { { ["id"] = Tilling.GetActualSeed(), ["count"] = Tilling.TotalPlots * 4 } } end Tilling.GetGardeningTools(); if pandaria_quest_rep_grind_active == 1 then for key, faction in pairs(Tilling.RepGrindFactions) do if key ~= nil then if IsQuestInLog(faction.step_2_quest) == false and IsQuestInLog(faction.step_1_quest) == false then Tilling.WalkTo({-178.037;650.586;165.409}); Sleep(1000); _Log(string.format("accepting step 2 quest for %q: %d", faction.name, faction.step_2_quest)); AcceptQuestByID(12803, faction.step_2_quest); if IsQuestInLog(faction.step_2_quest) == false then -- error("Bot error: failed to accept quest"); end WowLuaDoString("CloseGossip()"); Sleep(1000); end end end end Tilling.Harvest(); if pandaria_quest_rep_grind_active == 1 then for key, faction in pairs(Tilling.RepGrindFactions) do if key ~= nil then if IsQuestInLog(faction.step_2_quest) == true and IsQuestStepDone(faction.step_2_quest, 1) == true then Tilling.WalkTo({-178.037;650.586;165.409}); Sleep(1000); _Log(string.format("turning in step 2 quest for %q: %d", faction.name, faction.step_2_quest)); TurnInQuestByID(12803, faction.step_2_quest); if IsQuestInLog(faction.step_2_quest) == true then error("Bot error: failed to turn in quest"); end WowLuaDoString("CloseGossip()"); Sleep(1000); end end end for key, faction in pairs(Tilling.RepGrindFactions) do if key ~= nil then if IsQuestInLog(faction.step_1_quest) == false then Tilling.WalkTo({-178.303;627.756;165.409}); Sleep(1000); _Log(string.format("accepting step 1 quest for %q: %d", faction.name, faction.step_1_quest)); AcceptQuestByID(11458, faction.step_1_quest); if IsQuestInLog(faction.step_1_quest) == false then -- error("Bot error: failed to accept quest"); end WowLuaDoString("CloseGossip()"); Sleep(1000); end end end end Tilling.BuySeeds(); Tilling.Till(); Tilling.FixCrops(); if pandaria_quest_rep_grind_active == 1 then Tilling.AutoCompleteQuests(); Tilling.AutoCompleteQuests(); end if has_yoon_quest == 1 then Tilling.YoonDailyEnd(); end end end local status, err = pcall(Tilling.Main); if not status then if err == nil then err = "<nil>"; end _Log("LUA error encountered:"); _Log(err); _Log("aborting script"); end