Commit graph

91 commits

Author SHA1 Message Date
GaboGG
e20fe0495c v0.13.20 - Add SPELL_COSTS fallback for Mana Conservation-reduced MP costs
- Some spells show mp=1 in the DOM due to high Mana Conservation
  proficiency, making fill-level scoring produce near-zero values
- Now: if mpCost < 5, look up the base cost from SPELL_COSTS table
- This ensures Heartseeker (141 MP) scores correctly even when the
  DOM shows it costing 1 MP
2026-07-26 15:01:49 -04:00
GaboGG
e914c08475 v0.13.19 - Fix on-cooldown spells missing from spellsKnown
- Magic pane query used '.btsd[onclick]' which excludes
  on-cooldown spells (opacity:0.5, no onclick attribute)
- Heartseeker was invisible to hasSpell() during its cooldown
  period, which is exactly when channeling procs from it
- Changed to '.btsd' with onmouseover fallback
2026-07-26 14:31:38 -04:00
GaboGG
49c7ce9cab v0.13.18 - Add channeling score debug logging
- Logs the top candidate from findBestChannelingTarget() on every Q press
- Shows: spell, score, dur, maxDur, mpCost, emptiness%
- Next time channeling doesn't fire on a buff, the console will show
  the actual computed scores so we can see what's happening
2026-07-26 14:12:48 -04:00
GaboGG
e74c97f87a v0.13.17 - Fix fill-level scoring when maxBuffDur hasn't been learned
- When maxBuffDur for a buff equals its current duration (first observation
  in a battle), the emptiness was 0 — making the script think all buffs
  are full and skipping them
- Now: if maxDur <= current dur, assume a minimum of 30 turns as the max
- This ensures buffs like Shadow Veil at 8/8 are treated as 8/30 (73% empty)
  instead of 8/8 (0% empty)
2026-07-26 14:08:50 -04:00
GaboGG
3f865ee6fd v0.13.16 - Fix buff duration parsing for set_infopane_effect raw turn count
- The regex only matched 'X turns remaining' text format
- Buffs like channeling and freshly cast spells use the raw third
  parameter of set_infopane_effect('Name','desc',X) without 'turns rem'
- These were defaulting to 50 turns, making all fresh buffs appear
  as having 50 turns when they really had 0-5
- Added fallback to parse the last numeric argument of the function call
2026-07-26 14:05:29 -04:00
GaboGG
25ea8b4543 v0.13.15 - Fix stale Mystic Gem state, add debug logging to Q press
- Mystic Gem usage now tracked with STATE._mysticUsed flag
  Prevents re-triggering the gem check after it's been consumed
  (stale STATE.itemsKnown was causing infinite 'item → p' loops)
- Flag resets on new battle initialization
- Added buff durations + channeling status to Q-key console output
  Shows: ch=true/false mp=X% oc=X buffs: heartseeker=47 haste=24 ...
2026-07-26 14:01:48 -04:00
GaboGG
23f00450be v0.13.14 - Fix observer crash, raise channeling threshold to 30
- Removed call to undefined finalizeBattleLog() that was spamming
  ReferenceErrors and potentially corrupting the MutationObserver
- Raised channeling score threshold from 5 to 30: now only picks a
  buff for channeling if it's at least 30% empty on a 100-MP spell
  or 60% empty on a 50-MP spell
- Spark at 30/60 turns (50% empty, score 44) now falls to cheap
  damage fallback instead of wasting channeling
2026-07-26 13:53:01 -04:00
GaboGG
5f9297435d v0.13.13 - Fix channeling detection from effects pane (not just log)
- Channeling detection was ONLY from battle log text entries
- When log entries scroll off (new round starts), the 'gains the effect'
  message is lost and STATE.channeling stays false permanently
- Added effects pane check: if channeling.png is visible, force channeling=true
- This fixes the root cause of channeling being ignored when the log
  has scrolled past the proc message
- Also bumped version properly this time
2026-07-26 13:49:20 -04:00
GaboGG
c0c626c0bf v0.13.12 - Fill-level scoring for channeling consumption
- Score = emptiness_ratio × mp_cost
- emptiness_ratio = (max_dur - current) / max_dur
- max_dur is tracked dynamically per buff in STATE.maxBuffDur
  (learned from the highest duration seen per icon)
