diff --git a/_datafiles/world/default/audio.yaml b/_datafiles/world/default/audio.yaml
new file mode 100644
index 00000000..d1dc7a20
--- /dev/null
+++ b/_datafiles/world/default/audio.yaml
@@ -0,0 +1,29 @@
+# Sound that plays when a "change" confirmation/activation occurs
+change:
+ filepath: sound/other/change.mp3
+ volume: 80
+# When a target is hit in combat
+hit-other:
+ filepath: sound/combat/hit-other.mp3
+# When receiving a hit in combat
+hit-self:
+ filepath: sound/combat/hit-self.mp3
+# Plays at login screen
+intro:
+ filepath: music/intro.mp3
+ volume: 20
+# When Leveling up
+levelup:
+ filepath: sound/other/levelup.mp3
+# When missing a hit in combat
+miss:
+ filepath: sound/combat/miss1.mp3
+# When a purchase is made
+purchase:
+ filepath: sound/other/buy.mp3
+# When someone leaves the room
+room-exit:
+ filepath: sound/movement/room-exit.mp3
+# When someone enters the room
+room-enter:
+ filepath: sound/movement/room-enter.mp3
\ No newline at end of file
diff --git a/_datafiles/world/empty/audio.yaml b/_datafiles/world/empty/audio.yaml
new file mode 100644
index 00000000..d1dc7a20
--- /dev/null
+++ b/_datafiles/world/empty/audio.yaml
@@ -0,0 +1,29 @@
+# Sound that plays when a "change" confirmation/activation occurs
+change:
+ filepath: sound/other/change.mp3
+ volume: 80
+# When a target is hit in combat
+hit-other:
+ filepath: sound/combat/hit-other.mp3
+# When receiving a hit in combat
+hit-self:
+ filepath: sound/combat/hit-self.mp3
+# Plays at login screen
+intro:
+ filepath: music/intro.mp3
+ volume: 20
+# When Leveling up
+levelup:
+ filepath: sound/other/levelup.mp3
+# When missing a hit in combat
+miss:
+ filepath: sound/combat/miss1.mp3
+# When a purchase is made
+purchase:
+ filepath: sound/other/buy.mp3
+# When someone leaves the room
+room-exit:
+ filepath: sound/movement/room-exit.mp3
+# When someone enters the room
+room-enter:
+ filepath: sound/movement/room-enter.mp3
\ No newline at end of file
diff --git a/internal/audio/audio.go b/internal/audio/audio.go
new file mode 100644
index 00000000..1c900047
--- /dev/null
+++ b/internal/audio/audio.go
@@ -0,0 +1,48 @@
+package audio
+
+import (
+ "log/slog"
+ "os"
+ "time"
+
+ "github.com/pkg/errors"
+ "github.com/volte6/gomud/internal/configs"
+ "gopkg.in/yaml.v2"
+)
+
+type AudioConfig struct {
+ FilePath string `yaml:"filepath,omitempty"`
+ Volume int `yaml:"volume,omitempty"`
+}
+
+var (
+ audioLookup = map[string]AudioConfig{}
+)
+
+func GetFile(identifier string) AudioConfig {
+ if f, ok := audioLookup[identifier]; ok {
+ return f
+ }
+ return AudioConfig{}
+}
+
+func LoadAudioConfig() {
+
+ start := time.Now()
+
+ path := string(configs.GetConfig().FolderDataFiles) + `/audio.yaml`
+
+ bytes, err := os.ReadFile(path)
+ if err != nil {
+ panic(errors.Wrap(err, `filepath: `+path))
+ }
+
+ clear(audioLookup)
+
+ err = yaml.Unmarshal(bytes, &audioLookup)
+ if err != nil {
+ panic(errors.Wrap(err, `filepath: `+path))
+ }
+
+ slog.Info("...LoadAudioConfig()", "loadedCount", len(audioLookup), "Time Taken", time.Since(start))
+}
diff --git a/internal/combat/combat.go b/internal/combat/combat.go
index e2d992b2..7819c0c0 100644
--- a/internal/combat/combat.go
+++ b/internal/combat/combat.go
@@ -43,9 +43,9 @@ func AttackPlayerVsMob(user *users.UserRecord, mob *mobs.Mob) AttackResult {
mob.Character.TrackPlayerDamage(user.UserId, attackResult.DamageToTarget)
if attackResult.Hit {
- user.PlaySound(`sound/combat/hit-other.mp3`, `combat`)
+ user.PlaySound(`hit-other`, `combat`)
} else {
- user.PlaySound(`sound/combat/miss1.mp3`, `combat`)
+ user.PlaySound(`miss`, `combat`)
}
return attackResult
@@ -67,10 +67,10 @@ func AttackPlayerVsPlayer(userAtk *users.UserRecord, userDef *users.UserRecord)
}
if attackResult.Hit {
- userAtk.PlaySound(`sound/combat/hit-other.mp3`, `combat`)
- userDef.PlaySound(`sound/combat/hit-self.mp3`, `combat`)
+ userAtk.PlaySound(`hit-other`, `combat`)
+ userDef.PlaySound(`hit-self`, `combat`)
} else {
- userAtk.PlaySound(`sound/combat/miss1.mp3`, `combat`)
+ userAtk.PlaySound(`miss`, `combat`)
}
return attackResult
@@ -89,7 +89,7 @@ func AttackMobVsPlayer(mob *mobs.Mob, user *users.UserRecord) AttackResult {
}
if attackResult.Hit {
- user.PlaySound(`sound/combat/hit-self.mp3`, `combat`)
+ user.PlaySound(`hit-self`, `combat`)
}
return attackResult
diff --git a/internal/mobcommands/go.go b/internal/mobcommands/go.go
index 2e7239f8..218c8c89 100644
--- a/internal/mobcommands/go.go
+++ b/internal/mobcommands/go.go
@@ -138,8 +138,8 @@ func Go(rest string, mob *mobs.Mob, room *rooms.Room) (bool, error) {
destRoom.SendTextToExits(`You hear someone moving around.`, true, room.GetPlayers(rooms.FindAll)...)
- room.PlaySound(`sound/movement/room-exit.mp3`, `movement`, 100)
- destRoom.PlaySound(`sound/movement/room-enter.mp3`, `movement`, 100)
+ room.PlaySound(`room-exit`, `movement`)
+ destRoom.PlaySound(`room-enter`, `movement`)
return true, nil
}
diff --git a/internal/rooms/rooms.go b/internal/rooms/rooms.go
index a273bec4..04caceaf 100644
--- a/internal/rooms/rooms.go
+++ b/internal/rooms/rooms.go
@@ -8,6 +8,7 @@ import (
"strings"
"time"
+ "github.com/volte6/gomud/internal/audio"
"github.com/volte6/gomud/internal/buffs"
"github.com/volte6/gomud/internal/configs"
"github.com/volte6/gomud/internal/events"
@@ -248,12 +249,14 @@ func (r *Room) SendText(txt string, excludeUserIds ...int) {
}
-func (r *Room) PlaySound(soundFile string, category string, volume int, excludeUserIds ...int) {
+func (r *Room) PlaySound(soundId string, category string, excludeUserIds ...int) {
- if volume < 1 {
- volume = 1
- } else if volume > 100 {
- volume = 100
+ volume := 100
+ if soundConfig := audio.GetFile(soundId); soundConfig.FilePath != `` {
+ soundId = soundConfig.FilePath
+ if soundConfig.Volume > 0 && soundConfig.Volume <= 100 {
+ volume = soundConfig.Volume
+ }
}
for _, userId := range r.players {
@@ -277,7 +280,7 @@ func (r *Room) PlaySound(soundFile string, category string, volume int, excludeU
events.AddToQueue(events.MSP{
UserId: userId,
SoundType: `SOUND`,
- SoundFile: soundFile,
+ SoundFile: soundId,
Volume: volume,
Category: category,
})
diff --git a/internal/usercommands/buy.go b/internal/usercommands/buy.go
index bac46efa..b3db7456 100644
--- a/internal/usercommands/buy.go
+++ b/internal/usercommands/buy.go
@@ -332,7 +332,7 @@ func tryPurchase(request string, user *users.UserRecord, room *rooms.Room, shopM
// Give them the item
newItm := items.New(matchedShopItem.ItemId)
user.Character.StoreItem(newItm)
- user.PlaySound(`sound/other/buy.mp3`, `other`)
+ user.PlaySound(`purchase`, `other`)
iSpec := newItm.GetSpec()
if iSpec.QuestToken != `` {
diff --git a/internal/usercommands/go.go b/internal/usercommands/go.go
index a01fdc4d..4cb7cf82 100644
--- a/internal/usercommands/go.go
+++ b/internal/usercommands/go.go
@@ -321,8 +321,8 @@ func Go(rest string, user *users.UserRecord, room *rooms.Room) (bool, error) {
scripting.TryRoomScriptEvent(`onEnter`, user.UserId, destRoom.RoomId)
- room.PlaySound(`sound/movement/room-exit.mp3`, `movement`, user.UserId)
- destRoom.PlaySound(`sound/movement/room-enter.mp3`, `movement`, user.UserId)
+ room.PlaySound(`room-exit`, `movement`, user.UserId)
+ destRoom.PlaySound(`room-enter`, `movement`, user.UserId)
}
}
diff --git a/internal/usercommands/use.go b/internal/usercommands/use.go
index 1c664853..bed6ace4 100644
--- a/internal/usercommands/use.go
+++ b/internal/usercommands/use.go
@@ -47,7 +47,7 @@ func Use(rest string, user *users.UserRecord, room *rooms.Room) (bool, error) {
container.AddItem(newItem)
room.Containers[containerName] = container
- room.PlaySound(`sound/other/change.mp3`, `other`, 100)
+ room.PlaySound(`change`, `other`)
user.SendText(``)
user.SendText(fmt.Sprintf(`The %s produces a %s!`, containerName, newItem.DisplayName()))
diff --git a/internal/users/userrecord.go b/internal/users/userrecord.go
index b9eadd4f..c5edae8c 100644
--- a/internal/users/userrecord.go
+++ b/internal/users/userrecord.go
@@ -9,6 +9,7 @@ import (
"strings"
"time"
+ "github.com/volte6/gomud/internal/audio"
"github.com/volte6/gomud/internal/buffs"
"github.com/volte6/gomud/internal/characters"
"github.com/volte6/gomud/internal/configs"
@@ -145,33 +146,39 @@ func (u *UserRecord) GrantXP(amt int, source string) {
}
-func (u *UserRecord) PlayMusic(musicFile string) {
+func (u *UserRecord) PlayMusic(musicFileOrId string) {
+
+ v := 100
+ if soundConfig := audio.GetFile(musicFileOrId); soundConfig.FilePath != `` {
+ musicFileOrId = soundConfig.FilePath
+ if soundConfig.Volume > 0 && soundConfig.Volume <= 100 {
+ v = soundConfig.Volume
+ }
+ }
events.AddToQueue(events.MSP{
UserId: u.UserId,
SoundType: `MUSIC`,
- SoundFile: musicFile,
- Volume: 100,
+ SoundFile: musicFileOrId,
+ Volume: v,
})
}
-func (u *UserRecord) PlaySound(soundFile string, category string, volume ...int) {
+func (u *UserRecord) PlaySound(soundId string, category string) {
v := 100
- if len(volume) > 0 {
- v = volume[0]
- if v < 1 {
- v = 1
- } else if v > 100 {
- v = 100
+ if soundConfig := audio.GetFile(soundId); soundConfig.FilePath != `` {
+ soundId = soundConfig.FilePath
+ if soundConfig.Volume > 0 && soundConfig.Volume <= 100 {
+ v = soundConfig.Volume
}
}
events.AddToQueue(events.MSP{
UserId: u.UserId,
SoundType: `SOUND`,
- SoundFile: soundFile,
+ SoundFile: soundId,
Volume: v,
Category: category,
})
diff --git a/main.go b/main.go
index e7d48c7a..92313d35 100644
--- a/main.go
+++ b/main.go
@@ -19,6 +19,7 @@ import (
"github.com/gorilla/websocket"
"github.com/natefinch/lumberjack"
+ "github.com/volte6/gomud/internal/audio"
"github.com/volte6/gomud/internal/buffs"
"github.com/volte6/gomud/internal/characters"
"github.com/volte6/gomud/internal/colorpatterns"
@@ -327,10 +328,16 @@ func handleTelnetConnection(connDetails *connections.ConnectionDetails, wg *sync
// The default behavior is to just send a welcome screen first
inputhandlers.LoginInputHandler(clientInput, sharedState)
- connections.SendTo(
- term.MspCommand.BytesWithPayload([]byte("!!MUSIC(music/intro.mp3 V=20 L=-1 C=1)")),
- clientInput.ConnectionId,
- )
+ if audioConfig := audio.GetFile(`intro`); audioConfig.FilePath != `` {
+ v := 100
+ if audioConfig.Volume > 0 && audioConfig.Volume <= 100 {
+ v = audioConfig.Volume
+ }
+ connections.SendTo(
+ term.MspCommand.BytesWithPayload([]byte("!!MUSIC("+audioConfig.FilePath+" V="+strconv.Itoa(v)+" L=-1 C=1)")),
+ clientInput.ConnectionId,
+ )
+ }
var userObject *users.UserRecord
var sug suggestions.Suggestions
@@ -578,10 +585,16 @@ func HandleWebSocketConnection(conn *websocket.Conn) {
clientInput.ConnectionId,
)
- connections.SendTo(
- []byte("!!MUSIC(music/intro.mp3 V=20 L=-1 C=1)"),
- clientInput.ConnectionId,
- )
+ if audioConfig := audio.GetFile(`intro`); audioConfig.FilePath != `` {
+ v := 100
+ if audioConfig.Volume > 0 && audioConfig.Volume <= 100 {
+ v = audioConfig.Volume
+ }
+ connections.SendTo(
+ []byte("!!MUSIC("+audioConfig.FilePath+" V="+strconv.Itoa(v)+" L=-1 C=1)"),
+ clientInput.ConnectionId,
+ )
+ }
for {
_, message, err := conn.ReadMessage()
@@ -802,5 +815,6 @@ func loadAllDataFiles(isReload bool) {
keywords.LoadAliases()
mutators.LoadDataFiles()
colorpatterns.LoadColorPatterns()
+ audio.LoadAudioConfig()
characters.CompileAdjectiveSwaps() // This should come after loading color patterns.
}
diff --git a/world.go b/world.go
index 068b4c26..30e61a64 100644
--- a/world.go
+++ b/world.go
@@ -981,6 +981,10 @@ func (w *World) MessageTick() {
continue
}
+ if msp.SoundFile == `` {
+ continue
+ }
+
if user := users.GetByUserId(msp.UserId); user != nil {
if msp.SoundType == `MUSIC` {
diff --git a/world.roundtick.go b/world.roundtick.go
index 238159b6..1a7c99b0 100644
--- a/world.roundtick.go
+++ b/world.roundtick.go
@@ -1770,7 +1770,7 @@ func (w *World) CheckForLevelUps() {
}
}
- user.PlaySound(`sound/other/levelup.mp3`, `other`)
+ user.PlaySound(`levelup`, `other`)
users.SaveUser(*user)