The target dropdown starts on the likeliest subject
One module decides where a spell most likely goes given the field (a fireball at an ice elemental, charm monster at their strongest creature, remove enchantment at the wizard only if enchanted); the bot and the dropdown both use it. The dropdown lists that subject first and marks creatures by whose they are. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
dd6ff93606
commit
81acbd2172
@@ -14,6 +14,7 @@ import {
|
||||
} from './gestures';
|
||||
import { glyph } from './glyphs';
|
||||
import { allowedGestures, forcedGesture, resolveTurn } from './resolve';
|
||||
import { likelyTarget } from './targets';
|
||||
import {
|
||||
GESTURES,
|
||||
HANDS,
|
||||
@@ -72,11 +73,6 @@ export interface PlannedCast {
|
||||
turnCount: number;
|
||||
}
|
||||
|
||||
function defaultTarget(spell: Spell | undefined): TargetId | '' {
|
||||
if (!spell) return '';
|
||||
return spell.usualTarget === 'self' ? YOU : FOE;
|
||||
}
|
||||
|
||||
function blankDraft(): HandDraft {
|
||||
return { gesture: null, spellId: '', target: '', elemental: 'fire', chosenHand: 'left' };
|
||||
}
|
||||
@@ -541,12 +537,22 @@ export class Duel {
|
||||
);
|
||||
bankedSpell = $derived(this.you.banked ? SPELL_BY_ID[this.you.banked.spellId] : undefined);
|
||||
|
||||
/** Where a spell goes unless the player says otherwise. */
|
||||
defaultTarget(spell: Spell | undefined): TargetId | '' {
|
||||
return spell ? likelyTarget(this.state, YOU, spell) : '';
|
||||
}
|
||||
|
||||
/** Every possible subject, the likeliest first, creatures marked by whose they are. */
|
||||
targetsFor(spell: Spell | undefined): { id: TargetId; label: string }[] {
|
||||
const list: { id: TargetId; label: string }[] = [
|
||||
{ id: YOU, label: 'yourself' },
|
||||
{ id: FOE, label: this.foe.name }
|
||||
];
|
||||
for (const m of this.state.monsters) list.push({ id: m.id, label: m.name });
|
||||
for (const m of this.state.monsters) {
|
||||
list.push({ id: m.id, label: `${m.name} (${m.owner === YOU ? 'yours' : `${this.foe.name}'s`})` });
|
||||
}
|
||||
const likely = this.defaultTarget(spell);
|
||||
list.sort((a, b) => Number(b.id === likely) - Number(a.id === likely));
|
||||
if (spell && spell.id !== 'fire_storm' && spell.id !== 'ice_storm') list.push({ id: NOWHERE, label: 'nowhere (let it fade)' });
|
||||
return list;
|
||||
}
|
||||
@@ -563,13 +569,13 @@ export class Duel {
|
||||
const options = this.completions[set][hand];
|
||||
if (!options.some((c) => c.spell.id === draft.spellId)) {
|
||||
draft.spellId = options[0]?.spell.id ?? '';
|
||||
draft.target = defaultTarget(options[0]?.spell);
|
||||
draft.target = this.defaultTarget(options[0]?.spell);
|
||||
}
|
||||
}
|
||||
|
||||
setSpell(set: SetName, hand: Hand, id: SpellId | ''): void {
|
||||
this.sets[set][hand].spellId = id;
|
||||
this.sets[set][hand].target = defaultTarget(id ? SPELL_BY_ID[id] : undefined);
|
||||
this.sets[set][hand].target = this.defaultTarget(id ? SPELL_BY_ID[id] : undefined);
|
||||
}
|
||||
|
||||
private castFor(p: PlannedCast): CastChoice {
|
||||
@@ -578,7 +584,7 @@ export class Duel {
|
||||
hand: p.hand,
|
||||
spellId: spell.id,
|
||||
seqIndex: p.completion.seqIndex,
|
||||
target: p.draft.target || defaultTarget(spell)
|
||||
target: p.draft.target || this.defaultTarget(spell)
|
||||
};
|
||||
if (spell.id === 'summon_elemental') cast.elemental = p.draft.elemental;
|
||||
if (spell.id === 'paralysis' || spell.id === 'charm_person') cast.chosenHand = p.draft.chosenHand;
|
||||
|
||||
Reference in New Issue
Block a user