- Freshly cast buffs score ~0 regardless of MP cost
- A 100-MP buff at 1/90 turns scores 98.9
- A 40-MP buff at 25/50 turns scores 20.0
- A 140-MP buff at 71/80 turns scores 15.75
- Removed the Heartseeker >50 skip (no longer needed - fill level handles it)
2026-07-26 13:44:17 -04:00
GaboGG
37b502aa65 v0.13.11 - Score threshold for channeling buff consumption
- Reverted the >10 turns cutoff (wrong approach)
- Instead, added a minimum score threshold of 5 to the best candidate
- At score >= 5: a 50-MP spell with <9 turns, a 140-MP spell with <27 turns
- Below score 5: falls through to cheap damage spell fallback
- This prevents recasting fresh buffs while still considering all spells
2026-07-26 13:39:32 -04:00
GaboGG
e13b4c5206 v0.13.10 - Only consume channeling on buffs that need refresh (<10 turns)
- findBestChannelingTarget: skip buffs with >10 remaining turns
- When all buffs are fresh, falls through to cheap damage spell
  instead of wasting channeling on a nearly-full duration buff
- This prevents recasting Spark of Life at 15 turns just because
  its score happens to be highest among all fresh buffs
2026-07-26 13:38:31 -04:00
GaboGG
71da9b1214 v0.13.9 - Fix ReferenceError: battleLog is not defined
- The vitals observer check 'battleLog && !battleLog.summary' referenced
  an undefined variable, throwing on every observer tick
- Simplified to just check for pane_completion existence
- This crash may have been interfering with state parsing on the observer
2026-07-26 13:35:12 -04:00
GaboGG
47c42ea5fe v0.13.8 - Actually bump version in config.js and header.user.js
- config.js: 0.13.0 -> 0.13.8
- header.user.js: 0.12.0 -> 0.13.8 (was never bumped past 0.12.0)
- Now the @version tag in the userscript header matches the internal VERSION
2026-07-26 13:31:09 -04:00
GaboGG
c8fc09263a v0.13.8 - Lower MP thresholds and fix console error
- Reduced buff loop MP threshold from 20% to 10% in all three tiers
  (prevents skipping buffs when MP is moderately low)
- Also fixed the 'battleLog is not defined' ReferenceError from the
  vitals observer (removed in previous commit but was still referenced)
2026-07-26 13:29:54 -04:00
GaboGG
bbf7c95fb9 v0.13.7 - Channeling prioritized before buff priority loop
- Moved findBestChannelingTarget() BEFORE the BUFF_PRIORITY loop
- When Q is pressed and channeling is active, the script now picks the most
  expensive buff for the channeling charge instead of wasting it on the
  first buff in priority order (Haste at 32 MP instead of Heartseeker at 175)
- Reverted the vitals auto-execute (Q-key workflow, not auto-battle)
- All three tiers: channeling check fires after castInitialBuffs but
  before the regular shouldBuff loop
2026-07-26 13:27:24 -04:00
GaboGG
28a13449bd v0.13.6 - Auto-execute on vitals observer (no hover required)
- Added action execution to the vitals MutationObserver so the script
  fires on every round tick, not only when hovering a monster
- This fixes buffs expiring and channeling being wasted when the user
  isn't actively hovering a monster during auto-battle
- Removed unused STATE.battleRound
2026-07-26 13:26:19 -04:00
GaboGG
ee9bba90fc v0.13.5 - Fix channeling waste when all buffs are fresh
- findBestChannelingTarget() fallback: expanded damage spell list to
  include T2 spells (Inferno, Blizzard, etc.) and a last-resort loop
  that fires ANY offensive spell the player knows
- Prevents channeling from expiring when all buffs have high remaining
  durations and the player has no T1 elemental spells
2026-07-26 13:18:56 -04:00
GaboGG
5f61a5c4fc v0.13.4 - Round 1 buff-up: cheapest first, channeling on most expensive
- Added castInitialBuffs() that fires when 60%+ buffs are down (first round)
  - Without channeling: casts cheapest buff first (more casts = more procs)
  - With channeling: casts most expensive remaining buff (best value for free cast)
- Added isFirstRoundBuffs() helper: checks if most buffs are missing
- Injected into all three tiers (Novice, Adept, Veteran) before the
  regular BUFF_PRIORITY loop
