Credibility pass: one conflict check, one hostile list, one set of chrome
Duplicated logic and styling that had drifted apart is unified: the gesture-sharing check, the hostile spell list, the enchanted test, the plan limits, and the shared button, link, field and disabled styles. Dead plumbing is gone: the always-true implemented flag, the unread cast length, an unreachable guard, an impossible time-stop condition, the unused sequence formatter and utility class, the template placeholder. The counter-spell tests now put a counter-spell in front of a spell, the test helpers live in one file, and the resolver's sections are numbered in order. The deploy script's cache headers now do what its comment says, and the README describes the screen rather than listing features in the order they arrived. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
527820ee95
commit
5de352db43
+45
-16
@@ -81,8 +81,6 @@ export interface Spell {
|
||||
tokens: Token[][];
|
||||
usualTarget: 'self' | 'enemy';
|
||||
summary: string;
|
||||
/** False for spells the engine recognises but does not yet resolve. */
|
||||
implemented: boolean;
|
||||
}
|
||||
|
||||
export function parseSequence(sequence: string): Token[] {
|
||||
@@ -100,8 +98,7 @@ function spell(
|
||||
category: SpellCategory,
|
||||
sequences: string[],
|
||||
usualTarget: 'self' | 'enemy',
|
||||
summary: string,
|
||||
implemented = true
|
||||
summary: string
|
||||
): Spell {
|
||||
return {
|
||||
id,
|
||||
@@ -110,8 +107,7 @@ function spell(
|
||||
sequences,
|
||||
tokens: sequences.map(parseSequence),
|
||||
usualTarget,
|
||||
summary,
|
||||
implemented
|
||||
summary
|
||||
};
|
||||
}
|
||||
|
||||
@@ -158,8 +154,8 @@ export const SPELLS: Spell[] = [
|
||||
spell('invisibility', 'Invisibility', 'enchantment', ['P-P-(w-(s'], 'self', 'For three turns the opponent cannot see the subject’s gestures and monsters cannot attack them. Destroys a monster.'),
|
||||
spell('haste', 'Haste', 'enchantment', ['P-W-P-W-W-C'], 'self', 'For the next three turns the subject makes two pairs of gestures a turn, both taking effect together.'),
|
||||
spell('time_stop', 'Time stop', 'enchantment', ['S-P-P-C'], 'self', 'The subject at once takes an extra turn nobody else can see or resist.'),
|
||||
spell('delayed_effect', 'Delayed effect', 'enchantment', ['D-W-S-S-S-P'], 'self', 'The subject\u2019s next spell (this turn or the next three) is banked, to be released whenever they choose.'),
|
||||
spell('permanency', 'Permanency', 'enchantment', ['S-P-F-P-S-D-W'], 'self', 'The subject\u2019s next enchantment (this turn or the next three) lasts for the rest of the duel.')
|
||||
spell('delayed_effect', 'Delayed effect', 'enchantment', ['D-W-S-S-S-P'], 'self', 'The subject’s next spell (this turn or the next three) is banked, to be released whenever they choose.'),
|
||||
spell('permanency', 'Permanency', 'enchantment', ['S-P-F-P-S-D-W'], 'self', 'The subject’s next enchantment (this turn or the next three) lasts for the rest of the duel.')
|
||||
];
|
||||
|
||||
export const SPELL_BY_ID: Record<SpellId, Spell> = Object.fromEntries(
|
||||
@@ -176,19 +172,45 @@ export const CONTROL_SPELLS: SpellId[] = [
|
||||
'fear'
|
||||
];
|
||||
|
||||
/** Enchantments a permanency can extend for the rest of the duel. */
|
||||
/** Enchantments a permanency cannot extend. */
|
||||
export const PERMANENCY_EXCLUDED: SpellId[] = ['anti_spell', 'disease', 'poison', 'time_stop', 'permanency'];
|
||||
|
||||
export function permanencyEligible(spell: Spell): boolean {
|
||||
return spell.category === 'enchantment' && !PERMANENCY_EXCLUDED.includes(spell.id);
|
||||
}
|
||||
|
||||
/** Spells worth warning about, or defending against, when the other wizard's hands approach them. */
|
||||
export const HOSTILE_SPELLS: SpellId[] = [
|
||||
'missile',
|
||||
'finger_of_death',
|
||||
'lightning_bolt',
|
||||
'lightning_bolt_quick',
|
||||
'cause_light_wounds',
|
||||
'cause_heavy_wounds',
|
||||
'fireball',
|
||||
'fire_storm',
|
||||
'ice_storm',
|
||||
'amnesia',
|
||||
'confusion',
|
||||
'charm_person',
|
||||
'charm_monster',
|
||||
'paralysis',
|
||||
'fear',
|
||||
'anti_spell',
|
||||
'disease',
|
||||
'poison',
|
||||
'blindness',
|
||||
'remove_enchantment',
|
||||
'summon_goblin',
|
||||
'summon_ogre',
|
||||
'summon_troll',
|
||||
'summon_giant',
|
||||
'summon_elemental'
|
||||
];
|
||||
|
||||
/** Spells that affect everyone rather than one subject. */
|
||||
export const BLANKET_SPELLS: SpellId[] = ['fire_storm', 'ice_storm'];
|
||||
|
||||
export const SUMMON_KIND: Partial<Record<SpellId, MonsterKind>> = {
|
||||
summon_goblin: 'goblin',
|
||||
summon_ogre: 'ogre',
|
||||
summon_troll: 'troll',
|
||||
summon_giant: 'giant'
|
||||
};
|
||||
|
||||
export type MonsterKind = 'goblin' | 'ogre' | 'troll' | 'giant' | 'fire_elemental' | 'ice_elemental';
|
||||
|
||||
export const MONSTER_STATS: Record<MonsterKind, { name: string; hp: number; attack: number }> = {
|
||||
@@ -203,3 +225,10 @@ export const MONSTER_STATS: Record<MonsterKind, { name: string; hp: number; atta
|
||||
export function isElemental(kind: MonsterKind): boolean {
|
||||
return kind === 'fire_elemental' || kind === 'ice_elemental';
|
||||
}
|
||||
|
||||
export const SUMMON_KIND: Partial<Record<SpellId, MonsterKind>> = {
|
||||
summon_goblin: 'goblin',
|
||||
summon_ogre: 'ogre',
|
||||
summon_troll: 'troll',
|
||||
summon_giant: 'giant'
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user