From 206c682d9e9276c7e93a6ee64e62421c9b26a15a Mon Sep 17 00:00:00 2001 From: GaboGG Date: Tue, 28 Jul 2026 10:16:31 -0400 Subject: [PATCH] v0.14.27 - Enhanced logging: alive/dead markers, skill readiness, item counts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Log line now shows: - spBars: 0:29A 1:28A 2:59A 3:52A 4:34A 5:43A 6:29A (A=alive onclick, D=dead/no onclick — so you know which SP bars are actionable vs leftover from dead mobs) - sk: RC CC RC (R=Rending Blow Ready/C=Cooldown, S=Shatter, G=Great Cleave) — first char of skill name + R/C for ready/cooldown - h5 s3 m4 (heal=5, spirit=3, mana=4 — item counts per type) — so you can see consumable status at a glance --- scripts/hv-unified.user.js | 27 ++++++++++++++++++++++----- scripts/latest.user.js | 27 ++++++++++++++++++++++----- src/config.js | 2 +- src/header.user.js | 2 +- src/keybindings.js | 23 ++++++++++++++++++++--- 5 files changed, 66 insertions(+), 15 deletions(-) diff --git a/scripts/hv-unified.user.js b/scripts/hv-unified.user.js index 6dd1fa8..047e2e9 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.14.26 +// @version 0.14.27 // @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.14.26'; +const VERSION = '0.14.27'; const CFG = { // — Battle automation @@ -1850,17 +1850,34 @@ function setupKeybindings() { const activeBuffs = Object.entries(STATE.buffs) .filter(([k, v]) => v > 0 && k !== 'regen' || v > 0) .map(([k, v]) => `${k}=${v}`).join(' '); - // Monster SP bars (threat levels) + // Monster SP bars (threat levels) with alive/dead markers const threatLevels = STATE.monsters.map((m, i) => { const sp = STATE.monsterSp[i] || 0; - return `${i}:${sp}`; + const alive = m && m.hasAttribute && m.hasAttribute('onclick') ? 'A' : 'D'; + return `${i}:${sp}${alive}`; }).join(' '); + // Skill cooldowns — check DOM for opacity/onclick on skill elements + const skillCDs = ['Rending Blow', 'Shatter Strike', 'Great Cleave'] + .filter(s => STATE.skillsKnown.includes(s)) + .map(s => { + const el = document.querySelector(`.btqs[onmouseover*="set_infopane_spell('${s}'"], .btsd[onmouseover*="set_infopane_spell('${s}'"]`); + const ready = el && el.hasAttribute('onclick'); + return `${s.charAt(0)}${ready ? 'R' : 'C'}`; + }).join(''); const curMp = parseInt((document.getElementById('vrm') || {}).textContent) || 0; const curHp = parseInt((document.getElementById('vrhd') || {}).textContent) || 0; + // Item counts from itemsKnown + const itemTypes = {}; + Object.values(STATE.itemsKnown).forEach(info => { + const def = ITEMS[parseInt(info)]; + if (def) itemTypes[def.t] = (itemTypes[def.t] || 0) + 1; + }); + const itemStr = ['heal','spirit','mana'].filter(t => itemTypes[t]).map(t => `${t.charAt(0)}${itemTypes[t]}`).join(' '); 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} ` + + `mon:${STATE.monsters.length} sk:${skillCDs || '--'} ` + + `${itemStr} ` + `buffs: ${activeBuffs} | spBars: ${threatLevels}`, 'color:#888' ); diff --git a/scripts/latest.user.js b/scripts/latest.user.js index 6dd1fa8..047e2e9 100644 --- a/scripts/latest.user.js +++ b/scripts/latest.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name HV Unified // @namespace hvunified -// @version 0.14.26 +// @version 0.14.27 // @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.14.26'; +const VERSION = '0.14.27'; const CFG = { // — Battle automation @@ -1850,17 +1850,34 @@ function setupKeybindings() { const activeBuffs = Object.entries(STATE.buffs) .filter(([k, v]) => v > 0 && k !== 'regen' || v > 0) .map(([k, v]) => `${k}=${v}`).join(' '); - // Monster SP bars (threat levels) + // Monster SP bars (threat levels) with alive/dead markers const threatLevels = STATE.monsters.map((m, i) => { const sp = STATE.monsterSp[i] || 0; - return `${i}:${sp}`; + const alive = m && m.hasAttribute && m.hasAttribute('onclick') ? 'A' : 'D'; + return `${i}:${sp}${alive}`; }).join(' '); + // Skill cooldowns — check DOM for opacity/onclick on skill elements + const skillCDs = ['Rending Blow', 'Shatter Strike', 'Great Cleave'] + .filter(s => STATE.skillsKnown.includes(s)) + .map(s => { + const el = document.querySelector(`.btqs[onmouseover*="set_infopane_spell('${s}'"], .btsd[onmouseover*="set_infopane_spell('${s}'"]`); + const ready = el && el.hasAttribute('onclick'); + return `${s.charAt(0)}${ready ? 'R' : 'C'}`; + }).join(''); const curMp = parseInt((document.getElementById('vrm') || {}).textContent) || 0; const curHp = parseInt((document.getElementById('vrhd') || {}).textContent) || 0; + // Item counts from itemsKnown + const itemTypes = {}; + Object.values(STATE.itemsKnown).forEach(info => { + const def = ITEMS[parseInt(info)]; + if (def) itemTypes[def.t] = (itemTypes[def.t] || 0) + 1; + }); + const itemStr = ['heal','spirit','mana'].filter(t => itemTypes[t]).map(t => `${t.charAt(0)}${itemTypes[t]}`).join(' '); 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} ` + + `mon:${STATE.monsters.length} sk:${skillCDs || '--'} ` + + `${itemStr} ` + `buffs: ${activeBuffs} | spBars: ${threatLevels}`, 'color:#888' ); diff --git a/src/config.js b/src/config.js index 237226f..8cb020c 100644 --- a/src/config.js +++ b/src/config.js @@ -2,7 +2,7 @@ // CONFIG — default settings // ═══════════════════════════════════════════════════════════════════════ -const VERSION = '0.14.26'; +const VERSION = '0.14.27'; const CFG = { // — Battle automation diff --git a/src/header.user.js b/src/header.user.js index 2bc5427..e12d408 100644 --- a/src/header.user.js +++ b/src/header.user.js @@ -1,7 +1,7 @@ // ==UserScript== // @name HV Unified // @namespace hvunified -// @version 0.14.26 +// @version 0.14.27 // @description HV Unified — battle automation, guidance, and UI enhancements for HentaiVerse // @author GaboGG + Hermes // @match *://*.hentaiverse.org/* diff --git a/src/keybindings.js b/src/keybindings.js index 62dc299..a3357fd 100644 --- a/src/keybindings.js +++ b/src/keybindings.js @@ -34,17 +34,34 @@ function setupKeybindings() { const activeBuffs = Object.entries(STATE.buffs) .filter(([k, v]) => v > 0 && k !== 'regen' || v > 0) .map(([k, v]) => `${k}=${v}`).join(' '); - // Monster SP bars (threat levels) + // Monster SP bars (threat levels) with alive/dead markers const threatLevels = STATE.monsters.map((m, i) => { const sp = STATE.monsterSp[i] || 0; - return `${i}:${sp}`; + const alive = m && m.hasAttribute && m.hasAttribute('onclick') ? 'A' : 'D'; + return `${i}:${sp}${alive}`; }).join(' '); + // Skill cooldowns — check DOM for opacity/onclick on skill elements + const skillCDs = ['Rending Blow', 'Shatter Strike', 'Great Cleave'] + .filter(s => STATE.skillsKnown.includes(s)) + .map(s => { + const el = document.querySelector(`.btqs[onmouseover*="set_infopane_spell('${s}'"], .btsd[onmouseover*="set_infopane_spell('${s}'"]`); + const ready = el && el.hasAttribute('onclick'); + return `${s.charAt(0)}${ready ? 'R' : 'C'}`; + }).join(''); const curMp = parseInt((document.getElementById('vrm') || {}).textContent) || 0; const curHp = parseInt((document.getElementById('vrhd') || {}).textContent) || 0; + // Item counts from itemsKnown + const itemTypes = {}; + Object.values(STATE.itemsKnown).forEach(info => { + const def = ITEMS[parseInt(info)]; + if (def) itemTypes[def.t] = (itemTypes[def.t] || 0) + 1; + }); + const itemStr = ['heal','spirit','mana'].filter(t => itemTypes[t]).map(t => `${t.charAt(0)}${itemTypes[t]}`).join(' '); 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} ` + + `mon:${STATE.monsters.length} sk:${skillCDs || '--'} ` + + `${itemStr} ` + `buffs: ${activeBuffs} | spBars: ${threatLevels}`, 'color:#888' );