- Added STATE.battleRound counter for future round tracking
2026-07-26 13:13:48 -04:00
GaboGG
badfcde640 v0.13.3 - Auto-sell/salvage preset on settings page
- New settings-page.js: adds a toolbar above the auto-salvage table
  on Character Settings (ss=se) with bulk preset buttons
- Preset 1: Sell <=Fair (value 2) / Salvage <=Average (value 3)
- Preset 2: Sell <=Crude (value 1) / Salvage <=Fair (value 2)
- Disable All: reset both to No Auto-Sell/Salvage
- Shows current state summary (Sell X | Salvage Y)
- Also fixes init.js and build.sh to include new file
2026-07-26 12:42:56 -04:00
GaboGG
2f680a630d v0.13.2 - Rewrite armory.js with actual page DOM support
- Scrap the old floating panel approach (wrong DOM selectors)
- Now injects a toolbar directly into the equipment list on the Armory page
- Parses equipment from native #equiplist table rows using correct
  DOM selectors (hover_equip, select_equip, eqids[] checkboxes)
- Detects current screen (organize/sell/salvage/modify) to show relevant
  bulk-select buttons per tab
- Sell tab: select Crude, select <=Fair
- Salvage tab: select salvage-grade, select <=Average
- Organize tab: select equipped (for pinning)
- Plus: Select All, Invert, Clear on every screen
- Grades by quality: Keep (Magnificent+), Keep (Superior),
  Salvage (Average-Fair), Sell (Crude)
- Resets properly across page navigations (single-use id guard)
2026-07-26 11:33:10 -04:00
GaboGG
1669167373 v0.13.1 - Smart Armory, removed broken sell/salvage buttons
- Removed enhanceEquipShop() — broken bulk sell/salvage from equip shop page
- Rewrote enhanceArmory() with actionable equipment management panel:
  - Parses all equipment from the Armory (ss=am) page
  - Grades each piece by quality: Keep (Magnificent+), Keep (Superior),
    Salvage (Average-Fair), Sell (Crude)
  - Bulk Sell / Bulk Salvage buttons that click native game buttons
  - Shows slot separators, quality colors, status icons (equipped/locked/stored)
  - Sorting: equipped/pinned first, then by quality, then by level
  - Summary counts for each action category
2026-07-26 11:28:21 -04:00
GaboGG
2107527c72 v0.13.0 - Heartseeker buff, channeling efficiency, 100% buff uptime
- Added Heartseeker to BUFF_PRIORITY (+25% phys dmg, +10% crit self-buff)
- Channeling consumption: mp_cost/(dur+1) scoring, no arbitrary cutoff
- KickstartChanneling: prefers highest-MP-cost buffs for better proc chance
- Raised minTurns on all buffs for 100% uptime (Haste/Protect/Regen/Absorb/Shadow 2->4, Spark 1->3)
- Updated knowledge-base spellUnlocks and milestones
- Removed <10 turn hard cutoff from channeling target selection
2026-07-26 11:25:40 -04:00
GaboGG
3a041f41da Fix boss detection: remove SP bar check, only use gold border
At Lv100+ / Hell difficulty, all normal monsters also have SP bars
(the red nbarred.png). This made the script think every monster was
a boss, triggering debuffs (Imperil/Weaken) on every fight and
draining MP.

Changes:
- isRareMonster() no longer checks for nbarred.png
- Only gold border (BD7400/E6CCA3) indicates a real boss
- Debuffs now only fire on gold-border bosses, not on ≤2 monsters
2026-07-23 17:53:47 -04:00
GaboGG
3777de77fa Spirit gems: P-slot gem used immediately, draughts/potions at threshold
Spirit item logic split by source:
- P-slot gem (10007): used immediately on every turn, free to refill
  with crystals, keeps SP permanently high for Spark + Stance
- Spirit Draughts/Potions in item slots: only used when SP < threshold (30%)
  to conserve consumable credits
2026-07-22 07:13:55 -04:00
GaboGG
a90dd47ec0 Spirit gems: use whenever available, no SP threshold
Spirit gems now fire whenever one is slotted regardless of SP level.
This keeps SP constantly topped up for:
- Spark of Life (costs 50% SP to trigger)
- Manual Spirit Stance (costs 1 SP + 10% OC per round)
Removed the old SP < 30% threshold check.
2026-07-22 07:11:40 -04:00
GaboGG
cdd0fe5984 Spirit Stance: manual only, auto-disable at 65% SP (Spark needs 50%)
Spark of Life consumes 50% of your SP bar when triggered. If you're in
Spirit Stance with low SP, Spark fails to proc. Changes:
- No auto-activation of Spirit Stance (toggle manually with S key)
- Auto-disable if SP drops below 65% to reserve SP for Spark trigger
- Veteran still has optional auto-activation via CFG.autoSpirit but
  requires SP > 65% (practically never triggers)
2026-07-22 06:50:51 -04:00
GaboGG
0bbdb66b14 Fix Spark of Life icon key: sparklife.png, not fallenshield
The active buff icon is /y/e/sparklife.png -> stored as 'sparklife'.
The 'fallenshield.png' check is for detecting when it has been consumed
(triggered), not for the active buff. This was causing the script to
think Spark of Life was never active, recasting it every turn.
2026-07-22 06:18:39 -04:00
GaboGG
e745505c6e Bump version to 0.12.0 2026-07-22 06:15:24 -04:00
GaboGG
b69eabd1eb Fix: Spark of Life icon key, mana items after buffs
1. Spark of Life icon is 'fallenshield.png' not 'spark_of_life' -
   fixed BUFF_PRIORITY key so buff detection works correctly
2. Mana/spirit items moved to AFTER buffs in all 3 tiers -
   was drinking mana potions on turn 2 before buffs were cast
3. Priority order: Health items -> Cure -> Buffs -> Mana items ->
   Skills -> Spirit Stance -> Damage spells -> Channeling -> Attack
2026-07-22 06:13:54 -04:00
GaboGG
d9fc1e547c Fix channeling: consume charge on useful spell, don't let it wear off
Channeling works: proc on mana-costing spell -> next spell costs 1 MP
and is 50% stronger/longer. The charge lasts 5 ticks (15 with Mystic
Gem) then wears off and is wasted.

Previously the script would basic attack with channeling charged,
wasting the bonus. Now:
- If channeling is active and nothing more urgent, still cast a buff
  (refresh anything under 10 turns) or a cheap damage spell
- Never basic attack while channeling is charged
- Novice/Adept/Veteran all have this protection
2026-07-21 14:45:23 -04:00
GaboGG
7093409580 Fix channeling: wiki-correct formula, Regen/Absorb as best triggers
Channeling wiki fix:
- Procs randomly on any mana-costing spell
- Proc chance = spell_cost / (base_mana * 1.2)
- Higher cost = higher chance (Regen/Absorb at 17 MP = ~6%)
- Cannot re-proc while already channeling
- Duration: 5 ticks (15 with Mystic Gem)
- Effect: next spell costs 1 MP, 50% stronger/longer

Kickstart now only refreshes expiring buffs (missing or < 5 turns)
with decent-cost spells (Regen/Absorb). No more cheap attack spells
at 4 MP = 1.4% proc chance — that was a waste of MP.

Defaults reverted to full-conservative values since the 'mp-focused'
win was based on wrong channeling assumptions.
2026-07-21 14:35:54 -04:00
GaboGG
f060bd31a8 Benchmark v3: 17 configs, chan-mp-focused wins (149 rounds)
Channeling experiments (Lv90, Nightmare, 5 runs each):
1. chan-mp-focused: 149.0 rounds (WINNER)
   - Mana gems at 70%, potions at 50% = stay MP-rich
   - Attack spells on for channeling kickstart
   - Buff refresh at < 15 turns
   - Spirit stance at OC 80, skills at OC 75
2. chan-no-buff-refresh: 143.0 (good, skip buff refresh chan)
3. chan-aggressive-buff: 142.4 (refresh buffs at < 20 turns)
4. chan-buff-only: 140.6 (no attack spells, buff refresh only)
5. conservative-items: 139.8 (old winner)

New defaults set to chan-mp-focused values.
2026-07-21 14:12:54 -04:00
GaboGG
0d57fead61 Shadow Veil fix: use correct icon key 'shadowveil', minTurns=3
Shadow Veil buff icon is stored as 'shadowveil' (from img src filename,
no underscore). Priority list now uses the correct key. minTurns=3
prevents recasting while still active. Also moved to last priority
position — only cast when MP is plentiful.
2026-07-21 14:07:17 -04:00
GaboGG
0ee31b7266 Benchmark v2 with real Lv90 stats, Shadow Veil removed, full-conservative defaults
Shadow Veil removed from BUFF_PRIORITY - was draining MP aggressively.
Player stats updated to match real character (effective values with gear).

