diff options
Diffstat (limited to 'internal/validate')
| -rw-r--r-- | internal/validate/checks.go | 74 |
1 files changed, 53 insertions, 21 deletions
diff --git a/internal/validate/checks.go b/internal/validate/checks.go index 1a0a233..f89e52d 100644 --- a/internal/validate/checks.go +++ b/internal/validate/checks.go @@ -69,7 +69,7 @@ func validateRooms(s Source) []Issue { } issues = append(issues, validateTriggerBlock( fmt.Sprintf("Room %d: exit %q on_traverse", id, dir), - exit.OnTraverse, false, itemIDs, roomIndex, mobIDs)...) + exit.OnTraverse, false, itemIDs, roomIndex, mobIDs, nil)...) } for _, rm := range room.Mobs { @@ -221,7 +221,7 @@ func validateLocalObject(roomID int, robj world.RoomObject, itemIDs map[string]b } if len(def.OnLook) > 0 { - issues = append(issues, validateTriggerBlock(prefix+": on_look", def.OnLook, false, itemIDs, roomIndex, mobIDs)...) + issues = append(issues, validateTriggerBlock(prefix+": on_look", def.OnLook, false, itemIDs, roomIndex, mobIDs, nil)...) } return issues @@ -486,7 +486,7 @@ func validateMobs(s Source) []Issue { } issues = append(issues, validateTriggerBlock( - fmt.Sprintf("Mob %q: on_kill", id), def.OnKill, false, itemIDs, roomIndex, mobIDs)...) + fmt.Sprintf("Mob %q: on_kill", id), def.OnKill, false, itemIDs, roomIndex, mobIDs, dropIDs)...) } return issues @@ -591,7 +591,7 @@ func validateObjects(s Source) []Issue { } issues = append(issues, validateTriggerBlock( - fmt.Sprintf("Object %q: on_use", id), obj.OnUse, false, itemIDs, roomIndex, mobIDs)...) + fmt.Sprintf("Object %q: on_use", id), obj.OnUse, false, itemIDs, roomIndex, mobIDs, dropIDs)...) if obj.Gather != nil { issues = append(issues, validateGather(fmt.Sprintf("Object %q: gather", id), obj.Gather, itemIDs, dropIDs)...) @@ -602,7 +602,7 @@ func validateObjects(s Source) []Issue { } if len(obj.OnLook) > 0 { - issues = append(issues, validateTriggerBlock(fmt.Sprintf("Object %q: on_look", id), obj.OnLook, false, itemIDs, roomIndex, mobIDs)...) + issues = append(issues, validateTriggerBlock(fmt.Sprintf("Object %q: on_look", id), obj.OnLook, false, itemIDs, roomIndex, mobIDs, dropIDs)...) } } @@ -613,6 +613,8 @@ func validateItems(s Source) []Issue { var issues []Issue itemIDs := s.Items.IDSet() dropIDs := dropTableIDSet(s.DataDir) + roomIndex := s.World.RoomIndex() + mobIDs := s.Mobs.AllDefIDs() for id := range itemIDs { def, err := s.Items.Load(id) @@ -632,13 +634,9 @@ func validateItems(s Source) []Issue { }) } - if def.SearchTable != "" && !dropIDs[def.SearchTable] { - issues = append(issues, Issue{ - Level: "ERROR", - Type: "reference", - Message: fmt.Sprintf("Item %q: search_table %q does not exist", - id, def.SearchTable), - }) + if len(def.Search) > 0 { + issues = append(issues, validateTriggerBlock( + fmt.Sprintf("Item %q: search", id), def.Search, false, itemIDs, roomIndex, mobIDs, dropIDs)...) } if def.FarmProduct != "" && !itemIDs[def.FarmProduct] { @@ -803,11 +801,11 @@ func validateRoomTriggers(s Source) []Issue { } if len(room.OnEnter) > 0 { issues = append(issues, validateTriggerBlock( - fmt.Sprintf("Room %d: on_enter", id), room.OnEnter, false, itemIDs, roomIndex, mobIDs)...) + fmt.Sprintf("Room %d: on_enter", id), room.OnEnter, false, itemIDs, roomIndex, mobIDs, nil)...) } if len(room.OnExit) > 0 { issues = append(issues, validateTriggerBlock( - fmt.Sprintf("Room %d: on_exit", id), room.OnExit, false, itemIDs, roomIndex, mobIDs)...) + fmt.Sprintf("Room %d: on_exit", id), room.OnExit, false, itemIDs, roomIndex, mobIDs, nil)...) } } @@ -1166,10 +1164,9 @@ func validateExitReciprocity(s Source) []Issue { return issues } -// validateStep validates a single Step's effects. mobIDs may be nil when the -// caller doesn't track mob ids (e.g. local-object on_look); spawn/despawn mob -// references are then skipped. -func validateStep(prefix string, step *behavior.Step, itemIDs map[string]bool, roomIndex map[int]bool, mobIDs map[string]bool) []Issue { +// validateStep validates a single Step's effects. mobIDs and dropIDs may be nil +// when the caller doesn't track those entities; validation is skipped for nil sets. +func validateStep(prefix string, step *behavior.Step, itemIDs map[string]bool, roomIndex map[int]bool, mobIDs map[string]bool, dropIDs map[string]bool) []Issue { var issues []Issue if step == nil { return issues @@ -1241,6 +1238,41 @@ func validateStep(prefix string, step *behavior.Step, itemIDs map[string]bool, r }) } + for i, e := range step.DropTable { + if e.ItemID == "" && e.Table == "" { + issues = append(issues, Issue{ + Level: "WARN", + Type: "semantic", + Message: fmt.Sprintf("%s: drop_table[%d] has no item_id or table", + prefix, i), + }) + } + if e.ItemID != "" && e.ItemID != "credits" && !itemIDs[e.ItemID] { + issues = append(issues, Issue{ + Level: "ERROR", + Type: "reference", + Message: fmt.Sprintf("%s: drop_table item %q does not exist", + prefix, e.ItemID), + }) + } + if e.Table != "" && dropIDs != nil && !dropIDs[e.Table] { + issues = append(issues, Issue{ + Level: "ERROR", + Type: "reference", + Message: fmt.Sprintf("%s: drop_table table %q does not exist", + prefix, e.Table), + }) + } + if e.Weight <= 0 { + issues = append(issues, Issue{ + Level: "WARN", + Type: "semantic", + Message: fmt.Sprintf("%s: drop_table[%d] weight is %d (never drops)", + prefix, i, e.Weight), + }) + } + } + if step.Condition != nil { issues = append(issues, validateCondition(prefix, step.Condition, roomIndex)...) } @@ -1315,7 +1347,7 @@ func checkPlayerOnlyInCondition(prefix string, c *behavior.Condition) []Issue { // require on_player_flag/on_global_flag and forbid item_id) and false for verb // blocks (on_use/on_look/on_kill/on_enter/on_exit/on_traverse), where item_id // is checked against itemIDs. -func validateTriggerBlock(prefix string, block []behavior.Trigger, isFlag bool, itemIDs map[string]bool, roomIndex map[int]bool, mobIDs map[string]bool) []Issue { +func validateTriggerBlock(prefix string, block []behavior.Trigger, isFlag bool, itemIDs map[string]bool, roomIndex map[int]bool, mobIDs map[string]bool, dropIDs map[string]bool) []Issue { var issues []Issue for i := range block { t := &block[i] @@ -1369,7 +1401,7 @@ func validateTriggerBlock(prefix string, block []behavior.Trigger, isFlag bool, issues = append(issues, checkPlayerOnlyInCondition(entryPrefix, t.Condition)...) } for si := range t.Steps { - issues = append(issues, validateStep(fmt.Sprintf("%s: step[%d]", entryPrefix, si), &t.Steps[si], itemIDs, roomIndex, mobIDs)...) + issues = append(issues, validateStep(fmt.Sprintf("%s: step[%d]", entryPrefix, si), &t.Steps[si], itemIDs, roomIndex, mobIDs, dropIDs)...) if isFlag && t.OnGlobalFlag != "" && t.Steps[si].Condition != nil { issues = append(issues, checkPlayerOnlyInCondition(fmt.Sprintf("%s: step[%d]", entryPrefix, si), t.Steps[si].Condition)...) } @@ -1384,5 +1416,5 @@ func validateTalkStep(prefix string, step *behavior.Step, itemIDs map[string]boo if step == nil { return nil } - return validateStep(prefix, step, itemIDs, roomIndex, nil) + return validateStep(prefix, step, itemIDs, roomIndex, nil, nil) } |
