v0.13.15 - Fix stale Mystic Gem state, add debug logging to Q press
- Mystic Gem usage now tracked with STATE._mysticUsed flag Prevents re-triggering the gem check after it's been consumed (stale STATE.itemsKnown was causing infinite 'item → p' loops) - Flag resets on new battle initialization - Added buff durations + channeling status to Q-key console output Shows: ch=true/false mp=X% oc=X buffs: heartseeker=47 haste=24 ...
This commit is contained in:
parent
23f00450be
commit
25ea8b4543
9 changed files with 54 additions and 24 deletions
|
|
@ -1,7 +1,7 @@
|
|||
// ==UserScript==
|
||||
// @name HV Unified
|
||||
// @namespace hvunified
|
||||
// @version 0.13.14
|
||||
// @version 0.13.15
|
||||
// @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.14';
|
||||
const VERSION = '0.13.15';
|
||||
|
||||
const CFG = {
|
||||
// — Battle automation
|
||||
|
|
@ -77,6 +77,8 @@ const STATE = {
|
|||
inBattle: false,
|
||||
battleInitialized: false,
|
||||
|
||||
_mysticUsed: false, // Track if Mystic Gem has been used this battle
|
||||
|
||||
maxBuffDur: {}, // Tracks highest duration seen per buff icon
|
||||
|
||||
hoverTarget: -1,
|
||||
|
|
@ -967,10 +969,10 @@ function getSmartAction() {
|
|||
// ── Novice (1-50): survival first ──
|
||||
|
||||
function strategyNovice() {
|
||||
// 0. Mystic Gem for channeling — free OC
|
||||
// 0. Mystic Gem for channeling — only use once per battle
|
||||
// (channeling status is tracked from the battle log)
|
||||
const gem = hasUsableGem('channel');
|
||||
if (gem && !STATE.channeling)
|
||||
if (gem && !STATE.channeling && !STATE._mysticUsed)
|
||||
return { type: 'item', id: gem.id, selfTarget: true };
|
||||
|
||||
// 1. Health items — safe to use early
|
||||
|
|
@ -1088,9 +1090,9 @@ function strategyNovice() {
|
|||
// ── Adept (50-150): building power ──
|
||||
|
||||
function strategyAdept() {
|
||||
// 0. Mystic Gem for channeling — free OC
|
||||
// 0. Mystic Gem for channeling — only use once per battle
|
||||
const gem = hasUsableGem('channel');
|
||||
if (gem && !STATE.channeling)
|
||||
if (gem && !STATE.channeling && !STATE._mysticUsed)
|
||||
return { type: 'item', id: gem.id, selfTarget: true };
|
||||
|
||||
// 1. Health items — safe to use early
|
||||
|
|
@ -1220,9 +1222,9 @@ function strategyAdept() {
|
|||
// ── Veteran (150-300) / Master (300+): full rotation ──
|
||||
|
||||
function strategyVeteran() {
|
||||
// 0. Mystic Gem for channeling
|
||||
// 0. Mystic Gem for channeling — only use once per battle
|
||||
const gem = hasUsableGem('channel');
|
||||
if (gem && !STATE.channeling)
|
||||
if (gem && !STATE.channeling && !STATE._mysticUsed)
|
||||
return { type: 'item', id: gem.id, selfTarget: true };
|
||||
|
||||
// 1. Health items — safe to use early
|
||||
|
|
@ -1410,6 +1412,8 @@ function castTargetSpell(n, i) {
|
|||
function useItem(id) {
|
||||
const it = document.getElementById('ikey_' + id);
|
||||
if (!it) return false;
|
||||
// Track that we used the P-slot gem so we don't retry stale state
|
||||
if (id === 'p') STATE._mysticUsed = true;
|
||||
dummy.setAttribute('onclick', it.getAttribute('onmouseover'));
|
||||
dummy.click();
|
||||
it.click();
|
||||
|
|
@ -1516,6 +1520,11 @@ function setupKeybindings() {
|
|||
if (!isInputFocused() && isBattlePage()) {
|
||||
console.log('%c[HV] Q pressed — checking action...', 'color:#888');
|
||||
parseBattleState();
|
||||
// Debug: show active buffs and channeling status
|
||||
const activeBuffs = Object.entries(STATE.buffs)
|
||||
.filter(([k, v]) => v > 0 && k !== 'regen' || v > 0)
|
||||
.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');
|
||||
const a = getRecommendedAction();
|
||||
if (a) {
|
||||
e.preventDefault();
|
||||
|
|
@ -3270,6 +3279,7 @@ function initializeBattle() {
|
|||
if (STATE.battleInitialized && STATE.page === 'battle') return;
|
||||
STATE.page = 'battle';
|
||||
STATE.inBattle = true;
|
||||
STATE._mysticUsed = false; // Reset Mystic Gem tracking on new battle
|
||||
|
||||
parseBattleState();
|
||||
// Force tier update from cached level (battle page may not have level_readout)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// ==UserScript==
|
||||
// @name HV Unified
|
||||
// @namespace hvunified
|
||||
// @version 0.13.14
|
||||
// @version 0.13.15
|
||||
// @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.14';
|
||||
const VERSION = '0.13.15';
|
||||
|
||||
const CFG = {
|
||||
// — Battle automation
|
||||
|
|
@ -77,6 +77,8 @@ const STATE = {
|
|||
inBattle: false,
|
||||
battleInitialized: false,
|
||||
|
||||
_mysticUsed: false, // Track if Mystic Gem has been used this battle
|
||||
|
||||
maxBuffDur: {}, // Tracks highest duration seen per buff icon
|
||||
|
||||
hoverTarget: -1,
|
||||
|
|
@ -967,10 +969,10 @@ function getSmartAction() {
|
|||
// ── Novice (1-50): survival first ──
|
||||
|
||||
function strategyNovice() {
|
||||
// 0. Mystic Gem for channeling — free OC
|
||||
// 0. Mystic Gem for channeling — only use once per battle
|
||||
// (channeling status is tracked from the battle log)
|
||||
const gem = hasUsableGem('channel');
|
||||
if (gem && !STATE.channeling)
|
||||
if (gem && !STATE.channeling && !STATE._mysticUsed)
|
||||
return { type: 'item', id: gem.id, selfTarget: true };
|
||||
|
||||
// 1. Health items — safe to use early
|
||||
|
|
@ -1088,9 +1090,9 @@ function strategyNovice() {
|
|||
// ── Adept (50-150): building power ──
|
||||
|
||||
function strategyAdept() {
|
||||
// 0. Mystic Gem for channeling — free OC
|
||||
// 0. Mystic Gem for channeling — only use once per battle
|
||||
const gem = hasUsableGem('channel');
|
||||
if (gem && !STATE.channeling)
|
||||
if (gem && !STATE.channeling && !STATE._mysticUsed)
|
||||
return { type: 'item', id: gem.id, selfTarget: true };
|
||||
|
||||
// 1. Health items — safe to use early
|
||||
|
|
@ -1220,9 +1222,9 @@ function strategyAdept() {
|
|||
// ── Veteran (150-300) / Master (300+): full rotation ──
|
||||
|
||||
function strategyVeteran() {
|
||||
// 0. Mystic Gem for channeling
|
||||
// 0. Mystic Gem for channeling — only use once per battle
|
||||
const gem = hasUsableGem('channel');
|
||||
if (gem && !STATE.channeling)
|
||||
if (gem && !STATE.channeling && !STATE._mysticUsed)
|
||||
return { type: 'item', id: gem.id, selfTarget: true };
|
||||
|
||||
// 1. Health items — safe to use early
|
||||
|
|
@ -1410,6 +1412,8 @@ function castTargetSpell(n, i) {
|
|||
function useItem(id) {
|
||||
const it = document.getElementById('ikey_' + id);
|
||||
if (!it) return false;
|
||||
// Track that we used the P-slot gem so we don't retry stale state
|
||||
if (id === 'p') STATE._mysticUsed = true;
|
||||
dummy.setAttribute('onclick', it.getAttribute('onmouseover'));
|
||||
dummy.click();
|
||||
it.click();
|
||||
|
|
@ -1516,6 +1520,11 @@ function setupKeybindings() {
|
|||
if (!isInputFocused() && isBattlePage()) {
|
||||
console.log('%c[HV] Q pressed — checking action...', 'color:#888');
|
||||
parseBattleState();
|
||||
// Debug: show active buffs and channeling status
|
||||
const activeBuffs = Object.entries(STATE.buffs)
|
||||
.filter(([k, v]) => v > 0 && k !== 'regen' || v > 0)
|
||||
.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');
|
||||
const a = getRecommendedAction();
|
||||
if (a) {
|
||||
e.preventDefault();
|
||||
|
|
@ -3270,6 +3279,7 @@ function initializeBattle() {
|
|||
if (STATE.battleInitialized && STATE.page === 'battle') return;
|
||||
STATE.page = 'battle';
|
||||
STATE.inBattle = true;
|
||||
STATE._mysticUsed = false; // Reset Mystic Gem tracking on new battle
|
||||
|
||||
parseBattleState();
|
||||
// Force tier update from cached level (battle page may not have level_readout)
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ function castTargetSpell(n, i) {
|
|||
function useItem(id) {
|
||||
const it = document.getElementById('ikey_' + id);
|
||||
if (!it) return false;
|
||||
// Track that we used the P-slot gem so we don't retry stale state
|
||||
if (id === 'p') STATE._mysticUsed = true;
|
||||
dummy.setAttribute('onclick', it.getAttribute('onmouseover'));
|
||||
dummy.click();
|
||||
it.click();
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// CONFIG — default settings
|
||||
// ═══════════════════════════════════════════════════════════════════════
|
||||
|
||||
const VERSION = '0.13.14';
|
||||
const VERSION = '0.13.15';
|
||||
|
||||
const CFG = {
|
||||
// — Battle automation
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// ==UserScript==
|
||||
// @name HV Unified
|
||||
// @namespace hvunified
|
||||
// @version 0.13.14
|
||||
// @version 0.13.15
|
||||
// @description HV Unified — battle automation, guidance, and UI enhancements for HentaiVerse
|
||||
// @author GaboGG + Hermes
|
||||
// @match *://*.hentaiverse.org/*
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ function initializeBattle() {
|
|||
if (STATE.battleInitialized && STATE.page === 'battle') return;
|
||||
STATE.page = 'battle';
|
||||
STATE.inBattle = true;
|
||||
STATE._mysticUsed = false; // Reset Mystic Gem tracking on new battle
|
||||
|
||||
parseBattleState();
|
||||
// Force tier update from cached level (battle page may not have level_readout)
|
||||
|
|
|
|||
|
|
@ -23,6 +23,11 @@ function setupKeybindings() {
|
|||
if (!isInputFocused() && isBattlePage()) {
|
||||
console.log('%c[HV] Q pressed — checking action...', 'color:#888');
|
||||
parseBattleState();
|
||||
// Debug: show active buffs and channeling status
|
||||
const activeBuffs = Object.entries(STATE.buffs)
|
||||
.filter(([k, v]) => v > 0 && k !== 'regen' || v > 0)
|
||||
.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');
|
||||
const a = getRecommendedAction();
|
||||
if (a) {
|
||||
e.preventDefault();
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ const STATE = {
|
|||
inBattle: false,
|
||||
battleInitialized: false,
|
||||
|
||||
_mysticUsed: false, // Track if Mystic Gem has been used this battle
|
||||
|
||||
maxBuffDur: {}, // Tracks highest duration seen per buff icon
|
||||
|
||||
hoverTarget: -1,
|
||||
|
|
|
|||
|
|
@ -308,10 +308,10 @@ function getSmartAction() {
|
|||
// ── Novice (1-50): survival first ──
|
||||
|
||||
function strategyNovice() {
|
||||
// 0. Mystic Gem for channeling — free OC
|
||||
// 0. Mystic Gem for channeling — only use once per battle
|
||||
// (channeling status is tracked from the battle log)
|
||||
const gem = hasUsableGem('channel');
|
||||
if (gem && !STATE.channeling)
|
||||
if (gem && !STATE.channeling && !STATE._mysticUsed)
|
||||
return { type: 'item', id: gem.id, selfTarget: true };
|
||||
|
||||
// 1. Health items — safe to use early
|
||||
|
|
@ -429,9 +429,9 @@ function strategyNovice() {
|
|||
// ── Adept (50-150): building power ──
|
||||
|
||||
function strategyAdept() {
|
||||
// 0. Mystic Gem for channeling — free OC
|
||||
// 0. Mystic Gem for channeling — only use once per battle
|
||||
const gem = hasUsableGem('channel');
|
||||
if (gem && !STATE.channeling)
|
||||
if (gem && !STATE.channeling && !STATE._mysticUsed)
|
||||
return { type: 'item', id: gem.id, selfTarget: true };
|
||||
|
||||
// 1. Health items — safe to use early
|
||||
|
|
@ -561,9 +561,9 @@ function strategyAdept() {
|
|||
// ── Veteran (150-300) / Master (300+): full rotation ──
|
||||
|
||||
function strategyVeteran() {
|
||||
// 0. Mystic Gem for channeling
|
||||
// 0. Mystic Gem for channeling — only use once per battle
|
||||
const gem = hasUsableGem('channel');
|
||||
if (gem && !STATE.channeling)
|
||||
if (gem && !STATE.channeling && !STATE._mysticUsed)
|
||||
return { type: 'item', id: gem.id, selfTarget: true };
|
||||
|
||||
// 1. Health items — safe to use early
|
||||
|
|
|
|||
Loading…
Reference in a new issue