aboutsummaryrefslogtreecommitdiff
path: root/internal/game/sys_combat_test.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-07-17 19:54:21 -0400
committerhistoria <[not public]>2026-07-17 19:54:21 -0400
commitc23c87b56fd568956d263bb8b8c5d26fbd8d01ee (patch)
tree58737f94d5417e11a7d94b2a250d28ae05a25c58 /internal/game/sys_combat_test.go
parentd553a976dd2f899e28dc8e023ee4ca2eb8951c38 (diff)
downloadthehouseoficarus-c23c87b56fd568956d263bb8b8c5d26fbd8d01ee.tar.gz
feat: add test for mob aggro
Diffstat (limited to 'internal/game/sys_combat_test.go')
-rw-r--r--internal/game/sys_combat_test.go86
1 files changed, 86 insertions, 0 deletions
diff --git a/internal/game/sys_combat_test.go b/internal/game/sys_combat_test.go
new file mode 100644
index 0000000..788e62c
--- /dev/null
+++ b/internal/game/sys_combat_test.go
@@ -0,0 +1,86 @@
+package game
+
+import (
+ "testing"
+
+ "thehouseoficarus/internal/behavior"
+ "thehouseoficarus/internal/player"
+ "thehouseoficarus/internal/world"
+)
+
+func spawnTestMob(g *Game, defID string, roomID int) *world.MobInstance {
+ def, err := g.MobStore.LoadDef(defID)
+ if err != nil {
+ panic("spawnTestMob: " + err.Error())
+ }
+ cfg := &behavior.SpawnMobConfig{ID: defID}
+ return g.MobStore.SpawnTransient(def, cfg, roomID, "")
+}
+
+func patchAggroRand(val float64) func() {
+ orig := rollAggroRand
+ rollAggroRand = func() float64 { return val }
+ return func() { rollAggroRand = orig }
+}
+
+func TestAggroInlineRollFiresOnArrival(t *testing.T) {
+ defer patchAggroRand(0.0)()
+
+ g := escapeTestGame()
+ spawnTestMob(g, "skeleton", 100)
+ p := player.New("agro_fire")
+ p.RoomID = 100
+ sess := escapeTestSession(p)
+
+ g.checkAggro(sess)
+
+ if g.Combat.Get(p.Name) == nil {
+ t.Error("aggro should have started combat on inline roll")
+ }
+}
+
+func TestAggroPerTickRetrySubscriber(t *testing.T) {
+ t.Run("miss_then_retry_fires", func(t *testing.T) {
+ defer patchAggroRand(0.5)()
+
+ g := escapeTestGame()
+ spawnTestMob(g, "skeleton", 200)
+ p := player.New("agro_retry")
+ p.RoomID = 200
+ sess := escapeTestSession(p)
+
+ g.checkAggro(sess)
+
+ if g.Combat.Get(p.Name) != nil {
+ t.Fatal("inline roll should have missed (val=0.5)")
+ }
+
+ rollAggroRand = func() float64 { return 0.0 }
+ g.Ticks.Tick()
+
+ if g.Combat.Get(p.Name) == nil {
+ t.Error("per-tick retry subscriber should have started combat")
+ }
+ })
+
+ t.Run("miss_then_ineligible_unsubscribes", func(t *testing.T) {
+ defer patchAggroRand(0.5)()
+
+ g := escapeTestGame()
+ spawnTestMob(g, "skeleton", 300)
+ p := player.New("agro_leave")
+ p.RoomID = 300
+ sess := escapeTestSession(p)
+
+ g.checkAggro(sess)
+
+ if g.Combat.Get(p.Name) != nil {
+ t.Fatal("inline roll should have missed (val=0.5)")
+ }
+ p.RoomID = 999
+ g.Ticks.Tick()
+ if g.Combat.Get(p.Name) != nil {
+ t.Error("retry should have self-unsubscribed, no combat started")
+ }
+ })
+}