-- R5Version 2.5 setExecutionPath(getExecutionPath().."/..") bizarremechanism = 101489 guardianrockspirit = GetIdName(101269) guardian = GetIdName(101270) guardiandefender = GetIdName(101637) guardianswordsman = GetIdName(101271) franticcliffdemon = GetIdName(101272) brownwoodenchest = 111956 smallbomb = 101486 mediumbomb = 101487 largebomb = 101488 treasuretile = GetIdName(111811) joker = GetIdName(111814) logentry = nil numshells = inventory:getItemCount(240181) function checkRelog() -- Log result local filename = getExecutionPath() .. "/logs/survival.log"; local file, err = io.open(filename, "a+"); if file then file:write("Account: "..RoMScript("GetAccountName()").."\tName: " ..string.format("%-10s",player.Name ).." \tDate: " .. os.date() .. " \tShells gained/total: "..inventory:getItemCount(240181) - numshells.."/".. inventory:getItemCount(240181).. "\t" ..logentry .. "\n") file:close(); end local function loadprofile() -- Re-initialize player player = CPlayer.new(); settings.load(); settings.loadProfile(convertProfileName(player.Name)) end if When_Finished == "relog" then sendMacro("}LoginNextToon=true;a={") sendMacro("Logout();"); waitForLoadingScreen(); loadprofile() loadPaths("survivalr5"); elseif When_Finished == "charlist" then SetCharList(CharList) LoginNextChar() loadprofile() loadPaths("survivalr5"); elseif When_Finished == "end" then error("Ending script",2) else if not string.find(When_Finished,".", 1, true) then When_Finished = When_Finished .. ".xml" end local filename = getExecutionPath() .. "/waypoints/" .. When_Finished local file, err = io.open(filename, "r"); if file then file:close(); loadPaths(When_Finished) else error("'When_Finished' option is invalid",0) end end end --=== Function to sort tables, at angle ===-- local function SEsize(_x, _z) local X1 = 2622.1403808594 local Z1 = 2900.1105957031 local X2 = 2471.7895507813 local Z2 = 2954.833984375 return math.floor(((_x-X1)*(Z2-Z1)-(X2-X1)*(_z-Z1))/math.sqrt((X2-X1)^2 + (Z2-Z1)^2) + 0.5) end local function NEsize(_x, _z) local X1 = 2471.7895507813 local Z1 = 2954.833984375 local X2 = 2526.5126953125 local Z2 = 3105.1848144531 return math.floor(((_x-X1)*(Z2-Z1)-(X2-X1)*(_z-Z1))/math.sqrt((X2-X1)^2 + (Z2-Z1)^2) + 0.5) end function addToNE(_x, _z, _s) return _x + (_s * 0.9397), _z - (_s * 0.3420) end function addToSE(_x, _z, _s) return _x + (_s * 0.3420), _z + (_s * 0.9397) end function GetAttackPosition(_x, _z) local SEvalue = SEsize(_x, _z) local NEvalue = NEsize(_x, _z) if 1 > SEvalue then -- nw edge _x, _z = addToSE(_x, _z, - attackdistance) elseif SEvalue > 159 then -- se edge _x, _z = addToSE(_x, _z, attackdistance) end if 1 > NEvalue then -- sw edge _x, _z = addToNE(_x, _z, - attackdistance) elseif NEvalue > 159 then -- ne edge _x, _z = addToNE(_x, _z, attackdistance) end return _x, _z end --=== Create table of tiles ===-- function createTileTable() repeat tiles = {} local objectList = CObjectList(); objectList:update(); local objSize = objectList:size() for i = 0,objSize do local obj = objectList:getObject(i); if obj.Id == 111811 or obj.Id == 111812 then table.insert(tiles, table.copy(obj)) end end -- sort by address local function addresssortfunc(a,b) return a.Address > b.Address end table.sort(tiles, addresssortfunc) -- check for duplicate addresses local duplicatefound = false for i = 1, #tiles - 1 do if tiles[i].Address == tiles[i+1].Address then duplicatefound = true break end end if duplicatefound or #tiles ~= 36 then if duplicatefound then printf("Duplicate address found. ") end if #tiles ~= 36 then printf("#tiles = "..#tiles..". ") end printf("Redoing table.\n") yrest(500) end until duplicatefound == false and #tiles == 36 -- Sort function local function sortfunc(a,b) if SEsize(a.X,a.Z) == SEsize(b.X,b.Z) then return NEsize(b.X,b.Z) > NEsize(a.X,a.Z) else return SEsize(b.X,b.Z) > SEsize(a.X,a.Z) end end -- Sort tiles table.sort(tiles, sortfunc) end --=== look for indicator that the tile is clickable ===-- function clicktile(address) local tmp = memoryReadRepeat("int", getProc(), address + addresses.pawnAttackable_offset) or 0; if bitAnd(tmp,0x8) then return true else return false end end --=== look for indicator that the chest has loot ===-- function clickchest(address) local chest = memoryReadRepeat("byte", getProc(), address + 0x2F0) or 0 if chest ~= 0 then return true else return false end end --=== custom fight function ===-- function myfight(target) target = CPawn(target.Address) if player.Battling then repeat local _enemy = findaggroenemy() if _enemy then player:target(_enemy); player:fight() end until _enemy == nil or player.HP < 1 or player.Alive == false end target:update() while target.Id ~= 0 and target.HP > 4 do if target.Id ~= 0 then player:target(target) else return end if player.Class1 == CLASS_WARRIOR then Attack() end for i,v in pairs(settings.profile.skills) do if v.AutoUse and v:canUse(false, target) and AllowSkillCastTime >= v.CastTime then player:cast(v) repeat yrest(50) player:update() until not player.Casting yrest(500) target:update() player:update() if target.Id == 0 or 5 > target.HP then break end end end target:update() player:update() if (player.HP < 1 or player.Alive == false) then break end player:checkPotions() end if target.Name == franticcliffdemon then -- try to loot yrest(500) target:update() if target.Lootable then Attack() yrest(2000) end -- one more time target:update() if target.Lootable then Attack() yrest(2000) end end end local function evalfunc(addr) local pawn = CPawn(addr) return (pawn.HP > 4 and attackdistance*1.5 > distance(player.X, player.Z, pawn.X, pawn.Z) ) end --=== First mobs to kill ===-- function trashmelee() cprintf(cli.yellow,"Clearing trash...\n") while (player:findNearestNameOrId({bizarremechanism,guardianrockspirit},nil,function(addr) return CPawn(addr).HP > 4 end)) do for i = 1,#orderlist do local tile = tiles[orderlist[i]] fly() local x,z = GetAttackPosition(tile.X,tile.Z) repeat teleport(x, z, 18) if distance(player.X, player.Z, x, z) > 5 then yrest(500) end until 5 > distance(player.X, player.Z, x, z) repeat local trash = player:findNearestNameOrId(bizarremechanism, nil, evalfunc) if trash then player:target(trash) myfight(trash) player:clearTarget(); end until trash == nil or player.HP < 1 or player.Alive == false repeat local spawn = player:findNearestNameOrId(guardianrockspirit, nil, evalfunc) if spawn then player:target(spawn) myfight(spawn) player:clearTarget(); end until spawn == nil or player.HP < 1 or player.Alive == false if (player.HP < 1 or player.Alive == false) then logentry = "Player died." return end end end breaktiles() end --=== Start of tiles function ===-- function breaktiles() cprintf(cli.yellow,"Digging up tiles...\n") if aoefound then aoeskill.AutoUse = false end --=== First run of tiles ===-- orderlist = {6,24,5,23,4,22,3,21,2,20,1,19,16,36,18,35,17,34,15,33,14,32,13,31,28,12,30,11,29,10,27,9,26,8,25,7,25} -- last is to tele away from possible bomb. for i = 1,#orderlist do local tile = tiles[orderlist[i]] -- Dig tile local threshold = 120 repeat if not RoMScript("TimeKeeperFrame:IsVisible()") then return end fly() if player.X > tile.X+10 or tile.X-10 > player.X or player.Z > tile.Z+10 or tile.Z-10 > player.Z then teleport_SetStepSize(threshold) teleport(tile.X+1,tile.Z+1,18) threshold = threshold/2 end player:update() if player.Battling then repeat local _enemy = findaggroenemy() if _enemy then player:target(_enemy); player:fight() end until _enemy == nil or player.HP < 1 or player.Alive == false end if (player.HP < 1 or player.Alive == false) then logentry = "Player died." return end player:target(tile); yrest(200) Attack() yrest(500) repeat player:update() until player.Casting == false until clicktile(tile.Address) == false -- see what's there local starttime = os.clock() repeat local result = player:findNearestNameOrId({"^"..guardian.."$", guardiandefender,guardianswordsman,franticcliffdemon,brownwoodenchest,smallbomb,mediumbomb,largebomb}) if result and 15 > distance(player.X,player.Z,result.X,result.Z) then printf("%s found. Id %d.\n", result.Name, result.Id) if result.Name == guardian or result.Name == guardiandefender or result.Name == guardianswordsman or result.Name == franticcliffdemon then player:target(result) player:fight() if (player.HP < 1 or player.Alive == false) then logentry = "Player died." return end elseif result.Id == brownwoodenchest then repeat player:target(result); yrest(200) Attack() yrest(1000) repeat player:update() until player.Casting == false until clickchest(result.Address) ~= true end break end until os.clock() - starttime > 2 end teleport_SetStepSize(120) chests() -- double check for left over chests. There shouldn't be any end --=== Open chests ===-- function chests() local chest repeat chest = player:findNearestNameOrId(brownwoodenchest,nil,clickchest) if chest then fly() teleport(chest.X+10,chest.Z+10,18) repeat player:target_Object(chest.Id, nil, nil, true); until clickchest(chest.Address) ~= true end until chest == nil local secondsleft = RoMScript("TimeKeeperFrame.startTime-GetTime()") local mm, ss = math.floor(secondsleft/ 60), math.floor(math.mod(secondsleft, 60)) printf("Succeeded at Survival with %d:%d remaining.\n",mm,ss) logentry = string.format("Succeeded at Survival with %d:%d remaining.",mm,ss) end --=== find enemys that have you targeted ===-- function findaggroenemy() local obj = nil local pawn = nil local objectList = CObjectList(); objectList:update(); for i = 0,objectList:size() do obj = objectList:getObject(i); if( obj ~= nil and obj.Type == PT_MONSTER) then pawn = CPawn(obj.Address) if pawn.TargetPtr == player.Address then return pawn end end end end local wp = __WPL.Waypoints[__WPL.CurrentWaypoint] if distance(player.X,player.Z,wp.X,wp.Z) > 250 then print("Too far to run script.") logentry = "Too far to run script." checkRelog() return end if player.Class1 == CLASS_SCOUT or player.Class1 == CLASS_PRIEST or player.Class1 == CLASS_DRUID or player.Class1 == CLASS_MAGE then attackdistance = 50 orderlist = {12, 30, 35, 32, 25, 7, 2, 5} else attackdistance = 25 orderlist = {6, 12, 18, 24, 30, 36, 35, 34, 33, 32, 31, 25, 19, 13, 7, 1, 2, 3, 4, 5} end if player.Class1 == CLASS_WARRIOR then -- because warriors move closer. attackdistance = 20 end -- assume if user wants to use aoe it will be first attack skill -- find aoe skill aoefound = false firstskillpriority = nil for k,v in pairs(settings.profile.skills) do if v.Type == STYPE_DAMAGE or v.Type == STYPE_DOT then if not firstskillpriority then firstskillpriority = v.priority end aoeskill = settings.profile.skills[k] for k,v in pairs(aoeskills) do if aoeskill.Name == v then cprintf(cli.yellow,"AOE skill found as first skill, %s\n",aoeskill.Name) aoefound = true aoeskill.AutoUse = true aoeskill.priority = firstskillpriority + 1 table.sort(settings.profile.skills, function(a,b) return a.priority > b.priority end) attackdistance = 35 orderlist = {12, 30, 35, 32, 25, 7, 2, 5} break end end end if aoefound == true then break end end --=== Table numbering system ===-- --[[ 1 7 13 19 25 31 2 8 14 20 26 32 3 9 15 21 27 33 4 10 16 22 28 34 5 11 17 23 29 35 6 12 18 24 30 36 * -- entrance to room. ]] --=== Turn off looting, wastes time ===-- settings.profile.options.LOOT = false settings.profile.options.TARGET_LEVELDIF_ABOVE = "15" -- Need to try to kill anything in there or no point. settings.profile.options.TARGET_LEVELDIF_BELOW = "60" --trash is lvl 15 which people won't allow for in profile. settings.profile.options.ANTI_KS = false teleport_SetStepSize(120)