- 23 source files in src/ (build via scripts/build.sh) - Forum-sourced player knowledge in references/ - DESIGN.md with architecture and corrections - References to existing scripts (Monsterbation, jpx, HV Utils)
101 lines
3.3 KiB
JavaScript
101 lines
3.3 KiB
JavaScript
// ═══════════════════════════════════════════════════════════════════════
|
|
// ACTION EXECUTOR — carry out recommended actions
|
|
// ═══════════════════════════════════════════════════════════════════════
|
|
|
|
function executeAction(a) {
|
|
if (!a) return false;
|
|
switch (a.type) {
|
|
case 'attack': return attackMonster(a.target);
|
|
case 'spell': return a.selfTarget ? castSelfSpell(a.name) : castTargetSpell(a.name, a.target);
|
|
case 'skill': return useSkill(a.name, a.target);
|
|
case 'item': return useItem(a.id);
|
|
case 'toggle_spirit': return toggleSpiritStance();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function attackMonster(i) {
|
|
if (i < 0 || i >= STATE.monsters.length) return false;
|
|
const m = STATE.monsters[i];
|
|
if (!m || !m.hasAttribute || !m.hasAttribute('onclick')) return false;
|
|
m.click();
|
|
return true;
|
|
}
|
|
|
|
function castSelfSpell(n) {
|
|
const s = $$('.btsd[onclick]').find(el =>
|
|
(el.getAttribute('onmouseover') || '').includes(`set_infopane_spell('${n}'`));
|
|
if (!s) return false;
|
|
s.click();
|
|
return true;
|
|
}
|
|
|
|
function castTargetSpell(n, i) {
|
|
const s = $$('.btsd[onclick]').find(el =>
|
|
(el.getAttribute('onmouseover') || '').includes(`set_infopane_spell('${n}'`));
|
|
if (!s) return false;
|
|
s.click();
|
|
if (i >= 0 && i < STATE.monsters.length) {
|
|
setTimeout(() => {
|
|
const m = STATE.monsters[i];
|
|
if (m && m.hasAttribute && m.hasAttribute('onclick')) m.click();
|
|
}, 50);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function useItem(id) {
|
|
const it = document.getElementById('ikey_' + id);
|
|
if (!it) return false;
|
|
dummy.setAttribute('onclick', it.getAttribute('onmouseover'));
|
|
dummy.click();
|
|
it.click();
|
|
return true;
|
|
}
|
|
|
|
function useSkill(n, i) {
|
|
let el = null;
|
|
|
|
// Try quickbar first
|
|
for (const e of $$('#quickbar > .btqs[onclick]')) {
|
|
if ((e.getAttribute('onmouseover') || '').includes(`set_infopane_spell('${n}'`)) {
|
|
el = e; break;
|
|
}
|
|
}
|
|
// Try spellbook
|
|
if (!el) {
|
|
el = $$('.btsd[onclick]').find(e =>
|
|
(e.getAttribute('onmouseover') || '').includes(`set_infopane_spell('${n}'`));
|
|
}
|
|
// Fallback: onclick match
|
|
if (!el) {
|
|
for (const e of $$('.btqb[onclick]')) {
|
|
if ((e.getAttribute('onclick') || '').includes(n)) { el = e; break; }
|
|
}
|
|
}
|
|
// Fallback: image match
|
|
if (!el) {
|
|
for (const e of $$('.btqb img')) {
|
|
if ((e.src || '').toLowerCase().includes(n.toLowerCase().replace(/\s+/g, '_'))) {
|
|
el = e.parentElement; break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!el) return false;
|
|
el.click();
|
|
if (i >= 0 && i < STATE.monsters.length) {
|
|
setTimeout(() => {
|
|
const m = STATE.monsters[i];
|
|
if (m && m.hasAttribute && m.hasAttribute('onclick')) m.click();
|
|
}, 50);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function toggleSpiritStance() {
|
|
const t = document.getElementById('ckey_spirit');
|
|
if (!t) return false;
|
|
t.click();
|
|
return true;
|
|
}
|