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)
This commit is contained in:
parent
3f865ee6fd
commit
e74c97f87a
5 changed files with 15 additions and 9 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name HV Unified
|
// @name HV Unified
|
||||||
// @namespace hvunified
|
// @namespace hvunified
|
||||||
// @version 0.13.16
|
// @version 0.13.17
|
||||||
// @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.16';
|
const VERSION = '0.13.17';
|
||||||
|
|
||||||
const CFG = {
|
const CFG = {
|
||||||
// — Battle automation
|
// — Battle automation
|
||||||
|
|
@ -903,7 +903,9 @@ function findBestChannelingTarget() {
|
||||||
const sp = findSpell(b.spell);
|
const sp = findSpell(b.spell);
|
||||||
const mpCost = sp ? sp.mp : 0;
|
const mpCost = sp ? sp.mp : 0;
|
||||||
// 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
|
||||||
const maxDur = STATE.maxBuffDur[b.icon] || (dur + 10); // fallback if unknown
|
let maxDur = STATE.maxBuffDur[b.icon] || 0;
|
||||||
|
// If max matches current (first observation, no learning yet), assume min 30 turns
|
||||||
|
if (maxDur <= dur) maxDur = Math.max(dur + 1, 30);
|
||||||
const emptiness = maxDur > 0 ? Math.min(1, (maxDur - dur) / maxDur) : 1;
|
const emptiness = maxDur > 0 ? Math.min(1, (maxDur - dur) / maxDur) : 1;
|
||||||
// Score: emptiness × mp_cost — an empty expensive buff is best
|
// Score: emptiness × mp_cost — an empty expensive buff is best
|
||||||
const score = emptiness * mpCost;
|
const score = emptiness * mpCost;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name HV Unified
|
// @name HV Unified
|
||||||
// @namespace hvunified
|
// @namespace hvunified
|
||||||
// @version 0.13.16
|
// @version 0.13.17
|
||||||
// @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.16';
|
const VERSION = '0.13.17';
|
||||||
|
|
||||||
const CFG = {
|
const CFG = {
|
||||||
// — Battle automation
|
// — Battle automation
|
||||||
|
|
@ -903,7 +903,9 @@ function findBestChannelingTarget() {
|
||||||
const sp = findSpell(b.spell);
|
const sp = findSpell(b.spell);
|
||||||
const mpCost = sp ? sp.mp : 0;
|
const mpCost = sp ? sp.mp : 0;
|
||||||
// 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
|
||||||
const maxDur = STATE.maxBuffDur[b.icon] || (dur + 10); // fallback if unknown
|
let maxDur = STATE.maxBuffDur[b.icon] || 0;
|
||||||
|
// If max matches current (first observation, no learning yet), assume min 30 turns
|
||||||
|
if (maxDur <= dur) maxDur = Math.max(dur + 1, 30);
|
||||||
const emptiness = maxDur > 0 ? Math.min(1, (maxDur - dur) / maxDur) : 1;
|
const emptiness = maxDur > 0 ? Math.min(1, (maxDur - dur) / maxDur) : 1;
|
||||||
// Score: emptiness × mp_cost — an empty expensive buff is best
|
// Score: emptiness × mp_cost — an empty expensive buff is best
|
||||||
const score = emptiness * mpCost;
|
const score = emptiness * mpCost;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// CONFIG — default settings
|
// CONFIG — default settings
|
||||||
// ═══════════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
const VERSION = '0.13.16';
|
const VERSION = '0.13.17';
|
||||||
|
|
||||||
const CFG = {
|
const CFG = {
|
||||||
// — Battle automation
|
// — Battle automation
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name HV Unified
|
// @name HV Unified
|
||||||
// @namespace hvunified
|
// @namespace hvunified
|
||||||
// @version 0.13.16
|
// @version 0.13.17
|
||||||
// @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/*
|
||||||
|
|
|
||||||
|
|
@ -240,7 +240,9 @@ function findBestChannelingTarget() {
|
||||||
const sp = findSpell(b.spell);
|
const sp = findSpell(b.spell);
|
||||||
const mpCost = sp ? sp.mp : 0;
|
const mpCost = sp ? sp.mp : 0;
|
||||||
// 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
|
||||||
const maxDur = STATE.maxBuffDur[b.icon] || (dur + 10); // fallback if unknown
|
let maxDur = STATE.maxBuffDur[b.icon] || 0;
|
||||||
|
// If max matches current (first observation, no learning yet), assume min 30 turns
|
||||||
|
if (maxDur <= dur) maxDur = Math.max(dur + 1, 30);
|
||||||
const emptiness = maxDur > 0 ? Math.min(1, (maxDur - dur) / maxDur) : 1;
|
const emptiness = maxDur > 0 ? Math.min(1, (maxDur - dur) / maxDur) : 1;
|
||||||
// Score: emptiness × mp_cost — an empty expensive buff is best
|
// Score: emptiness × mp_cost — an empty expensive buff is best
|
||||||
const score = emptiness * mpCost;
|
const score = emptiness * mpCost;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue