Adv 2.0 D&D Phase 9 SP3: wire pending spells into combat

applyPendingCast resolves c.PendingCast against the upcoming fight before
SimulateCombat. Damage spells (Fire Bolt, Burning Hands, Magic Missile,
Fireball, etc.) emit a pre-combat spell_cast event via new
CombatModifiers.SpellPreDamage{,Desc}. Control spells (Hold Person, Sleep,
Command) set SpellEnemySkipFirst so the engine skips the enemy's round-1
attack with a spell_held event; Hold-family also primes AutoCritFirst.
Buffs (Mage Armor, Bless, Hunter's Mark, Shield of Faith, Aid, Spiritual
Weapon, Mirror Image, Greater Invisibility) fold into stats/mods directly.

Concentration-on-damage break is left for Phase 11 (turn-based bosses);
ConcentrationSpell persists across fights until manually dropped.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
prosolis
2026-05-08 08:31:08 -07:00
parent 9e1a1f606c
commit 01c70f5297
4 changed files with 499 additions and 5 deletions

View File

@@ -49,6 +49,7 @@ func (p *AdventurePlugin) runArenaCombat(
slog.Info("dnd: armed ability fired", "user", userID, "ability", firedName)
}
applyDnDArenaMonsterLayer(&enemyStats, monster.ThreatLevel)
applyPendingCast(userID, dndChar, &playerStats, &playerMods, &enemyStats)
selected := SelectConsumables(consumables, playerStats, enemyStats, arenaRound, arenaTier)
ApplyConsumableMods(&playerStats, &playerMods, selected)
@@ -172,6 +173,7 @@ func (p *AdventurePlugin) runDungeonCombat(
slog.Info("dnd: armed ability fired", "user", userID, "ability", firedName)
}
applyDnDDungeonMonsterLayer(&enemyStats, loc.Tier)
applyPendingCast(userID, dndChar, &playerStats, &playerMods, &enemyStats)
selected := SelectConsumables(consumables, playerStats, enemyStats, 0, loc.Tier)
ApplyConsumableMods(&playerStats, &playerMods, selected)