v0.14.27 - Enhanced logging: alive/dead markers, skill readiness, item counts
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
This commit is contained in:
parent
ff728fe68f
commit
206c682d9e
5 changed files with 66 additions and 15 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name HV Unified
|
// @name HV Unified
|
||||||
// @namespace hvunified
|
// @namespace hvunified
|
||||||
// @version 0.14.26
|
// @version 0.14.27
|
||||||
// @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.14.26';
|
const VERSION = '0.14.27';
|
||||||
|
|
||||||
const CFG = {
|
const CFG = {
|
||||||
// — Battle automation
|
// — Battle automation
|
||||||
|
|
@ -1850,17 +1850,34 @@ function setupKeybindings() {
|
||||||
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(' ');
|
||||||
// Monster SP bars (threat levels)
|
// Monster SP bars (threat levels) with alive/dead markers
|
||||||
const threatLevels = STATE.monsters.map((m, i) => {
|
const threatLevels = STATE.monsters.map((m, i) => {
|
||||||
const sp = STATE.monsterSp[i] || 0;
|
const sp = STATE.monsterSp[i] || 0;
|
||||||
return `${i}:${sp}`;
|
const alive = m && m.hasAttribute && m.hasAttribute('onclick') ? 'A' : 'D';
|
||||||
|
return `${i}:${sp}${alive}`;
|
||||||
}).join(' ');
|
}).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 curMp = parseInt((document.getElementById('vrm') || {}).textContent) || 0;
|
||||||
const curHp = parseInt((document.getElementById('vrhd') || {}).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(
|
console.log(
|
||||||
`%c[HV] ch=${STATE.channeling} hp=${curHp} mp=${curMp}(${(STATE.mp*100).toFixed(0)}%) ` +
|
`%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)} ` +
|
`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}`,
|
`buffs: ${activeBuffs} | spBars: ${threatLevels}`,
|
||||||
'color:#888'
|
'color:#888'
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// ==UserScript==
|
// ==UserScript==
|
||||||
// @name HV Unified
|
// @name HV Unified
|
||||||
// @namespace hvunified
|
// @namespace hvunified
|
||||||
// @version 0.14.26
|
// @version 0.14.27
|
||||||
// @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.14.26';
|
const VERSION = '0.14.27';
|
||||||
|
|
||||||
const CFG = {
|
const CFG = {
|
||||||
// — Battle automation
|
// — Battle automation
|
||||||
|
|
@ -1850,17 +1850,34 @@ function setupKeybindings() {
|
||||||
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(' ');
|
||||||
// Monster SP bars (threat levels)
|
// Monster SP bars (threat levels) with alive/dead markers
|
||||||
const threatLevels = STATE.monsters.map((m, i) => {
|
const threatLevels = STATE.monsters.map((m, i) => {
|
||||||
const sp = STATE.monsterSp[i] || 0;
|
const sp = STATE.monsterSp[i] || 0;
|
||||||
return `${i}:${sp}`;
|
const alive = m && m.hasAttribute && m.hasAttribute('onclick') ? 'A' : 'D';
|
||||||
|
return `${i}:${sp}${alive}`;
|
||||||
}).join(' ');
|
}).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 curMp = parseInt((document.getElementById('vrm') || {}).textContent) || 0;
|
||||||
const curHp = parseInt((document.getElementById('vrhd') || {}).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(
|
console.log(
|
||||||
`%c[HV] ch=${STATE.channeling} hp=${curHp} mp=${curMp}(${(STATE.mp*100).toFixed(0)}%) ` +
|
`%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)} ` +
|
`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}`,
|
`buffs: ${activeBuffs} | spBars: ${threatLevels}`,
|
||||||
'color:#888'
|
'color:#888'
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
// CONFIG — default settings
|
// CONFIG — default settings
|
||||||
// ═══════════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
const VERSION = '0.14.26';
|
const VERSION = '0.14.27';
|
||||||
|
|
||||||
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.14.26
|
// @version 0.14.27
|
||||||
// @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/*
|
||||||
|
|
|
||||||
|
|
@ -34,17 +34,34 @@ function setupKeybindings() {
|
||||||
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(' ');
|
||||||
// Monster SP bars (threat levels)
|
// Monster SP bars (threat levels) with alive/dead markers
|
||||||
const threatLevels = STATE.monsters.map((m, i) => {
|
const threatLevels = STATE.monsters.map((m, i) => {
|
||||||
const sp = STATE.monsterSp[i] || 0;
|
const sp = STATE.monsterSp[i] || 0;
|
||||||
return `${i}:${sp}`;
|
const alive = m && m.hasAttribute && m.hasAttribute('onclick') ? 'A' : 'D';
|
||||||
|
return `${i}:${sp}${alive}`;
|
||||||
}).join(' ');
|
}).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 curMp = parseInt((document.getElementById('vrm') || {}).textContent) || 0;
|
||||||
const curHp = parseInt((document.getElementById('vrhd') || {}).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(
|
console.log(
|
||||||
`%c[HV] ch=${STATE.channeling} hp=${curHp} mp=${curMp}(${(STATE.mp*100).toFixed(0)}%) ` +
|
`%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)} ` +
|
`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}`,
|
`buffs: ${activeBuffs} | spBars: ${threatLevels}`,
|
||||||
'color:#888'
|
'color:#888'
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue