diff --git a/scripts/hv-unified.user.js b/scripts/hv-unified.user.js index 508784f..77b2594 100644 --- a/scripts/hv-unified.user.js +++ b/scripts/hv-unified.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name HV Unified // @namespace hvunified -// @version 0.13.19 +// @version 0.13.20 // @description HV Unified — battle automation, guidance, and UI enhancements for HentaiVerse // @author GaboGG + Hermes // @match *://*.hentaiverse.org/* @@ -17,7 +17,7 @@ // CONFIG — default settings // ═══════════════════════════════════════════════════════════════════════ -const VERSION = '0.13.19'; +const VERSION = '0.13.20'; const CFG = { // — Battle automation @@ -580,6 +580,18 @@ function hasUsableGem(type) { // KNOWLEDGE BASE — game data, spell unlocks, milestones, stat advice // ═══════════════════════════════════════════════════════════════════════ +// Base MP costs for buff spells (used for channeling value calculation when +// the DOM shows Mana Conservation-reduced costs like 1 MP) +const SPELL_COSTS = { + 'Absorb': 40, + 'Haste': 51, + 'Heartseeker': 141, + 'Protection': 32, + 'Regen': 71, + 'Shadow Veil': 52, + 'Spark of Life': 70, +}; + const KB = { qualities: ['Crude', 'Fair', 'Average', 'Superior', 'Exquisite', 'Magnificent', 'Legendary', 'Peerless'], @@ -903,7 +915,15 @@ function findBestChannelingTarget() { const dur = buffDuration(b.icon); if (b.icon === 'regen' && STATE.hp >= CFG.cureRegenHP) continue; const sp = findSpell(b.spell); - const mpCost = sp ? sp.mp : 0; + // Use a reasonable MP cost: ignore Mana Conservation-reduced values + // (the DOM may show 1 MP at high proficiency, but the real base cost + // determines the savings from a free channeling cast) + let mpCost = sp ? sp.mp : 0; + if (mpCost > 0 && mpCost < 5 && sp) { + // Try to get base cost from knowledge-base + const kb = SPELL_COSTS[b.spell]; + if (kb) mpCost = kb; + } // Fill level: how empty is this buff relative to its max observed duration let maxDur = STATE.maxBuffDur[b.icon] || 0; // If max matches current (first observation, no learning yet), assume min 30 turns diff --git a/scripts/latest.user.js b/scripts/latest.user.js index 508784f..77b2594 100644 --- a/scripts/latest.user.js +++ b/scripts/latest.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name HV Unified // @namespace hvunified -// @version 0.13.19 +// @version 0.13.20 // @description HV Unified — battle automation, guidance, and UI enhancements for HentaiVerse // @author GaboGG + Hermes // @match *://*.hentaiverse.org/* @@ -17,7 +17,7 @@ // CONFIG — default settings // ═══════════════════════════════════════════════════════════════════════ -const VERSION = '0.13.19'; +const VERSION = '0.13.20'; const CFG = { // — Battle automation @@ -580,6 +580,18 @@ function hasUsableGem(type) { // KNOWLEDGE BASE — game data, spell unlocks, milestones, stat advice // ═══════════════════════════════════════════════════════════════════════ +// Base MP costs for buff spells (used for channeling value calculation when +// the DOM shows Mana Conservation-reduced costs like 1 MP) +const SPELL_COSTS = { + 'Absorb': 40, + 'Haste': 51, + 'Heartseeker': 141, + 'Protection': 32, + 'Regen': 71, + 'Shadow Veil': 52, + 'Spark of Life': 70, +}; + const KB = { qualities: ['Crude', 'Fair', 'Average', 'Superior', 'Exquisite', 'Magnificent', 'Legendary', 'Peerless'], @@ -903,7 +915,15 @@ function findBestChannelingTarget() { const dur = buffDuration(b.icon); if (b.icon === 'regen' && STATE.hp >= CFG.cureRegenHP) continue; const sp = findSpell(b.spell); - const mpCost = sp ? sp.mp : 0; + // Use a reasonable MP cost: ignore Mana Conservation-reduced values + // (the DOM may show 1 MP at high proficiency, but the real base cost + // determines the savings from a free channeling cast) + let mpCost = sp ? sp.mp : 0; + if (mpCost > 0 && mpCost < 5 && sp) { + // Try to get base cost from knowledge-base + const kb = SPELL_COSTS[b.spell]; + if (kb) mpCost = kb; + } // Fill level: how empty is this buff relative to its max observed duration let maxDur = STATE.maxBuffDur[b.icon] || 0; // If max matches current (first observation, no learning yet), assume min 30 turns diff --git a/src/config.js b/src/config.js index e45aaea..efe273a 100644 --- a/src/config.js +++ b/src/config.js @@ -2,7 +2,7 @@ // CONFIG — default settings // ═══════════════════════════════════════════════════════════════════════ -const VERSION = '0.13.19'; +const VERSION = '0.13.20'; const CFG = { // — Battle automation diff --git a/src/header.user.js b/src/header.user.js index 00cd0b5..39f3de4 100644 --- a/src/header.user.js +++ b/src/header.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name HV Unified // @namespace hvunified -// @version 0.13.19 +// @version 0.13.20 // @description HV Unified — battle automation, guidance, and UI enhancements for HentaiVerse // @author GaboGG + Hermes // @match *://*.hentaiverse.org/* diff --git a/src/knowledge-base.js b/src/knowledge-base.js index 085d905..6ea02a3 100644 --- a/src/knowledge-base.js +++ b/src/knowledge-base.js @@ -2,6 +2,18 @@ // KNOWLEDGE BASE — game data, spell unlocks, milestones, stat advice // ═══════════════════════════════════════════════════════════════════════ +// Base MP costs for buff spells (used for channeling value calculation when +// the DOM shows Mana Conservation-reduced costs like 1 MP) +const SPELL_COSTS = { + 'Absorb': 40, + 'Haste': 51, + 'Heartseeker': 141, + 'Protection': 32, + 'Regen': 71, + 'Shadow Veil': 52, + 'Spark of Life': 70, +}; + const KB = { qualities: ['Crude', 'Fair', 'Average', 'Superior', 'Exquisite', 'Magnificent', 'Legendary', 'Peerless'], diff --git a/src/strategy-engine.js b/src/strategy-engine.js index 292a171..be3a344 100644 --- a/src/strategy-engine.js +++ b/src/strategy-engine.js @@ -238,7 +238,15 @@ function findBestChannelingTarget() { const dur = buffDuration(b.icon); if (b.icon === 'regen' && STATE.hp >= CFG.cureRegenHP) continue; const sp = findSpell(b.spell); - const mpCost = sp ? sp.mp : 0; + // Use a reasonable MP cost: ignore Mana Conservation-reduced values + // (the DOM may show 1 MP at high proficiency, but the real base cost + // determines the savings from a free channeling cast) + let mpCost = sp ? sp.mp : 0; + if (mpCost > 0 && mpCost < 5 && sp) { + // Try to get base cost from knowledge-base + const kb = SPELL_COSTS[b.spell]; + if (kb) mpCost = kb; + } // Fill level: how empty is this buff relative to its max observed duration let maxDur = STATE.maxBuffDur[b.icon] || 0; // If max matches current (first observation, no learning yet), assume min 30 turns