Raw Source
brother-torn / Torn Respect Calculator

// ==UserScript==
// @name         Torn Respect Calculator
// @namespace    https://torn.com/
// @version      1.1
// @description  Respect calculator with auto chain detection and manual FF input
// @match        https://www.torn.com/*
// @author       Brother [2590792]
// @grant        none
// @license      AGPL-3.0-only
// @downloadURL https://update.greasyfork.org/scripts/573628/Torn%20Respect%20Calculator.user.js
// @updateURL https://update.greasyfork.org/scripts/573628/Torn%20Respect%20Calculator.meta.js
// ==/UserScript==

(function () {
  'use strict';

  let autoChain = true;

  const box = document.createElement('div');
  box.style = `
    position: fixed;
    top: 100px;
    right: 20px;
    background: #111;
    color: #eee;
    padding: 12px;
    border-radius: 8px;
    z-index: 9999;
    font-size: 12px;
    width: 260px;
    box-shadow: 0 0 10px #000;
  `;

  box.innerHTML = `
    <b>Respect Calculator</b><br><br>
    Target Level:
    <input id="lvl" type="number" style="width:100%"><br><br>
    Chain hit #:
    <input id="chain" type="number" style="width:100%">
    <button id="liveChain" style="width:100%;margin-top:4px">
      Use live chain
    </button><br><br>
    Fair Fight (1.0 – 3.0):
    <input id="ff" type="number" step="0.01" value="1.00" style="width:100%"><br><br>
    Weapon bonus %:
    <input id="weapon" type="number" value="0" style="width:100%"><br><br>
    <label>
      <input id="war" type="checkbox"> War bonus (x2)
    </label><br><br>
    <button id="calc" style="width:100%">Calculate</button>
    <hr>
    <div id="out">—</div>
  `;

  document.body.appendChild(box);

  const chainInput = document.getElementById('chain');

  chainInput.addEventListener('input', () => autoChain = false);
  document.getElementById('liveChain').onclick = () => autoChain = true;

  function getLiveChain() {
    const el = document.querySelector('[class*="chain"]');
    if (!el) return null;
    const match = el.textContent.replace(/,/g, '').match(/\d+/);
    return match ? Number(match[0]) : null;
  }

  setInterval(() => {
    if (!autoChain) return;
    const live = getLiveChain();
    if (live) chainInput.value = live;
  }, 1000);

  document.getElementById('calc').onclick = () => {
    const level = +lvl.value;
    if (!level) {
      out.innerText = 'Enter target level';
      return;
    }

    const base = Math.floor(((level / 200) + 1) * 100) / 100;
    const ch = +chainInput.value;
    const chainMult = ch >= 11 ? 0.25 * Math.log10(ch) + 0.75 : 1;

    let ff = +document.getElementById('ff').value || 1;
    ff = Math.min(3, Math.max(1, ff));

    const weaponMult = 1 + (+weapon.value || 0) / 100;
    const warMult = war.checked ? 2 : 1;

    const final = base * chainMult * weaponMult * warMult * ff;

    out.innerHTML = `
      Base: <b>${base.toFixed(2)}</b><br>
      Chain: x<b>${chainMult.toFixed(2)}</b><br>
      FF: x<b>${ff.toFixed(2)}</b><br>
      Final: <b>${final.toFixed(4)}</b>
    `;
  };
})();