Results 1 to 17 of 17

Thread: ClarityNex Source

  1. #1
    Join Date
    Dec 2011
    Posts
    2,134
    Mentioned
    218 Post(s)
    Quoted
    1063 Post(s)

    Lightbulb ClarityNex Source

    Hey everyone,
    Slight repost, but as I no longer use this script and will likely never use it again, I'm posting the complete version with IDs removed for learning purposes. At this point, OSRS has been much easier to script with far better profit than RS3 (think bosses 10x easier than this, with 10x the profit), so I'm going to keep exploring that. Also, Telos has just been annoying lately If you gather all the IDs and understand how it works (which in my opinion is the most annoying part), it probably will work fine again.

    At the time of running (over a year ago) this averaged around 20m GP/HR but Nex nowadays is nowhere near as profitable. Another problem was the constant server message spam that would announce to the world when I got a drop (cannot disable), which I felt might trigger suspicions on the account when I was completely unresponsive to congratulatory messages from close ingame friends.

    Previously I posted just a snippet of part of the loop which I now realize wasn't that helpful. Here is the full structure and logic of the script. The intention is to prove that high level PvM is easily possible with Simba (arguably a lot/all of this could be done in color, but slower). I strongly advocate people stepping away from these cliche, overdone, instaban methods, and trying something actually challenging/fun to script instead. This coding project took about a week to complete.

    Learned scripters will immediately notice a low amount of failsafes during the actual fight, some hackish scripting methods (many labels because too lazy to restructure), and simple waits in between actions instead of proper checks for things happening. For many situations, this was all that was required. Often times I like to "expect" things to happen in scripts anyway because it's closer to human behavior. Don't form these habits if you are just getting here learning how to script, go read the scripting tutorials instead. This is meant for people who already have some scripting under their belt and can understand what is going on in the code and why, and get motivated to do something top-tier ingame.



    It worked flawlessly for months, probably still works if you get all the IDs!

    Simba Code:
    program ClarityNex;

    {$i ogLib/lib/core/core.simba}
    {$i ClarityGLX.simba}

    {ClarityNex v1.6}

    const
      SCRIPT_VERSION = '1.6';

      MODEL_PLAYER: TIntegerArray = [0];

      MODEL_BANKER_MAX: TCardinalArray = [0];
      MODEL_THRONE: TCardinalArray = [0];
      MODEL_PORTAL: TCardinalArray = [0];
      MODEL_HOLE: TCardinalArray = [0];
      MODEL_DOOR: TCardinalArray = [0];
      MODEL_WARD: TCardinalArray = [0];
      MODEL_BANKER_NEX: TCardinalArray = [0];
      MODEL_NEX: TCardinalArray = [0];
      MODEL_FUMUS: TCardinalArray = [0];
      MODEL_UMBRA: TCardinalArray = [0];
      MODEL_CRUOR: TCardinalArray = [0];
      MODEL_GLACIES: TCardinalArray = [0];
      MODEL_DEATH: TCardinalArray = [0];

      MODEL_FUMUS_PROJECTILE = 0;
      MODEL_SHADOW_TRAP = 0;

      MODELS_LOOT = 0;

      TEXTURE_PRIMARY_TID = 0;
      TEXTURE_PRIMARY_CID = 0;

      KEYBIND_ROCKTAIL = 'x';
      KEYBIND_BREW = 'x';
      KEYBIND_RESTORE = 'x';
      KEYBIND_REPLENISHMENT = 'x';
      KEYBIND_MAGIC = 'x';
      KEYBIND_RANGE = 'x';
      KEYBIND_OVERLOAD = 'x';
      KEYBIND_RENEWAL = 'x';

      KEYBIND_SHIELD = 'x';
      KEYBIND_PRIMARY = 'x';

      KEYBIND_ANTICIPATION = 'x';
      KEYBIND_FREEDOM = 'x';
      KEYBIND_RESONANCE = 'x';
      KEYBIND_PREPARATION = 'x';
      KEYBIND_DEVOTION = '';
      KEYBIND_IMMORTALITY = 'x';

      USING_SCRIMSHAW = true;

      HEALTH_THRESHOLD_1 = 62;
      HEALTH_THRESHOLD_2 = 43;
      HEALTH_THRESHOLD_3 = 18;
      HEALTH_THRESHOLD_4 = 88;
      HEALTH_THRESHOLD_5 = 70;
      PRAYER_THRESHOLD = 28;

    var
      didThresholdCD, canAttackNex, canAttackCruor, canHandleIcePrison, canCheckDeath, canDPS, prisonWait, canQuickPrayer, canDevotion, canImmortality, canDeathsSwiftness, canRectifyTarget, canDrinkOverload, canEquipNoxiousBow, canDrinkAdrenalinePotion, cancelCheck, canAvoidNex, canCheckSmokeDrag, canAnticipation, canFreedom, canHeal, canAvoidShadowTraps, canBarricade, canDrinkSuperRestore, canTogglePrayer: tCountDown;
      currentPhase, nextAttack: string;
      currentLocal, previousLocal: tPoint;
      didNotHaveAnti, wrath, superWrath, overrideTrapSearch, didDS, hasMinionGlitch, cancelCombat, didDie: boolean;
      healthRegion: tBox = [0, 0, 0, 0];
      pouchPoint: tPoint = [0, 0];
      shadowTraps: glModelArray;
      w, h, i: integer;
      allTextures: glTextureArray;

    label
      switchToBasics;
    label
      beginNewTrip;
    label
      alreadyAtBank;

    procedure ClarityDebug(message: string);
    begin
      writeln('ClarityNex v' + SCRIPT_VERSION + ' || ' + currentPhase + ' || ' + toStr(getTimeRunning) + ' || ' + message);
    end;

    function tActionbar.getAdrenaline(): int32; override;
    var
      receivedString: string;
      sa: tStringArray;
    begin
      receivedString := ogl.getChars(IntToBox(1106, 1012, 1156, 1032)).parseInt().toString();
      result := strToIntDef(receivedString, -1);
    end;

    function tActionBar.getLifePoints():int32; override;
    var
      funcPointer:^glTexture;
      funcPointerSize:uInt32;
      receivedString: string;
      sa: tStringArray;
    begin
      funcPointer:=glTextures(funcPointerSize);
      for 0 to funcPointerSize-1 do
      begin
        if (funcPointer^.id=79816) and (funcPointer^.colourID=15419436) then
        begin
          case funcPointer^.bounds.x1<funcPointer^.bounds.x2 of
            false: begin
                    receivedString := ogl.getChars(IntToBox(412, 1010, 496, 1031)).parseInt().toString();
                    sa := explode(' ', receivedString);
                    result := floor((strToInt(sa[0]) / strToInt(sa[1])) * 100);
                   end;
            true: begin result:=floor(funcPointer^.bounds.width()/103*100); end;
          end;
          break;
        end;
        funcPointer+=oglTextureSize;
      end;
      exit(result);
    end;

    function hasFood(): boolean;
    begin
      result := false;
      if (length(inventory.getItems([97410, 91290], [2366745, 2694424])) > 0) or (length(inventory.getItems([91800, 92055], [3947282, 3947286, 3815705, 3552796, 3158046, 2697502])) > 0) then
        result := true;
    end;

    function hasRocktail(): boolean;
    begin
      result := (length(inventory.getItems([97410, 91290], [2366745, 2694424])) > 0);
    end;

    function hasSaradominBrew(): boolean;
    begin
      result := (length(inventory.getItems([91800, 92055], [3947282, 3947286, 3815705, 3552796, 3158046, 2697502])) > 0);
    end;

    procedure drinkAdrenalinePotion();
    begin
      ClarityDebug('drinkAdrenalinePotion()');
      sendKeys(KEYBIND_REPLENISHMENT, 65 + random(65), 65 + random(65));
      canDrinkAdrenalinePotion.setTime(121000);
    end;

    procedure drinkHolyOverload();
    begin
      ClarityDebug('drinkHolyOverload()');
      sendKeys(KEYBIND_OVERLOAD, 65 + random(65), 65 + random(65));
      wait(random(50, 120));
      sendKeys(KEYBIND_OVERLOAD, 65 + random(65), 65 + random(65));
      wait(random(1000, 1100));
      sendKeys(KEYBIND_RENEWAL, 65 + random(65), 65 + random(65));
      wait(random(50, 120));
      sendKeys(KEYBIND_RENEWAL, 65 + random(65), 65 + random(65));
    end;

    procedure drinkSuperRestore();
    begin
      ClarityDebug('drinkSuperRestore()');
      wait(random(200, 300));
      sendKeys(KEYBIND_RESTORE, 65 + random(65), 65 + random(65));
      canDrinkSuperRestore.setTime(random(1250, 3000));
    end;

    procedure drinkAntipoison();
    begin
      ClarityDebug('drinkAntipoison()');
      inventory.clickItem([91800, 92055], [1645067, 1776654, 1842450, 1776659, 1710612, 1579285]);
    end;

    procedure sendFreedom();
    begin
      ClarityDebug('sendFreedom()');
      sendKeys(KEYBIND_FREEDOM, 65 + random(65), 65 + random(65));
      canFreedom.setTime(29000 + random(600));
      canDPS.setTime(1400 + random(300));
    end;

    procedure unStun();
    begin
      ClarityDebug('handleIcePrison(): we are (or will be) stunned, attempting to freedom.');
      repeat
        wait(random(151, 160));
        if (not combat.hasBuff('stunned')) and (not didNotHaveAnti) then
          break();
      until canFreedom.isFinished();
      if (not combat.hasBuff('stunned')) and (not didNotHaveAnti) then
      begin
        if (not combat.hasBuff('stunned')) then
          exit();
      end;
      sendFreedom();
      repeat
        wait(random(151, 160));
      until (not combat.hasBuff('stunned'));
      didNotHaveAnti := false;
    end;

    procedure equipDarkBow();
    begin
      ClarityDebug('equipDarkBow()');
      if combat.hasBuff('stunned') then
        unStun();
      sendKeys(KEYBIND_SHIELD, 65 + random(65), 65 + random(65));
    end;

    procedure useExcalibur();
    begin
      ClarityDebug('useExcalibur()');
      mouse.rightClickOption(ogl.getTextures([46410], [526344])[0].bounds, 'Activate Augmented enhanced Excalibur');
      wait(random(150, 250));
    end;

    procedure teleportToMaxGuild();
    begin
      ClarityDebug('teleportToMaxGuild()');
      mouse.rightClickOption(ogl.getTextures([139740, 132600], [3349790, 3152668, 3218204, 3020826, 2955289])[0].bounds, 'Max Guild');
    end;

    procedure equipNoxiousBow();
    begin
      ClarityDebug('equipNoxiousBow()');
      sendKeys(KEYBIND_PRIMARY, 65 + random(65), 65 + random(65));
      canEquipNoxiousBow.setTime(random(700, 800));
    end;

    procedure equipSirenic();
    begin
      ClarityDebug('equipSirenic()');
      inventory.clickItem(86190, 526609); {Helm}
      wait(random(200, 350));
      inventory.clickItem(125970, 725534); {Body}
      wait(random(200, 350));
      inventory.clickItem(65790, 329227); {Legs}
      wait(random(200, 350));
      inventory.clickItem(58650, 1117706); {Gloves}
    end;

    procedure equipBandosBoots();
    begin
      ClarityDebug('equipBandosBoots()');
      inventory.clickItem(127500, 2168854);
    end;

    procedure equipPernixBoots();
    begin
      ClarityDebug('equipPernixBoots()');
      inventory.clickItem(62985, 1052688);
    end;

    procedure equipVoid();
    begin
      ClarityDebug('equipVoid()');
      inventory.clickItem(83130, 328965); {Helm}
      wait(random(200, 350));
      inventory.clickItem(112200, 2828329); {Body}
      wait(random(200, 350));
      inventory.clickItem(79050, 1775898); {Legs}
      wait(random(200, 350));
      inventory.clickItem(60435, 197379); {Gloves}
    end;

    procedure toggleScrimshaw();
    begin
      ClarityDebug('toggleScrimshaw()');
      mouse.rightClickOption(ogl.getTextures([84660, 85170], [2697255, 2631462, 2499876])[0].bounds, 'Activate');
    end;

    procedure equipVigour();
    begin
      ClarityDebug('equipVigour()');
      inventory.clickItem([88230], [3091755, 3223597]);
    end;

    procedure equipRingOfDeath();
    begin
      ClarityDebug('equipRingOfDeath()');
      inventory.clickItem([68850], [1577996, 1709581]); //86190, 3023891 ring of death
    end;

    function hasFreedomBuff(): boolean;
    begin
      result := length(ogl.getTextures(137700, 5790556, buffRegion)) > 0;
    end;

    function hasAnticipationBuff(): boolean;
    begin
      result := length(ogl.getTextures(137700, 8153941, buffRegion)) > 0;
    end;

    procedure handleHealing();
    var
      currentPercent: integer;
    begin
      currentPercent := actionbar.getLifePoints();
      if ((currentPhase = 'Ice (Nex)') or (currentPhase = 'Ice (Glacies)')) and (currentPercent < HEALTH_THRESHOLD_5) then
      begin
        ClarityDebug('handleHealing(): healing via brews');
        if (currentPercent < HEALTH_THRESHOLD_2) and (hasRocktail()) then
        begin
          sendKeys(KEYBIND_ROCKTAIL, 65 + random(65), 65 + random(65));
          wait(random(100, 300));
        end;
        sendKeys(KEYBIND_BREW, 65 + random(65), 65 + random(65));
        canHeal.setTime(random(600, 700));
        exit();
      end;
      if (currentPhase = 'Shadow (Umbra)') and (currentPercent < HEALTH_THRESHOLD_4) then
      begin
        ClarityDebug('handleHealing(): healing via rocktail and brews');
        sendKeys(KEYBIND_ROCKTAIL, 65 + random(65), 65 + random(65));
        wait(random(100, 300));
        sendKeys(KEYBIND_BREW, 65 + random(65), 65 + random(65));
        canHeal.setTime(random(600, 700));
        exit();
      end;
      if (currentPercent < HEALTH_THRESHOLD_2) then
      begin
        ClarityDebug('handleHealing(): healing via rocktail and brews');
        if hasRocktail() then
        begin
          sendKeys(KEYBIND_ROCKTAIL, 65 + random(65), 65 + random(65));
          wait(random(100, 300));
        end;
        sendKeys(KEYBIND_BREW, 65 + random(65), 65 + random(65));
        canHeal.setTime(random(600, 700));
        exit();
      end;
      if (currentPercent < HEALTH_THRESHOLD_1) and (currentPercent > HEALTH_THRESHOLD_2) then
      begin
        ClarityDebug('handleHealing(): healing via brews');
        sendKeys(KEYBIND_BREW, 65 + random(65), 65 + random(65));
        canHeal.setTime(random(600, 700));
      end;
      canHeal.setTime(random(600, 700));
    end;

    procedure sendAnticipation();
    begin
      ClarityDebug('sendAnticipation()');
      sendKeys(KEYBIND_ANTICIPATION, 65 + random(65), 65 + random(65));
      canAnticipation.setTime(23000 + random(600));
      canDPS.setTime(1400 + random(300));
    end;

    procedure sendDevotion();
    begin
      ClarityDebug('sendDevotion()');
      sendKeys(KEYBIND_DEVOTION, 65 + random(65), 65 + random(65));
      canDevotion.setTime(59000 + random(600));
      canDPS.setTime(1400 + random(300));
    end;

    procedure sendDeathsSwiftness();
    begin
      equipVigour();
      wait(random(50, 150));
      actionbar.sendAbility('deathsswiftness');
      wait(random(1800, 2400));
      canDeathsSwiftness.setTime(60000);
      equipRingOfDeath();
      wait(random(400, 500));
      didDS := true;
      if canDrinkAdrenalinePotion.isFinished() then
        drinkAdrenalinePotion();
    end;

    function getNexLifePoints(): integer;
    begin
      result := strToIntDef(replace(ogl.getChars(healthRegion).parseInt().toString(), ' ', '', [rfReplaceAll]), 666666);
    end;

    procedure bankingMaxGuild();
    label
      bankAgain;
    var
      attempts: integer;
      timeoutCD: tCountDown;
    begin
      ClarityDebug('bankingMaxGuild()');
      attempts := 0;
      minimap.clickResetCamera();
      keyDown(VK_UP);
      wait(random(1200, 1800));
      keyUp(VK_UP);
      wait(random(400, 700));
      bankAgain:
      while (attempts <= 3) do
      begin
        timeoutCD.setTime(10000);
        interactObject(MODEL_BANKER_MAX, ['Bank Banker'], clientCenter, 5000, 0, -7);
        repeat
          wait(random(400, 600));
        until bank.hasBank() or timeoutCD.isFinished();
        if bank.hasBank() then
          break()
        else
        begin
          ClarityDebug('bankingMaxGuild(): failed to open bank, retrying.');
          inc(attempts);
          continue();
        end;
      end;
      if (attempts > 3) then
      begin
        ClarityDebug('bankingMaxGuild(): total failure, terminating.');
        terminateScript();
      end;
      timeoutCD.setTime(10000);
      if (didDie = true) then
      begin
        mouse.click(pouchPoint.randomizePointEllipse(18));
        repeat
          typeByte(VK_ESCAPE);
          wait(random(650, 750));
        until (not bank.hasBank());
        wait(random(300, 500));
        inventory.clickItem(133365, 3355444);
        wait(random(650, 750));
        didDie := false;
        goto bankAgain;
      end;
      repeat
        if random(3) then
          sendKeys('1', 65 + random(65), 65 + random(65))
        else
          bank.clickPreset(1);
        wait(random(1800, 2400));
      until (not bank.hasBank()) or timeoutCD.isFinished();
      if timeoutCD.isFinished() or (inventory.getItemCount() <> 2) then
      begin
        wait(random(5000, 8000));
        if (inventory.getItemCount() <> 2) then
        begin
          ClarityDebug('bankingMaxGuild(): failed to withdraw travel preset, terminating.');
          terminateScript();
        end;
      end;
      ClarityDebug('bankingMaxGuild(): successfully withdrew travel preset.');
    end;

    procedure enterNexPortal();
    var
      attempts: integer;
      timeoutCD: tCountDown;
      iconTextures: glTextureArray;
      clickPoint: tPoint;
    begin
      ClarityDebug('enterNexPortal()');
      attempts := 0;
      iconTextures := ogl.getTextures(51673, 4605773);
      if (length(iconTextures) = 3) then
      begin
        clickPoint := iconTextures[2].toPoint().randomizePointEllipse(12);
        mouse.click(clickPoint);
      end else
      begin
        ClarityDebug('enterNexPortal(): failed to find the transport minimap symbol.');
        terminateScript();
      end;
      waitFlag(15000);
      if (actionbar.getPrayerPoints() < 80) then
      begin
        interactObject(MODEL_THRONE, ['Admire']);
        waitFlag(5000);
        wait(random(1200, 1800));
      end;
      while (attempts <= 3) do
      begin
        timeoutCD.setTime(10000);
        interactObject(MODEL_PORTAL, ['Enter Nex portal'], clientCenter, 5000, 0, -7, 12, 12);
        repeat
          wait(random(400, 600));
        until (length(ogl.getModels(MODEL_HOLE)) > 0) or timeoutCD.isFinished();
        if (length(ogl.getModels(MODEL_HOLE)) > 0) then
          break()
        else
        begin
          ClarityDebug('enterNexPortal(): portal navigation failed, retrying.');
          inc(attempts);
          continue();
        end;
      end;
      if (attempts > 3) then
      begin
        ClarityDebug('enterNexPortal(): total failure, terminating.');
        terminateScript();
      end;
      ClarityDebug('enterNexPortal(): successfully arrived at the Zaros encampment');
    end;

    procedure travelToLobby();
    var
      attempts: integer;
      timeoutCD: tCountDown;
    begin
      ClarityDebug('travelToLobby()');
      attempts := 0;
      while (attempts <= 3) do
      begin
        timeoutCD.setTime(10000);
        interactObject(MODEL_HOLE, ['Squeeze-through Frozen Doorway'], clientCenter, 5000, 0, -7);
        repeat
          wait(random(400, 600));
        until (minimap.getLocalPosition().equals(point(68, 65))) or timeoutCD.isFinished();
        if (minimap.getLocalPosition().equals(point(68, 65))) then
          break()
        else
        begin
          ClarityDebug('travelToLair(): failed to squeeze through frozen doorway.');
          inc(attempts);
          continue();
        end;
      end;
      if (attempts > 3) then
      begin
        ClarityDebug('travelToLobby(): total failure, terminating.');
        terminateScript();
      end;
      wait(random(1200, 1400));
      ClarityDebug('travelToLobby(): navigating to the Zaros lobby.');
      walkToPoint(point(99, 81), 7, 7);
      drinkAntipoison();
      wait(random(400, 800));
      attempts := 0;
      while (attempts <= 3) do
      begin
        timeoutCD.setTime(10000);
        interactObject(MODEL_DOOR, ['Open Big door'], clientCenter, 5000, 0, -9);
        repeat
          wait(random(400, 600));
        until (minimap.getLocalPosition().equals(point(65, 65))) or timeoutCD.isFinished();
        if (minimap.getLocalPosition().equals(point(65, 65))) then
          break()
        else
        begin
          ClarityDebug('travelToLobby(): failed to enter Zaros door, retrying.');
          inc(attempts);
          continue();
        end;
      end;
      if (attempts > 3) then
      begin
        ClarityDebug('travelToLobby(): total failure, terminating.');
        terminateScript();
      end;
    end;

    procedure bankingNexLobby();
    var
      attempts: integer;
      timeoutCD: tCountDown;
    begin
      ClarityDebug('bankingNexLobby()');
      attempts := 0;
      while (attempts <= 3) do
      begin
        timeoutCD.setTime(10000);
        interactObject(MODEL_BANKER_NEX, ['Bank Ashuelot Reis'], clientCenter, 5000, 0, -7);
        repeat
          wait(random(400, 600));
        until bank.hasBank() or timeoutCD.isFinished();
        if bank.hasBank() then
          break()
        else
        begin
          ClarityDebug('bankingNexLobby(): failed to open bank, retrying.');
          inc(attempts);
          continue();
        end;
      end;
      if (attempts > 3) then
      begin
        ClarityDebug('bankingNexLobby(): total failure, terminating.');
        terminateScript();
      end;
      timeoutCD.setTime(10000);
      repeat
        if random(3) then
          sendKeys('2', 65 + random(65), 65 + random(65))
        else
          bank.clickPreset(2);
        wait(random(1800, 2400));
      until (not bank.hasBank()) or timeoutCD.isFinished();
      if timeoutCD.isFinished() or (inventory.getItemCount() <> 28) then
      begin
        wait(random(5000, 8000));
        if (inventory.getItemCount() <> 28) then
        begin
          ClarityDebug('bankingNexLobby(): failed to withdraw combat preset, terminating.');
          terminateScript();
        end;
      end;
      ClarityDebug('bankingNexLobby(): successfully withdrew combat preset.');
    end;

    procedure enterInstance();
    label
      retry;
    label
      actual;
    var
      attempts: integer;
      timeoutCD: tCountDown;
      needRestart, enterActual: boolean;
      charString: string;
    begin
      ClarityDebug('enterInstance()');
      attempts := 0;
      needRestart := false;
      enterActual := false;
      wait(random(900, 1200));
      if USING_SCRIMSHAW then
      begin
        repeat
          try
            toggleScrimshaw();
          except ClarityDebug('enterInstance(): scrimshaw error'); end;
          wait(random(750, 850));
        until combat.hasBuff('scrimshaw');
      end;
      mainscreen.setHorizontalDirection('east');
      wait(random(100, 300));
      retry:
      while (attempts <= 3) do
      begin
        timeoutCD.setTime(10000);
        interactObject(MODEL_WARD, ['Banish ward Prison Barrier'], clientCenter, 5000, 0, -36);
        repeat
          wait(random(200, 400));
        until dialogue.hasDialogue() or timeoutCD.isFinished();
        if dialogue.hasDialogue() then
          break()
        else
        begin
          ClarityDebug('enterInstance(): failed to click prison barrier, retrying.');
          inc(attempts);
          continue();
        end;
      end;
      if (attempts > 3) then
      begin
        ClarityDebug('enterInstance(): total failure, terminating.');
        terminateScript();
      end;
      wait(random(250, 750));
      if enterActual then
        goto actual;
      while dialogue.hasDialogue() do
      begin
        ClarityDebug('enterInstance(): found dialogue options ' + toStr(dialogue.getOptions()));
        sendKeys('2', 60 + random(60), 60 + random(60));
        wait(random(500, 1500));
      end;
      repeat
        wait(random(500, 1500));
      until length(ogl.getTextures(419275));
      wait(random(300, 600));
      actual:
      if needRestart then
        mouse.click('Start', false)
      else if (not enterActual) then
        mouse.click('Rejoin', false)
      else
      begin
        sendKeys(' ', 65 + random(65), 65 + random(65));
        repeat
          wait(random(50, 150));
        until (pos('you wish to jump down', ogl.getChars().toString()) > 0);
        sendKeys('1', 65 + random(65), 65 + random(65));
        exit();
      end;
      timeoutCD.setTime(7000);
      repeat
        wait(random(300, 800));
        charString := ogl.getChars().toString();
        if (pos('have a battle to rejoin', charString) > 0) or (pos('valid session could be found', charString) > 0) then
        begin
          needRestart := true;
          ClarityDebug('enterInstance(): we must create a new instance.');
          goto retry;
        end;
      until (pos('Welcome to your session', charString) > 0) or timeoutCD.isFinished();
      if timeoutCD.isFinished() then
      begin
        ClarityDebug('enterInstance(): total failure, terminating.');
        terminateScript();
      end;
      wait(random(200, 400));
      enterActual := true;
      needRestart := false;
      goto retry;
    end;

    function isMinionPhase(): boolean;
    begin
      result := false;
      case currentPhase of
      'Smoke (Fumus)': result := true;
      'Shadow (Umbra)': result := true;
      'Blood (Cruor)': result := true;
      'Ice (Glacies)': result := true;
      end;
    end;

    procedure preFightRoutine();
    var
      timeoutCD: tCountDown;
      workingID: integer;
    begin
      ClarityDebug('preFightRoutine()');
      timeoutCD.setTime(15000);
      repeat
        wait(random(400, 600));
      until (minimap.getLocalPosition().equals(point(52, 65))) or timeoutCD.isFinished();
      if timeoutCD.isFinished() then
      begin
        ClarityDebug('preFightRoutine(): total failure, terminating.');
        terminateScript();
      end;
      wait(random(600, 1200));
      equipDarkBow();
      wait(random(600, 1200));
      drinkAdrenalinePotion();
      wait(random(1000, 1100));
      drinkHolyOverload();
      wait(random(200, 400));
      mainscreenWalk(point(584 + random(-50, 50), 497 + random(-50, 50)), false);
      waitFlag(2000);
      repeat
        ClarityDebug('preFightRoutine(): finding Fumus.');
        wait(random(100, 400));
      until length(ogl.getModels(MODEL_FUMUS).getVisible()) > 0;
      wait(random(200, 400));
      interactObject(MODEL_FUMUS);
      waitFlag(5000);
      wait(random(200, 400));
      actionbar.sendAbility('escape');
      wait(1200 + random(300));
      {sendKeys(KEYBIND_FREEDOM, 65 + random(65), 65 + random(65));
      canFreedom.setTime(29000 + random(500));
      wait(1200 + random(300));
      sendKeys(KEYBIND_ANTICIPATION, 65 + random(65), 65 + random(65));
      canAnticipation.setTime(23000 + random(500));}

      wait(1200 + random(300));
      sendKeys(KEYBIND_RESONANCE, 65 + random(65), 65 + random(65));
      wait(1200 + random(300));
      sendKeys(KEYBIND_PREPARATION , 65 + random(65), 65 + random(65));
      wait(1200 + random(300));
      actionbar.setQuickPrayer(true);
      wait(random(450, 700));
      equipNoxiousBow();
      wait(random(650, 700));
      equipNoxiousBow();
      wait(random(450, 700));
      repeat
        interactObject(MODEL_NEX);
        wait(random(600, 1200));
      until (combat.getTargetName() = 'Nex');
      actionbar.sendAbility('fragmentationshot');
      wait(600 + random(500));
      walkToPoint(point(56, 55), 12, 12);
      waitFlag(3000);
      interactObject(MODEL_NEX);
    end;

    procedure checkDeath();
    label
      alreadyReclaimed;
    var
      dragPoint: tPoint;
      already: boolean;
    begin
      if (not isStrInArr('Oh dear, you are dead!', true, chat.getChat())) then
      begin
        canCheckDeath.setTime(15000);
        exit();
      end;
      ClarityDebug('checkDeath(): we died, reclaiming items.');
      wait(random(1200, 1800));
      interactObject(MODEL_DEATH, ['Reclaim items']);
      repeat
        wait(random(600, 700));
      until (pos('You save these items for free!', ogl.getChars().toString()) > 0) or (already := (pos('You have nothing to reclaim', ogl.getChars().toString()) > 0));
      if already then
        goto alreadyReclaimed;
      ClarityDebug('checkDeath(): reshuffling protected items.');
      dragPoint := ogl.getTextures(68850, 1841168).closestTo(clientCenter)[0].toPoint().randomizePointEllipse(16);
      moveMouse(dragPoint.X, dragPoint.Y);
      wait(random(200, 400));
      holdMouse(dragPoint.X, dragPoint.Y, 1);
      dragPoint := point(594, 325).randomizePointEllipse(16);
      wait(random(700, 900));
      moveMouse(dragPoint.X, dragPoint.Y);
      wait(random(300, 400));
      releaseMouse(dragPoint.X, dragPoint.Y, 1);
      wait(random(600, 800));
      mouse.click('Confirm');
      repeat
        wait(random(600, 700));
      until (pos('Are you sure you', ogl.getChars().toString()) > 0);
      mouse.click('Yes');
      repeat
        wait(random(600, 700));
      until (pos('Are you sure you', ogl.getChars().toString()) = 0);
      terminateScript();
      alreadyReclaimed:
      teleportToMaxGuild();
      didDie := true;
      goto beginNewTrip;
    end;

    procedure basicDPS();
    var
      tickDelay: integer;
    begin
      {switchToBasics:
      ClarityDebug('basicDPS()');
      tickDelay := 1200;
      ogl.setCacheTime(500);
      ogl.setColourTolerance(0);
      if (lastAbility <> 'dazingshot') and (not actionbar.isAbilityOnCoolDown('dazingshot')) and (not actionbar.isAbilityQueued('dazingshot')) then
        actionbar.sendAbility('dazingshot')
      else if (lastAbility <> 'corruptionshot') and (not actionbar.isAbilityOnCoolDown('corruptionshot')) and (not actionbar.isAbilityQueued('corruptionshot'))  then
        actionbar.sendAbility('corruptionshot')
      else if (not isMinionPhase) and (lastAbility <> 'snipe') and (not actionbar.isAbilityOnCoolDown('snipe')) and (not actionbar.isAbilityQueued('snipe')) then
      begin
        actionbar.sendAbility('snipe');
        tickDelay := 1800;
      end
      else if (lastAbility <> 'fragmentationshot') and (not actionbar.isAbilityOnCoolDown('fragmentationshot')) and (not actionbar.isAbilityQueued('fragmentationshot'))  then
        actionbar.sendAbility('fragmentationshot')
      else if (lastAbility <> 'ricochet') and (not actionbar.isAbilityOnCoolDown('ricochet')) and (not actionbar.isAbilityQueued('ricochet'))  then
        actionbar.sendAbility('ricochet')
      else if (lastAbility <> 'bindingshot') and (not actionbar.isAbilityOnCoolDown('bindingshot')) and (not actionbar.isAbilityQueued('bindingshot'))  then
        actionbar.sendAbility('bindingshot');
      ogl.setCacheTime(150);
      ogl.setColourTolerance(4);
      canDPS.setTime(tickDelay + random(375, 425));}

    end;

    procedure thresholdDPS();
    var
      tickDelay: integer;
      didThreshold: boolean;
    begin
      if combat.hasBuff('snipe') then
        exit();
      ClarityDebug('thresholdDPS()');
      didThreshold := false;
      tickDelay := 1200;
      if (not actionbar.isAbilityOnCoolDown('rapidfire')) and (not actionbar.isAbilityQueued('rapidfire')) then
      begin
        actionbar.sendAbility('rapidfire');
        tickDelay := 4800;
        didThreshold := true;
      end
      else if (not actionbar.isAbilityOnCoolDown('snapshot')) and (not actionbar.isAbilityQueued('snapshot')) then
      begin
        actionbar.sendAbility('snapshot');
        didThreshold := true;
      end
      else if (currentPhase = 'Blood (Nex)') and (not actionbar.isAbilityOnCoolDown('shadowtendrils')) and (not actionbar.isAbilityQueued('shadowtendrils')) and (actionbar.getLifePoints() >= 65) then
      begin
        actionbar.sendAbility('shadowtendrils');
        didThreshold := true;
      end
      else if (not isMinionPhase) and (not actionbar.isAbilityOnCoolDown('bombardment')) and (not actionbar.isAbilityQueued('bombardment')) then
      begin
        actionbar.sendAbility('bombardment');
        didThreshold := true;
      end;
      {if (not didThreshold) then
        goto switchToBasics;}

      if didThreshold then
        didThresholdCD.setTime(2600);
      canDPS.setTime(tickDelay + random(375, 425));
    end;

    procedure avoidNex();
    var
      player, rocks, nex: glModelArray;
      bestRock: glModel;
      i, wrathMod, wrathMod2, wrathMod3, wrathMod4: integer;
      nexDistance: extended;
    begin
      if (wrath = true) then
      begin
        wrathMod := 200;
        wrathMod2 := 3;
        wrathMod3 := 350;
      end else
      begin
        wrathMod := 0;
        wrathMod2 := 0;
        wrathMod3 := 0;
      end;
      if (superWrath = true) then
        wrathMod4 := 200
      else
        wrathMod4 := 0;
      player := ogl.getModels(MODEL_PLAYER).closestTo(clientCenter);
      nex := ogl.getModels(MODEL_NEX).closestTo(clientCenter);
      if (length(nex) = 0) or (length(player) = 0) then
      begin
        ClarityDebug('avoidNex(): nex:' + toStr(length(nex)));
        ClarityDebug('avoidNex(): player:' + toStr(length(player)));
        ClarityDebug('avoidNex(): WARNING - model array length of 0');
        exit();
      end;
      nexDistance := player[0].toPoint().distanceFrom(nex[0].toPoint());
      if (nexDistance < 140) or (wrath = true) or (cancelCombat = true) then
      begin
        ClarityDebug('avoidNex(): we are too close to Nex, walking away');
        rocks := ogl.getModels([24295686, 3419315035, 206421581, 1169179175, 3937330774, 861052434]).closestTo(clientCenter);
        for i := 0 to high(rocks) do
        begin
          if (pointInBox(rocks[i].toPoint(), IntToBox(1, 1, w - 1, h - 1))) and (rocks[i].toPoint().distanceFrom(nex[0].toPoint()) > (170 + wrathMod)) and (rocks[i].toPoint().distanceFrom(player[0].toPoint()) < (330 + wrathMod + wrathMod4)) and (rocks[i].toPoint().Y > (0 + wrathMod3)) then
          begin
            bestRock := rocks[i];
            break();
          end;
        end;
        mainscreenWalkMulti(bestRock.toPoint(), 36, wrathMod2);
        waitFlag(2500);
        wait(random(100, 200));
        case currentPhase of
          'Smoke (Nex)': interactObject(MODEL_NEX);
          'Smoke (Fumus)':interactObject(MODEL_FUMUS);
          'Shadow (Nex)': interactObject(MODEL_NEX);
          'Shadow (Umbra)': interactObject(MODEL_UMBRA);
          'Blood (Nex)': begin end;
          'Blood (Cruor)': interactObject(MODEL_CRUOR, [], clientCenter, 2000);
          'Ice (Nex)': interactObject(MODEL_NEX);
          'Ice (Glacies)': interactObject(MODEL_GLACIES, [], clientCenter, 2000);
        end;
        canAvoidNex.setTime(random(3000, 4000));
      end;
      canAvoidNex.setTime(random(3000, 4000));
    end;

    procedure avoidShadowTraps();
    var
      player, shadow, rocks, nex: glModelArray;
      bestRock: glModel;
      i: integer;
      trapDistance: extended;
    begin
      ogl.setCacheTime(0);
      player := ogl.getModels(MODEL_PLAYER).closestTo(clientCenter);
      nex := ogl.getModels(MODEL_NEX).closestTo(clientCenter);
      shadow := shadowTraps.closestTo(clientCenter);
      ogl.setCacheTime(150);
      ClarityDebug('avoidShadowTraps(): found a shadow trap');
      if (length(nex) = 0) or (length(player) = 0) or (length(shadow) = 0) then
      begin
        ClarityDebug('avoidShadowTrap(): nex:' + toStr(length(nex)));
        ClarityDebug('avoidShadowTrap(): player:' + toStr(length(player)));
        ClarityDebug('avoidShadowTrap(): shadow:' + toStr(length(shadow)));
        ClarityDebug('avoidShadowTrap(): WARNING - model array length of 0');
        exit();
      end;
      trapDistance := player[0].toPoint().distanceFrom(shadow[0].toPoint());
      if (trapDistance < 40) or (trapDistance > 500) then
      begin
        ClarityDebug('avoidShadowTraps(): walking to a nearby safe area');
        rocks := ogl.getModels([24295686, 3419315035, 206421581, 1169179175, 3937330774, 861052434]).closestTo(clientCenter);
        for i := 0 to high(rocks) do
        begin
          if (rocks[i].toPoint().distanceFrom(shadow[0].toPoint()) > 40) and (rocks[i].toPoint().distanceFrom(nex[0].toPoint()) > 120) and (pointInBox(rocks[i].toPoint(), mainscreenRegion)) then
          begin
            bestRock := rocks[i];
            break();
          end;
        end;
        //mouse.rightClickOption(bestRock.toPoint().randomizePointEllipse(36), ['Walk here']);
        mainscreenWalkMulti(bestRock.toPoint(), 52);
        wait(random(250, 500));
        if (currentPhase = 'Shadow (Nex)') then
          interactObject(MODEL_NEX)
        else
          interactObject(MODEL_UMBRA);
        canAvoidShadowTraps.setTime(random(4000, 6000));
      end else
        ClarityDebug('avoidShadowTraps(): we are safe from the currently deployed trap');
    end;

    procedure correctLocalPosition();
    var
      currentPosition: tPoint;
    begin
      currentPosition := minimap.getLocalPosition();
      if ((currentPosition.X >= 58) and (currentPosition.Y >= 57)) or (currentPosition.X >= 61) then
      begin
        ClarityDebug('correctLocalPosition(): activated');
        walkToPoint(point(55, 54), 12, 12);
        waitFlag(1200);
        wait(random(150, 250));
        if (currentPhase = 'Smoke (Nex)') then
          interactObject(MODEL_NEX)
        else
          interactObject(MODEL_FUMUS, [], clientCenter, 1200);
      end;
    end;

    function specialChatsPresent(): boolean;
    var
      charString: string;
    begin
      result := false;
      hasMinionGlitch := false;
      charString := ogl.getChars().toString();
      if (pos('There is', charString) > 0) or (pos('NO ESCAPE', charString) > 0) then
      begin
        result := true;
        ClarityDebug('specialChatsPresent(): true');
      end;
      if pos('This minion is still drawing power from Nex.', charString) then
        hasMinionGlitch := true;
    end;

    procedure toggleDeflectMagic();
    begin
      ClarityDebug('toggleDeflectMagic(): activated');
      sendKeys(KEYBIND_MAGIC, 65 + random(65), 65 + random(65));
      canTogglePrayer.setTime(random(800, 1200));
    end;

    procedure checkSmokeDrag();
    begin
      ClarityDebug('checkSmokeDrag(): Nex dragged us in.');
      if canFreedom.isFinished() then
        sendFreedom()
      else
      begin
        repeat
          wait(random(500, 700));
        until (not combat.hasBuff('stunned'));
      end;
      if (actionbar.getLifePoints < 50) then
        sendKeys(KEYBIND_ROCKTAIL, 65 + random(65), 65 + random(65));
      wait(random(250, 500));
      if (actionbar.getLifePoints < 70) then
        sendKeys(KEYBIND_BREW, 65 + random(65), 65 + random(65));
      wait(random(250, 500));
      toggleDeflectMagic();
      walkToPoint(point(55, 54), 12, 12);
      wait(random(150, 250));
      cancelCheck.setTime(8000);
      if (currentPhase = 'Smoke (Nex)') then
        interactObject(MODEL_NEX);
      if (currentPhase = 'Smoke (Fumus)') then
        interactObject(MODEL_FUMUS, [], clientCenter, 2000);
      if (currentPhase = 'Shadow (Nex)') then
        interactObject(MODEL_NEX);
      canCheckSmokeDrag.setTime(random(3000, 5000));
      canAnticipation.setTime(canAnticipation.timeRemaining() + 4000);
      canFreedom.setTime(canFreedom.timeRemaining() + 4000);
    end;

    procedure walkToGlacies(walkPoint: tPoint; randomX, randomY: integer = 5);
    var
      randomizedPoint: TPoint;
    begin
      ClarityDebug('walkToGlacies(): ' + toStr(walkPoint));
      randomizedPoint := minimap.getScreenPosition(walkPoint);
      mouse.click(point(randomizedPoint.X + random(-randomX, randomX), randomizedPoint.Y + random(-randomY, randomY)));
    end;

    procedure handleIcePrison();
    label
      potted;
    label
      potted2;
    label
      caded;
    label
      mustResonance;
    var
      previousHP, currentAdrenaline: integer;
      didImmortality, onlyNeedBasic, fixedGlacies: boolean;
      iTimer, healTimer: tCountDown;
    begin
      didImmortality := false;
      onlyNeedBasic := false;
      fixedGlacies := false;
      ClarityDebug('handleIcePrison(): activated.');
      if (not hasAnticipationBuff()) then
      begin
        ClarityDebug('Anticipation buff was not active, we will be stunned.');
        didNotHaveAnti := true;
        unStun();
      end;
      if combat.hasBuff('stunned') then
        unStun();
      equipDarkBow();
      if combat.hasBuff('stunned') then
        unStun();
      if (not didThresholdCD.isFinished()) then
        goto mustResonance;
      if canBarricade.isFinished() then
      begin
        currentAdrenaline := actionbar.getAdrenaline();
        ClarityDebug('handleIcePrison(): current adrenaline: ' + toStr(currentAdrenaline));
        if ((canDrinkAdrenalinePotion.isFinished() and (currentAdrenaline >= 75)) or (onlyNeedBasic := (currentAdrenaline >= 92))) and (currentAdrenaline < 100) then
        begin
          if onlyNeedBasic then
          begin
            wait(random(650, 700));
            if combat.hasBuff('stunned') then
              unStun();
            ClarityDebug('handleIcePrison(): sending basic ability to reach 100% adrenaline.');
            sendKeys(KEYBIND_PREPARATION, 65 + random(65), 65 + random(65));
            wait(random(250, 300));
            goto potted;
          end;
          wait(random(650, 700));
          if combat.hasBuff('stunned') then
            unStun();
          drinkAdrenalinePotion();
          goto potted;
        end;
        if (actionbar.getAdrenaline() >= 100) then
        begin
          potted:
          if combat.hasBuff('stunned') then
            unStun();
          wait(random(650, 700));
          if combat.hasBuff('stunned') then
            unStun();
          actionbar.sendAbility('barricade');
          canBarricade.setTime(60600);
          canEquipNoxiousBow.setTime(9000);
          canAvoidNex.setTime(8000);
          nextAttack := 'contain';
          goto caded;
        end;
      end else if canImmortality.isFinished() then
      begin
        currentAdrenaline := actionbar.getAdrenaline();
        ClarityDebug('handleIcePrison(): current adrenaline: ' + toStr(currentAdrenaline));
        if ((canDrinkAdrenalinePotion.isFinished() and (currentAdrenaline >= 75)) or (onlyNeedBasic := (currentAdrenaline >= 92))) and (currentAdrenaline < 100) then
        begin
          if onlyNeedBasic then
          begin
            wait(random(650, 700));
            if combat.hasBuff('stunned') then
              unStun();
            ClarityDebug('handleIcePrison(): sending basic ability to reach 100% adrenaline.');
            sendKeys(KEYBIND_PREPARATION, 65 + random(65), 65 + random(65));
            wait(random(250, 300));
            goto potted2;
          end;
          wait(random(650, 700));
          if combat.hasBuff('stunned') then
            unStun();
          drinkAdrenalinePotion();
          goto potted2;
        end;
        if (actionbar.getAdrenaline() >= 100) then
        begin
          potted2:
          if combat.hasBuff('stunned') then
            unStun();
          wait(random(650, 700));
          if combat.hasBuff('stunned') then
            unStun();
          actionbar.sendAbility('immortality');
          iTimer.setTime(28000);
          canImmortality.setTime(120600);
          canEquipNoxiousBow.setTime(9000);
          canAvoidNex.setTime(8000);
          nextAttack := 'contain';
          didImmortality := true;
          goto caded;
        end;
      end;
      mustResonance:
      healTimer.setTime(6000);
      if (actionbar.getLifePoints() < 83) then
      begin
        repeat
          if combat.hasBuff('stunned') then
            unStun();
          if hasRocktail() then
          begin
            sendKeys(KEYBIND_ROCKTAIL, 65 + random(65), 65 + random(65));
            wait(random(150, 250));
          end;
          sendKeys(KEYBIND_BREW, 65 + random(65), 65 + random(65));
          wait(random(150, 250));
        until (actionbar.getLifePoints() >= 96) or healTimer.isFinished();
        if healTimer.isFinished() then
          exit();
      end;
      wait(random(75, 150));
      ClarityDebug('sendAbility(): resonance');
      if combat.hasBuff('stunned') then
        unStun();
      sendKeys(KEYBIND_RESONANCE, 65 + random(65), 65 + random(65));
      canTogglePrayer.setTime(4000);
      nextAttack := 'contain';
      canEquipNoxiousBow.setTime(4000);
      canAvoidNex.setTime(3000);
      caded:
      wait(random(200, 400));
      if (currentPhase = 'Ice (Nex)') then
        interactObject(MODEL_NEX)
      else if (currentPhase = 'Ice (Glacies)') then
        interactObject(MODEL_GLACIES, [], clientCenter, 2000);
      if didImmortality then
      begin
        repeat
          wait(random(50, 150));
          if (currentPhase = 'Ice (Nex)') and (getNexLifePoints() <= 40000) and (not fixedGlacies) then
          begin
            repeat
              walkToGlacies(point(56, 75), 12, 12);
            until (length(ogl.getModels(MODEL_GLACIES).getVisible()) > 0);
            wait(random(100, 200));
            interactObject(MODEL_GLACIES, [], clientCenter, 2000);
            fixedGlacies := true;
          end;
        until (pos('gain a second wind', ogl.getChars().toString()) > 0) or iTimer.isFinished();
      end;
      canHandleIcePrison.setTime(3000);
    end;

    function isNexSouth(): boolean;
    var
      nex: glModelArray;
    begin
      result := false;
      nex := ogl.getModels(MODEL_NEX).closestTo(clientCenter);
      if (length(nex) = 0) then
        exit(false);
      if ((nex[0].Y - clientCenter.Y) > 30) then
        exit(true);
    end;

    procedure handleContainThis();
    begin
      ClarityDebug('handleContainThis(): activated.');
      wrath := true;
      avoidNex();
      wrath := false;
      waitFlag(2000);
      canAnticipation.setTime(canAnticipation.timeRemaining() + 2800);
      prisonWait.setTime(6000);
      nextAttack := 'prison';
    end;

    procedure walkToCruor(walkPoint: tPoint; randomX, randomY: integer = 5);
    var
      randomizedPoint: TPoint;
    begin
      ClarityDebug('walkToCruor(): ' + toStr(walkPoint));
      randomizedPoint := minimap.getScreenPosition(walkPoint);
      mouse.click(point(randomizedPoint.X + random(-randomX, randomX), randomizedPoint.Y + random(-randomY, randomY)));
      waitFlag(random(100, 1000));
    end;

    procedure lootItems();
    label
      retry;
    label
      alreadyInBox;
    var
      bones: glModelArray;
      lootAll: glTextureArray;
      previousCount: integer;
      lootTimer: tCountDown;
    begin
      retry:
      previousCount := inventory.getItemCount();
      lootTimer.setTime(30000);
      bones := ogl.getModels([189892155]).closestTo(clientCenter);
      if (length(bones.getVisible()) > 0) then
      begin
        if pointInBox(bones[0].toPoint(), mainscreenRegion) then
          goto alreadyInBox;
      end;
      repeat
        bones := ogl.getModels([189892155]).closestTo(clientCenter);
        mainScreen.setDegrees(normalRandom(0,360),random(45, 51));
        bones := ogl.getModels([189892155]).closestTo(clientCenter);
        wait(random(400, 700));
      until (length(bones.getVisible()) > 0) or lootTimer.isFinished();
      if lootTimer.isFinished() then
        exit();
      bones := ogl.getModels([189892155]).closestTo(clientCenter);
      if (not pointInBox(bones[0].toPoint(), mainscreenRegion)) then
      begin
        goto retry;
      end;
      alreadyInBox:
      bones := ogl.getModels([189892155]).closestTo(clientCenter);
      while (not mouse.rightClickOption(bones[0].randomizePointEllipse(12), ['Take', 'Super', 'Saradomin'])) do
        wait(random(400, 800));
      waitFlag(8000);
      repeat
        wait(200);
        lootAll := ogl.getTextures(91275);
      until (length(lootAll) > 0);
      repeat
        wait(random(100, 300));
        sendKeys(' ', 65 + random(65), 65 + random(65));
        wait(random(600, 1200));
      until (inventory.getItemCount <> previousCount);
    end;

    procedure bossFight();
    label
      skipBloodDPS;
    label
      fumusGlitch;
    label
      umbraGlitch;
    var
      hasChats, didEscape, didSwitch, didCompensate, firstSiphon: boolean;
      charString: string;
      siphonTimer: tCountDown;
      cPos: tPoint;
    begin
      ClarityDebug('bossFight(): initiated.');
      {SMOKE PHASE}
      currentPhase := 'Smoke (Nex)';
      nextAttack := '';
      didDS := false;
      didDie := false;
      didSwitch := false;
      didCompensate := false;
      superWrath := false;
      didNotHaveAnti := false;
      repeat
        if canCheckDeath.isFinished() then
          checkDeath();
        hasChats := specialChatsPresent();
        correctLocalPosition();
        if canCheckSmokeDrag.isFinished() and combat.hasBuff('stunned') then
          checkSmokeDrag();
        if canAvoidNex.isFinished() then
          avoidNex()
        else if (not combat.hasBuff('deflectmagic')) and canTogglePrayer.isFinished() then
          toggleDeflectMagic()
        else if canFreedom.isFinished() and canDPS.isFinished() and (not hasAnticipationBuff()) and (not hasChats) then
          sendFreedom()
        else if canAnticipation.isFinished() and canDPS.isFinished() and (not hasFreedomBuff()) and (not hasChats) then
          sendAnticipation()
        else if canHeal.isFinished() and (actionbar.getLifePoints() < HEALTH_THRESHOLD_1) then
          handleHealing()
        else if canDrinkSuperRestore.isFinished() and (actionbar.getPrayerPoints() < PRAYER_THRESHOLD) then
          drinkSuperRestore()
        else if canDevotion.isFinished() and (actionbar.getAdrenaline() >= 50) and canDPS.isFinished() and (not hasChats) then
          sendDevotion()
        else if (actionbar.getAdrenaline() >= 50) and (canDPS.isFinished()) and (not hasChats) and (getNexLifePoints() >= 163500) then
          thresholdDPS();
      until (getNexLifePoints() <= 160000);
      fumusGlitch:
      currentPhase := 'Smoke (Fumus)';
      wait(random(150, 350));
      if canCheckSmokeDrag.isFinished() and combat.hasBuff('stunned') then
        checkSmokeDrag();
      walkToPoint(point(54, 54), 12, 12);
      waitFlag(5000);
      wait(random(200, 600));
      if canCheckSmokeDrag.isFinished() and combat.hasBuff('stunned') then
        checkSmokeDrag();
      interactObject(MODEL_FUMUS);
      waitFlag(5000);
      if canCheckSmokeDrag.isFinished() and combat.hasBuff('stunned') then
        checkSmokeDrag();
      repeat
        if canCheckDeath.isFinished() then
          checkDeath();
        hasChats := specialChatsPresent();
        correctLocalPosition();
        if canCheckSmokeDrag.isFinished() and combat.hasBuff('stunned') then
          checkSmokeDrag()
        if (hasMinionGlitch) and (not didCompensate) then
        begin
          ClarityDebug('bossFight(): detected minion glitch (Fumus). Rectifying.');
          interactObject(MODEL_NEX);
          waitFlag(2000);
        end;
        if canAvoidNex.isFinished() then
          avoidNex()
        else if (not combat.hasBuff('deflectmagic')) and canTogglePrayer.isFinished() then
          toggleDeflectMagic()
        else if canFreedom.isFinished() and canDPS.isFinished() and (not hasAnticipationBuff()) and (not hasChats) then
          sendFreedom()
        else if canAnticipation.isFinished() and canDPS.isFinished() and (not hasFreedomBuff()) and (not hasChats) then
          sendAnticipation()
        else if canHeal.isFinished() and (actionbar.getLifePoints() < HEALTH_THRESHOLD_1) then
          handleHealing()
        else if canDrinkSuperRestore.isFinished() and (actionbar.getPrayerPoints() < PRAYER_THRESHOLD) then
          drinkSuperRestore()
        else if canDevotion.isFinished() and (actionbar.getAdrenaline() >= 50) and canDPS.isFinished() and (not hasChats) then
          sendDevotion()
        else if (actionbar.getAdrenaline() >= 50) and canDPS.isFinished() then
          thresholdDPS();
        if (hasMinionGlitch) and (not didCompensate) then
        begin
          ClarityDebug('bossFight(): detected minion glitch (Fumus). Fix attempt completed.');
          didCompensate := true;
          goto fumusGlitch;
        end;
        cPos := minimap.getLocalPosition();
      until ((combat.getTargetName() = 'Fumus') and (combat.getTargetLifePoints() = 0)) or ((((cPos.X <= 58) and (cPos.Y <= 57)) or (cPos.X <= 61)) and (length(ogl.getModels(MODEL_FUMUS)) = 0));
      wait(random(100, 300));
      {SHADOW PHASE}
      currentPhase := 'Shadow (Nex)';
      didCompensate := false;
      repeat
        interactObject(MODEL_NEX);
        waitFlag(2000);
        if canCheckSmokeDrag.isFinished() and combat.hasBuff('stunned') then
          checkSmokeDrag();
        correctLocalPosition();
      until (pos('Darken my shadow', ogl.getChars().toString())) or (length(shadowTraps := ogl.getModels(MODEL_SHADOW_TRAP)) > 0);
      sendKeys(KEYBIND_RANGE, 65 + random(65), 65 + random(65));
      repeat
        if canAvoidShadowTraps.isFinished() then
        begin
          ogl.setCacheTime(0);
          if (length(shadowTraps := ogl.getModels(MODEL_SHADOW_TRAP)) > 0) then
            avoidShadowTraps();
          ogl.setCacheTime(150);
        end;
        if canCheckDeath.isFinished() then
          checkDeath();
        if canAvoidNex.isFinished() then
          avoidNex()
        else if canHeal.isFinished() and (actionbar.getLifePoints() < HEALTH_THRESHOLD_1) then
          handleHealing()
        else if canDrinkSuperRestore.isFinished() and (actionbar.getPrayerPoints() < PRAYER_THRESHOLD) then
          drinkSuperRestore()
        else if canDevotion.isFinished() and (actionbar.getAdrenaline() >= 50) and canDPS.isFinished() then
          sendDevotion()
        else if (actionbar.getAdrenaline() >= 50) and canDPS.isFinished() and (getNexLifePoints() >= 123500) then
          thresholdDPS();
      until (getNexLifePoints() <= 120000);
      currentPhase := 'Shadow (Umbra)';
      wait(random(50, 150));
      walkToPoint(point(75, 54), 12, 12);
      waitFlag(2500);
      repeat
        if (length(ogl.getModels(MODEL_UMBRA).getVisible()) = 0) then
          walkToPoint(point(75, 54), 12, 12);
        waitFlag(2500);
      until (length(ogl.getModels(MODEL_UMBRA).getVisible()) > 0);
      umbraGlitch:
      wait(random(300, 400));
      interactObject(MODEL_UMBRA);
      mainscreen.setHorizontalDirection('north');
      waitFlag(2000);
      repeat
        wait(random(50, 150));
      until (combat.getTargetName() = 'Umbra');
      actionbar.setAutoRetaliate(false);
      mouse.move(point(1000 + random(-100, 100), 700 + random(-100, 100)));
      repeat
        if canAvoidShadowTraps.isFinished() then
        begin
          ogl.setCacheTime(0);
          if (length(shadowTraps := ogl.getModels(MODEL_SHADOW_TRAP)) > 0) then
            avoidShadowTraps();
          ogl.setCacheTime(150);
        end;
        if (hasMinionGlitch := pos('This minion is still drawing power from Nex.', ogl.getChars().toString())) and (not didCompensate) then
        begin
          ClarityDebug('bossFight(): detected minion glitch (Umbra). Rectifying.');
          interactObject(MODEL_NEX);
          waitFlag(2000);
        end;
        if canCheckDeath.isFinished() then
          checkDeath();
        if canHeal.isFinished() and (actionbar.getLifePoints() < HEALTH_THRESHOLD_4) then
          handleHealing()
        else if canDrinkSuperRestore.isFinished() and (actionbar.getPrayerPoints() < PRAYER_THRESHOLD) then
          drinkSuperRestore();
        if (hasMinionGlitch) and (not didCompensate) then
        begin
          ClarityDebug('bossFight(): detected minion glitch (Umbra). Fix attempt completed.');
          didCompensate := true;
          goto umbraGlitch;
        end;
      until ((combat.getTargetName() = 'Umbra') and (combat.getTargetLifePoints() = 0)) or (length(ogl.getModels(MODEL_UMBRA)) = 0);
      {BLOOD PHASE}
      hasMinionGlitch := false;
      currentPhase := 'Blood (Prephase)';
      sendKeys(KEYBIND_RESTORE, 65 + random(65), 65 + random(65));
      wait(random(75, 150));
      interactObject(MODEL_NEX, ['Walk here']);
      wait(random(75, 150));
      actionbar.setActionBar('4');
      wait(random(150, 250));
      waitFlag(5000);
      if (actionbar.getLifePoints < 80) then
        sendKeys(KEYBIND_ROCKTAIL, 65 + random(65), 65 + random(65));
      wait(random(150, 250));
      if (actionbar.getLifePoints < 95) then
      begin
        sendKeys(KEYBIND_BREW, 65 + random(65), 65 + random(65));
        wait(random(150, 250));
      end;
      interactObject(MODEL_NEX);
      wait(random(50, 150));
      actionbar.sendAbility('snapshot');
      currentPhase := 'Blood (Nex)';
      wait(random(50, 150));
      sendKeys(KEYBIND_MAGIC, 65 + random(65), 65 + random(65));
      wait(random(200, 350));
      interactObject(MODEL_NEX, ['Walk here']);
      wait(random(400, 800));
      ogl.setColourTolerance(0);
      if (actionbar.getLifePoints < 80) then
        sendKeys(KEYBIND_ROCKTAIL, 65 + random(65), 65 + random(65));
      sendFreedom();
      canFreedom.setTime(29000 + random(500));
      wait(random(1800, 1900));
      sendAnticipation();
      wait(random(650, 700));
      canAnticipation.setTime(23000 + random(500));
      ogl.setColourTolerance(4);
      equipSirenic();
      ogl.setColourTolerance(0);
      if isStrInArr('engulf', true, chat.getChat()) then
      begin
        ClarityDebug('Failed to prephase Nex, restarting kill.');
        teleportToMaxGuild();
        wait(random(8000, 10000));
        if USING_SCRIMSHAW then
        begin
          repeat
          toggleScrimshaw();
          wait(random(750, 900));
          until (not combat.hasBuff('scrimshaw'));
        end;
        actionbar.setQuickPrayer(false);
        wait(random(600, 800));
        goto beginNewTrip;
      end;
      wait(random(1700, 1800));
      actionbar.sendAbility('snipe');
      if (actionbar.getAdrenaline < 100) then
      begin
        wait(random(1600, 1800));
        drinkAdrenalinePotion();
      end;
      repeat
        wait(random(151, 200));
      until (not combat.hasBuff('snipe'));
      actionbar.sendAbility('onslaught');
      ogl.setColourTolerance(4);
      didEscape := false;
      repeat
        if (pos('demand a blood', ogl.getChars().toString()) > 0) and (getNexLifePoints() > 89000) then
        begin
          ClarityDebug('bossFight(): we must escape the sacrifice');
          wait(random(800, 850));
          if isNexSouth() then
            actionbar.sendAbility('surge')
          else
            actionbar.sendAbility('escape');
          didEscape := true;
          break();
        end;
      until (actionbar.getLifePoints() < 32) or (getNexLifePoints() <= 80000);
      if (not didEscape) then
      begin
        if isNexSouth() then
          actionbar.sendAbility('surge')
        else
          actionbar.sendAbility('escape');
        wait(random(50, 150));
      end;
      sendKeys(KEYBIND_ROCKTAIL, 65 + random(65), 65 + random(65));
      wait(random(50, 150));
      sendKeys(KEYBIND_BREW, 65 + random(65), 65 + random(65));
      wait(random(650, 700));
      sendKeys(KEYBIND_ROCKTAIL, 65 + random(65), 65 + random(65));
      wait(random(50, 150));
      sendKeys(KEYBIND_BREW, 65 + random(65), 65 + random(65));
      wait(random(50, 150));
      if (getNexLifePoints() <= 80000) then
        goto skipBloodDPS;
      interactObject(MODEL_NEX);
      firstSiphon := true;
      repeat
        charString := ogl.getChars().toString();
        if (pos('solve this', charString) > 0) and (getNexLifePoints() > 80000) then
        begin
          ClarityDebug('bossFight(): avoiding first siphon.');
          if (not firstSiphon) then
          begin
            ClarityDebug('bossFight(): second siphon, kill failed.');
            teleportToMaxGuild();
            wait(random(8000, 10000));
            if USING_SCRIMSHAW then
            begin
              repeat
                toggleScrimshaw();
                wait(random(750, 900));
              until (not combat.hasBuff('scrimshaw'));
            end;
            actionbar.setQuickPrayer(false);
            wait(random(600, 800));
            goto beginNewTrip;
          end;
          cancelCombat := true;
          avoidNex();
          cancelCombat := false;
          siphonTimer.setTime(random(2200, 2400));
          repeat
            if (not combat.hasBuff('deflectmagic')) and canTogglePrayer.isFinished() then
              toggleDeflectMagic()
            else if canHeal.isFinished() and (actionbar.getLifePoints() < HEALTH_THRESHOLD_1) then
              handleHealing()
            else if canDrinkAdrenalinePotion.isFinished() and (actionbar.getAdrenaline() < 50) then
              drinkAdrenalinePotion()
            else if canDrinkSuperRestore.isFinished() and (actionbar.getPrayerPoints() < PRAYER_THRESHOLD) then
              drinkSuperRestore();
          until siphonTimer.isFinished();
          actionbar.sendAbility('snipe');
          firstSiphon := false;
        end;
        if canCheckDeath.isFinished() then
          checkDeath();
        if (not combat.hasBuff('deflectmagic')) and canTogglePrayer.isFinished() then
          toggleDeflectMagic()
        else if canHeal.isFinished() and (actionbar.getLifePoints() < HEALTH_THRESHOLD_1) then
          handleHealing()
        else if canDrinkAdrenalinePotion.isFinished() and (actionbar.getAdrenaline() < 50) then
          drinkAdrenalinePotion()
        else if canDrinkSuperRestore.isFinished() and (actionbar.getPrayerPoints() < PRAYER_THRESHOLD) then
          drinkSuperRestore()
        else if (actionbar.getAdrenaline() >= 50) and canDPS.isFinished() then
          thresholdDPS();
      until (getNexLifePoints() <= 80000);
      skipBloodDPS:
      wait(random(150, 350));
      actionbar.setActionBar('5');
      wait(random(150, 350));
      currentPhase := 'Blood (Cruor)';
      equipVoid();
      wait(random(150, 300));
      repeat
        if (length(ogl.getModels(MODEL_CRUOR).getVisible()) = 0) then
          walkToCruor(point(75, 75), 12, 12);
        if (actionbar.getLifePoints() < HEALTH_THRESHOLD_1) then
          handleHealing();
        if canCheckDeath.isFinished() then
          checkDeath();
        wait(random(100, 300));
      until (length(ogl.getModels(MODEL_CRUOR).getVisible()) > 0);
      interactObject(MODEL_CRUOR);
      waitFlag(5000);
      repeat
        if canAttackCruor.isFinished() then
        begin
          interactObject(MODEL_CRUOR);
          canAttackCruor.setTime(random(5000, 7500));
        end;
        if canCheckDeath.isFinished() then
          checkDeath();
        if (not combat.hasBuff('deflectmagic')) and canTogglePrayer.isFinished() then
          toggleDeflectMagic();
        if canHeal.isFinished() and (actionbar.getLifePoints() < HEALTH_THRESHOLD_1) then
          handleHealing()
        else if canDrinkSuperRestore.isFinished() and (actionbar.getPrayerPoints() < PRAYER_THRESHOLD) then
          drinkSuperRestore();
      until ((combat.getTargetName() = 'Cruor') and (combat.getTargetLifePoints() = 0)) or (length(ogl.getModels(MODEL_CRUOR)) = 0);
      {ICE PHASE}
      actionbar.setAutoRetaliate(true);
      wait(random(150, 350));
      currentPhase := 'Ice (Nex)';
      interactObject(MODEL_NEX);
      waitFlag(5000);
      repeat
        if canCheckDeath.isFinished() then
          checkDeath();
        charString := ogl.getChars().toString();
        if canHandleIcePrison.isFinished() and ((pos('prison of ice', charString) > 0) or (prisonWait.isFinished() and (nextAttack <> 'contain') and (combat.hasBuff('stunned')))) then
          handleIcePrison();
        if (pos('Contain this', charString) > 0) then
        begin
          if (ogl.getTextures(1275).isEmpty()) then
            handleContainThis()
          else
          begin
            prisonWait.setTime(6000);
            nextAttack := 'prison';
          end;
        end;
        if canAvoidNex.isFinished() then
          avoidNex()
        else if (not combat.hasBuff('deflectmagic')) and canTogglePrayer.isFinished() then
          toggleDeflectMagic()
        else if canAnticipation.isFinished() and (nextAttack = 'prison') then
          sendAnticipation()
        else if canHeal.isFinished() and (actionbar.getLifePoints() < HEALTH_THRESHOLD_5) then
          handleHealing()
        else if (length(inventory.getItems(TEXTURE_PRIMARY_TID, TEXTURE_PRIMARY_CID)) > 0) and canEquipNoxiousBow.isFinished() then
          equipNoxiousBow()
        else if canDrinkSuperRestore.isFinished() and (actionbar.getPrayerPoints() < PRAYER_THRESHOLD) then
          drinkSuperRestore()
        else if (actionbar.getAdrenaline() >= 80) and canDPS.isFinished() and (getNexLifePoints() >= 43500) then
          thresholdDPS();
      until (getNexLifePoints() <= 40000);
      currentPhase := 'Ice (Glacies)';
      repeat
        if canCheckDeath.isFinished() then
          checkDeath();
        charString := ogl.getChars().toString();
        if canHandleIcePrison.isFinished() and ((pos('prison of ice', charString) > 0) or (prisonWait.isFinished() and (nextAttack <> 'contain') and (combat.hasBuff('stunned'))))  then
          handleIcePrison();
        if (pos('Contain this', charString) > 0) then
        begin
          if (ogl.getTextures(1275).isEmpty()) then
            handleContainThis()
          else
          begin
            prisonWait.setTime(6000);
            nextAttack := 'prison';
          end;
        end;
        walkToGlacies(point(56, 75), 12, 12);
        if (nextAttack <> 'prison') and (not didSwitch) and (not combat.hasBuff('stunned')) then
        begin
          equipSirenic();
          wait(random(150, 250));
          didSwitch := true;
        end;
        if canAnticipation.isFinished() and (nextAttack = 'prison') then
          sendAnticipation()
        else if canHeal.isFinished() and (actionbar.getLifePoints() < HEALTH_THRESHOLD_5) then
          handleHealing()
        else if (length(inventory.getItems(TEXTURE_PRIMARY_TID, TEXTURE_PRIMARY_CID)) > 0) and canEquipNoxiousBow.isFinished() then
          equipNoxiousBow()
        else if (not combat.hasBuff('deflectmagic')) and canTogglePrayer.isFinished() then
          toggleDeflectMagic();
        wait(random(100, 300));
      until (length(ogl.getModels(MODEL_GLACIES).getVisible()) > 0);
      wait(random(100, 200));
      interactObject(MODEL_GLACIES, [], clientCenter, 2000);
      repeat
        if canCheckDeath.isFinished() then
          checkDeath();
        charString := ogl.getChars().toString();
        if canHandleIcePrison.isFinished() and ((pos('prison of ice', charString) > 0) or (prisonWait.isFinished() and (nextAttack <> 'contain') and (combat.hasBuff('stunned')))) then
          handleIcePrison();
        if (pos('Contain this', charString) > 0) then
        begin
          if (ogl.getTextures(1275).isEmpty()) then
            handleContainThis()
          else
          begin
            prisonWait.setTime(6000);
            nextAttack := 'prison';
          end;
        end;
        if (nextAttack <> 'prison') and (not didSwitch) and (not combat.hasBuff('stunned')) then
        begin
          equipSirenic();
          wait(random(150, 250));
          didSwitch := true;
        end;
        if (length(ogl.getModels(MODEL_GLACIES).getVisible()) = 0) then
          walkToGlacies(point(56, 75), 12, 12);
        if (length(ogl.getModels(MODEL_GLACIES).getVisible()) > 0) and (not (combat.getTargetName() = 'Glacies')) then
          interactObject(MODEL_GLACIES);
        if (not combat.hasBuff('deflectmagic')) and canTogglePrayer.isFinished() then
          toggleDeflectMagic()
        else if canAnticipation.isFinished() and (nextAttack = 'prison') then
          sendAnticipation()
        else if canHeal.isFinished() and (actionbar.getLifePoints() < HEALTH_THRESHOLD_5) then
          handleHealing()
        else if (length(inventory.getItems(TEXTURE_PRIMARY_TID, TEXTURE_PRIMARY_CID)) > 0) and canEquipNoxiousBow.isFinished() then
          equipNoxiousBow()
        else if canDrinkSuperRestore.isFinished() and (actionbar.getPrayerPoints() < PRAYER_THRESHOLD) then
          drinkSuperRestore()
        else if (actionbar.getAdrenaline() >= 50) and canDPS.isFinished() then
          thresholdDPS();
      until ((combat.getTargetName() = 'Glacies') and (combat.getTargetLifePoints() = 0)) or (length(ogl.getModels(MODEL_GLACIES)) = 0);
      wait(random(150, 350));
      interactObject(MODEL_NEX);
      repeat
        if canCheckDeath.isFinished() then
          checkDeath();
        charString := ogl.getChars().toString();
        if canHandleIcePrison.isFinished() and ((pos('prison of ice', charString) > 0) or (prisonWait.isFinished() and (nextAttack <> 'contain') and (combat.hasBuff('stunned')))) then
          handleIcePrison();
        if (pos('Contain this', charString) > 0) then
        begin
          if (ogl.getTextures(1275).isEmpty()) then
            handleContainThis()
          else
          begin
            prisonWait.setTime(6000);
            nextAttack := 'prison';
          end;
        end;
        if canAttackNex.isFinished() then
        begin
          interactObject(MODEL_NEX);
          canAttackNex.setTime(random(2000, 4000));
        end;
        if (not combat.hasBuff('deflectmagic')) and canTogglePrayer.isFinished() then
          toggleDeflectMagic()
        else if canAnticipation.isFinished() and (nextAttack = 'prison') then
          sendAnticipation()
        else if canHeal.isFinished() and (actionbar.getLifePoints() < HEALTH_THRESHOLD_5) then
          handleHealing()
        else if canDrinkSuperRestore.isFinished() and (actionbar.getPrayerPoints() < PRAYER_THRESHOLD) then
          drinkSuperRestore()
        else if (length(inventory.getItems(TEXTURE_PRIMARY_TID, TEXTURE_PRIMARY_CID)) > 0) and canEquipNoxiousBow.isFinished() then
          equipNoxiousBow();
      until (pos('POWER OF ZAROS', ogl.getChars().toString()) > 0) or ((getNexLifePoints() > 60000) and (getNexLifePoints() <> 666666));
      charString := ogl.getChars().toString();
      if canHandleIcePrison.isFinished() and ((pos('prison of ice', charString) > 0) or (prisonWait.isFinished() and (nextAttack <> 'contain') and (combat.hasBuff('stunned')))) then
        handleIcePrison();
      if (pos('Contain this', charString) > 0) then
      begin
        if (ogl.getTextures(1275).isEmpty()) then
          handleContainThis()
        else
        begin
          prisonWait.setTime(6000);
          nextAttack := 'prison';
        end;
      end;
      {ZAROS PHASE}
      currentPhase := 'Zaros';
      //equipPernixBoots();
      useExcalibur();
      wait(random(600, 700));
      sendKeys(KEYBIND_RENEWAL, 65 + random(65), 65 + random(65));
      wait(random(600, 700));
      repeat
        if canCheckDeath.isFinished() then
          checkDeath();
        if (not combat.hasBuff('deflectmagic')) and canTogglePrayer.isFinished() then
          toggleDeflectMagic()
        if (not combat.isOverloaded()) then
          drinkHolyOverload();
        if canHeal.isFinished() and (actionbar.getLifePoints() < HEALTH_THRESHOLD_1) then
          handleHealing()
        else if canDrinkSuperRestore.isFinished() and (actionbar.getPrayerPoints() < PRAYER_THRESHOLD) and (length(inventory.getItems([91800, 92055, 79815, 77520, 79560], [2625818, 2757661, 2627101, 2364956, 2102810, 1840408, 2692381, 2430749, 2432289, 2757147, 1845541, 1453606, 1062697, 1324586])) > 0) then
          drinkSuperRestore()
        else if (length(inventory.getItems(TEXTURE_PRIMARY_TID, TEXTURE_PRIMARY_CID)) > 0) and canEquipNoxiousBow.isFinished() then
          equipNoxiousBow()
        else if canDrinkAdrenalinePotion.isFinished() and (actionbar.getAdrenaline() <= 75) then
          drinkAdrenalinePotion()
        else if canDeathsSwiftness.isFinished() and (actionbar.getAdrenaline() >= 100) and canDPS.isFinished() then
          sendDeathsSwiftness()
        else if canDevotion.isFinished() and (actionbar.getAdrenaline() >= 50) and canDPS.isFinished() and (didDS) then
          sendDevotion()
        else if (actionbar.getAdrenaline() >= 50) and canDPS.isFinished() and (didDS) then
          thresholdDPS();
      until (getNexLifePoints() <= 0) or (getNexLifePoints() = 666666);
      wrath := true;
      superWrath := true;
      avoidNex();
      superWrath := false;
      wrath := false;
      waitFlag(7000);
      checkDeath();
      ClarityDebug('bossFight(): kill complete!');
      wait(random(3000, 5000));
      lootItems();
      wait(random(600, 800));
      if USING_SCRIMSHAW then
      begin
        repeat
          toggleScrimshaw();
          wait(random(700, 900));
        until (not combat.hasBuff('scrimshaw'));
      end;
      actionbar.setQuickPrayer(false);
      wait(random(600, 800));
      teleportToMaxGuild();
      wait(random(2400, 3000));
    end;

    procedure mainLoop();
    begin
      beginNewTrip:
      currentPhase := 'Banking';
      actionbar.setAutoRetaliate(true);
      wait(random(250, 500));
      actionbar.setActionBar('5');
      wait(random(250, 500));
      bankingMaxGuild();
      enterNexPortal();
      travelToLobby();
      alreadyAtBank:
      bankingNexLobby();
      enterInstance();
      preFightRoutine();
      bossFight();
      ClarityDebug('Main loop complete, resetting.');
    end;

    begin
      clearDebug;
      debugClicks := false;
      ogl.setCacheTime(150);
      ogl.setColourTolerance(4);
      ogl.setAngleTolerance(0.24);
      displayScalingMod := 1.5;
      buffRegion := IntToBox(8, 89, 279, 207);
      targetRegion := IntToBox(379, 910, 671, 995);
      mainScreenRegion := IntToBox(34, 167, 1317, 797);
      GLXMapHooks(getRuneScapeClient());
      activateClient();
      ogl.getClientDimensions(w, h);
      ClarityDebug('Client dimensions: ' + toStr(w) + ' x ' + toStr(h));
      if (w = 0) and (h = 0) then
      begin
        ClarityDebug('No target selected. Terminating.');
        terminateScript();
      end;
      GLXViewPort(w, h, w, h);
      ogl.setDebugMode('n');
      clientCenter := point(round(w / 2), round(h / 2));
      currentPhase := 'Initial';

      canDPS.setTime(1000);
      canQuickPrayer.setTime(1000);
      canAnticipation.setTime(1000);
      canFreedom.setTime(1000);
      canHeal.setTime(1000);
      canAvoidShadowTraps.setTime(1000);
      canDrinkSuperRestore.setTime(1000);
      canTogglePrayer.setTime(1000);
      cancelCheck.setTime(1000);
      canEquipNoxiousBow.setTime(1000);
      canDrinkOverload.setTime(1000);
      canBarricade.setTime(1000);
      canDeathsSwiftness.setTime(1000);
      canImmortality.setTime(1000);
      prisonWait.setTime(1000);
      didThresholdCD.setTime(1000);
      canCheckDeath.setTime(10000);
      canHandleIcePrison.setTime(1000);
      canAttackCruor.setTime(1000);
      canAttackNex.setTime(1000);

      {repeat
        //writeln(inventory.getItems(688));
        writeln(combat.hasBuff('stunned'));
        //writeln(ogl.getTextures(68850));
        //writeln(ogl.getTextures(IntToBox(7, 62, 316, 200)));
        //ogl.getTextures(68850);
        //writeln(ogl.getTextures(IntToBox(525, 430, 571, 470)));
        //wait(25);
        writeln('=====');
      until false;}


      {repeat
        allTextures := ogl.getTextures(91290);              //74, 54       //75, 75         //56, 75
        for i := 0 to high(allTextures) do
          if allTextures[i].Y < 300 then
            writeln(allTextures[i]);

      until false; }


      {repeat
        ClarityDebug(toStr(combat.getTargetLifePoints()));
      until false;}




      //mouse.rightClickOption(point(597 + random(-200, 200), 406 + random(-200, 200)), ['']);
      {repeat
        //writeln(minimap.getLocalPosition(mouse.getRealPoint()));
        writeln(minimap.getLocalPosition());
        ClarityDebug(toStr(actionbar.getLifePoints()));
      until false;}

      //writeln(minimap.getLocalPosition());

     {repeat
      writeln(actionbar.getAdrenaline());
       //writeln(combat.getTarget());
        //writeln(isNexSouth());
        //actionbar.getLifePoints().debug;
       //writeln(ogl.getTextures(139740));
       //writeln(getNexLifePoints());
       //writeln(ogl.getModels(189892155));
       wait(100);
       writeln('=======================================');
      until false;}


      {
      -local positions of minions after load
      }

      //equipSirenic();
      //writeln(inventory.getItems(62475));
      //writeln(ogl.getChars().toString());
      //writeln(hasFreedomBuff());
      //checkDeath();
      {repeat
        avoidNex();
      until false;}

      if (length(ogl.getModels(MODEL_BANKER_NEX)) > 0) then
        goto alreadyAtBank;
      repeat
        mainLoop();
      until false;
      writeln('broke out of the loop somehow');
    end.

    Good luck with your botting endeavors
    Last edited by Clarity; 04-26-2018 at 11:07 PM.

  2. #2
    Join Date
    Nov 2011
    Location
    Norway
    Posts
    203
    Mentioned
    4 Post(s)
    Quoted
    100 Post(s)

    Default

    A pleasure to watch in action. Very impressive release, maybe I'll try grabbing all the IDs sometime

  3. #3
    Join Date
    Dec 2011
    Posts
    2,134
    Mentioned
    218 Post(s)
    Quoted
    1063 Post(s)

    Default

    Quote Originally Posted by Aufi View Post
    A pleasure to watch in action. Very impressive release, maybe I'll try grabbing all the IDs sometime
    Some can be seen in the video if you want a head start
    Anyways, will see if I can follow up with a Chambers of Xeric script. Woox does it pretty masterfully, it's a pleasure to try and emulate his gameplay.

  4. #4
    Join Date
    Nov 2011
    Location
    Norway
    Posts
    203
    Mentioned
    4 Post(s)
    Quoted
    100 Post(s)

    Default

    Quote Originally Posted by Clarity View Post
    Some can be seen in the video if you want a head start
    Anyways, will see if I can follow up with a Chambers of Xeric script. Woox does it pretty masterfully, it's a pleasure to try and emulate his gameplay.
    Good luck with that!

    Also am I right in assuming ClarityNex can't be ran without ClarityGLX? Even if that's the case, the source is really helpful for learning purposes.

  5. #5
    Join Date
    May 2012
    Posts
    10
    Mentioned
    0 Post(s)
    Quoted
    1 Post(s)

    Default

    seems like an decent one

  6. #6
    Join Date
    Apr 2016
    Posts
    126
    Mentioned
    1 Post(s)
    Quoted
    37 Post(s)

    Default

    Wow thanks for sharing! Do you think it would be possible for one to make an araxxor script?

  7. #7
    Join Date
    Feb 2016
    Posts
    3
    Mentioned
    0 Post(s)
    Quoted
    5 Post(s)

    Default

    Are you using your own unreleased openGL plugin?
    will you be using openGL method or reflection/injection for OSRS?
    are you ever considering releasing your plugin or any kind of tutorials on openGL plugin development, its application?
    or would it hurt your profits too much, assuming you bot for real life money?

    sorry for many questions, im new to both botting scene and this forum community.

  8. #8
    Join Date
    May 2012
    Location
    Glorious Nippon
    Posts
    944
    Mentioned
    47 Post(s)
    Quoted
    476 Post(s)

    Default

    Quote Originally Posted by iBleedBlack View Post
    Are you using your own unreleased openGL plugin?
    will you be using openGL method or reflection/injection for OSRS?
    are you ever considering releasing your plugin or any kind of tutorials on openGL plugin development, its application?
    or would it hurt your profits too much, assuming you bot for real life money?

    sorry for many questions, im new to both botting scene and this forum community.
    Check the OP's signature.

    https://villavu.com/forum/showthread.php?t=112486

  9. #9
    Join Date
    Dec 2011
    Posts
    2,134
    Mentioned
    218 Post(s)
    Quoted
    1063 Post(s)

    Default

    Quote Originally Posted by Aufi View Post
    Good luck with that!

    Also am I right in assuming ClarityNex can't be ran without ClarityGLX? Even if that's the case, the source is really helpful for learning purposes.
    Oh whoops, really that's just an include file with a bunch of combo-functions and some overrides I use all the time to avoid having to repeat code. For instance, interactObject() is a model search with optional boundaries, failsafes, and clicking/option-selecting all in one single function for ease of use.

    Quote Originally Posted by DonVitoCorleone View Post
    Wow thanks for sharing! Do you think it would be possible for one to make an araxxor script?
    In my opinion Araxxor is easier to script than solo Nex, but I never completed a script because this interested me more. There's far less to deal with/keep track of with Rax.

    Quote Originally Posted by iBleedBlack View Post
    Are you using your own unreleased openGL plugin?
    will you be using openGL method or reflection/injection for OSRS?
    are you ever considering releasing your plugin or any kind of tutorials on openGL plugin development, its application?
    or would it hurt your profits too much, assuming you bot for real life money?

    sorry for many questions, im new to both botting scene and this forum community.
    Welcome to SRL No, everything used here is publicly available for you to use as well. This community places emphasis on education/learning. I script for fun, not really for money.
    OpenGL Scripting Tutorial: https://villavu.com/forum/showthread.php?t=112486
    OpenGL Plugin Development Tutorial: https://villavu.com/forum/showthread.php?t=89645
    Last edited by Clarity; 05-19-2017 at 02:34 PM.

  10. #10
    Join Date
    Apr 2016
    Posts
    126
    Mentioned
    1 Post(s)
    Quoted
    37 Post(s)

    Default

    Quote Originally Posted by Clarity View Post
    In my opinion Araxxor is easier to script than solo Nex, but I never completed a script because this interested me more. There's far less to deal with/keep track of with Rax.
    In that case i think i might give it a go then after my exams are done

  11. #11
    Join Date
    Feb 2016
    Posts
    3
    Mentioned
    0 Post(s)
    Quoted
    5 Post(s)

    Default

    Quote Originally Posted by Clarity View Post
    Some can be seen in the video if you want a head start
    Anyways, will see if I can follow up with a Chambers of Xeric script. Woox does it pretty masterfully, it's a pleasure to try and emulate his gameplay.
    Thanks for response,
    by the way what method/library are you planing to use for OSRS?

  12. #12
    Join Date
    Aug 2016
    Location
    Kentucky
    Posts
    242
    Mentioned
    3 Post(s)
    Quoted
    94 Post(s)

    Default

    Quote Originally Posted by iBleedBlack View Post
    Thanks for response,
    by the way what method/library are you planing to use for OSRS?
    LOL-Undercover-Kitten.jpg

  13. #13
    Join Date
    Apr 2016
    Location
    New Zealand
    Posts
    76
    Mentioned
    0 Post(s)
    Quoted
    32 Post(s)

    Default

    Quote Originally Posted by iBleedBlack View Post
    Thanks for response,
    by the way what method/library are you planing to use for OSRS?
    Clarity is going to be using Robotz in Disguise™ and their patented Botting Bio-metrics™ to farm Goblin Mails in Lumbridge.

  14. #14
    Join Date
    Sep 2014
    Posts
    445
    Mentioned
    10 Post(s)
    Quoted
    202 Post(s)

    Default

    Reading the post about HSR on /r/runescape just reminded me. Doesn't turning off private chat turn off drop notifications?

  15. #15
    Join Date
    Nov 2011
    Location
    Norway
    Posts
    203
    Mentioned
    4 Post(s)
    Quoted
    100 Post(s)

    Default

    Quote Originally Posted by yourule97 View Post
    Reading the post about HSR on /r/runescape just reminded me. Doesn't turning off private chat turn off drop notifications?
    I mentioned this to Clarity on discord and he said it used to be unavoidable.

  16. #16
    Join Date
    Mar 2016
    Location
    Canada
    Posts
    32
    Mentioned
    0 Post(s)
    Quoted
    3 Post(s)

    Default

    Damn, seeing a script like this is unbelievable. It's amazing what you/others are able to do.

  17. #17
    Join Date
    Dec 2011
    Posts
    2,134
    Mentioned
    218 Post(s)
    Quoted
    1063 Post(s)

    Default

    Quote Originally Posted by yourule97 View Post
    Reading the post about HSR on /r/runescape just reminded me. Doesn't turning off private chat turn off drop notifications?
    Yeah it is now after an update, I don't know exactly when. I would still get world announcements for rare Nex drops even with all chats off and broadcasts disabled.
    Quote Originally Posted by J0rdeh View Post
    Damn, seeing a script like this is unbelievable. It's amazing what you/others are able to do.
    You can too!

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •