feat: replace all hardcoded constants with config values

Replace hardcoded game constants with values from the config system:
- GameSession now receives *config.Config from Lobby
- TurnTimeout, MaxFloors, SkillUses, InventoryLimit use config values
- combat.AttemptFlee accepts fleeChance param
- combat.ResolveAttacks accepts coopBonus param
- entity.NewMonster accepts scaling param
- Solo HP/DEF reduction uses config SoloHPReduction
- Lobby JoinRoom uses config MaxPlayers

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-25 13:08:52 +09:00
parent ad1482ae03
commit f85775dd3e
10 changed files with 56 additions and 43 deletions

View File

@@ -31,7 +31,7 @@ type AttackResult struct {
IsAoE bool
}
func ResolveAttacks(intents []AttackIntent, monsters []*entity.Monster) []AttackResult {
func ResolveAttacks(intents []AttackIntent, monsters []*entity.Monster, coopBonus float64) []AttackResult {
targetCount := make(map[int]int)
targetOrder := make(map[int]int)
for i, intent := range intents {
@@ -63,7 +63,7 @@ func ResolveAttacks(intents []AttackIntent, monsters []*entity.Monster) []Attack
dmg := CalcDamage(intent.PlayerATK, m.DEF, intent.Multiplier)
coopApplied := false
if targetCount[intent.TargetIdx] >= 2 && targetOrder[intent.TargetIdx] != i {
dmg = int(math.Round(float64(dmg) * 1.10))
dmg = int(math.Round(float64(dmg) * (1.0 + coopBonus)))
coopApplied = true
}
m.TakeDamage(dmg)
@@ -77,8 +77,8 @@ func ResolveAttacks(intents []AttackIntent, monsters []*entity.Monster) []Attack
return results
}
func AttemptFlee() bool {
return rand.Float64() < 0.5
func AttemptFlee(fleeChance float64) bool {
return rand.Float64() < fleeChance
}
func MonsterAI(m *entity.Monster, players []*entity.Player, turnNumber int) (targetIdx int, isAoE bool) {

View File

@@ -25,7 +25,7 @@ func TestCoopBonus(t *testing.T) {
{PlayerATK: 12, TargetIdx: 0, Multiplier: 1.0, IsAoE: false},
{PlayerATK: 15, TargetIdx: 0, Multiplier: 1.0, IsAoE: false},
}
results := ResolveAttacks(attackers, []*entity.Monster{entity.NewMonster(entity.MonsterSlime, 1)})
results := ResolveAttacks(attackers, []*entity.Monster{entity.NewMonster(entity.MonsterSlime, 1, 1.15)}, 0.10)
if !results[1].CoopApplied {
t.Error("Second attacker should get co-op bonus")
}
@@ -37,10 +37,10 @@ func TestAoENoCoopBonus(t *testing.T) {
{PlayerATK: 20, TargetIdx: -1, Multiplier: 0.8, IsAoE: true},
}
monsters := []*entity.Monster{
entity.NewMonster(entity.MonsterSlime, 1),
entity.NewMonster(entity.MonsterSlime, 1),
entity.NewMonster(entity.MonsterSlime, 1, 1.15),
entity.NewMonster(entity.MonsterSlime, 1, 1.15),
}
results := ResolveAttacks(attackers, monsters)
results := ResolveAttacks(attackers, monsters, 0.10)
if results[0].CoopApplied {
t.Error("AoE should not trigger co-op bonus")
}
@@ -68,7 +68,7 @@ func TestMonsterAITauntDeadWarrior(t *testing.T) {
func TestFleeChance(t *testing.T) {
successes := 0
for i := 0; i < 100; i++ {
if AttemptFlee() {
if AttemptFlee(0.50) {
successes++
}
}