87 lines
3.1 KiB
Go
87 lines
3.1 KiB
Go
package world
|
|
|
|
import (
|
|
"bd2server/internal/server/gamedata"
|
|
"bd2server/internal/server/wire"
|
|
"strconv"
|
|
"testing"
|
|
)
|
|
|
|
func recruitNPCPosition(t *testing.T, s *Service, pack, mapID int) {
|
|
t.Helper()
|
|
request := wire.AppendVarint(nil, 1, 1)
|
|
request = wire.AppendVarint(request, 2, uint64(pack))
|
|
request = wire.AppendString(request, 3, `{"MapId":`+strconv.Itoa(mapID)+`,"PlayerPosition":{"x":0,"y":0,"z":0},"ColleaguePositions":[]}`)
|
|
if err := s.state.SaveUserPosition(request); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestResolveRecruitNPCRequiresMapStoryCompletionAndOrdinaryType(t *testing.T) {
|
|
s := testService()
|
|
d := &gamedata.RecruitDesign{Rules: map[uint64]gamedata.RecruitRule{40: {ID: 40, Type: 0, PackID: 21}}}
|
|
npc := gamedata.RecruitNPC{ID: 7, MapID: 9, ScoutID: 40}
|
|
if _, err := s.resolveRecruitNPC(npc, d); err == nil {
|
|
t.Fatal("accepted NPC without saved map")
|
|
}
|
|
recruitNPCPosition(t, s, 21, 9)
|
|
if _, err := s.resolveRecruitNPC(npc, d); err == nil {
|
|
t.Fatal("accepted incomplete story")
|
|
}
|
|
for _, id := range []int{1, 2, 3} {
|
|
if err := s.state.ClearQuest(id, 21); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
if id, err := s.resolveRecruitNPC(npc, d); err != nil || id != 40 {
|
|
t.Fatalf("resolved=%d err=%v", id, err)
|
|
}
|
|
recruitNPCPosition(t, s, 21, 8)
|
|
if _, err := s.resolveRecruitNPC(npc, d); err == nil {
|
|
t.Fatal("accepted NPC in other map")
|
|
}
|
|
recruitNPCPosition(t, s, 21, 9)
|
|
d.Rules[40] = gamedata.RecruitRule{ID: 40, Type: 1, PackID: 21}
|
|
if _, err := s.resolveRecruitNPC(npc, d); err == nil {
|
|
t.Fatal("accepted special NPC through ordinary endpoint")
|
|
}
|
|
}
|
|
|
|
func TestResolveRecruitNPCBlocksActiveQuestRangesAfterEarlierRecruitChapter(t *testing.T) {
|
|
s := testService()
|
|
s.activePack = 22
|
|
s.packs = map[int]map[int]gamedata.QuestDesign{21: s.quests, 22: {1: {ID: 1}, 2: {ID: 2}}}
|
|
s.transitions = map[int]gamedata.PackTransition{21: {PackID: 21, NextPackID: 22}}
|
|
attachTestStoryCatalog(s)
|
|
for _, id := range []int{1, 2, 3} {
|
|
if err := s.state.ClearQuest(id, 21); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
recruitNPCPosition(t, s, 22, 9)
|
|
d := &gamedata.RecruitDesign{Rules: map[uint64]gamedata.RecruitRule{40: {ID: 40, Type: 0, PackID: 21}}}
|
|
npc := gamedata.RecruitNPC{ID: 7, MapID: 9, ScoutID: 40, QuestEnableTypes: []uint64{0}, QuestRanges: []uint64{1}, QuestTypes: map[uint64]uint64{1: 0, 2: 0}}
|
|
if _, err := s.resolveRecruitNPC(npc, d); err == nil {
|
|
t.Fatal("accepted NPC used by active main quest")
|
|
}
|
|
npc.QuestRanges[0] = 2
|
|
if id, err := s.resolveRecruitNPC(npc, d); err != nil || id != 40 {
|
|
t.Fatalf("future quest blocked NPC=%d err=%v", id, err)
|
|
}
|
|
npc.QuestTypes[1] = 1
|
|
npc.QuestRanges[0] = 1
|
|
request := wire.AppendVarint(wire.AppendVarint(wire.AppendVarint(nil, 1, 1), 2, 1), 3, 22)
|
|
if _, err := s.state.UpdateQuest(request); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := s.resolveRecruitNPC(npc, d); err == nil {
|
|
t.Fatal("accepted NPC used by active subquest")
|
|
}
|
|
if err := s.state.ClearQuest(1, 22); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if id, err := s.resolveRecruitNPC(npc, d); err != nil || id != 40 {
|
|
t.Fatalf("cleared subquest still blocked NPC=%d err=%v", id, err)
|
|
}
|
|
}
|