aboutsummaryrefslogtreecommitdiff
path: root/internal/world/room.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-06-28 02:40:30 -0400
committerhistoria <[not public]>2026-06-28 02:40:30 -0400
commita1b6613c6c6a2f8d6e1ecd47e766bd40f92ac295 (patch)
tree4ff8fefb029c93f2aa3db7361658b0b4e9805b66 /internal/world/room.go
parent87dacfbb3dd16e7f55a82361eace98f9a39d75c8 (diff)
downloadthehouseoficarus-a1b6613c6c6a2f8d6e1ecd47e766bd40f92ac295.tar.gz
feat: admin accounts, god mode, OLC commands like dig/room, 'inline' objects changed to 'local' objects
Diffstat (limited to 'internal/world/room.go')
-rw-r--r--internal/world/room.go94
1 files changed, 76 insertions, 18 deletions
diff --git a/internal/world/room.go b/internal/world/room.go
index 8b8830e..21e1277 100644
--- a/internal/world/room.go
+++ b/internal/world/room.go
@@ -49,10 +49,10 @@ type SpawnDef struct {
type ExitDef struct {
Room int `yaml:"room"`
- Condition *behavior.Condition `yaml:"condition"`
- BlockedMessage string `yaml:"blocked_message"`
- SetFlags map[string]any `yaml:"set_flags"`
- SetPlayerFlags map[string]any `yaml:"set_player_flags"`
+ Condition *behavior.Condition `yaml:"condition,omitempty"`
+ BlockedMessage string `yaml:"blocked_message,omitempty"`
+ SetFlags map[string]any `yaml:"set_flags,omitempty"`
+ SetPlayerFlags map[string]any `yaml:"set_player_flags,omitempty"`
}
func (e *ExitDef) UnmarshalYAML(value *yaml.Node) error {
@@ -85,8 +85,8 @@ type Room struct {
type RoomMob struct {
ID string `yaml:"id"`
- WanderRooms []int `yaml:"wander_rooms"`
- WanderInterval float64 `yaml:"wander_interval"`
+ WanderRooms []int `yaml:"wander_rooms,omitempty"`
+ WanderInterval float64 `yaml:"wander_interval,omitempty"`
}
func (rm *RoomMob) UnmarshalYAML(value *yaml.Node) error {
@@ -129,16 +129,17 @@ func (e EnterStep) IsTimed() bool {
}
// RoomObject is either a reference to a file-backed object definition (only
-// `id`/wander fields set) or a fully inline object definition (Inline != nil).
-// An entry is treated as inline when it carries any passive content field
+// `id`/wander fields set) or a fully local object definition (Local != nil).
+// An entry is treated as local when it carries any passive content field
// (name, description, aliases, inroom_description, color, hidden, on_look).
-// Inline objects are room-scoped: their identity (ID, used as the ObjState
+// Local objects are room-scoped: their identity (ID, used as the ObjState
// DefID) is derived from the normalized name; `id:` is reserved for references.
type RoomObject struct {
ID string
WanderRooms []int
WanderInterval float64
- Inline *object.ObjectDef
+ Local *object.ObjectDef
+ HiddenOverride bool `yaml:"hidden,omitempty"`
}
func (ro *RoomObject) UnmarshalYAML(value *yaml.Node) error {
@@ -146,6 +147,7 @@ func (ro *RoomObject) UnmarshalYAML(value *yaml.Node) error {
ID string `yaml:"id"`
WanderRooms []int `yaml:"wander_rooms"`
WanderInterval float64 `yaml:"wander_interval"`
+ Hidden bool `yaml:"hidden"`
}
var ref rawRef
if err := value.Decode(&ref); err != nil {
@@ -158,24 +160,80 @@ func (ro *RoomObject) UnmarshalYAML(value *yaml.Node) error {
if err := value.Decode(&def); err != nil {
return err
}
- inline := def.Name != "" || len(def.Description) > 0 || def.InRoomDescription != "" ||
- len(def.Aliases) > 0 || def.Color != "" || def.Hidden || def.OnLook != nil
- if inline {
- // Identity derives from the name. def.ID still holds any explicit `id:`
- // the builder wrote; it is left in place only so validation can flag it
- // as a stray field (runtime resolution overrides the copy's ID anyway).
+ isLocal := def.Name != "" || len(def.Description) > 0 || def.InRoomDescription != "" ||
+ len(def.Aliases) > 0 || def.Color != "" || def.OnLook != nil
+ if isLocal {
ro.ID = NormalizeObjectName(def.Name)
- ro.Inline = &def
+ ro.Local = &def
return nil
}
ro.ID = ref.ID
+ ro.HiddenOverride = ref.Hidden
return nil
}
+func (ro RoomObject) MarshalYAML() (interface{}, error) {
+ if ro.Local != nil {
+ type inlineObj struct {
+ Name string `yaml:"name"`
+ Aliases []string `yaml:"aliases,omitempty"`
+ Color string `yaml:"color,omitempty"`
+ Hidden bool `yaml:"hidden,omitempty"`
+ InRoomDescription string `yaml:"inroom_description,omitempty"`
+ RemovalItem string `yaml:"removal_item,omitempty"`
+ Description behavior.DescList `yaml:"description,omitempty"`
+ UseInteractions []object.UseInteraction `yaml:"use_interactions,omitempty"`
+ StealTable string `yaml:"steal_table,omitempty"`
+ StealLevel int `yaml:"steal_level,omitempty"`
+ StealXP int `yaml:"steal_xp,omitempty"`
+ StealSpeed float64 `yaml:"steal_speed,omitempty"`
+ GuardMob string `yaml:"guard_mob,omitempty"`
+ Gather *behavior.GatherConfig `yaml:"gather,omitempty"`
+ Talk *behavior.TalkConfig `yaml:"talk,omitempty"`
+ Use *behavior.UseConfig `yaml:"use,omitempty"`
+ Safespot *object.SafespotConfig `yaml:"safespot,omitempty"`
+ OnLook *behavior.NodeAction `yaml:"on_look,omitempty"`
+ }
+ def := ro.Local
+ return inlineObj{
+ Name: def.Name,
+ Aliases: def.Aliases,
+ Color: def.Color,
+ Hidden: def.Hidden,
+ InRoomDescription: def.InRoomDescription,
+ RemovalItem: def.RemovalItem,
+ Description: def.Description,
+ UseInteractions: def.UseInteractions,
+ StealTable: def.StealTable,
+ StealLevel: def.StealLevel,
+ StealXP: def.StealXP,
+ StealSpeed: def.StealSpeed,
+ GuardMob: def.GuardMob,
+ Gather: def.Gather,
+ Talk: def.Talk,
+ Use: def.Use,
+ Safespot: def.Safespot,
+ OnLook: def.OnLook,
+ }, nil
+ }
+ type rawRef struct {
+ ID string `yaml:"id"`
+ WanderRooms []int `yaml:"wander_rooms,omitempty"`
+ WanderInterval float64 `yaml:"wander_interval,omitempty"`
+ Hidden bool `yaml:"hidden,omitempty"`
+ }
+ return rawRef{
+ ID: ro.ID,
+ WanderRooms: ro.WanderRooms,
+ WanderInterval: ro.WanderInterval,
+ Hidden: ro.HiddenOverride,
+ }, nil
+}
+
// NormalizeObjectName lowercases, trims, and collapses internal whitespace,
// keeping spaces (not underscores) so the word-prefix matcher treats the name
// as a single token in its `_`-split fallback. It is the canonical derivation
-// of an inline object's ObjState DefID from its name.
+// of a local object's ObjState DefID from its name.
func NormalizeObjectName(name string) string {
return strings.Join(strings.Fields(strings.ToLower(name)), " ")
}