v0.13.31 - Enhanced battle logging for deep diagnostics

- Q-key log now shows: HP, current MP, MP%, SP%, OC, monster count,
  buff durations, and per-monster SP bar levels (spBars: 0:120 1:95 ...)
- High-threat detection logs a red '⚠ HIGH THREAT' warning
- Emergency skill usage at low OC logs an orange '⚠ emergency' warning
- Now you can paste me the console log and I'll see exact threat levels,
  why skills did/didn't fire, and what the state was before each action
This commit is contained in:
GaboGG 2026-07-27 13:13:59 -04:00
parent b5a5c3df54
commit 533fad252a
6 changed files with 63 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.30 // @version 0.13.31
// @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.30'; const VERSION = '0.13.31';
const CFG = { const CFG = {
// — Battle automation // — Battle automation
@ -1260,8 +1260,10 @@ function strategyAdept() {
// 5. Weapon skills — prioritize high-threat monsters (high SP/OC bar) // 5. Weapon skills — prioritize high-threat monsters (high SP/OC bar)
const isHighThreat = hasHighThreat(THREAT_PX); const isHighThreat = hasHighThreat(THREAT_PX);
if (isHighThreat) console.log('%c[HV] ⚠ HIGH THREAT (Adept): 2+ monsters with SP >85%', 'color:#f44');
const skillOC_N = CFG.skillOC || 75; const skillOC_N = CFG.skillOC || 75;
if (STATE.oc >= skillOC_N || isHighThreat) { if (STATE.oc >= skillOC_N || isHighThreat) {
if (isHighThreat && STATE.oc < skillOC_N) console.log('%c[HV] ⚠ emergency skill at OC=' + STATE.oc.toFixed(0), 'color:#f80');
// Rending Blow: AoE armor pen vs 5+ enemies (highest priority in Grindfest) // Rending Blow: AoE armor pen vs 5+ enemies (highest priority in Grindfest)
if (STATE.monsters.length >= 5 && STATE.skillsKnown.includes('Rending Blow')) { if (STATE.monsters.length >= 5 && STATE.skillsKnown.includes('Rending Blow')) {
const t = isHighThreat ? findDangerousMonster() : findStrongestMonster(); const t = isHighThreat ? findDangerousMonster() : findStrongestMonster();
@ -1395,9 +1397,11 @@ function strategyVeteran() {
// 5. Weapon skills — prioritize high-threat monsters (high SP/OC bar) // 5. Weapon skills — prioritize high-threat monsters (high SP/OC bar)
// If 2+ enemies have >85% SP bar, they're about to special — emergency // If 2+ enemies have >85% SP bar, they're about to special — emergency
const isHighThreat = hasHighThreat(THREAT_PX); const isHighThreat = hasHighThreat(THREAT_PX);
if (isHighThreat) console.log('%c[HV] ⚠ HIGH THREAT: 2+ monsters with SP >85%', 'color:#f44');
const askillOC3 = CFG.skillOC || 80; const askillOC3 = CFG.skillOC || 80;
if (STATE.oc >= askillOC3 || isHighThreat) { if (STATE.oc >= askillOC3 || isHighThreat) {
if (isHighThreat && STATE.oc < askillOC3) console.log('%c[HV] ⚠ emergency: using skill at OC=' + STATE.oc.toFixed(0), 'color:#f80');
// Emergency: 2+ monsters about to special — spend OC to kill them fast // Emergency: 2+ monsters about to special — spend OC to kill them fast
// Rending Blow: AoE armor pen vs 5+ enemies (highest priority in Grindfest) // Rending Blow: AoE armor pen vs 5+ enemies (highest priority in Grindfest)
if (STATE.monsters.length >= 5 && STATE.skillsKnown.includes('Rending Blow')) { if (STATE.monsters.length >= 5 && STATE.skillsKnown.includes('Rending Blow')) {
@ -1626,11 +1630,24 @@ function setupKeybindings() {
console.log('%c[HV] Q pressed — checking action...', 'color:#888'); console.log('%c[HV] Q pressed — checking action...', 'color:#888');
parseBattleState(); parseBattleState();
// Debug: show active buffs and channeling status // Debug: show full battle state
const activeBuffs = Object.entries(STATE.buffs) const activeBuffs = Object.entries(STATE.buffs)
.filter(([k, v]) => v > 0 && k !== 'regen' || v > 0) .filter(([k, v]) => v > 0 && k !== 'regen' || v > 0)
.map(([k, v]) => `${k}=${v}`).join(' '); .map(([k, v]) => `${k}=${v}`).join(' ');
console.log(`%c[HV] ch=${STATE.channeling} mp=${(STATE.mp*100).toFixed(0)}% oc=${STATE.oc.toFixed(0)} buffs: ${activeBuffs}`, 'color:#888'); // Monster SP bars (threat levels)
const threatLevels = STATE.monsters.map((m, i) => {
const sp = STATE.monsterSp[i] || 0;
return `${i}:${sp}`;
}).join(' ');
const curMp = parseInt((document.getElementById('vrm') || {}).textContent) || 0;
const curHp = parseInt((document.getElementById('vrhd') || {}).textContent) || 0;
console.log(
`%c[HV] ch=${STATE.channeling} hp=${curHp} mp=${curMp}(${(STATE.mp*100).toFixed(0)}%) ` +
`sp=${(STATE.sp*100).toFixed(0)}% oc=${STATE.oc.toFixed(0)} ` +
`mon:${STATE.monsters.length} ` +
`buffs: ${activeBuffs} | spBars: ${threatLevels}`,
'color:#888'
);
const a = getRecommendedAction(); const a = getRecommendedAction();
if (a) { if (a) {
e.preventDefault(); e.preventDefault();

View file

@ -1,7 +1,7 @@
// ==UserScript== // ==UserScript==
// @name HV Unified // @name HV Unified
// @namespace hvunified // @namespace hvunified
// @version 0.13.30 // @version 0.13.31
// @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.30'; const VERSION = '0.13.31';
const CFG = { const CFG = {
// — Battle automation // — Battle automation
@ -1260,8 +1260,10 @@ function strategyAdept() {
// 5. Weapon skills — prioritize high-threat monsters (high SP/OC bar) // 5. Weapon skills — prioritize high-threat monsters (high SP/OC bar)
const isHighThreat = hasHighThreat(THREAT_PX); const isHighThreat = hasHighThreat(THREAT_PX);
if (isHighThreat) console.log('%c[HV] ⚠ HIGH THREAT (Adept): 2+ monsters with SP >85%', 'color:#f44');
const skillOC_N = CFG.skillOC || 75; const skillOC_N = CFG.skillOC || 75;
if (STATE.oc >= skillOC_N || isHighThreat) { if (STATE.oc >= skillOC_N || isHighThreat) {
if (isHighThreat && STATE.oc < skillOC_N) console.log('%c[HV] ⚠ emergency skill at OC=' + STATE.oc.toFixed(0), 'color:#f80');
// Rending Blow: AoE armor pen vs 5+ enemies (highest priority in Grindfest) // Rending Blow: AoE armor pen vs 5+ enemies (highest priority in Grindfest)
if (STATE.monsters.length >= 5 && STATE.skillsKnown.includes('Rending Blow')) { if (STATE.monsters.length >= 5 && STATE.skillsKnown.includes('Rending Blow')) {
const t = isHighThreat ? findDangerousMonster() : findStrongestMonster(); const t = isHighThreat ? findDangerousMonster() : findStrongestMonster();
@ -1395,9 +1397,11 @@ function strategyVeteran() {
// 5. Weapon skills — prioritize high-threat monsters (high SP/OC bar) // 5. Weapon skills — prioritize high-threat monsters (high SP/OC bar)
// If 2+ enemies have >85% SP bar, they're about to special — emergency // If 2+ enemies have >85% SP bar, they're about to special — emergency
const isHighThreat = hasHighThreat(THREAT_PX); const isHighThreat = hasHighThreat(THREAT_PX);
if (isHighThreat) console.log('%c[HV] ⚠ HIGH THREAT: 2+ monsters with SP >85%', 'color:#f44');
const askillOC3 = CFG.skillOC || 80; const askillOC3 = CFG.skillOC || 80;
if (STATE.oc >= askillOC3 || isHighThreat) { if (STATE.oc >= askillOC3 || isHighThreat) {
if (isHighThreat && STATE.oc < askillOC3) console.log('%c[HV] ⚠ emergency: using skill at OC=' + STATE.oc.toFixed(0), 'color:#f80');
// Emergency: 2+ monsters about to special — spend OC to kill them fast // Emergency: 2+ monsters about to special — spend OC to kill them fast
// Rending Blow: AoE armor pen vs 5+ enemies (highest priority in Grindfest) // Rending Blow: AoE armor pen vs 5+ enemies (highest priority in Grindfest)
if (STATE.monsters.length >= 5 && STATE.skillsKnown.includes('Rending Blow')) { if (STATE.monsters.length >= 5 && STATE.skillsKnown.includes('Rending Blow')) {
@ -1626,11 +1630,24 @@ function setupKeybindings() {
console.log('%c[HV] Q pressed — checking action...', 'color:#888'); console.log('%c[HV] Q pressed — checking action...', 'color:#888');
parseBattleState(); parseBattleState();
// Debug: show active buffs and channeling status // Debug: show full battle state
const activeBuffs = Object.entries(STATE.buffs) const activeBuffs = Object.entries(STATE.buffs)
.filter(([k, v]) => v > 0 && k !== 'regen' || v > 0) .filter(([k, v]) => v > 0 && k !== 'regen' || v > 0)
.map(([k, v]) => `${k}=${v}`).join(' '); .map(([k, v]) => `${k}=${v}`).join(' ');
console.log(`%c[HV] ch=${STATE.channeling} mp=${(STATE.mp*100).toFixed(0)}% oc=${STATE.oc.toFixed(0)} buffs: ${activeBuffs}`, 'color:#888'); // Monster SP bars (threat levels)
const threatLevels = STATE.monsters.map((m, i) => {
const sp = STATE.monsterSp[i] || 0;
return `${i}:${sp}`;
}).join(' ');
const curMp = parseInt((document.getElementById('vrm') || {}).textContent) || 0;
const curHp = parseInt((document.getElementById('vrhd') || {}).textContent) || 0;
console.log(
`%c[HV] ch=${STATE.channeling} hp=${curHp} mp=${curMp}(${(STATE.mp*100).toFixed(0)}%) ` +
`sp=${(STATE.sp*100).toFixed(0)}% oc=${STATE.oc.toFixed(0)} ` +
`mon:${STATE.monsters.length} ` +
`buffs: ${activeBuffs} | spBars: ${threatLevels}`,
'color:#888'
);
const a = getRecommendedAction(); const a = getRecommendedAction();
if (a) { if (a) {
e.preventDefault(); e.preventDefault();

View file

@ -2,7 +2,7 @@
// CONFIG — default settings // CONFIG — default settings
// ═══════════════════════════════════════════════════════════════════════ // ═══════════════════════════════════════════════════════════════════════
const VERSION = '0.13.30'; const VERSION = '0.13.31';
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.30 // @version 0.13.31
// @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

@ -30,11 +30,24 @@ function setupKeybindings() {
console.log('%c[HV] Q pressed — checking action...', 'color:#888'); console.log('%c[HV] Q pressed — checking action...', 'color:#888');
parseBattleState(); parseBattleState();
// Debug: show active buffs and channeling status // Debug: show full battle state
const activeBuffs = Object.entries(STATE.buffs) const activeBuffs = Object.entries(STATE.buffs)
.filter(([k, v]) => v > 0 && k !== 'regen' || v > 0) .filter(([k, v]) => v > 0 && k !== 'regen' || v > 0)
.map(([k, v]) => `${k}=${v}`).join(' '); .map(([k, v]) => `${k}=${v}`).join(' ');
console.log(`%c[HV] ch=${STATE.channeling} mp=${(STATE.mp*100).toFixed(0)}% oc=${STATE.oc.toFixed(0)} buffs: ${activeBuffs}`, 'color:#888'); // Monster SP bars (threat levels)
const threatLevels = STATE.monsters.map((m, i) => {
const sp = STATE.monsterSp[i] || 0;
return `${i}:${sp}`;
}).join(' ');
const curMp = parseInt((document.getElementById('vrm') || {}).textContent) || 0;
const curHp = parseInt((document.getElementById('vrhd') || {}).textContent) || 0;
console.log(
`%c[HV] ch=${STATE.channeling} hp=${curHp} mp=${curMp}(${(STATE.mp*100).toFixed(0)}%) ` +
`sp=${(STATE.sp*100).toFixed(0)}% oc=${STATE.oc.toFixed(0)} ` +
`mon:${STATE.monsters.length} ` +
`buffs: ${activeBuffs} | spBars: ${threatLevels}`,
'color:#888'
);
const a = getRecommendedAction(); const a = getRecommendedAction();
if (a) { if (a) {
e.preventDefault(); e.preventDefault();

View file

@ -560,8 +560,10 @@ function strategyAdept() {
// 5. Weapon skills — prioritize high-threat monsters (high SP/OC bar) // 5. Weapon skills — prioritize high-threat monsters (high SP/OC bar)
const isHighThreat = hasHighThreat(THREAT_PX); const isHighThreat = hasHighThreat(THREAT_PX);
if (isHighThreat) console.log('%c[HV] ⚠ HIGH THREAT (Adept): 2+ monsters with SP >85%', 'color:#f44');
const skillOC_N = CFG.skillOC || 75; const skillOC_N = CFG.skillOC || 75;
if (STATE.oc >= skillOC_N || isHighThreat) { if (STATE.oc >= skillOC_N || isHighThreat) {
if (isHighThreat && STATE.oc < skillOC_N) console.log('%c[HV] ⚠ emergency skill at OC=' + STATE.oc.toFixed(0), 'color:#f80');
// Rending Blow: AoE armor pen vs 5+ enemies (highest priority in Grindfest) // Rending Blow: AoE armor pen vs 5+ enemies (highest priority in Grindfest)
if (STATE.monsters.length >= 5 && STATE.skillsKnown.includes('Rending Blow')) { if (STATE.monsters.length >= 5 && STATE.skillsKnown.includes('Rending Blow')) {
const t = isHighThreat ? findDangerousMonster() : findStrongestMonster(); const t = isHighThreat ? findDangerousMonster() : findStrongestMonster();
@ -695,9 +697,11 @@ function strategyVeteran() {
// 5. Weapon skills — prioritize high-threat monsters (high SP/OC bar) // 5. Weapon skills — prioritize high-threat monsters (high SP/OC bar)
// If 2+ enemies have >85% SP bar, they're about to special — emergency // If 2+ enemies have >85% SP bar, they're about to special — emergency
const isHighThreat = hasHighThreat(THREAT_PX); const isHighThreat = hasHighThreat(THREAT_PX);
if (isHighThreat) console.log('%c[HV] ⚠ HIGH THREAT: 2+ monsters with SP >85%', 'color:#f44');
const askillOC3 = CFG.skillOC || 80; const askillOC3 = CFG.skillOC || 80;
if (STATE.oc >= askillOC3 || isHighThreat) { if (STATE.oc >= askillOC3 || isHighThreat) {
if (isHighThreat && STATE.oc < askillOC3) console.log('%c[HV] ⚠ emergency: using skill at OC=' + STATE.oc.toFixed(0), 'color:#f80');
// Emergency: 2+ monsters about to special — spend OC to kill them fast // Emergency: 2+ monsters about to special — spend OC to kill them fast
// Rending Blow: AoE armor pen vs 5+ enemies (highest priority in Grindfest) // Rending Blow: AoE armor pen vs 5+ enemies (highest priority in Grindfest)
if (STATE.monsters.length >= 5 && STATE.skillsKnown.includes('Rending Blow')) { if (STATE.monsters.length >= 5 && STATE.skillsKnown.includes('Rending Blow')) {