v0.13.23 - Fix affordable MP check using actual current MP from DOM

- Was using vrhd (HP element) instead of vrm (current MP)
- Now reads #vrm textContent for current MP value
- Simply compares mpCost > curMp to skip unaffordable spells
- This prevents the infinite Heartseeker loop when you
  don't have enough MP even though the buff is a good target
This commit is contained in:
GaboGG 2026-07-26 15:09:38 -04:00
parent 31799a7261
commit 0aa268b3f9
5 changed files with 15 additions and 12 deletions

View file

@ -1,7 +1,7 @@
// ==UserScript== // ==UserScript==
// @name HV Unified // @name HV Unified
// @namespace hvunified // @namespace hvunified
// @version 0.13.22 // @version 0.13.23
// @description HV Unified — battle automation, guidance, and UI enhancements for HentaiVerse // @description HV Unified — battle automation, guidance, and UI enhancements for HentaiVerse
// @author GaboGG + Hermes // @author GaboGG + Hermes
// @match *://*.hentaiverse.org/* // @match *://*.hentaiverse.org/*
@ -17,7 +17,7 @@
// CONFIG — default settings // CONFIG — default settings
// ═══════════════════════════════════════════════════════════════════════ // ═══════════════════════════════════════════════════════════════════════
const VERSION = '0.13.22'; const VERSION = '0.13.23';
const CFG = { const CFG = {
// — Battle automation // — Battle automation
@ -940,8 +940,9 @@ function findBestChannelingTarget() {
} }
// Skip if we can't afford the base cost — game pre-checks even when // Skip if we can't afford the base cost — game pre-checks even when
// channeling makes the effective cost 1 MP // channeling makes the effective cost 1 MP
const maxMp = parseInt((document.getElementById('vrhd') || {}).textContent) || 414; const curMp = parseInt((document.getElementById('vrm') || {}).textContent) || 0;
if (mpCost > 0 && (mpCost / maxMp) > STATE.mp) continue; const estMaxMp = (STATE.mp > 0 && curMp > 0) ? Math.round(curMp / STATE.mp) : 414;
if (mpCost > 0 && curMp > 0 && mpCost > curMp) continue;
// Fill level: how empty is this buff relative to its max observed duration // Fill level: how empty is this buff relative to its max observed duration
let maxDur = STATE.maxBuffDur[b.icon] || 0; let maxDur = STATE.maxBuffDur[b.icon] || 0;
// If max matches current (first observation, no learning yet), assume min 30 turns // If max matches current (first observation, no learning yet), assume min 30 turns

View file

@ -1,7 +1,7 @@
// ==UserScript== // ==UserScript==
// @name HV Unified // @name HV Unified
// @namespace hvunified // @namespace hvunified
// @version 0.13.22 // @version 0.13.23
// @description HV Unified — battle automation, guidance, and UI enhancements for HentaiVerse // @description HV Unified — battle automation, guidance, and UI enhancements for HentaiVerse
// @author GaboGG + Hermes // @author GaboGG + Hermes
// @match *://*.hentaiverse.org/* // @match *://*.hentaiverse.org/*
@ -17,7 +17,7 @@
// CONFIG — default settings // CONFIG — default settings
// ═══════════════════════════════════════════════════════════════════════ // ═══════════════════════════════════════════════════════════════════════
const VERSION = '0.13.22'; const VERSION = '0.13.23';
const CFG = { const CFG = {
// — Battle automation // — Battle automation
@ -940,8 +940,9 @@ function findBestChannelingTarget() {
} }
// Skip if we can't afford the base cost — game pre-checks even when // Skip if we can't afford the base cost — game pre-checks even when
// channeling makes the effective cost 1 MP // channeling makes the effective cost 1 MP
const maxMp = parseInt((document.getElementById('vrhd') || {}).textContent) || 414; const curMp = parseInt((document.getElementById('vrm') || {}).textContent) || 0;
if (mpCost > 0 && (mpCost / maxMp) > STATE.mp) continue; const estMaxMp = (STATE.mp > 0 && curMp > 0) ? Math.round(curMp / STATE.mp) : 414;
if (mpCost > 0 && curMp > 0 && mpCost > curMp) continue;
// Fill level: how empty is this buff relative to its max observed duration // Fill level: how empty is this buff relative to its max observed duration
let maxDur = STATE.maxBuffDur[b.icon] || 0; let maxDur = STATE.maxBuffDur[b.icon] || 0;
// If max matches current (first observation, no learning yet), assume min 30 turns // If max matches current (first observation, no learning yet), assume min 30 turns

View file

@ -2,7 +2,7 @@
// CONFIG — default settings // CONFIG — default settings
// ═══════════════════════════════════════════════════════════════════════ // ═══════════════════════════════════════════════════════════════════════
const VERSION = '0.13.22'; const VERSION = '0.13.23';
const CFG = { const CFG = {
// — Battle automation // — Battle automation

View file

@ -1,7 +1,7 @@
// ==UserScript== // ==UserScript==
// @name HV Unified // @name HV Unified
// @namespace hvunified // @namespace hvunified
// @version 0.13.22 // @version 0.13.23
// @description HV Unified — battle automation, guidance, and UI enhancements for HentaiVerse // @description HV Unified — battle automation, guidance, and UI enhancements for HentaiVerse
// @author GaboGG + Hermes // @author GaboGG + Hermes
// @match *://*.hentaiverse.org/* // @match *://*.hentaiverse.org/*

View file

@ -255,8 +255,9 @@ function findBestChannelingTarget() {
} }
// Skip if we can't afford the base cost — game pre-checks even when // Skip if we can't afford the base cost — game pre-checks even when
// channeling makes the effective cost 1 MP // channeling makes the effective cost 1 MP
const maxMp = parseInt((document.getElementById('vrhd') || {}).textContent) || 414; const curMp = parseInt((document.getElementById('vrm') || {}).textContent) || 0;
if (mpCost > 0 && (mpCost / maxMp) > STATE.mp) continue; const estMaxMp = (STATE.mp > 0 && curMp > 0) ? Math.round(curMp / STATE.mp) : 414;
if (mpCost > 0 && curMp > 0 && mpCost > curMp) continue;
// Fill level: how empty is this buff relative to its max observed duration // Fill level: how empty is this buff relative to its max observed duration
let maxDur = STATE.maxBuffDur[b.icon] || 0; let maxDur = STATE.maxBuffDur[b.icon] || 0;
// If max matches current (first observation, no learning yet), assume min 30 turns // If max matches current (first observation, no learning yet), assume min 30 turns