v0.13.5 - Fix channeling waste when all buffs are fresh

- findBestChannelingTarget() fallback: expanded damage spell list to
  include T2 spells (Inferno, Blizzard, etc.) and a last-resort loop
  that fires ANY offensive spell the player knows
- Prevents channeling from expiring when all buffs have high remaining
  durations and the player has no T1 elemental spells
This commit is contained in:
GaboGG 2026-07-26 13:18:56 -04:00
parent 5f61a5c4fc
commit ee9bba90fc
3 changed files with 39 additions and 6 deletions

View file

@ -894,13 +894,24 @@ function findBestChannelingTarget() {
return { type: 'spell', name: candidates[0].spell, selfTarget: true };
}
// Fallback: cheap damage spell rather than waste the charge on basic attack
const cheap = findDmgSpell(['Fiery Blast', 'Freeze', 'Shockblast', 'Gale']);
// Fallback: ANY damage spell rather than waste the charge on basic attack
// Try elementals first (cheapest), then any spell we know
const cheap = findDmgSpell(['Fiery Blast', 'Freeze', 'Shockblast', 'Gale',
'Smite', 'Corruption', 'Inferno', 'Blizzard', 'Chained Lightning', 'Downburst',
'Banishment', 'Disintegrate']);
if (cheap) {
const t = findWeakestMonster();
if (t >= 0 && STATE.monsters[t] && STATE.monsters[t].hasAttribute('onclick'))
return { type: 'spell', name: cheap, target: t };
}
// Last resort: any spell we know that costs MP
for (const sp of STATE.spellsKnown) {
if (sp.mp > 0 && sp.mp < (STATE.mp * 100)) {
const t = findWeakestMonster();
if (t >= 0 && STATE.monsters[t] && STATE.monsters[t].hasAttribute('onclick'))
return { type: 'spell', name: sp.n, target: t };
}
}
return null;
}

View file

@ -894,13 +894,24 @@ function findBestChannelingTarget() {
return { type: 'spell', name: candidates[0].spell, selfTarget: true };
}
// Fallback: cheap damage spell rather than waste the charge on basic attack
const cheap = findDmgSpell(['Fiery Blast', 'Freeze', 'Shockblast', 'Gale']);
// Fallback: ANY damage spell rather than waste the charge on basic attack
// Try elementals first (cheapest), then any spell we know
const cheap = findDmgSpell(['Fiery Blast', 'Freeze', 'Shockblast', 'Gale',
'Smite', 'Corruption', 'Inferno', 'Blizzard', 'Chained Lightning', 'Downburst',
'Banishment', 'Disintegrate']);
if (cheap) {
const t = findWeakestMonster();
if (t >= 0 && STATE.monsters[t] && STATE.monsters[t].hasAttribute('onclick'))
return { type: 'spell', name: cheap, target: t };
}
// Last resort: any spell we know that costs MP
for (const sp of STATE.spellsKnown) {
if (sp.mp > 0 && sp.mp < (STATE.mp * 100)) {
const t = findWeakestMonster();
if (t >= 0 && STATE.monsters[t] && STATE.monsters[t].hasAttribute('onclick'))
return { type: 'spell', name: sp.n, target: t };
}
}
return null;
}

View file

@ -245,13 +245,24 @@ function findBestChannelingTarget() {
return { type: 'spell', name: candidates[0].spell, selfTarget: true };
}
// Fallback: cheap damage spell rather than waste the charge on basic attack
const cheap = findDmgSpell(['Fiery Blast', 'Freeze', 'Shockblast', 'Gale']);
// Fallback: ANY damage spell rather than waste the charge on basic attack
// Try elementals first (cheapest), then any spell we know
const cheap = findDmgSpell(['Fiery Blast', 'Freeze', 'Shockblast', 'Gale',
'Smite', 'Corruption', 'Inferno', 'Blizzard', 'Chained Lightning', 'Downburst',
'Banishment', 'Disintegrate']);
if (cheap) {
const t = findWeakestMonster();
if (t >= 0 && STATE.monsters[t] && STATE.monsters[t].hasAttribute('onclick'))
return { type: 'spell', name: cheap, target: t };
}
// Last resort: any spell we know that costs MP
for (const sp of STATE.spellsKnown) {
if (sp.mp > 0 && sp.mp < (STATE.mp * 100)) {
const t = findWeakestMonster();
if (t >= 0 && STATE.monsters[t] && STATE.monsters[t].hasAttribute('onclick'))
return { type: 'spell', name: sp.n, target: t };
}
}
return null;
}