Benchmark results (Lv90, Nightmare, 5 runs each):
1. full-conservative: 146 rounds, 4485 dmg/rd — WINNER
2. conservative-items: 143 rounds, 4468 dmg/rd
3. spirit-40: 136 rounds, 4457 dmg/rd

New defaults (full-conservative):
- cureHP: 0.45, cureItemHP: 0.50 (save items use cure)
- manaGemMP: 0.45, manaPotionMP: 0.25
- spiritPotionSP: 0.30, spiritStanceOC: 80
- skillOC: 75
2026-07-21 14:00:44 -04:00
GaboGG
4bc90d9332 Monster Lab floating panel + page detection, Beast recommendation
- Monster Lab page detected via ss=ml
- Floating draggable panel replaces inline UI (was messing layout)
- Feed All + Happy Pills All buttons
- Class recommendation for first monster
- Drag-to-move via header grab
2026-07-20 20:35:14 -04:00
GaboGG
e8c3f465d2 Spirit Stance: 40% SP minimum to toggle on (from 20%)
At 20% SP (~10 SP = 10 rounds of sustain), the player would toggle on
during a Grindfest round, consume SP quickly, toggle off when SP < 3%,
then 3 turns later the cooldown expires and OC is back to 60+ -> toggle
on again. Raising the threshold to 40% means ~20 rounds of sustained
Spirit Stance, making the engagement meaningful and rarely cycling.
2026-07-20 20:19:58 -04:00
GaboGG
a415b932d3 Spirit Stance: require 20% SP to toggle on, prevent flip-flop
Spirit Stance costs 1 SP + 10% OC per round (wiki). Previously toggled
on at 10% SP which meant ~5 rounds of sustain, often running out
immediately. Now requires 20% SP (~10 rounds sustain) to toggle on.
3-turn cooldown still prevents rapid flip-flopping between states.
2026-07-20 20:18:02 -04:00
GaboGG
e415a7660f Fix spirit stance flip-flop: 3-turn cooldown on toggle
Spirit stance was toggling on/off every turn because conditions (OC >= 60,
SP > 10%) would be met immediately after toggling off. Added a 3-turn
cooldown via STATE._spiritCooldown that blocks re-toggling until it
expires. Prevents wasted turns on spirit stance spam.
2026-07-20 20:00:19 -04:00
GaboGG
eb5f99dbfb Fix: skills before spirit stance, Rending Blow priority reorder
Priority order now:
1. Items
2. Cure
3. Buffs
4. Debuffs
5. Weapon skills (BEFORE spirit stance - fixes Rending Blow never firing)
   - Rending Blow first (AoE clear)
   - Shatter Strike second (needs Penetrated Armor)
   - Great Cleave last (single target, bosses only)
6. Spirit Stance (only if OC didn't get spent on skills)
7. Damage spells
8. Channeling kickstart
9. Basic attack
2026-07-20 19:58:27 -04:00
GaboGG
39ad28007c Sim benchmark: full-conservative wins, configurable skill OC
Benchmark results (1000 rounds, Lv64 Nightmare, infinite items):
1. full-conservative: 225.6 rounds, 3141 dmg/rd — BEST
2. conservative-items: 223.6 rounds, 3128 dmg/rd
3. attack-spells: 213.0 rounds, 2974 dmg/rd

Changes:
- Grindfest scaling: monsters +1 per 100 rounds, damage +0.4%/round
- skillOC config option (default: 70) for weapon skill OC threshold
- Spirit gem threshold bumped to 45%
- Simulator uses real monster count/damage scaling from wiki
- Benchmark results saved to simulator/results/benchmark.json
2026-07-20 19:53:03 -04:00
GaboGG
402db6bb2f Initial commit: HV Unified v0.11.0 structure
- 23 source files in src/ (build via scripts/build.sh)
- Forum-sourced player knowledge in references/
- DESIGN.md with architecture and corrections
- References to existing scripts (Monsterbation, jpx, HV Utils)
2026-07-20 19:30:26 -04:00