mirror of
https://github.com/YspCoder/clawgo.git
synced 2026-04-13 15:37:30 +08:00
104 lines
3.2 KiB
Go
104 lines
3.2 KiB
Go
package world
|
|
|
|
import "testing"
|
|
|
|
func TestVisibleEventsForNPCIncludesNeighborLocationsWithinScope(t *testing.T) {
|
|
engine := NewEngine()
|
|
state := DefaultWorldState()
|
|
npc := NPCState{NPCID: "keeper", CurrentLocation: "commons"}
|
|
events := []WorldEvent{
|
|
{ID: "a", Type: "noise", LocationID: "square", Content: "neighbor event"},
|
|
{ID: "b", Type: "noise", LocationID: "far", Content: "far event"},
|
|
}
|
|
state.Locations["far"] = Location{ID: "far", Neighbors: []string{}}
|
|
out := engine.VisibleEventsForNPC(state, npc, events, 1)
|
|
if len(out) != 1 || out[0].ID != "a" {
|
|
t.Fatalf("expected only neighbor event, got %+v", out)
|
|
}
|
|
}
|
|
|
|
func TestApplyIntentInteractUpdatesEntityState(t *testing.T) {
|
|
engine := NewEngine()
|
|
state := DefaultWorldState()
|
|
state.Entities["fountain"] = Entity{
|
|
ID: "fountain",
|
|
Name: "Fountain",
|
|
LocationID: "square",
|
|
State: map[string]interface{}{},
|
|
}
|
|
npc := &NPCState{NPCID: "merchant", CurrentLocation: "square"}
|
|
delta := engine.ApplyIntent(&state, npc, ActionIntent{
|
|
ActorID: "merchant",
|
|
Action: "interact",
|
|
TargetEntity: "fountain",
|
|
Speech: "inspects the fountain",
|
|
})
|
|
if !delta.Applied || delta.Event == nil {
|
|
t.Fatalf("expected interact delta to apply, got %+v", delta)
|
|
}
|
|
entity := state.Entities["fountain"]
|
|
if entity.State["last_actor"] != "merchant" {
|
|
t.Fatalf("expected entity last_actor updated, got %+v", entity.State)
|
|
}
|
|
if entity.State["interaction_count"] == nil {
|
|
t.Fatalf("expected interaction_count, got %+v", entity.State)
|
|
}
|
|
}
|
|
|
|
func TestApplyIntentInteractRejectsDistantEntity(t *testing.T) {
|
|
engine := NewEngine()
|
|
state := DefaultWorldState()
|
|
state.Locations["far"] = Location{ID: "far", Neighbors: []string{}}
|
|
state.Entities["orb"] = Entity{
|
|
ID: "orb",
|
|
LocationID: "far",
|
|
}
|
|
npc := &NPCState{NPCID: "sage", CurrentLocation: "commons"}
|
|
delta := engine.ApplyIntent(&state, npc, ActionIntent{
|
|
ActorID: "sage",
|
|
Action: "interact",
|
|
TargetEntity: "orb",
|
|
})
|
|
if delta.Applied {
|
|
t.Fatalf("expected distant interact to be rejected, got %+v", delta)
|
|
}
|
|
if delta.Reason != "entity_not_reachable" {
|
|
t.Fatalf("unexpected rejection reason: %+v", delta)
|
|
}
|
|
}
|
|
|
|
func TestApplyIntentInteractAppliesQuestAndResourceEffects(t *testing.T) {
|
|
engine := NewEngine()
|
|
state := DefaultWorldState()
|
|
state.Entities["chest"] = Entity{
|
|
ID: "chest",
|
|
LocationID: "square",
|
|
State: map[string]interface{}{},
|
|
}
|
|
npc := &NPCState{NPCID: "rogue", CurrentLocation: "square"}
|
|
delta := engine.ApplyIntent(&state, npc, ActionIntent{
|
|
ActorID: "rogue",
|
|
Action: "interact",
|
|
TargetEntity: "chest",
|
|
ProposedEffects: map[string]interface{}{
|
|
"resource_delta": map[string]interface{}{"gold": 3},
|
|
"quest_update": map[string]interface{}{
|
|
"id": "find-chest",
|
|
"title": "Find The Chest",
|
|
"status": "completed",
|
|
},
|
|
},
|
|
})
|
|
if !delta.Applied {
|
|
t.Fatalf("expected interact to apply, got %+v", delta)
|
|
}
|
|
resources, ok := state.Entities["chest"].State["resources"].(map[string]int)
|
|
if !ok || resources["gold"] != 3 {
|
|
t.Fatalf("expected gold resource delta, got %+v", state.Entities["chest"].State)
|
|
}
|
|
quest := state.ActiveQuests["find-chest"]
|
|
if quest.Status != "completed" {
|
|
t.Fatalf("expected quest completion, got %+v", quest)
|
|
}
|
|
}
|