diff --git a/_datafiles/world/default/rooms/catacombs/32.yaml b/_datafiles/world/default/rooms/catacombs/32.yaml
index 8388b172..80678b08 100755
--- a/_datafiles/world/default/rooms/catacombs/32.yaml
+++ b/_datafiles/world/default/rooms/catacombs/32.yaml
@@ -1,11 +1,5 @@
roomid: 32
zone: Catacombs
-zoneconfig:
- roomid: 32
- autoscale:
- minimum: 8
- maximum: 13
- musicfile: static/audio/music/catacombs.mp3
title: Entrance to the Catacombs
description: Beneath the Sanctuary of the Benevolent Heart lies the labyrinthine expanse
known as the Catacombs. A network of narrow, winding tunnels and chambers, the Catacombs
diff --git a/_datafiles/world/default/rooms/catacombs/zone-config.yaml b/_datafiles/world/default/rooms/catacombs/zone-config.yaml
new file mode 100644
index 00000000..917612af
--- /dev/null
+++ b/_datafiles/world/default/rooms/catacombs/zone-config.yaml
@@ -0,0 +1,7 @@
+name: Catacombs
+roomid: 32
+autoscale:
+ minimum: 8
+ maximum: 13
+musicfile: static/audio/music/catacombs.mp3
+defaultbiome: dungeon
diff --git a/_datafiles/world/default/rooms/dark_forest/300.yaml b/_datafiles/world/default/rooms/dark_forest/300.yaml
index 5dff1d64..1dab353e 100755
--- a/_datafiles/world/default/rooms/dark_forest/300.yaml
+++ b/_datafiles/world/default/rooms/dark_forest/300.yaml
@@ -1,10 +1,5 @@
roomid: 300
zone: Dark Forest
-zoneconfig:
- roomid: 300
- mutators:
- - mutatorid: forest-mist
- musicfile: static/audio/music/dark-forest.mp3
title: Forest Road
description: As you venture further along the old road, it leads you into the heart
of the foreboding Dark Forest. The transition from the tranquil Frost Lake to this
diff --git a/_datafiles/world/default/rooms/dark_forest/zone-config.yaml b/_datafiles/world/default/rooms/dark_forest/zone-config.yaml
new file mode 100644
index 00000000..96f80593
--- /dev/null
+++ b/_datafiles/world/default/rooms/dark_forest/zone-config.yaml
@@ -0,0 +1,6 @@
+name: Dark Forest
+roomid: 300
+mutators:
+ - mutatorid: forest-mist
+musicfile: static/audio/music/dark-forest.mp3
+defaultbiome: forest
diff --git a/_datafiles/world/default/rooms/endless_trashheap/139.yaml b/_datafiles/world/default/rooms/endless_trashheap/139.yaml
index 06ee09a1..d0232fba 100755
--- a/_datafiles/world/default/rooms/endless_trashheap/139.yaml
+++ b/_datafiles/world/default/rooms/endless_trashheap/139.yaml
@@ -1,7 +1,5 @@
roomid: 139
zone: Endless Trashheap
-zoneconfig:
- roomid: 139
title: The wasteland
description: The Endless Trashheap stretches to the horizon, a bizarre landscape of
discarded wealth where mountains of forgotten relics rise like the ruins of a once-glorious
diff --git a/_datafiles/world/default/rooms/endless_trashheap/zone-config.yaml b/_datafiles/world/default/rooms/endless_trashheap/zone-config.yaml
new file mode 100644
index 00000000..6262e108
--- /dev/null
+++ b/_datafiles/world/default/rooms/endless_trashheap/zone-config.yaml
@@ -0,0 +1,2 @@
+name: Endless Trashheap
+roomid: 139
diff --git a/_datafiles/world/default/rooms/frost_lake/304.yaml b/_datafiles/world/default/rooms/frost_lake/304.yaml
index 8b770999..b36a0346 100755
--- a/_datafiles/world/default/rooms/frost_lake/304.yaml
+++ b/_datafiles/world/default/rooms/frost_lake/304.yaml
@@ -1,11 +1,5 @@
roomid: 304
zone: Frost Lake
-zoneconfig:
- roomid: 304
- autoscale:
- minimum: 10
- maximum: 13
- musicfile: static/audio/music/frost-lake.mp3
title: Frost Lake Shore
description: The stillness here is profound, the world holding its breath in reverence
for this enchanting realm. The silence is broken only by the soft, melodic chime
diff --git a/_datafiles/world/default/rooms/frost_lake/zone-config.yaml b/_datafiles/world/default/rooms/frost_lake/zone-config.yaml
new file mode 100644
index 00000000..3ca00808
--- /dev/null
+++ b/_datafiles/world/default/rooms/frost_lake/zone-config.yaml
@@ -0,0 +1,7 @@
+name: Frost Lake
+roomid: 304
+autoscale:
+ minimum: 10
+ maximum: 13
+musicfile: static/audio/music/frost-lake.mp3
+defaultbiome: shore
diff --git a/_datafiles/world/default/rooms/frostfang/1.yaml b/_datafiles/world/default/rooms/frostfang/1.yaml
index 1d939f70..2f9df92a 100755
--- a/_datafiles/world/default/rooms/frostfang/1.yaml
+++ b/_datafiles/world/default/rooms/frostfang/1.yaml
@@ -1,13 +1,5 @@
roomid: 1
zone: Frostfang
-zoneconfig:
- roomid: 1
- autoscale:
- minimum: 1
- maximum: 5
- idlemessages:
- - A cold wind blows through the city.
- musicfile: static/audio/music/frostfang.mp3
title: Town Square
description: In the shimmering heart of Frostfang, a city wrapped in a perpetual blanket
of snow and illuminated by the ethereal glow of the auroras, lies the Town Square.
diff --git a/_datafiles/world/default/rooms/frostfang/zone-config.yaml b/_datafiles/world/default/rooms/frostfang/zone-config.yaml
new file mode 100755
index 00000000..584913f8
--- /dev/null
+++ b/_datafiles/world/default/rooms/frostfang/zone-config.yaml
@@ -0,0 +1,9 @@
+name: Frostfang
+roomid: 1
+autoscale:
+ minimum: 1
+ maximum: 5
+idlemessages:
+ - A cold wind blows through the city.
+musicfile: static/audio/music/frostfang.mp3
+defaultbiome: city
\ No newline at end of file
diff --git a/_datafiles/world/default/rooms/frostfang_slums/439.yaml b/_datafiles/world/default/rooms/frostfang_slums/439.yaml
index 5993147f..4f6e7092 100755
--- a/_datafiles/world/default/rooms/frostfang_slums/439.yaml
+++ b/_datafiles/world/default/rooms/frostfang_slums/439.yaml
@@ -1,13 +1,5 @@
roomid: 439
zone: Frostfang Slums
-zoneconfig:
- roomid: 439
- autoscale:
- minimum: 5
- maximum: 10
- mutators:
- - mutatorid: pvp-enabled
- musicfile: static/audio/music/frostfang-slums.mp3
title: Poorly Lit Street
description: 'Tucked away in the heart of Frostfang''s sprawling slums, a dimly lit
alleyway meanders from the bustling Beggars Lane. This concealed corner, a world
diff --git a/_datafiles/world/default/rooms/frostfang_slums/zone-config.yaml b/_datafiles/world/default/rooms/frostfang_slums/zone-config.yaml
new file mode 100644
index 00000000..b7c6c06c
--- /dev/null
+++ b/_datafiles/world/default/rooms/frostfang_slums/zone-config.yaml
@@ -0,0 +1,9 @@
+name: Frostfang Slums
+roomid: 439
+autoscale:
+ minimum: 5
+ maximum: 10
+mutators:
+ - mutatorid: pvp-enabled
+musicfile: static/audio/music/frostfang-slums.mp3
+defaultbiome: city
diff --git a/_datafiles/world/default/rooms/mirror_caves/218.yaml b/_datafiles/world/default/rooms/mirror_caves/218.yaml
index 9b5e4edf..5c871dfd 100755
--- a/_datafiles/world/default/rooms/mirror_caves/218.yaml
+++ b/_datafiles/world/default/rooms/mirror_caves/218.yaml
@@ -1,8 +1,5 @@
roomid: 218
zone: Mirror Caves
-zoneconfig:
- roomid: 218
- musicfile: static/audio/music/mirror-caves.mp3
title: Cave Entrance
description: "As you cautiously step into the entrance of the mirror caves, a chilling
draft greets you, carrying the faint scent of earth and ancient stone. The cave's
diff --git a/_datafiles/world/default/rooms/mirror_caves/zone-config.yaml b/_datafiles/world/default/rooms/mirror_caves/zone-config.yaml
new file mode 100644
index 00000000..4da92390
--- /dev/null
+++ b/_datafiles/world/default/rooms/mirror_caves/zone-config.yaml
@@ -0,0 +1,4 @@
+name: Mirror Caves
+roomid: 218
+musicfile: static/audio/music/mirror-caves.mp3
+defaultbiome: cave
diff --git a/_datafiles/world/default/rooms/mystarion/612.yaml b/_datafiles/world/default/rooms/mystarion/612.yaml
index babd0249..40fea7d2 100755
--- a/_datafiles/world/default/rooms/mystarion/612.yaml
+++ b/_datafiles/world/default/rooms/mystarion/612.yaml
@@ -1,8 +1,5 @@
roomid: 612
zone: Mystarion
-zoneconfig:
- roomid: 612
- musicfile: static/audio/music/mystarion.mp3
title: Main road
description: The road itself becomes a cobblestone path, the stones worn smooth by
centuries of use, each one seemingly placed with intention, leading inexorably towards
diff --git a/_datafiles/world/default/rooms/mystarion/zone-config.yaml b/_datafiles/world/default/rooms/mystarion/zone-config.yaml
new file mode 100644
index 00000000..ada9c379
--- /dev/null
+++ b/_datafiles/world/default/rooms/mystarion/zone-config.yaml
@@ -0,0 +1,4 @@
+name: Mystarion
+roomid: 612
+musicfile: static/audio/music/mystarion.mp3
+defaultbiome: city
diff --git a/_datafiles/world/default/rooms/nowhere/-1.yaml b/_datafiles/world/default/rooms/nowhere/-1.yaml
index 98dcafd9..5d812e72 100755
--- a/_datafiles/world/default/rooms/nowhere/-1.yaml
+++ b/_datafiles/world/default/rooms/nowhere/-1.yaml
@@ -1,7 +1,5 @@
roomid: -1
zone: Nowhere
-zoneconfig:
- roomid: -1
title: The Void
description: As your senses attune to the stillness around, you find yourself engulfed
in an impenetrable void, a realm where darkness reigns supreme. The abyss seems
diff --git a/_datafiles/world/default/rooms/nowhere/zone-config.yaml b/_datafiles/world/default/rooms/nowhere/zone-config.yaml
new file mode 100644
index 00000000..7073f623
--- /dev/null
+++ b/_datafiles/world/default/rooms/nowhere/zone-config.yaml
@@ -0,0 +1,2 @@
+name: Nowhere
+roomid: -1
diff --git a/_datafiles/world/default/rooms/shadow_realm/75.yaml b/_datafiles/world/default/rooms/shadow_realm/75.yaml
index 984d81a6..6391d3c2 100755
--- a/_datafiles/world/default/rooms/shadow_realm/75.yaml
+++ b/_datafiles/world/default/rooms/shadow_realm/75.yaml
@@ -1,7 +1,5 @@
roomid: 75
zone: Shadow Realm
-zoneconfig:
- roomid: 75
title: Waiting room
description: You find yourself in the heart of the Shadow Realm, a place suspended
between the corporeal and the ethereal. The air is heavy with a palpable stillness,
diff --git a/_datafiles/world/default/rooms/shadow_realm/zone-config.yaml b/_datafiles/world/default/rooms/shadow_realm/zone-config.yaml
new file mode 100644
index 00000000..86e8e709
--- /dev/null
+++ b/_datafiles/world/default/rooms/shadow_realm/zone-config.yaml
@@ -0,0 +1,2 @@
+name: Shadow Realm
+roomid: 75
diff --git a/_datafiles/world/default/rooms/stormshards/575.yaml b/_datafiles/world/default/rooms/stormshards/575.yaml
index 2e4c3865..fad86f74 100755
--- a/_datafiles/world/default/rooms/stormshards/575.yaml
+++ b/_datafiles/world/default/rooms/stormshards/575.yaml
@@ -1,8 +1,5 @@
roomid: 575
zone: Stormshards
-zoneconfig:
- roomid: 575
- musicfile: static/audio/music/stormshards.mp3
title: Mountain path
description: As the path ascends, the terrain becomes more rugged; the trees thin
out, giving way to rocky outcrops and steep, craggy inclines. The earth underfoot
diff --git a/_datafiles/world/default/rooms/stormshards/zone-config.yaml b/_datafiles/world/default/rooms/stormshards/zone-config.yaml
new file mode 100644
index 00000000..f844c3d7
--- /dev/null
+++ b/_datafiles/world/default/rooms/stormshards/zone-config.yaml
@@ -0,0 +1,4 @@
+name: Stormshards
+roomid: 575
+musicfile: static/audio/music/stormshards.mp3
+defaultbiome: mountains
diff --git a/_datafiles/world/default/rooms/stormwatchers_keep/880.yaml b/_datafiles/world/default/rooms/stormwatchers_keep/880.yaml
index 9adefe64..c9daf9ed 100755
--- a/_datafiles/world/default/rooms/stormwatchers_keep/880.yaml
+++ b/_datafiles/world/default/rooms/stormwatchers_keep/880.yaml
@@ -1,11 +1,5 @@
roomid: 880
zone: Stormwatchers Keep
-zoneconfig:
- roomid: 880
- autoscale:
- minimum: 15
- maximum: 25
- musicfile: static/audio/music/whispering-wastes.mp3
title: Stormwatchers Keep
description: The Halls of Stormwatchers Keep are a labyrinthine network of grand corridors
and chambers carved into the heart of a colossal glacier. Each hall is adorned with
diff --git a/_datafiles/world/default/rooms/stormwatchers_keep/zone-config.yaml b/_datafiles/world/default/rooms/stormwatchers_keep/zone-config.yaml
new file mode 100644
index 00000000..6cd4e9ce
--- /dev/null
+++ b/_datafiles/world/default/rooms/stormwatchers_keep/zone-config.yaml
@@ -0,0 +1,7 @@
+name: Stormwatchers Keep
+roomid: 880
+autoscale:
+ minimum: 15
+ maximum: 25
+musicfile: static/audio/music/whispering-wastes.mp3
+defaultbiome: city
diff --git a/_datafiles/world/default/rooms/sun_anvil/1000.yaml b/_datafiles/world/default/rooms/sun_anvil/1000.yaml
index 08f0cd90..c632f0f7 100755
--- a/_datafiles/world/default/rooms/sun_anvil/1000.yaml
+++ b/_datafiles/world/default/rooms/sun_anvil/1000.yaml
@@ -1,10 +1,5 @@
roomid: 1000
zone: Sun Anvil
-zoneconfig:
- roomid: 1000
- mutators:
- - mutatorid: desert-sun
- musicfile: static/audio/music/sun-anvil.mp3
title: Desert's Edge
description: You find yourself at the threshold of the Sun Anvil Desert, where the
air itself seems to shimmer under the relentless glare of a merciless sun. The ground
diff --git a/_datafiles/world/default/rooms/sun_anvil/zone-config.yaml b/_datafiles/world/default/rooms/sun_anvil/zone-config.yaml
new file mode 100644
index 00000000..2596fe0e
--- /dev/null
+++ b/_datafiles/world/default/rooms/sun_anvil/zone-config.yaml
@@ -0,0 +1,6 @@
+name: Sun Anvil
+roomid: 1000
+mutators:
+- mutatorid: desert-sun
+musicfile: static/audio/music/sun-anvil.mp3
+defaultbiome: desert
diff --git a/_datafiles/world/default/rooms/tutorial/900.yaml b/_datafiles/world/default/rooms/tutorial/900.yaml
index e872b380..8a1f506f 100755
--- a/_datafiles/world/default/rooms/tutorial/900.yaml
+++ b/_datafiles/world/default/rooms/tutorial/900.yaml
@@ -1,7 +1,5 @@
roomid: 900
zone: Tutorial
-zoneconfig:
- roomid: 900
title: Learning to Look
description: You are at the Newbie School. Here you will learn the very basics of
how to navigate and interact with the world. Pay attention, because once you complete
diff --git a/_datafiles/world/default/rooms/tutorial/zone-config.yaml b/_datafiles/world/default/rooms/tutorial/zone-config.yaml
new file mode 100644
index 00000000..504a66ef
--- /dev/null
+++ b/_datafiles/world/default/rooms/tutorial/zone-config.yaml
@@ -0,0 +1,2 @@
+name: Tutorial
+roomid: 900
diff --git a/_datafiles/world/default/rooms/whispering_wastes/168.yaml b/_datafiles/world/default/rooms/whispering_wastes/168.yaml
index 2dce597e..0e1aebba 100755
--- a/_datafiles/world/default/rooms/whispering_wastes/168.yaml
+++ b/_datafiles/world/default/rooms/whispering_wastes/168.yaml
@@ -1,13 +1,5 @@
roomid: 168
zone: Whispering Wastes
-zoneconfig:
- roomid: 168
- autoscale:
- minimum: 5
- maximum: 15
- mutators:
- - mutatorid: freezing-cold
- musicfile: static/audio/music/whispering-wastes.mp3
title: Frozen Wasteland
description: The relentless blizzard swallows the world in a veil of white. The sky,
a perpetual twilight, casts a surreal glow over the endless expanse of snow and
diff --git a/_datafiles/world/default/rooms/whispering_wastes/zone-config.yaml b/_datafiles/world/default/rooms/whispering_wastes/zone-config.yaml
new file mode 100644
index 00000000..fc5ffd0a
--- /dev/null
+++ b/_datafiles/world/default/rooms/whispering_wastes/zone-config.yaml
@@ -0,0 +1,9 @@
+name: Whispering Wastes
+roomid: 168
+autoscale:
+ minimum: 5
+ maximum: 15
+mutators:
+- mutatorid: freezing-cold
+musicfile: static/audio/music/whispering-wastes.mp3
+defaultbiome: snow
diff --git a/_datafiles/world/empty/rooms/endless_trashheap/139.yaml b/_datafiles/world/empty/rooms/endless_trashheap/139.yaml
index 06ee09a1..d0232fba 100755
--- a/_datafiles/world/empty/rooms/endless_trashheap/139.yaml
+++ b/_datafiles/world/empty/rooms/endless_trashheap/139.yaml
@@ -1,7 +1,5 @@
roomid: 139
zone: Endless Trashheap
-zoneconfig:
- roomid: 139
title: The wasteland
description: The Endless Trashheap stretches to the horizon, a bizarre landscape of
discarded wealth where mountains of forgotten relics rise like the ruins of a once-glorious
diff --git a/_datafiles/world/empty/rooms/endless_trashheap/zone-config.yaml b/_datafiles/world/empty/rooms/endless_trashheap/zone-config.yaml
new file mode 100644
index 00000000..6262e108
--- /dev/null
+++ b/_datafiles/world/empty/rooms/endless_trashheap/zone-config.yaml
@@ -0,0 +1,2 @@
+name: Endless Trashheap
+roomid: 139
diff --git a/_datafiles/world/empty/rooms/shadow_realm/75.yaml b/_datafiles/world/empty/rooms/shadow_realm/75.yaml
index 984d81a6..6391d3c2 100755
--- a/_datafiles/world/empty/rooms/shadow_realm/75.yaml
+++ b/_datafiles/world/empty/rooms/shadow_realm/75.yaml
@@ -1,7 +1,5 @@
roomid: 75
zone: Shadow Realm
-zoneconfig:
- roomid: 75
title: Waiting room
description: You find yourself in the heart of the Shadow Realm, a place suspended
between the corporeal and the ethereal. The air is heavy with a palpable stillness,
diff --git a/_datafiles/world/empty/rooms/shadow_realm/zone-config.yaml b/_datafiles/world/empty/rooms/shadow_realm/zone-config.yaml
new file mode 100644
index 00000000..061f86bc
--- /dev/null
+++ b/_datafiles/world/empty/rooms/shadow_realm/zone-config.yaml
@@ -0,0 +1,2 @@
+name: Shadow Realm
+roomid: 75
\ No newline at end of file
diff --git a/_datafiles/world/empty/rooms/startland/1.yaml b/_datafiles/world/empty/rooms/startland/1.yaml
index 44af7637..bdd98b33 100755
--- a/_datafiles/world/empty/rooms/startland/1.yaml
+++ b/_datafiles/world/empty/rooms/startland/1.yaml
@@ -1,10 +1,5 @@
roomid: 1
zone: Startland
-zoneconfig:
- roomid: 1
- autoscale:
- minimum: 1
- maximum: 5
title: Town Square
description: You stand at the town square of startland. This is the first room you
enter upon completing training and beginning the mud.
diff --git a/_datafiles/world/empty/rooms/startland/zone-config.yaml b/_datafiles/world/empty/rooms/startland/zone-config.yaml
new file mode 100644
index 00000000..01b3a6fe
--- /dev/null
+++ b/_datafiles/world/empty/rooms/startland/zone-config.yaml
@@ -0,0 +1,6 @@
+name: Startland
+roomid: 1
+autoscale:
+ minimum: 1
+ maximum: 5
+defaultbiome: city
diff --git a/_datafiles/world/empty/rooms/tutorial/900.yaml b/_datafiles/world/empty/rooms/tutorial/900.yaml
index e872b380..8a1f506f 100755
--- a/_datafiles/world/empty/rooms/tutorial/900.yaml
+++ b/_datafiles/world/empty/rooms/tutorial/900.yaml
@@ -1,7 +1,5 @@
roomid: 900
zone: Tutorial
-zoneconfig:
- roomid: 900
title: Learning to Look
description: You are at the Newbie School. Here you will learn the very basics of
how to navigate and interact with the world. Pay attention, because once you complete
diff --git a/_datafiles/world/empty/rooms/tutorial/zone-config.yaml b/_datafiles/world/empty/rooms/tutorial/zone-config.yaml
new file mode 100644
index 00000000..504a66ef
--- /dev/null
+++ b/_datafiles/world/empty/rooms/tutorial/zone-config.yaml
@@ -0,0 +1,2 @@
+name: Tutorial
+roomid: 900
diff --git a/internal/fileloader/fileloader.go b/internal/fileloader/fileloader.go
index ed8f66f2..d2d34f24 100644
--- a/internal/fileloader/fileloader.go
+++ b/internal/fileloader/fileloader.go
@@ -1,7 +1,6 @@
package fileloader
import (
- "encoding/json"
"fmt"
"io"
"io/fs"
@@ -38,10 +37,6 @@ type Loadable[K comparable] interface {
}
const (
- // File types to load
- FileTypeYaml FileType = iota
- FileTypeJson
-
// Save options
SaveCareful SaveOption = iota // Save a backup and rename vs. just overwriting
)
@@ -61,35 +56,19 @@ func LoadFlatFile[T LoadableSimple](path string) (T, error) {
return loaded, errors.New(`filepath: ` + path + ` is a directory`)
}
- fpathLower := strings.ToLower(path[len(path)-5:]) // Only need to compare the last 5 characters
-
- if fpathLower == `.yaml` {
-
- bytes, err := os.ReadFile(path)
- if err != nil {
- return loaded, errors.Wrap(err, `filepath: `+path)
- }
-
- err = yaml.Unmarshal(bytes, &loaded)
- if err != nil {
- return loaded, errors.Wrap(err, `filepath: `+path)
- }
-
- } else if fpathLower == `.json` {
-
- bytes, err := os.ReadFile(path)
- if err != nil {
- return loaded, errors.Wrap(err, `filepath: `+path)
- }
+ fExt := filepath.Ext(path)
+ if fExt != `.yaml` {
+ return loaded, errors.New(`invalid file type: ` + path)
+ }
- err = json.Unmarshal(bytes, &loaded)
- if err != nil {
- return loaded, errors.Wrap(err, `filepath: `+path)
- }
+ bytes, err := os.ReadFile(path)
+ if err != nil {
+ return loaded, errors.Wrap(err, `filepath: `+path)
+ }
- } else {
- // Skip the file altogether
- return loaded, errors.New(`invalid file type: ` + path)
+ err = yaml.Unmarshal(bytes, &loaded)
+ if err != nil {
+ return loaded, errors.Wrap(err, `filepath: `+path)
}
// Make sure the Filepath it claims is correct in case we need to save it later
@@ -106,40 +85,35 @@ func LoadFlatFile[T LoadableSimple](path string) (T, error) {
}
// LoadAllFlatFilesSimple doesn't require a unique Id() for each item
-func LoadAllFlatFilesSimple[T LoadableSimple](basePath string, fileTypes ...FileType) ([]T, error) {
+func LoadAllFlatFilesSimple[T LoadableSimple](basePath string, filePattern ...string) ([]T, error) {
loadedData := make([]T, 0, 128)
- includeYaml := true
- includeJson := true
-
- if len(fileTypes) > 0 {
- includeYaml = false
- includeJson = false
-
- for _, fType := range fileTypes {
- if fType == FileTypeYaml {
- includeYaml = true
- } else if fType == FileTypeJson {
- includeJson = true
- }
- }
- }
+ fileSuffix := `.yaml` // Only support yaml
+ suffixLen := len(fileSuffix)
err := filepath.Walk(basePath, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
- // only lower the last 5 characters of the path string
- fpathLower := strings.ToLower(path[len(path)-5:])
+ if info.IsDir() {
+ return nil
+ }
- if !includeYaml && fpathLower == `.yaml` {
- return errors.New(`invalid file type (yaml): ` + path)
+ if len(path) < suffixLen {
+ return nil
}
- if !includeJson && fpathLower == `.json` {
- return errors.New(`invalid file type (json): ` + path)
+ if path[len(path)-suffixLen:] != fileSuffix {
+ return nil
+ }
+
+ if len(filePattern) > 0 {
+ fileName := filepath.Base(path)
+ if ok, _ := filepath.Match(filePattern[0], fileName); !ok {
+ return nil
+ }
}
loaded, err := LoadFlatFile[T](path)
@@ -157,27 +131,14 @@ func LoadAllFlatFilesSimple[T LoadableSimple](basePath string, fileTypes ...File
}
// Will check the ID() of each item to make sure it's unique
-func LoadAllFlatFiles[K comparable, T Loadable[K]](basePath string, fileTypes ...FileType) (map[K]T, error) {
+func LoadAllFlatFiles[K comparable, T Loadable[K]](basePath string, filePattern ...string) (map[K]T, error) {
basePath = filepath.FromSlash(basePath)
loadedData := make(map[K]T)
- includeYaml := true
- includeJson := true
-
- if len(fileTypes) > 0 {
- includeYaml = false
- includeJson = false
-
- for _, fType := range fileTypes {
- if fType == FileTypeYaml {
- includeYaml = true
- } else if fType == FileTypeJson {
- includeJson = true
- }
- }
- }
+ fileSuffix := `.yaml` // Only support yaml
+ suffixLen := len(fileSuffix)
err := filepath.Walk(basePath, func(path string, info os.FileInfo, err error) error {
if err != nil {
@@ -188,36 +149,31 @@ func LoadAllFlatFiles[K comparable, T Loadable[K]](basePath string, fileTypes ..
return nil
}
- var loaded T
-
- fpathLower := path[len(path)-5:] // Only need to compare the last 5 characters
- if includeYaml && fpathLower == `.yaml` {
+ if len(path) < suffixLen {
+ return nil
+ }
- bytes, err := os.ReadFile(path)
- if err != nil {
- return errors.Wrap(err, `filepath: `+path)
- }
+ if path[len(path)-suffixLen:] != fileSuffix {
+ return nil
+ }
- err = yaml.Unmarshal(bytes, &loaded)
- if err != nil {
- return errors.Wrap(err, `filepath: `+path)
+ if len(filePattern) > 0 {
+ fileName := filepath.Base(path)
+ if ok, _ := filepath.Match(filePattern[0], fileName); !ok {
+ return nil
}
+ }
- } else if includeJson && fpathLower == `.json` {
-
- bytes, err := os.ReadFile(path)
- if err != nil {
- return errors.Wrap(err, `filepath: `+path)
- }
+ bytes, err := os.ReadFile(path)
+ if err != nil {
+ return errors.Wrap(err, `filepath: `+path)
+ }
- err = json.Unmarshal(bytes, &loaded)
- if err != nil {
- return errors.Wrap(err, `filepath: `+path)
- }
+ var loaded T
- } else {
- // Skip the file altogether
- return nil
+ err = yaml.Unmarshal(bytes, &loaded)
+ if err != nil {
+ return errors.Wrap(err, `filepath: `+path)
}
if !strings.HasSuffix(path, filepath.FromSlash(loaded.Filepath())) {
@@ -257,23 +213,16 @@ func SaveFlatFile[T LoadableSimple](basePath string, dataUnit T, saveOptions ...
// Get filepath from interface
path := filepath.Join(basePath, dataUnit.Filepath())
-
- os.MkdirAll(filepath.Dir(path), os.ModePerm)
-
- var bytes []byte
- var err error
-
- fpathLower := path[len(path)-5:] // Only need to compare the last 5 characters
+ fExt := filepath.Ext(path)
// Use filepath to determine file marshal type
- if fpathLower == `.yaml` {
- bytes, err = yaml.Marshal(dataUnit)
- } else if fpathLower == `.json` {
- bytes, err = json.Marshal(dataUnit)
- } else {
+ if fExt != `.yaml` {
return errors.New(fmt.Sprint(`SaveFlatFile`, `basePath`, basePath, `type`, fmt.Sprintf(`%T`, *new(T)), `path`, path, `err`, `unsupported file type`))
}
+ os.MkdirAll(filepath.Dir(path), os.ModePerm)
+
+ bytes, err := yaml.Marshal(dataUnit)
if err != nil {
return errors.New(fmt.Sprint(`SaveFlatFile`, `basePath`, basePath, `type`, fmt.Sprintf(`%T`, *new(T)), `path`, path, `err`, err))
}
@@ -340,17 +289,14 @@ func SaveAllFlatFiles[K comparable, T Loadable[K]](basePath string, data map[K]T
// Get filepath from interface
path := filepath.Join(basePath, dataUnit.Filepath())
- fpathLower := path[len(path)-5:] // Only need to compare the last 5 characters
+ fExt := filepath.Ext(path)
// Use filepath to determine file marshal type
- if fpathLower == `.yaml` {
- bytes, err = yaml.Marshal(dataUnit)
- } else if fpathLower == `.json` {
- bytes, err = json.Marshal(dataUnit)
- } else {
+ if fExt != `.yaml` {
panic(fmt.Sprint(`SaveAllFlatFiles`, `basePath`, basePath, `type`, fmt.Sprintf(`%T`, *new(T)), `path`, path, `err`, `unsupported file type`))
}
+ bytes, err = yaml.Marshal(dataUnit)
if err != nil {
panic(fmt.Sprint(`SaveAllFlatFiles`, `basePath`, basePath, `type`, fmt.Sprintf(`%T`, *new(T)), `path`, path, `err`, err))
}
diff --git a/internal/hooks/NewRound_UpdateZoneMutators.go b/internal/hooks/NewRound_UpdateZoneMutators.go
index 5e55f9be..2646c5a3 100644
--- a/internal/hooks/NewRound_UpdateZoneMutators.go
+++ b/internal/hooks/NewRound_UpdateZoneMutators.go
@@ -13,10 +13,10 @@ func UpdateZoneMutators(e events.Event) events.ListenerReturn {
evt := e.(events.NewRound)
// Update all zone based mutators once a round
- _, mutZoneRoomIds := rooms.GetZonesWithMutators()
- for _, rid := range mutZoneRoomIds {
- if r := rooms.LoadRoom(rid); r != nil {
- r.ZoneConfig.Mutators.Update(evt.RoundNumber)
+ zoneNames, _ := rooms.GetZonesWithMutators()
+ for _, zoneName := range zoneNames {
+ if zoneInfo := rooms.GetZoneConfig(zoneName); zoneInfo != nil {
+ zoneInfo.Mutators.Update(evt.RoundNumber)
}
}
diff --git a/internal/rooms/biomes.go b/internal/rooms/biomes.go
index 8d60332c..46eb8286 100644
--- a/internal/rooms/biomes.go
+++ b/internal/rooms/biomes.go
@@ -51,12 +51,24 @@ func (bi BiomeInfo) Burns() bool {
var (
AllBiomes = map[string]BiomeInfo{
+ `land`: { // default biome to fall back on if no biome is supplied.
+ name: `Land`,
+ symbol: '•',
+ litArea: true,
+ description: `The world is made of land.`,
+ },
`city`: {
name: `City`,
symbol: '•',
litArea: true,
description: `Cities are generally well protected, with well built roads. Usually they will have shops, inns, and law enforcement. Fighting and Killing in cities can lead to a lasting bad reputation.`,
},
+ `dungeon`: {
+ name: `Dungeon`,
+ symbol: '•',
+ darkArea: true,
+ description: `These are cave-like underground areas built with a purpose.`,
+ },
`fort`: {
name: `Fort`,
symbol: '•',
@@ -140,6 +152,9 @@ var (
)
func GetBiome(name string) (BiomeInfo, bool) {
+ if name == `` {
+ name = `land`
+ }
b, ok := AllBiomes[strings.ToLower(name)]
return b, ok
}
diff --git a/internal/rooms/ephemeral.go b/internal/rooms/ephemeral.go
index 7b18ebc0..95c0e108 100644
--- a/internal/rooms/ephemeral.go
+++ b/internal/rooms/ephemeral.go
@@ -96,11 +96,6 @@ func CreateEphemeralRoomIds(roomIds ...int) (map[int]int, error) {
continue
}
- // Don't allow an ephemeral copy to identify as a zone root.
- if room.ZoneConfig.RoomId == room.RoomId {
- room.ZoneConfig = ZoneConfig{}
- }
-
room.RoomId = ephemeralRoomIdMinimum + (chunkId * ephemeralChunkSize) + idx
// Save the original room ID in case we need it at some point
diff --git a/internal/rooms/roommanager.go b/internal/rooms/roommanager.go
index 2f6aa937..eb2afd65 100644
--- a/internal/rooms/roommanager.go
+++ b/internal/rooms/roommanager.go
@@ -14,6 +14,7 @@ import (
"github.com/GoMudEngine/GoMud/internal/configs"
"github.com/GoMudEngine/GoMud/internal/events"
"github.com/GoMudEngine/GoMud/internal/exit"
+ "github.com/GoMudEngine/GoMud/internal/fileloader"
"github.com/GoMudEngine/GoMud/internal/mobs"
"github.com/GoMudEngine/GoMud/internal/mudlog"
"github.com/GoMudEngine/GoMud/internal/users"
@@ -23,7 +24,7 @@ import (
var (
roomManager = &RoomManager{
rooms: make(map[int]*Room),
- zones: make(map[string]ZoneInfo),
+ zones: make(map[string]*ZoneConfig),
roomsWithUsers: make(map[int]int),
roomsWithMobs: make(map[int]int),
roomIdToFileCache: make(map[int]string),
@@ -36,10 +37,10 @@ const (
type RoomManager struct {
rooms map[int]*Room
- zones map[string]ZoneInfo // a map of zone name to room id
- roomsWithUsers map[int]int // key is roomId to # players
- roomsWithMobs map[int]int // key is roomId to # mobs
- roomIdToFileCache map[int]string // key is room id, value is the file path
+ zones map[string]*ZoneConfig // a map of zone name to room id
+ roomsWithUsers map[int]int // key is roomId to # players
+ roomsWithMobs map[int]int // key is roomId to # mobs
+ roomIdToFileCache map[int]string // key is room id, value is the file path
}
// Deletes any knowledge of a room in memory.
@@ -52,11 +53,6 @@ func ClearRoomCache(roomId int) error {
}
if zoneData, ok := roomManager.zones[room.Zone]; ok {
-
- if zoneData.RootRoomId == roomId {
- return fmt.Errorf(`room %d is the zone root`, roomId)
- }
-
delete(zoneData.RoomIds, roomId)
roomManager.zones[room.Zone] = zoneData
}
@@ -144,9 +140,9 @@ func GetZonesWithMutators() ([]string, []int) {
rootRoomIds := []int{}
for zName, zInfo := range roomManager.zones {
- if zInfo.HasZoneMutators {
+ if len(zInfo.Mutators) > 0 {
zNames = append(zNames, zName)
- rootRoomIds = append(rootRoomIds, zInfo.RootRoomId)
+ rootRoomIds = append(rootRoomIds, zInfo.RoomId)
}
}
return zNames, rootRoomIds
@@ -512,19 +508,16 @@ func addRoomToMemory(room *Room, forceOverWrite ...bool) error {
//
zoneInfo, ok := roomManager.zones[room.Zone]
if !ok {
- zoneInfo = ZoneInfo{
- RootRoomId: 0,
- RoomIds: make(map[int]struct{}),
+ zoneInfo = &ZoneConfig{
+ Name: room.Zone,
+ RoomId: room.RoomId,
+ RoomIds: make(map[int]struct{}),
}
}
// Populate the room present lookup in the zone info
zoneInfo.RoomIds[room.RoomId] = struct{}{}
- if room.ZoneConfig.RoomId == room.RoomId {
- zoneInfo.RootRoomId = room.RoomId
- }
-
roomManager.zones[room.Zone] = zoneInfo
return nil
@@ -533,22 +526,14 @@ func addRoomToMemory(room *Room, forceOverWrite ...bool) error {
func GetZoneRoot(zone string) (int, error) {
if zoneInfo, ok := roomManager.zones[zone]; ok {
- return zoneInfo.RootRoomId, nil
+ return zoneInfo.RoomId, nil
}
return 0, fmt.Errorf("zone %s does not exist.", zone)
}
func GetZoneConfig(zone string) *ZoneConfig {
-
- zoneInfo, ok := roomManager.zones[zone]
-
- if ok {
- if r := LoadRoom(zoneInfo.RootRoomId); r != nil {
- return &r.ZoneConfig
- }
- }
- return nil
+ return roomManager.zones[zone]
}
func IsRoomLoaded(roomId int) bool {
@@ -559,7 +544,7 @@ func IsRoomLoaded(roomId int) bool {
func ZoneStats(zone string) (rootRoomId int, totalRooms int, err error) {
if zoneInfo, ok := roomManager.zones[zone]; ok {
- return zoneInfo.RootRoomId, len(zoneInfo.RoomIds), nil
+ return zoneInfo.RoomId, len(zoneInfo.RoomIds), nil
}
return 0, 0, fmt.Errorf("zone %s does not exist.", zone)
@@ -638,7 +623,7 @@ func MoveToZone(roomId int, newZoneName string) error {
return errors.New("new zone doesn't exist")
}
- if oldZoneInfo.RootRoomId == roomId {
+ if oldZoneInfo.RoomId == roomId {
return errors.New("can't move the root room of a zone")
}
@@ -674,15 +659,22 @@ func CreateZone(zoneName string) (roomId int, err error) {
}
if zoneInfo, ok := roomManager.zones[zoneName]; ok {
-
- return zoneInfo.RootRoomId, errors.New("zone already exists")
+ return zoneInfo.RoomId, errors.New("zone already exists")
}
+ zoneInfo := NewZoneConfig(zoneName)
+
zoneFolder := util.FilePath(configs.GetFilePathsConfig().DataFiles.String(), "/", "rooms", "/", ZoneToFolder(zoneName))
if err := os.Mkdir(zoneFolder, 0755); err != nil {
return 0, err
}
+ if err := fileloader.SaveFlatFile[*ZoneConfig](zoneFolder, zoneInfo); err != nil {
+ return 0, err
+ }
+
+ roomManager.zones[zoneName] = zoneInfo
+
instanceZoneFolder := util.FilePath(configs.GetFilePathsConfig().DataFiles.String(), "/", "rooms.instances", "/", ZoneToFolder(zoneName))
if err := os.Mkdir(instanceZoneFolder, 0755); err != nil {
return 0, err
@@ -690,8 +682,6 @@ func CreateZone(zoneName string) (roomId int, err error) {
newRoom := NewRoom(zoneName)
- newRoom.ZoneConfig = ZoneConfig{RoomId: newRoom.RoomId}
-
if err := newRoom.Validate(); err != nil {
return 0, err
}
diff --git a/internal/rooms/rooms.go b/internal/rooms/rooms.go
index 31d924e3..1e0a328c 100644
--- a/internal/rooms/rooms.go
+++ b/internal/rooms/rooms.go
@@ -65,7 +65,7 @@ type Room struct {
//mutex
RoomId int `yaml:"roomid"` // a unique numeric index of the room. Also the filename.
Zone string `yaml:"zone"` // zone is a way to partition rooms into groups. Also into folders.
- ZoneConfig ZoneConfig `yaml:"zoneconfig,omitempty" instance:"skip"` // If non-null is a root room.
+ ZoneConfig *ZoneConfig `yaml:"zoneconfig,omitempty" instance:"skip"` // If non-null is a root room.
MusicFile string `yaml:"musicfile,omitempty"` // background music to play when in this room
IsBank bool `yaml:"isbank,omitempty"` // Is this a bank room? If so, players can deposit/withdraw gold here.
IsStorage bool `yaml:"isstorage,omitempty"` // Is this a storage room? If so, players can add/remove objects here.
@@ -2209,14 +2209,6 @@ func (r *Room) Validate() error {
r.Containers[cName] = c
}
- if r.ZoneConfig.RoomId != r.RoomId {
- r.ZoneConfig = ZoneConfig{}
- } else {
-
- r.ZoneConfig.Validate()
-
- }
-
return nil
}
diff --git a/internal/rooms/save_and_load.go b/internal/rooms/save_and_load.go
index b76676e5..180c3b3d 100644
--- a/internal/rooms/save_and_load.go
+++ b/internal/rooms/save_and_load.go
@@ -353,6 +353,19 @@ func SaveAllRooms() error {
return nil
}
+// Overwrite file and memory for zoneconfig
+func SaveZoneConfig(zoneConfig *ZoneConfig) error {
+
+ zoneFolder := util.FilePath(configs.GetFilePathsConfig().DataFiles.String(), "/", "rooms")
+ if err := fileloader.SaveFlatFile(zoneFolder, zoneConfig); err != nil {
+ return err
+ }
+
+ roomManager.zones[zoneConfig.Name] = zoneConfig
+
+ return nil
+}
+
// Goes through all of the rooms and caches key information
func loadAllRoomZones() error {
start := time.Now()
@@ -364,7 +377,21 @@ func loadAllRoomZones() error {
}
}()
- loadedRooms, err := fileloader.LoadAllFlatFiles[int, *Room](configs.GetFilePathsConfig().DataFiles.String() + `/rooms`)
+ loadedZones, err := fileloader.LoadAllFlatFiles[string, *ZoneConfig](configs.GetFilePathsConfig().DataFiles.String()+`/rooms`, "zone-config.yaml")
+ if err != nil {
+ return err
+ }
+
+ for zoneName, zoneConfig := range loadedZones {
+ roomManager.zones[zoneName] = zoneConfig
+
+ folderPath := util.FilePath(configs.GetFilePathsConfig().DataFiles.String(), `/rooms.instances/`, ZoneNameSanitize(zoneConfig.Name))
+ if _, err := os.Stat(folderPath); os.IsNotExist(err) {
+ os.MkdirAll(folderPath, 0755)
+ }
+ }
+
+ loadedRooms, err := fileloader.LoadAllFlatFiles[int, *Room](configs.GetFilePathsConfig().DataFiles.String()+`/rooms`, "[0-9]*.yaml")
if err != nil {
return err
}
@@ -373,6 +400,28 @@ func loadAllRoomZones() error {
for _, loadedRoom := range loadedRooms {
+ //
+ // This code migrates old format data to the new format (separate zone file)
+ //
+ if loadedRoom.ZoneConfig != nil {
+ if loadedRoom.ZoneConfig.RoomId == loadedRoom.RoomId {
+ if _, ok := roomManager.zones[loadedRoom.Zone]; !ok {
+ newZone := NewZoneConfig(loadedRoom.Zone)
+ newZone.DefaultBiome = loadedRoom.Biome
+ newZone.IdleMessages = loadedRoom.ZoneConfig.IdleMessages
+ newZone.MusicFile = loadedRoom.ZoneConfig.MusicFile
+ newZone.MobAutoScale = loadedRoom.ZoneConfig.MobAutoScale
+ newZone.Mutators = loadedRoom.ZoneConfig.Mutators
+ newZone.RoomId = loadedRoom.ZoneConfig.RoomId
+ if err := SaveZoneConfig(newZone); err != nil {
+ return err
+ }
+ loadedRoom.ZoneConfig = nil // if successfully saved, blank out the ZoneConfig for the room
+ SaveRoomTemplate(*loadedRoom)
+ }
+ }
+ }
+
// configs.GetConfig().DeathRecoveryRoom is the death/shadow realm and gets a pass
if loadedRoom.RoomId == int(configs.GetSpecialRoomsConfig().DeathRecoveryRoom) {
continue
@@ -411,34 +460,12 @@ func loadAllRoomZones() error {
// Update the zone info cache
if _, ok := roomManager.zones[loadedRoom.Zone]; !ok {
- roomManager.zones[loadedRoom.Zone] = ZoneInfo{
- RootRoomId: 0,
- RoomIds: make(map[int]struct{}),
- }
-
- folderPath := util.FilePath(configs.GetFilePathsConfig().DataFiles.String(), `/rooms.instances/`, ZoneNameSanitize(loadedRoom.Zone))
- if _, err := os.Stat(folderPath); os.IsNotExist(err) {
- os.MkdirAll(folderPath, 0755)
- }
+ // Form one?
+ return fmt.Errorf("No zone-config.yaml was loaded for roomId: %d zone: %s", loadedRoom.RoomId, loadedRoom.Zone)
}
-
- // Update the zone info
- zoneInfo := roomManager.zones[loadedRoom.Zone]
- zoneInfo.RoomIds[loadedRoom.RoomId] = struct{}{}
-
- if loadedRoom.ZoneConfig.RoomId == loadedRoom.RoomId {
- zoneInfo.RootRoomId = loadedRoom.RoomId
- zoneInfo.DefaultBiome = loadedRoom.Biome
-
- if len(loadedRoom.ZoneConfig.Mutators) > 0 {
- zoneInfo.HasZoneMutators = true
- }
- }
-
- roomManager.zones[loadedRoom.Zone] = zoneInfo
}
- mudlog.Info("rooms.loadAllRoomZones()", "loadedCount", len(loadedRooms), "Time Taken", time.Since(start))
+ mudlog.Info("rooms.loadAllRoomZones()", "zoneCount", len(loadedZones), "loadedCount", len(loadedRooms), "Time Taken", time.Since(start))
return nil
}
diff --git a/internal/rooms/zoneconfig.go b/internal/rooms/zoneconfig.go
index 54f540c4..7ee16d03 100644
--- a/internal/rooms/zoneconfig.go
+++ b/internal/rooms/zoneconfig.go
@@ -6,7 +6,8 @@ import (
)
type ZoneConfig struct {
- RoomId int `yaml:"roomid,omitempty"`
+ Name string `yaml:"name,omitempty"`
+ RoomId int `yaml:"roomid,omitempty"`
MobAutoScale struct {
Minimum int `yaml:"minimum,omitempty"` // level scaling minimum
Maximum int `yaml:"maximum,omitempty"` // level scaling maximum
@@ -14,9 +15,20 @@ type ZoneConfig struct {
Mutators mutators.MutatorList `yaml:"mutators,omitempty"` // mutators defined here apply to entire zone
IdleMessages []string `yaml:"idlemessages,omitempty"` // list of messages that can be displayed to players in the zone, assuming a room has none defined
MusicFile string `yaml:"musicfile,omitempty"` // background music to play when in this zone
+ DefaultBiome string `yaml:"defaultbiome,omitempty"` // city, swamp etc. see biomes.go
+ RoomIds map[int]struct{} `yaml:"-"` // Does not get written. Built dyanmically when rooms are loaded.
}
-func (z *ZoneConfig) Validate() {
+// Generates a random number between min and max
+func (z *ZoneConfig) GenerateRandomLevel() int {
+ return util.Rand(z.MobAutoScale.Maximum-z.MobAutoScale.Minimum) + z.MobAutoScale.Minimum
+}
+
+func (z *ZoneConfig) Id() string {
+ return z.Name
+}
+
+func (z *ZoneConfig) Validate() error {
if z.MobAutoScale.Minimum < 0 {
z.MobAutoScale.Minimum = 0
}
@@ -37,9 +49,25 @@ func (z *ZoneConfig) Validate() {
}
}
+ if z.RoomIds == nil {
+ z.RoomIds = make(map[int]struct{})
+ }
+
+ return nil
}
-// Generates a random number between min and max
-func (z *ZoneConfig) GenerateRandomLevel() int {
- return util.Rand(z.MobAutoScale.Maximum-z.MobAutoScale.Minimum) + z.MobAutoScale.Minimum
+func (z *ZoneConfig) Filename() string {
+ return "zone-config.yaml"
+}
+
+func (z *ZoneConfig) Filepath() string {
+ zone := ZoneNameSanitize(z.Name)
+ return util.FilePath(zone, `/`, z.Filename())
+}
+
+func NewZoneConfig(zName string) *ZoneConfig {
+ return &ZoneConfig{
+ Name: zName,
+ RoomIds: map[int]struct{}{},
+ }
}
diff --git a/internal/usercommands/admin.zone.go b/internal/usercommands/admin.zone.go
index b37f3c92..c5639b24 100644
--- a/internal/usercommands/admin.zone.go
+++ b/internal/usercommands/admin.zone.go
@@ -53,8 +53,8 @@ func Zone(rest string, user *users.UserRecord, room *rooms.Room, flags events.Ev
if zoneCmd == `info` {
user.SendText(``)
- user.SendText(fmt.Sprintf(`Zone Config for %s`, room.Zone))
- user.SendText(fmt.Sprintf(` Root Room Id: %d`, zoneConfig.RoomId))
+ user.SendText(fmt.Sprintf(`Zone Config for: %s`, room.Zone))
+ user.SendText(fmt.Sprintf(` Root Room Id: %d`, zoneConfig.RoomId))
if zoneConfig.MobAutoScale.Maximum == 0 {
user.SendText(` Mob AutoScale: [disabled]`)
@@ -281,17 +281,7 @@ func zone_Edit(rest string, user *users.UserRecord, room *rooms.Room, flags even
editZoneConfig.Mutators = append(editZoneConfig.Mutators, mutators.Mutator{MutatorId: mutId})
}
- // Make sure the edited zone config's roomId gets the changes.
- if r := rooms.LoadRoom(editZoneConfig.RoomId); r != nil {
- r.ZoneConfig = editZoneConfig
- }
-
- // If the root zone room has been changed, clear the original rooms zone config.
- if originalZoneConfig.RoomId != editZoneConfig.RoomId {
- if r := rooms.LoadRoom(originalZoneConfig.RoomId); r != nil {
- room.ZoneConfig = rooms.ZoneConfig{}
- }
- }
+ rooms.SaveZoneConfig(&editZoneConfig)
user.SendText(``)
user.SendText(`Changes saved.`)
diff --git a/internal/web/admin.rooms.go b/internal/web/admin.rooms.go
index a324abcb..cd62ce7e 100644
--- a/internal/web/admin.rooms.go
+++ b/internal/web/admin.rooms.go
@@ -58,11 +58,9 @@ func roomsIndex(w http.ResponseWriter, r *http.Request) {
autoScale := ``
- if rootRoomId, err := rooms.GetZoneRoot(room.Zone); err == nil {
- if rootRoom := rooms.LoadRoom(rootRoomId); rootRoom != nil {
- if rootRoom.ZoneConfig.MobAutoScale.Minimum > 0 || rootRoom.ZoneConfig.MobAutoScale.Maximum > 0 {
- autoScale = fmt.Sprintf(`%d to %d`, rootRoom.ZoneConfig.MobAutoScale.Minimum, rootRoom.ZoneConfig.MobAutoScale.Maximum)
- }
+ if zoneConfig := rooms.GetZoneConfig(room.Zone); zoneConfig != nil {
+ if zoneConfig.MobAutoScale.Minimum > 0 || zoneConfig.MobAutoScale.Maximum > 0 {
+ autoScale = fmt.Sprintf(`%d to %d`, zoneConfig.MobAutoScale.Minimum, zoneConfig.MobAutoScale.Maximum)
}
}
@@ -88,10 +86,15 @@ func roomsIndex(w http.ResponseWriter, r *http.Request) {
}
}
+ rootRoomId := 0
+ if zCfg := rooms.GetZoneConfig(room.Zone); zCfg != nil {
+ rootRoomId = zCfg.RoomId
+ }
+
allRooms = append(allRooms, shortRoomInfo{
RoomId: room.RoomId,
RoomZone: room.Zone,
- ZoneRoot: room.ZoneConfig.RoomId == room.RoomId,
+ ZoneRoot: rootRoomId == room.RoomId,
RoomTitle: room.Title,
IsBank: room.IsBank,
IsStorage: room.IsStorage,
diff --git a/main.go b/main.go
index 162ed16d..538f3612 100644
--- a/main.go
+++ b/main.go
@@ -56,11 +56,6 @@ import (
textLang "golang.org/x/text/language"
)
-const (
- // Version is the current version of the server
- Version = `1.0.0`
-)
-
var (
sigChan = make(chan os.Signal, 1)
workerShutdownChan = make(chan bool, 1)
diff --git a/modules/webhelp/webhelp.go b/modules/webhelp/webhelp.go
index 10372d41..5cbd138b 100644
--- a/modules/webhelp/webhelp.go
+++ b/modules/webhelp/webhelp.go
@@ -111,7 +111,7 @@ func (w *WebHelpModule) getHelpCommand(r *http.Request) map[string]any {
data[`error`] = ``
data[`topic`] = searchTerm
- if searchTerm == `` {
+ if searchTerm == `` || searchTerm == `help` { // skip empty searches and circular help searches
data[`error`] = `"` + searchTerm + `" Not Found`
} else {
contents, err := usercommands.GetHelpContents(searchTerm)