StatForge

Live ratio panel for Torn gym stats with rep-counter automation and per-stat gym switching, plus a styled floating drug-cooldown alarm shown on all Torn pages via the Torn API (requires your own API key). Also reads your gym-gain perks (Steadfast, education, property, books) from the Torn API to weight training gains by your real multipliers and protect your special-gym access ratios. Inspired by ClasixTV's original Torn ratio helper. TornPDA users should set injection time to END.

Ниже показаны версии этого скрипта, в которых изменялся код. Показать все версии.

  • вер. 1.12.1 22.06.2026

    fix: only protect special-gym combo ratio when the gym is actually held

    The access guard derived the combo gym from the build's high stat and always enforced it. For builds that can never satisfy that combo (e.g. aec3 Defense-high can't reach Balboa's def+dex >= 1.25*(str+spd), since str+spd are each ~78% of def), this permanently capped the secondary pair to 0 trains, freezing str/spd and training the dump stat first.

    Gate the combo rule on comboHeld = primarySum >= 1.25 * secondarySum so an unreachable/already-lost combo gym no longer blocks training. The single-stat rule (high >= 1.25 * second-highest) is always kept — it aligns with the build and is restorable by training the high stat.

    Also name gym id 32 "Fight Club" (was null -> "Gym #32").

    Co-Authored-By: Claude Opus 4.8 (1M context) [email protected] Claude-Session: https://claude.ai/code/session_01LZLpdWB5L4FhhD8DBpJoM5

  • вер. 1.12.0 22.06.2026

    feat: weight rep plan by gym-gain perks and protect special-gym access

    Read the player's gym-gain perks (Steadfast, education, property, books) from api.torn.com user?selections=perks, combine them multiplicatively per stat (matching Torn's gym formula), and feed them into the rep plan so each stat's projected gains reflect the player's real multipliers.

    Add a P1 hard guard that keeps special-gym access: caps how many trains each non-high stat may take before crossing the x1.25 access ratio (single-stat Hank's rule + combo Frontline/Balboa rule), derived automatically from the build's high stat. The high stat is uncapped so surplus energy raises the ceiling. Guard activates only for special-gym-compatible builds (baldr/hank/aec3); balanced builds are unchanged. Without an API key, multipliers default to 1.0 and caps to Infinity, so existing behavior is preserved.

    Reuses the existing API key and fetch path (drug-cooldown feature); adds a Settings section disclosing the multipliers and access-protection status.

    Co-Authored-By: Claude Opus 4.8 (1M context) [email protected] Claude-Session: https://claude.ai/code/session_01LZLpdWB5L4FhhD8DBpJoM5

  • вер. 1.11.8 14.06.2026

    feat: alarm shows only in final 5 min, doubled size, blink on ready

    Hide the floating drug-cooldown pill until the cooldown has <=5 min left (DRUG_ALARM_SEC=300) or is ready; set-key/error states stay visible so it can still be configured. Double the pill size (font 13->26px, padding /dot/border doubled). Blink (sf-drug-blink) only in the ready state; the final-5-min countdown (sf-alarm) is steady. Bump to v1.11.8.

    Co-Authored-By: Claude Opus 4.8 (1M context) [email protected]

  • вер. 1.11.6 14.06.2026

    feat: redesign drug cooldown alarm as styled floating pill

    Replace the sidebar status-icons indicator (which inherited Torn's icon styling and looked out of place) with a fully self-contained floating pill appended to document.body: own id #sf-drug-alarm, namespaced .sf-* classes, injected CSS with idle/countdown/ready(green+pulse)/error states. No Torn class is read or written, so nothing bleeds in. API polling, active-view gating, item.php click and bad-key auto-prompt are unchanged. Fixed bottom-left. Bump to v1.11.6.

    Co-Authored-By: Claude Opus 4.8 (1M context) [email protected]

  • вер. 1.11.4 14.06.2026

    fix: neutralise inherited status-icon background on drug badge

    Torn styles every status-icons

  • as a fixed-size icon with a background sprite/colour, which bled through behind the drug-cooldown pill (a green sprite corner). Inject a #sf-drug-badge-scoped style that resets background, sizing, box-shadow and ::before/::after with !important. Bump to v1.11.4.

    Co-Authored-By: Claude Opus 4.8 (1M context) [email protected]

  • вер. 1.11.3 14.06.2026

    feat: move drug cooldown to status-icons row + key UX

    Relocate the drug-cooldown indicator from the Energy bar to the first item of the sidebar status-icons row (li#sf-drug-badge inserted via insertBefore, hardened ul[class*="status-icons___"] selector, verified dump). Click with a working key opens item.php; no key / bad key opens the key prompt, and a code-2 'incorrect key' auto-prompts once. Bump to v1.11.3.

    Co-Authored-By: Claude Opus 4.8 (1M context) [email protected]

  • вер. 1.11.1 14.06.2026

    feat: render drug cooldown inline in sidebar Energy bar

    Replace the floating fixed badge with an inline span inserted right after the Energy bar-value in Torn's left sidebar (verified DOM dump). Locate the Energy row via hash-safe [class*="bar-name_"] + /energy/i, insert after [class*="bar-value_"], and re-attach on sidebar re-render. Colored text instead of a pill: amber countdown, green "ready". Bump to v1.11.1.

    Co-Authored-By: Claude Opus 4.8 (1M context) [email protected]

  • вер. 1.11.0 14.06.2026

    feat: drug cooldown badge on all Torn pages via API

    Widen @match to https://www.torn.com/* and add an all-pages drug cooldown badge driven by api.torn.com (selections=cooldowns). Polls every 60s only while the tab is actively viewed, shows a live local countdown, and turns green ("Drug ready") when the cooldown expires. API key entered via prompt() and stored locally. Gym ratio panel is still gated to gym.php via isGymPage(). Bump to v1.11.0.

    Co-Authored-By: Claude Opus 4.8 (1M context) [email protected]

  • вер. 1.10.10 01.06.2026

    chore: remove internal TORN_DOM.md references from public comments

    The 5 comments referencing the private DOM-dump doc name leaked an internal artifact name into the public repo. Reworded to 'verified against gym.php DOM dump' — same meaning, nothing internal exposed.

    Co-Authored-By: Claude Opus 4.8 (1M context) [email protected]

  • вер. 1.10.9 30.05.2026

    fix: abbreviate numbers in history table to fit mobile screen

    Co-Authored-By: Claude Sonnet 4.6 [email protected]

  • вер. 1.10.8 13.05.2026

    feat: gate DOM-reading auto-paths on actively-viewed tab

    Adds isActivelyViewed() (visibilityState + hasFocus) and gates the four auto-paths that read the gym page: waitAndInject, backgroundStatWatch, syncEnergyBaseline, and the trainObserver callback. Adds visibilitychange

    • focus listeners to resume work and resync the energy baseline when the tab becomes actively viewed again.

    Bumps to v1.10.8. Aligns with Torn's 2026-05-13 scripting-rule clarification that scripts may only read from pages the user is actively viewing (foreground tab + focused window).

    Co-Authored-By: Claude Opus 4.7 (1M context) [email protected]

  • вер. 1.10.7 30.04.2026

    chore: bump v1.10.7

  • вер. 1.10.6 30.04.2026

    chore: drop dead initial assignment in clear-history confirm

    ESLint v9.13's no-useless-assignment caught let confirmed = false; — the value is never read because both try and catch branches assign before the next read. Cleanup; behavior unchanged.

    Bumps version to 1.10.6.

    Co-Authored-By: Claude Opus 4.7 (1M context) [email protected]

  • вер. 1.10.5 29.04.2026

    fix(ratio): drop forcedDump from isStatDumped — multipliers drive skipping

    1.10.4 over-corrected by treating RATIOS[ratioKey].forcedDump as a "skip this stat" signal. That was wrong:

    • forcedDump is the recommended default for the user's dump-stat picker UI (so selecting Aec3 auto-picks DEX in the dump dropdown), not a directive to exclude the stat from training.
    • Aec3's DEX has multiplier 0.1351 (13.51%). The ratio's intent is to KEEP DEX at that ratio, not zero it. Treating forcedDump as a skip caused the planner to ignore DEX entirely — directly violating the ratio the user wants respected.

    Strip the forcedDump check from isStatDumped. The remaining rule is: the ratio's multiplier for whichever role this stat occupies must be exactly 0 to count as a dump.

    Concrete behaviour after this:

    • Hank: tert2 multiplier is 0 → that role's stat is skipped (unchanged from the original hardcoded check).
    • Aec3: DEX has multiplier 0.1351 → DEX is trained up to its 13.51% target like any other ratio stat.
    • Custom ratios with one or more 0 multipliers → those stats skipped. Two-stat or three-stat builds still work without code changes.

    Co-Authored-By: Claude Opus 4.7 (1M context) [email protected]

  • вер. 1.10.4 29.04.2026

    fix(ratio): respect any ratio's dump intent, not just Hank's

    Six sites hardcoded the dump-stat check as ratioKey === 'hank' && roles.tert2 === key which meant the rep allocator and grade ignored every other ratio's dump declaration:

    • Aec3 declares forcedDump: 'dex' but the planner queued reps for DEX when it was below its 13.51% target.
    • Custom ratios with one or more 0-multiplier slots were trained anyway, since only tert2 was checked.
    • "Only train 2 stats" / "only train 3 stats" builds had no clean declarative way to be honoured.

    Replace all six sites with a single helper:

    isStatDumped(key, ratioKey, roles)

    That returns true when:

    1. RATIOS[ratioKey].forcedDump matches key (Aec3 → DEX), OR
    2. The ratio's multiplier for whichever role key occupies is 0 (Hank's tert2; or any Custom slot zeroed out — this is what makes 2/3-stat builds work without further code changes).

    Sites updated: computeRepPlan (rep allocator) overallGrade (overall ratio grade) getDriftWarnings (per-stat drift detection) buildExportText (export panel display) renderOverview x2 (recommended stat picker + per-stat status)

    Effect for Aec3 + DEX dump (the user's loadout): DEX is now skipped in the rep planner, the grade, drift warnings, recommended stat, status row, and exported text. Reps redistribute to STR/SPD/DEF based on whichever is most behind its ratio target. Hank behaviour is preserved (its tert2 multiplier of 0 still triggers the skip).

    Custom ratios automatically get the same treatment for any 0-multiplier slot — including 2-stat or 3-stat training plans without further code.

    Co-Authored-By: Claude Opus 4.7 (1M context) [email protected]

  • вер. 1.10.3 29.04.2026

    feat: serialise train-button clicks behind Torn's UI-ready signal

    Spamming the train button could race Torn's mid-transition UI. Each click fired executeTrainStep synchronously, so a second click might land on a stale button reference, miss the freshly-rendered confirm button, or send the rep-counter to the wrong gym.

    Two changes:

    1. New sfWaitForCondition(predicate, maxMs) — same shape as TSA's qtWaitForCondition. Resolves true when the predicate becomes truthy under any DOM mutation, false on timeout.

    2. executeTrainStep → executeTrainStepAsync. After each click, await Torn reaching the expected next state:

      switch → wait for membership-confirm to appear OR active gym to match step.target (free switches don't show confirm). confirm → wait for membership-confirm to disappear. fill → wait for the input value to reflect the requested reps. train → wait for the train button to re-enable OR energy to drop.

    Each wait has a 3 s ceiling (500 ms for fill); on timeout the step resolves anyway so the user can manually retry.

    1. Click handler at #trh-train-now now sets a module-level trainStepInFlight flag while the async step runs. Spam clicks while the flag is set are silently dropped — once the previous step resolves, the next legitimate click is processed against the already-stable Torn UI.

    Net effect: clicking faster than Torn can render no longer breaks the flow; the script processes one click at a time, waiting for Torn's UI to settle between each.

    Co-Authored-By: Claude Opus 4.7 (1M context) [email protected]

  • вер. 1.10.2 25.04.2026 Imported from URL
  • вер. 1.10.1 22.04.2026

    Sync scripts from Claude repo

  • вер. 1.10.0 22.04.2026

    Sync scripts from Claude repo

  • вер. 1.9.10 22.04.2026

    Sync scripts from Claude repo

  • вер. 1.9.9 22.04.2026

    Sync scripts from Claude repo

  • вер. 1.9.8 22.04.2026

    Sync scripts from Claude repo

  • вер. 1.9.7 22.04.2026 Imported from URL
  • вер. 1.9.7 22.04.2026