feat: add floor themes with status effect modifiers

Add 4 floor themes (Swamp/Volcano/Glacier/Inferno) that boost status
effect damage on matching floors. Realign boss patterns to match themes
and add PatternFreeze for the Glacier boss.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-25 15:22:17 +09:00
parent 69ac6cd383
commit 1e155c62fb
5 changed files with 94 additions and 5 deletions

View File

@@ -119,13 +119,13 @@ func (s *GameSession) spawnBoss() {
boss := entity.NewMonster(mt, s.state.FloorNum, s.cfg.Combat.MonsterScaling)
switch mt {
case entity.MonsterBoss5:
boss.Pattern = entity.PatternAoE
boss.Pattern = entity.PatternPoison // Swamp theme
case entity.MonsterBoss10:
boss.Pattern = entity.PatternPoison
boss.Pattern = entity.PatternBurn // Volcano theme
case entity.MonsterBoss15:
boss.Pattern = entity.PatternBurn
boss.Pattern = entity.PatternFreeze // Glacier theme
case entity.MonsterBoss20:
boss.Pattern = entity.PatternHeal
boss.Pattern = entity.PatternHeal // Inferno theme (+ natural AoE every 3 turns)
}
if s.state.SoloMode {
boss.HP = int(float64(boss.HP) * s.cfg.Combat.SoloHPReduction)

View File

@@ -72,13 +72,30 @@ collecting:
}
func (s *GameSession) resolvePlayerActions() {
// Tick status effects
// Tick status effects with floor theme damage bonus
theme := dungeon.GetTheme(s.state.FloorNum)
for _, p := range s.state.Players {
if !p.IsOut() {
// Snapshot effects before tick to compute theme bonus
effectsBefore := make([]entity.ActiveEffect, len(p.Effects))
copy(effectsBefore, p.Effects)
msgs := p.TickEffects()
for _, msg := range msgs {
s.addLog(msg)
}
// Apply theme damage bonus for matching status effects
for _, e := range effectsBefore {
if e.Value > 0 && (theme.StatusBoost == entity.StatusEffect(-1) || e.Type == theme.StatusBoost) {
bonus := int(float64(e.Value) * (theme.DamageMult - 1.0))
if bonus > 0 {
p.TakeDamage(bonus)
s.addLog(fmt.Sprintf(" (%s theme: +%d damage)", theme.Name, bonus))
}
}
}
if p.IsDead() {
s.addLog(fmt.Sprintf("☠ %s has fallen!", p.Name))
}
@@ -409,6 +426,13 @@ func (s *GameSession) resolveMonsterActions() {
s.addLog(fmt.Sprintf("%s burns %s!", m.Name, p.Name))
}
}
case entity.PatternFreeze:
for _, p := range s.state.Players {
if !p.IsOut() {
p.AddEffect(entity.ActiveEffect{Type: entity.StatusFreeze, Duration: 1, Value: 0})
s.addLog(fmt.Sprintf("%s freezes %s!", m.Name, p.Name))
}
}
case entity.PatternHeal:
healAmt := m.MaxHP / 10
m.HP += healAmt