program AIOFighter; {$DEFINE SRLCOMPATIBILITY} {$I SRL-6/SRL.simba} {$include_once ogLib/lib/core/core.Simba} const REVISION = 3.0; { *Setup Tools* GATHER_MONSTER_IDs finds IDs that move, then hovers over to check for 'Attack' uptext. GET_INVENTORY_IDs writelns the all of the Texture IDs in your inventory. } GATHER_MONSTER_IDs = false; GET_INVENTORY_IDs = false; { *Combat* Type in the skills that you will use, in order of priority. } USE_THRESHOLDS = true; THRESHOLD_ORDER = ['pulverise', 'overpower']; USE_SGS = false; USE_SGS_AT = 70; USE_QUICK_PRAYERS = false; { *Regeneration* Requires Revolution combat mode. Health % is randomized between +/-5 } USE_REGENERATE = true; REGENERATE_WHILE_LOOTING = true; REGENERATE_AT = 50; { *Looting Charms and Items* Charm IDs are included. Getting the IDs for loot is on the user. I recommend Clarity's Highlight tool. Make sure you are using "Custom Looting" in gameplay settings. } LOOT_CHARMS = true; LOOT_ITEMS = false; { *Looting Bones* http://cherrytree.at/misc/vk.htm Use the value in the middle column corresponding to actionbar key. '1' is 49 (1 KEY); Use 0-9 Keys } LOOT_BONES = false; VKEY_TO_BURY_BONES = 49; { *Skills to Track* Choose one. 'attack', 'strength', 'defense', 'ranged', 'mage', or 'overall' } SKILL_TO_TRACK = 'overall'; { *Food* Supports lobster, swordfish, monkfish, shark, rocktail Health % is randomized between +/-5 } USE_FOOD = true; FOOD_KEY = '-'; EAT_AT_PERCENT = 20; { *Failsafes* Teleports and terminates at certain health percent TERMINATE_AFTER calls for minutes. Randomizes between +/-5 minutes } ONE_CLICK_TELEPORT_KEY = '='; TERMINATE_AT_HP_PERCENT = 1; TERMINATE_ON_INVENTORY_FULL = true; TERMINATE_AFTER = 9999; TERMINATE_AT_KILL_COUNT = 999999999; { *High Alching* No need for V_KEY like bones. } HIGH_ALCH = false; HIGH_ALCH_KEY = '-'; { *Potions to drink* Supports: Super Attack, Super Strength, Super Defense Super Magic, Super Ranging, Prayer Potion, Prayer Renewal } DRINK_POTIONS = false; POTIONS_TO_DRINK = ['Super Attack', 'Super Strength']; DRINK_PRAYER_POTION_AT = 50; { *Micro Breaking* Each break lasts between 10 and 30 seconds TAKE_MICRO_BREAK_EVERY calls for minutes. Randomizes between +/-5 minutes } TAKE_MICRO_BREAKS = false; TAKE_MICRO_BREAK_EVERY = 15; var { *IDs* Insert IDs into the arrays below. You do NOT need to put in Bone IDs if you are looting bones. } MONSTER_IDs: TCardinalArray := [0]; LOOT_MODEL_ARRAY: TCardinalArray := [0]; ITEMS_TO_ALCH: TIntegerArray := [0]; (* Don't edit anything after this. *) canRotateCamera: boolean; lastFight, center: TPoint; startXP, currentXP, kills, breaksTaken: integer; microBreakCountdown, terminateTimer: tCountDown; procedure getUpdate(); var newFile: Integer; newRev: Extended; begin newRev := strToFloat(getPage('http://tomstewart.net/proxy.php?url=https://raw.githubusercontent.com/SRLRoss/AIO-Combat/master/version.txt')); if newRev > REVISION then begin writeln('Updating from revision ' + toStr(REVISION) + ' to revision ' + toStr(newRev)); newFile := rewriteFile(scriptPath + 'Ross'' AIO Combat v' + toStr(newRev) + '.simba', false); writeFileString(newFile, getPage('http://tomstewart.net/proxy.php?url=https://raw.githubusercontent.com/SRLRoss/AIO-Combat/master/AIOCombat.simba')); closeFile(newFile); writeln('Please open the new file.'); terminateScript(); end else writeln('Script is up-to-date.'); end; function tmouse.getTooltip(): string; override; var ID: int32; Bounds: tBox; Pointer: pointer; PointerIndex, PointerSize: uInt32 = 0; begin Pointer := glTextures(PointerSize) + (36 * (PointerSize - 1)); if Pointer <> nil then begin for PointerIndex to PointerSize div 5 do begin if Pointer ^ = 15878 then begin Bounds := [(Pointer - 88) ^, (Pointer - 84) ^, (Pointer + 28) ^, (Pointer + 32) ^]; break; end; Pointer := Pointer - 36; end; if PointerIndex < PointerSize div 5 then begin Pointer := glFonts(PointerSize) + (48 * (PointerSize - 1)); if Pointer <> nil then begin for PointerIndex := 0 to PointerSize div 2 do begin if pointInBox([(Pointer + 8) ^, (Pointer + 12) ^], Bounds) then begin if (result <> '') and (single((Pointer + 68) ^) - (single((Pointer + 20) ^) + integer((Pointer + 40) ^)) <> 1) then result := ' ' + result; result := char((Pointer + 16) ^) + result; end else if result <> '' then break; Pointer := Pointer - 96; end; end; end; end; exit(result); end; function tOGL.getFormattedTime(time: uint32): string; var h, m, s: integer; begin s := time mod 3600000 mod 60000 div 1000; m := time mod 3600000 div 60000; h := time div 3600000; result:= (toStr(h) + 'h ' + toStr(m) + 'm ' + toStr(s) + 's'); end; function tMainscreen.getXP(skill: string): integer; var i, skillID: uint32; skillTextures: glTextureArray; skillBoxTexture: glTexture; skillBox: TBox; begin case lowercase(skill) of 'attack': skillID := 16918; 'strength': skillID := 39319; 'defence': skillID := 41952; 'range': skillID := 20999; 'magic': skillID := 51211; 'constitution': skillID := 38262; 'thieving': skillID := 25506; 'crafting': skillID := 33559; 'fletching': skillID := 19315; 'mining': skillID := 16653; 'smithing': skillID := 31773; 'fishing': skillID := 54626; 'runecrafting': skillID := 33877; 'slayer': skillID := 64733; 'farming': skillID := 34536; 'construction': skillID := 54189; 'hunter': skillID := 30306; 'summoning': skillID := 37582; 'prayer': skillID := 23912; 'agility': skillID := 29580; 'herblore': skillID := 54427; 'cooking': skillID := 47376; 'firemaking': skillID := 46008; 'woodcutting': skillID := 44243; 'dungeoneering': skillID := 58390; 'divination': skillID := 22933; 'combat': skillID := 31110; 'overall': skillID := 48705; end; skillTextures:=ogl.getTextures(skillID); if skillTextures.isEmpty() then exit(result-1); skillBoxTexture:=skillTextures[low(skillTextures)]; skillBox:=skillBoxTexture.bounds.adjustPosition(-150, 0, 0, 0); result := explode('+', ogl.getChars(skillBox).toString())[0].parseInt(); end; procedure progressReport(status: string); var i, x, y: integer; currentXp :uint32; paintXp, xpHour, killsHour :integer; time: string; reportStrings: TStringArray; begin currentXp := tMainscreen.getXP(SKILL_TO_TRACK); paintXp := currentXp - startXp; xpHour := round(paintXp * (3600.0 / (getTimeRunning / 1000.0))); killsHour := round(kills * (3600.0 / (getTimeRunning / 1000.0))); time:=togl.getFormattedTime(getTimeRunning()); x:=11; y:=11; reportStrings:=[toStr(paintXp) + ' ' + SKILL_TO_TRACK + ' xp gained', toStr(xpHour) + ' ' + SKILL_TO_TRACK + ' xp/hr', 'Kills: ' + toStr(kills), 'Kills/hr: ' + toStr(killsHour), 'Status: ' + status, 'Time Running: ' + time, 'Time until next micro break: ' + tOgl.getFormattedTime(microBreakCountdown.timeRemaining()), 'Breaks Taken: ' + toStr(breaksTaken)]; smart.__graphics.clear; for i:= 0 to high(reportStrings) do begin if (i >= (high(reportStrings)-1)) and (not TAKE_MICRO_BREAKS) then continue else begin smart.__graphics.DrawText(reportStrings[i], 'smallChars', point(x+1, y+1), 1); smart.__graphics.DrawText(reportStrings[i], 'smallChars', point(x-1, y-1), 1); smart.__graphics.DrawText(reportStrings[i], 'smallChars', point(x-1, y+1), 1); smart.__graphics.DrawText(reportStrings[i], 'smallChars', point(x+1, y-1), 1); smart.__graphics.DrawText(reportStrings[i], 'smallChars', point(x, y), clWhite); incEx(y, 18); end; end; end; procedure gatherMonsterIDs; var i, j: integer; ID, potentialID, potentialID2: glModelArray; excludedIDs: TIntegerArray; begin writeln('Gathering monster IDs- use these IDs to place in MONSTER_IDs array.'); repeat ID:=ogl.getModels(); excludedIDs:=[4390934, 65536, 65538, 0]; for i:=0 to high(ID) do begin if (not excludedIDs.contains(ID[i].id)) then begin potentialID:=ogl.getModels(ID[i]); wait(100); potentialID2:=ogl.getModels(ID[i]); for j:=0 to high(potentialID) do begin if (potentialID[j].x > 0) then if (potentialID[j].x <> potentialID2[j].x) or (potentialID[j].y <> potentialID2[j].y) then begin tMouse.move(potentialID[j].toPoint()); wait(100); if isMouseOverText(['Attack']) then begin writeln('ID ' + toStr(potentialID[j].id) + ' may be a monster.'); writeln('Searching for IDs.'); break; end else wait(100); end; end; end; end; until(false); end; procedure getInventoryIDs; var i: integer; begin writeln('Following slots start at 1.'); for i:=0 to 27 do begin if (inventory.getSlot(i).id <> 0) then begin writeln('Slot ' + toStr(i + 1) + ' ID is: ' + toStr(inventory.getSlot(i).id)); end; end; end; procedure waitFlag; begin wait(250); while (not ogl.getTextures(1275).isEmpty()) do wait(1000); end; function hasAlchables: boolean; begin if (not HIGH_ALCH) then exit(false); result := not inventory.getItems(ITEMS_TO_ALCH).isEmpty(); end; function inCombat: boolean; var i: integer; lock: glTextureArray; begin lock:=ogl.getTextures(7750); if not (lock.isEmpty()) then begin for i:=0 to high(lock) do if pointInbox(lock[i].toPoint(), mainscreen.getBounds()) then exit(true); end; end; function regenerateHealth(waitCombat: boolean): boolean; begin if not (USE_REGENERATE and (tActionbar.getLifePoints() < (REGENERATE_AT + randomRange(-5, 5)))) then exit; progressReport('Regenerating health.'); tActionbar.setRegenerate(true); wait(randomRange(750, 1250)); if waitCombat then begin while (tActionbar.getAdrenaline() > 0) do begin wait(randomRange(750, 1250)); if inCombat() then break; end; end; end; function drinkPotion(potion: string): boolean; begin case potion of 'superstrength': result := inventory.clickItem([79560, 79815, 77520], [3486515, 3354929, 2894379, 2697258]); 'superattack': result := inventory.clickItem([79560, 79815, 77520], [1118520, 1315894, 1447470, 1842217]); 'superdefence': result := inventory.clickItem([79560, 79815, 77520], [3747601, 3550484, 3024919, 2630941]); 'supermagic': result := inventory.clickItem([79560, 79815, 77520], [1254189, 1451053, 1515815, 1909286]); 'superranging': result := inventory.clickItem([79560, 79815, 77520], [1125945, 1322295, 1451823, 1910315]); 'prayerpotion': result := inventory.clickItem([79560, 79815, 77520], [1128490, 1258793, 1453606, 1845541]); 'prayerrenewal': result := inventory.clickItem([79560, 79815, 77520], [2033156, 2099721, 1969935, 2169114]); end; end; function hasBuff(buff: string): boolean; begin case buff of 'superstrength': result := not ogl.getTextures([35262], [3482653]).isEmpty(); 'superattack': result := not ogl.getTextures([23328], [1710097]).isEmpty(); 'superdefence': result := not ogl.getTextures([46691], [1647916]).isEmpty(); 'supermagic': result := not ogl.getTextures([44496], [1316644]).isEmpty(); 'superranging': result := not ogl.getTextures([21062], [1512203]).isEmpty(); 'prayerpotion': result := not (tActionbar.getPrayerPoints() < (DRINK_PRAYER_POTION_AT + (randomRange(-5, 5)))); 'prayerrenewal': result := not ogl.getTextures([55080, 44496]).isEmpty(); end; end; procedure checkBuffs; var i: integer; potion: string; begin if not DRINK_POTIONS then exit; for i:= 0 to high(POTIONS_TO_DRINK) do begin potion := lowercase(extractFromStr(POTIONS_TO_DRINK[i], letters)); if (not hasBuff(potion)) then if drinkPotion(potion) then wait(randomRange(750, 1250)) else begin writeln('Out of ' + POTIONS_TO_DRINK[i] + ' potions.'); terminateScript; end; end; end; function hasLoot: boolean; begin result:= not ogl.getModels(LOOT_MODEL_ARRAY).isEmpty(); end; function hasBones: boolean; begin result:= not ogl.getModels([2406257549, 189892155, 193554437]).isEmpty(); end; function hasBonesInventory: boolean; begin result := not inventory.getItems([52275, 62985, 84405, 97410]).isEmpty(); end; function hasCharms: boolean; begin result:= not ogl.getModels([1107824708,585563216,2950982353,3759434362,2984528207,544819542]).isEmpty(); end; procedure alchItems; begin if (not HIGH_ALCH) then exit; progressReport('Alching item.'); wait(randomRange(500, 750)); sendKeys(HIGH_ALCH_KEY, random(25, 40), random(80, 110)); wait(randomRange(750, 1500)); if (tActionbar.getActionActive(79489)) then begin inventory.clickItem(ITEMS_TO_ALCH); wait(randomRange(750, 1500)); end; end; function findAndClick(ID: TCardinalArray = []; optionText: TStringArray = []; point: TPoint = []): boolean; var modelID: glModelArray; tries: integer; begin waitFlag; if ID.isEmpty() then begin while (tries < 10) do begin if (not point.isVisible()) then begin if (point.x < (center.x)) then tMinimap.setDegrees(tMinimap.getDegrees() + random(20, 30)) else tMinimap.setDegrees(tMinimap.getDegrees() - random(10, 40)); inc(tries); end else begin if optionText.isEmpty() then begin tMouse.click(point.randomizePointEllipse(5), 1); exit(true); end else if (tMouse.rightClickOption(point.randomizePointEllipse(5), optionText, 500)) then exit(true); inc(tries); end; end; end; if ogl.getModels(ID).isEmpty() then exit(false) else begin while (tries < 10) do begin modelID := ogl.getModels(ID); if ogl.getModels(ID).isEmpty() then exit(false); if (not center.closest(modelID)[0].isVisible()) then begin if ((modelID)[0].x < (center.x)) then tMinimap.setDegrees(tMinimap.getDegrees() + random(20, 30)) else tMinimap.setDegrees(tMinimap.getDegrees() - random(10, 40)); inc(tries); end else begin if optionText.isEmpty() then begin tMouse.click(center.closest(modelID)[0].randomizePointEllipse(5), 1); exit(true); end else if (tMouse.rightClickOption(center.closest(modelID)[0].randomizePointEllipse(20), optionText, 500)) then exit(true) else begin if ((modelID)[0].x < (center.x)) then tMinimap.setDegrees(tMinimap.getDegrees() + random(5, 15)) else tMinimap.setDegrees(tMinimap.getDegrees() - random(5, 15)); wait(randomRange(250, 750)); inc(tries); end; end; end; end; exit(false); end; function clickExitButton: boolean; var i: integer; exitButton, bounds: glTextureArray; begin if (ogl.getTextures(714000).isEmpty()) then exit; progressReport('Clicking exit button.'); exitButton := ogl.getTextures(16320); bounds := ogl.getTextures(714000); if bounds.isEmpty() then exit; for i:= 0 to high(exitButton) do begin if pointInBox(exitButton[i].toPoint(), bounds[low(bounds)].bounds) then begin tMouse.click((exitButton)[i]); wait(randomRange(750, 1000)); end; end; end; function clickLootCustom: boolean; var lootCustom: glTextureArray; begin lootCustom := ogl.getTextures(91275); if (not lootCustom.isEmpty()) then begin tMouse.click(lootCustom[0]); wait(randomRange(750, 1000)); clickExitButton(); end; end; function lootItems: boolean; begin if not (((LOOT_ITEMS) and (hasLoot()) and (not inventory.isFull()))) then exit; progressReport('Looting items.'); result := findAndClick(LOOT_MODEL_ARRAY); end; function lootBones: boolean; begin if not (((LOOT_BONES) and (hasBones()) and (not inventory.isFull()))) then exit; progressReport('Looting bones.'); result := findAndClick([2406257549, 189892155, 193554437], ['bones', 'Bones']); end; function lootCharms: boolean; begin if not (((LOOT_CHARMS) and (hasCharms()) and (not inventory.isFull()))) then exit; progressReport('Looting charms.'); result := findAndClick([1107824708,585563216,2950982353,3759434362,2984528207,544819542], ['charm']); end; procedure clickCharms; var i: integer; charms: glTextureArray; begin repeat charms:=ogl.getTextures(120870); if not charms.isEmpty() then begin for i:=0 to high(charms) do begin if pointInBox(charms[i].toPoint(), mainscreen.getBounds()) then begin tmouse.click(charms[i]); wait(randomRange(750, 1250)); break; end; end; end; until(charms.isEmpty()); end; procedure lootProcedure; begin if lootBones or lootItems then begin if REGENERATE_WHILE_LOOTING then regenerateHealth(false); waitFlag; wait(randomRange(1000, 1250)); while (not ogl.getTextures(714000).isEmpty()) do begin clickLootCustom; end; end else if lootCharms then begin if REGENERATE_WHILE_LOOTING then regenerateHealth(false); waitFlag; wait(randomRange(1000, 1250)); while (not ogl.getTextures(714000).isEmpty()) do begin clickCharms; clickExitButton; end; end; end; function dropBones: boolean; var boneTextures: glTextureArray; begin if not (LOOT_BONES and inventory.isFull()) then exit; progressReport('Dropping bones.'); keyDown(VKEY_TO_BURY_BONES); while (hasBonesInventory()) do begin wait(randomRange(500, 1250)); end; keyUp(VKEY_TO_BURY_BONES); exit(true); end; function lowHealth: boolean; begin result := (tActionbar.getLifePoints() < (EAT_AT_PERCENT + randomRange(-5, 5))); end; function eatFood: boolean; var hp: integer; begin if not (USE_FOOD and lowHealth()) then exit; hp := tActionbar.getLifePoints(); progressReport('Eating food.'); //food := ogl.getTextures([94605, 59670, 102255, 112710, 97410], [3217671, 1445400, 2301468, 3352865, 2300952]); sendKeys(FOOD_KEY, random(25, 40), random(80, 110)); wait(randomRange(1250, 1500)); if ((tActionbar.getLifePoints() - hp) > 1) then exit(true) else begin writeln('Out of food, terminating.'); terminateScript; end; end; function getLastFight(): TPoint; var ringModel: glModelArray; begin ringModel:=ogl.getModels([1829014414, 1938370197]); if (not ringModel.isEmpty()) then result := center.closest(ringModel)[0].toPoint else if combat.hasTarget() then result := combat.getTarget().toPoint() else result := lastFight; exit(result); end; procedure rotateCamera; var adjustment, currentRadians: extended; begin if canRotateCamera then begin progressReport('Rotating camera.'); currentRadians := tMinimap.getRadians(); tMinimap.setDegrees(abs(tMinimap.getDegrees() - randomRange(20, 180))); if tMinimap.getRadians <> currentRadians then canRotateCamera:=false; adjustment := currentRadians - tMinimap.getRadians(); lastFight := rotatePoint(getLastFight, - adjustment, center.x, center.y); end; end; function closestValidModel(arrayResult:gLModelArray; comparePoint: TPoint; distance: Integer):TPoint; var i: integer; begin if arrayResult.isEmpty() then result := [0, 0]; for i := 0 to high(arrayResult) do begin if (center.closest(arrayResult)[i].distanceFrom(comparePoint) > distance) then begin result:=center.closest(arrayResult)[i].toPoint; exit(result); end; end; result := [0, 0]; end; function attackMonster: boolean; var currentRadians, adjustment: extended; monster: TIntegerArray; rx, ry, x, y, tries: integer; attackTimer: tCountDown; closestMonster: TPoint; begin rx := 0; ry := 0; tries := 0; progressReport('Killing monsters.'); while (tries < 6) do begin closestMonster := closestValidModel(ogl.getModels(MONSTER_IDs, [mainscreen.getBounds()]), lastFight, 125); if (closestMonster.x = 0) then begin wait(1500); exit(false); end else if (not closestMonster.isVisible()) then begin currentRadians := tMinimap.getRadians(); if (closestMonster.x < (center.x)) then tMinimap.setDegrees(tMinimap.getDegrees() + random(20, 30)) else tMinimap.setDegrees(tMinimap.getDegrees() - random(10, 40)); adjustment := currentRadians - tMinimap.getRadians(); lastFight := rotatePoint(getLastFight, - adjustment, center.x, center.y); exit(false); end else begin tMouse.click(closestMonster.adjustposition(rx, ry).randomizePointEllipse(5), 2); wait(75); if pos('Attack', tMouse.getTooltip()) then begin tMouse.click(tMouse.getPoint(), 1); wait(100); if pos('red', tMouse.getClick()) then begin attackTimer.setTime(randomRange(3000, 4500)); while (not attackTimer.isFinished) do begin wait(250); lastFight := getLastFight(); if inCombat() then break; end; progressReport('Attacking Monster.'); canRotateCamera:=true; exit(true); end else begin progressReport('Attacking Monster.'); wait(randomRange(100, 250)); exit(false); end; end else if ((tries >= 5)) and (tMouse.rightClickOption(tMouse.getPoint(), 'Attack', 750)) then begin attackTimer.setTime(randomRange(3000, 4500)); while (not attackTimer.isFinished) do begin wait(250); lastFight := getLastFight(); if inCombat() then break; end; progressReport('Attacking Monster.'); canRotateCamera:=true; exit(true); end else begin inc(tries); rx := rx + (random( - 5, 5)); ry := ry + (random( - 5, 5)); end; end; end; end; function canThreshold(ability: string): boolean; var adrenReq: integer; begin case ability of 'overpower': adrenReq := 100; 'forcefulbackhand': adrenReq := 50; 'flurry': adrenReq := 50; 'hurricane': adrenReq := 50; 'massacre': adrenReq := 100; 'meteorstrike': adrenReq := 100; 'stomp': adrenReq := 50; 'destroy': adrenReq := 50; 'quake': adrenReq := 50; 'berserk': adrenReq := 100; 'assault': adrenReq := 50; 'pulverise': adrenReq := 100; 'frenzy': adrenReq := 100; 'specialattack': adrenReq := 50; 'snapshot': adrenReq := 50; 'deadshot': adrenReq := 100; 'tightbindings': adrenReq := 50; 'rapidfire': adrenReq := 50; 'bombardment': adrenReq := 50; 'incendiaryshot': adrenReq := 100; 'asphyxiate': adrenReq := 50; 'omnipower': adrenReq := 100; 'deepimpact': adrenReq := 50; 'detonate': adrenReq := 50; 'wildmagic': adrenReq := 50; 'metamorphosis': adrenReq := 100; 'tsunami': adrenReq := 100; 'revenge': adrenReq := 50; 'immortality': adrenReq := 100; 'reflect': adrenReq := 50; 'rejuvenate': adrenReq := 100; 'debilitate': adrenReq := 50; 'barricade': adrenReq := 100; end; if (tActionbar.getAdrenaline() >= adrenReq) then if (not tActionbar.isAbilityOnCoolDown(ability)) then if (not tActionbar.isAbilityQueued(ability)) then result:=true; end; function useSGS(): boolean; begin if (not USE_SGS) or (not (tActionbar.getLifePoints() <= (USE_SGS_AT + randomRange(-5, 5)))) then exit; if canThreshold('special attack') then begin sendkeys(tActionbar.getAbilityKey('special attack'), random(25, 40), random(80, 110)); wait(randomRange(750, 1250)); exit(true); end; end; procedure useThresholds; var i: integer; threshold: string; begin if (not USE_THRESHOLDS) or (useSGS()) then exit; for i:=0 to high(THRESHOLD_ORDER) do begin threshold := lowercase(extractFromStr(THRESHOLD_ORDER[i], letters)); if canThreshold(threshold) then begin sendkeys(tActionbar.getAbilityKey(threshold), random(25, 40), random(80, 110)); wait(randomRange(750, 1250)); exit; end; end; end; procedure useQuickPrayers; begin if (not USE_QUICK_PRAYERS) then exit; if tActionbar.setQuickPrayer(true) then wait(randomRange(500, 1000)); end; procedure setMicroBreak; begin microBreakCountdown.setTime((TAKE_MICRO_BREAK_EVERY * 60000) + (randomRange(-300000, 300000))); end; procedure takeMicroBreak; var breakTime: tCountDown; begin if not (TAKE_MICRO_BREAKS and microBreakCountdown.isFinished()) then exit; breakTime.setTime(randomRange(10000, 30000)); inc(breaksTaken); while (not breaktime.isFinished()) do begin progressReport('Taking break for ' + toStr(round(breakTime.timeRemaining()/1000)) + ' more seconds.'); wait(1000); end; setMicroBreak; end; procedure getKills; begin if tMainscreen.getXP(SKILL_TO_TRACK) <> currentXP then begin inc(kills); currentXP := tMainscreen.getXP(SKILL_TO_TRACK); progressReport('Attacking Monster.'); end; end; procedure checkTerminate; begin if (terminateTimer.isFinished()) then begin writeln('Time failsafe is up, terminating.'); terminateScript; end; if (tActionbar.getLifePoints() < TERMINATE_AT_HP_PERCENT) then begin writeln('Life points too low, teleporting and terminating.'); sendkeys(ONE_CLICK_TELEPORT_KEY, random(25, 40), random(80, 110)); terminateScript; end; if (TERMINATE_ON_INVENTORY_FULL and inventory.isFull()) then begin writeln('Inventory is full, terminating.'); terminateScript; end; if (kills >= TERMINATE_AT_KILL_COUNT) then begin writeln('Time failsafe is up, terminating.'); terminateScript; end; end; procedure fixCamera; begin if (tMainScreen.getVerticalDegrees() < random(45, 50)) then begin tMainscreen.setVerticalDegrees(random(58, 60)); wait(250); end; end; procedure setRetaliate; begin if tActionbar.setAutoRetaliate(true) then wait(randomRange(500, 1000)); end; procedure combatLoop; begin repeat getKills; checkTerminate; takeMicroBreak; fixCamera; clickExitButton; setRetaliate; while hasAlchables() do alchItems; checkBuffs; useThresholds; useQuickPrayers; if (not inCombat()) then begin if tActionbar.setQuickPrayer(false) then wait(randomRange(500, 1000)); regenerateHealth(true); lootProcedure; if not dropBones() then if not attackMonster() then rotateCamera; end; lastFight := getLastFight; eatFood; until(false); end; procedure initialSetup; begin center := mainscreen.getCenterPoint(); terminateTimer.setTime((TERMINATE_AFTER * 60000) + (randomRange(-300000, 300000))); writeln('Terminating in: ' + tOGL.getFormattedTime(terminateTimer.timeRemaining())); if TAKE_MICRO_BREAKS then setMicroBreak; currentXP := tMainscreen.getXP(SKILL_TO_TRACK); startXp := currentXP; end; begin getUpdate(); ogl.setup(); disableSRLDebug:=true; if (not isLoggedIn()) then begin writeln('Not logged into game.'); terminateScript; end; glxViewPort(mainscreen.getBounds().x1,mainscreen.getBounds().y1,mainscreen.getBounds().x2,mainscreen.getBounds().y2); smart.__graphics.DrawBox(mainscreen.getBounds()); ogl.setDebugMode('n'); initialSetup; if GATHER_MONSTER_IDs then gatherMonsterIDs else if GET_INVENTORY_IDs then getInventoryIDs else combatLoop; end.