/** * The Red Dragon's fire breath: the switch and the numbers both sides read. * * The dragon bites in melee and, on a cooldown, breathes fire at the player * it is fighting from up to DRAGONFIRE_RANGE tiles. The server decides and * rolls it (dreadwoods-backend src/dragonfire.ts, hooked into the NPC turn in * world.ts tickCombat / performNpcAttack); the client draws it from two * messages it already handles (dreadwoods-frontend src/render/DragonfireFx.ts): * * - `combat_windup` with `attack: 'dragonfire'` (and `targetId`), sent * DRAGONFIRE_WINDUP_MS before the fire lands, instead of the bite's * 250-320 ms cue. The dragon's jaw opens and glows for `durationMs` (no * body pose yet: a "Breath" rig clip is planned after the current rig round). * - `combat_hit` with `projectile: 'dragonfire'` when it lands: the flame * stream from the jaw to the target and the damage splat. The target also * reads one chat line on the first breath of each fight (the server's * dragonfireNotice, "The Dragon breathes fire over you!"). * * LIVE since 2026-09-24 (James approved the new dragon and the fire). The * switch below turns it off again: false and a dragon only ever bites, exactly * as before, and neither message above carries the field. A dev backend can * still force it on with DREADWOODS_DRAGONFIRE=1 while the switch is false * (refused under NODE_ENV production and on Render). The client effect has no * switch of its own: it draws whatever the server sends. * * Going live (the full steps are the "Dragonfire" section of dreadwoods-backend * creature-workshop/dragon/docs/DRAGON_GOLIVE.md): * 1. Publish a types release that contains this file and raise the backend's * and frontend's dependency to it (the backend build fails on Render * against a types release without it, switch on or off). * 2. Deploy the web client and upload a TikTok package with the effect before * the flip; a client without it draws a plain bite. * 3. Set DRAGONFIRE_ENABLED = true here, publish types again, raise the * backend's dependency, and deploy the backend. * 4. Replace the backend's ADMIN_VERIFY_LINKS with the fire stands, merge the * guide row with the 3-tile bite sentence, and take the screenshots. */ /** The one switch: true since the go-live (2026-09-24); false turns the fire off. */ export declare const DRAGONFIRE_ENABLED: boolean; /** The dev-only override: DREADWOODS_DRAGONFIRE=1 on a local backend. */ export declare const DRAGONFIRE_OVERRIDE_ENV = "DREADWOODS_DRAGONFIRE"; /** * How far the fire reaches, Chebyshev tiles (the Ice Lich casts from the * same 6). Past its bite and inside this, a dragon whose breath is ready * breathes instead of walking in; the bite reach is the dragon's own * npcAttackRange (1 today, 3 at the go-live). */ export declare const DRAGONFIRE_RANGE = 6; /** * Every Nth dragon attack is fire: two bites, then a breath, over and over. * The same count is the cooldown when the target stands off out of the * bite: the breath is ready once the dragon has bitten N - 1 times since its * last one, and the first breath of a fight is ready at once against a * target it cannot bite (an archer opening from range is answered with fire). * 4 is the lever if the fight is too hard (steel, combat 40: about 93 damage * taken per fight at 3, 83 at 4, 53 with bites only). */ export declare const DRAGONFIRE_EVERY = 3; /** * The wind-up before the fire lands, ms. The NPC turn comes 1200 ms after the * player's, so the cue starts inside that gap and never slows the cadence. */ export declare const DRAGONFIRE_WINDUP_MS = 900; /** * Armour counts at this fraction against fire: plate turns some of the heat, * not all of it. The roll is otherwise the bite's rules (the dragon's own max * hit, NPC_DAMAGE_SCALE, at least 1), but it always lands and rolls from half * to all of the max hit. */ export declare const DRAGONFIRE_ARMOUR_FACTOR = 0.5; /** The sheet's glowing orange-red (mouth, eyes, the heart of the flame). */ export declare const DRAGONFIRE_GLOW = 15354398; /** What `combat_windup.attack` and `combat_hit.projectile` say for the breath. */ export type DragonfireAttack = 'dragonfire'; /** * The frost weapons (James, 2026-10-01: "ice weapons should deal high damage vs them"): the Frozen Depths' * blades, staffs and bow. Against a dragon every hit they land does FROST_VS_DRAGON times its damage; every other * weapon hits a dragon as it hits anything else (James agreed full damage, no "dragon hide"). */ export declare const FROST_WEAPONS: ReadonlySet; /** A frost weapon's hits on a dragon are worth this many times their damage. */ export declare const FROST_VS_DRAGON = 1.75; export declare function isFrostWeapon(kind: string | null | undefined): boolean; /** * The silver weapons (plan D6, 2026-10-14: "silver as anti-undead weapons, as frost hits dragons"): a silver blade is * softer than steel against the living, but every hit it lands on an undead kind does SILVER_VS_UNDEAD times its damage. */ export declare const SILVER_WEAPONS: ReadonlySet; /** A silver weapon's hits on the undead are worth this many times their damage (a placeholder for the balance pass). */ export declare const SILVER_VS_UNDEAD = 1.6; export declare function isSilverWeapon(kind: string | null | undefined): boolean; /** The undead NPC kinds the silver weapons bite. Hollowed kinds (the Cracked Bell's night-only dead) match by prefix. */ export declare const UNDEAD_NPC_KINDS: ReadonlySet; export declare function isUndeadNpcKind(kind: string | null | undefined): boolean; /** How much a player's hit on this NPC is scaled for the weapon in hand (a frost weapon on a dragon, silver on the dead; else 1). */ export declare function weaponVsNpcScale(npcKind: string, weaponKind: string | null | undefined): number; //# sourceMappingURL=dragonfire.d.ts.map