diff --git a/_datafiles/html/static/public/audio/sound/combat/explosion1.mp3 b/_datafiles/html/static/public/audio/sound/combat/explosion1.mp3 new file mode 100644 index 00000000..f916eded Binary files /dev/null and b/_datafiles/html/static/public/audio/sound/combat/explosion1.mp3 differ diff --git a/_datafiles/html/static/public/audio/sound/combat/explosion2.mp3 b/_datafiles/html/static/public/audio/sound/combat/explosion2.mp3 index f916eded..d28a9bf4 100644 Binary files a/_datafiles/html/static/public/audio/sound/combat/explosion2.mp3 and b/_datafiles/html/static/public/audio/sound/combat/explosion2.mp3 differ diff --git a/_datafiles/html/static/public/audio/sound/combat/explosion3.mp3 b/_datafiles/html/static/public/audio/sound/combat/explosion3.mp3 deleted file mode 100644 index d28a9bf4..00000000 Binary files a/_datafiles/html/static/public/audio/sound/combat/explosion3.mp3 and /dev/null differ diff --git a/_datafiles/html/static/public/audio/sound/combat/explosion.mp3 b/_datafiles/html/static/public/audio/sound/other/change.mp3 similarity index 100% rename from _datafiles/html/static/public/audio/sound/combat/explosion.mp3 rename to _datafiles/html/static/public/audio/sound/other/change.mp3 diff --git a/_datafiles/world/default/items/armor-20000/neck/20045-rat_skin_cape.yaml b/_datafiles/world/default/items/armor-20000/neck/20045-rat_skin_cape.yaml new file mode 100755 index 00000000..e47c01c4 --- /dev/null +++ b/_datafiles/world/default/items/armor-20000/neck/20045-rat_skin_cape.yaml @@ -0,0 +1,10 @@ +itemid: 20045 +value: 100 +name: rat-skin cape +namesimple: cape +description: A patchwork cape made up of many rat hides. +type: neck +subtype: wearable +damagereduction: 5 +wornbuffids: + - 3 # Cold Tolerant \ No newline at end of file diff --git a/_datafiles/world/default/keywords.yaml b/_datafiles/world/default/keywords.yaml index 79270420..3f808ef8 100644 --- a/_datafiles/world/default/keywords.yaml +++ b/_datafiles/world/default/keywords.yaml @@ -129,6 +129,7 @@ help: - build - command - deafen + - item - grant - locate - modify diff --git a/_datafiles/world/default/rooms/frostfang/611.yaml b/_datafiles/world/default/rooms/frostfang/611.yaml index 884a01e8..6f94e63c 100755 --- a/_datafiles/world/default/rooms/frostfang/611.yaml +++ b/_datafiles/world/default/rooms/frostfang/611.yaml @@ -10,6 +10,9 @@ description: As you step into this residence, a sense of artistic flair is immed the owner's artistic inclinations. This home feels like a personal retreat, a place for creativity and relaxation amidst the harshness of Frostfang. biome: house +containers: + tattertail loom: + recipes: {20045: [20001, 20001, 20001, 20001, 20001, 20001, 20001, 20001, 20001]} exits: north: roomid: 260 diff --git a/_datafiles/world/default/templates/descriptions/insidecontainer.template b/_datafiles/world/default/templates/descriptions/insidecontainer.template index 530365d0..f87804e8 100644 --- a/_datafiles/world/default/templates/descriptions/insidecontainer.template +++ b/_datafiles/world/default/templates/descriptions/insidecontainer.template @@ -1,6 +1,8 @@ {{- $displayed := 0 -}} {{- $itemCt := len . -}} -Inside you see: + ┌─────────────────────────────────────────────────────────────────────────┐ + + Inside you see: {{- if ne $itemCt 0 -}} {{- range $index, $itemName := . -}} {{- $displayed = add $displayed 1 -}} @@ -9,3 +11,4 @@ {{ else -}} Nothing {{ end }} + └─────────────────────────────────────────────────────────────────────────┘ \ No newline at end of file diff --git a/_datafiles/world/empty/keywords.yaml b/_datafiles/world/empty/keywords.yaml index 79270420..3f808ef8 100644 --- a/_datafiles/world/empty/keywords.yaml +++ b/_datafiles/world/empty/keywords.yaml @@ -129,6 +129,7 @@ help: - build - command - deafen + - item - grant - locate - modify diff --git a/_datafiles/world/empty/templates/descriptions/insidecontainer.template b/_datafiles/world/empty/templates/descriptions/insidecontainer.template index 530365d0..7d201aeb 100644 --- a/_datafiles/world/empty/templates/descriptions/insidecontainer.template +++ b/_datafiles/world/empty/templates/descriptions/insidecontainer.template @@ -1,5 +1,7 @@ {{- $displayed := 0 -}} {{- $itemCt := len . -}} + ┌─────────────────────────────────────────────────────────────────────────┐ + Inside you see: {{- if ne $itemCt 0 -}} {{- range $index, $itemName := . -}} @@ -9,3 +11,4 @@ {{ else -}} Nothing {{ end }} + └─────────────────────────────────────────────────────────────────────────┘ \ No newline at end of file diff --git a/internal/rooms/container.go b/internal/rooms/container.go index be984744..3f336fb5 100644 --- a/internal/rooms/container.go +++ b/internal/rooms/container.go @@ -10,6 +10,7 @@ type Container struct { Items []items.Item `yaml:"items,omitempty"` // Save contents now, since players can put new items in there Gold int `yaml:"gold,omitempty"` // Save contents now, since players can put new items in there DespawnRound uint64 `yaml:"despawnround,omitempty"` // If this is set, it's a chest that will disappear with time. + Recipes map[int][]int `yaml:"recipes,omitempty,flow"` // Item Id's (key) that are created when the recipe is present in the container (values) and it is "used" } func (c Container) HasLock() bool { @@ -44,3 +45,60 @@ func (c *Container) FindItem(itemName string) (items.Item, bool) { return items.Item{}, false } + +func (c *Container) FindItemById(itemId int) (items.Item, bool) { + + // Search floor + for _, matchItem := range c.Items { + if matchItem.ItemId == itemId { + return matchItem, true + } + } + + return items.Item{}, false +} + +// Returns an itemId if it can produce one based on contents + recipe +func (c *Container) RecipeReady() int { + + if len(c.Recipes) == 0 { + return 0 + } + + for finalItemId, recipeList := range c.Recipes { + + totalNeeded := 0 + neededItems := map[int]int{} + + for _, inputItemId := range recipeList { + neededItems[inputItemId] += 1 + totalNeeded++ + } + + for _, containsItem := range c.Items { + if neededItems[containsItem.ItemId] > 0 { + neededItems[containsItem.ItemId] -= 1 + totalNeeded-- + } + if totalNeeded == 0 { + break + } + } + + if totalNeeded < 1 { + return finalItemId + } + } + + return 0 +} + +func (c *Container) Count(itemId int) int { + total := 0 + for _, containsItem := range c.Items { + if containsItem.ItemId == itemId { + total++ + } + } + return total +} diff --git a/internal/usercommands/get.go b/internal/usercommands/get.go index a509cf61..c9b30523 100644 --- a/internal/usercommands/get.go +++ b/internal/usercommands/get.go @@ -190,6 +190,8 @@ func Get(rest string, user *users.UserRecord, room *rooms.Room) (bool, error) { scripting.TryItemScriptEvent(`onFound`, matchItem, user.UserId) + return true, nil + } else { user.SendText( fmt.Sprintf(`You can't carry the %s.`, matchItem.DisplayName()), @@ -314,7 +316,12 @@ func Get(rest string, user *users.UserRecord, room *rooms.Room) (bool, error) { return true, nil } - user.SendText(fmt.Sprintf("You don't see a %s around.", rest)) + containerName = room.FindContainerByName(rest) + if containerName != `` { + user.SendText(fmt.Sprintf(`You can't pick up the %s. Try looking at it.`, containerName)) + } else { + user.SendText(fmt.Sprintf("You don't see a %s around.", rest)) + } return true, nil } diff --git a/internal/usercommands/look.go b/internal/usercommands/look.go index a382d0e2..04588aeb 100644 --- a/internal/usercommands/look.go +++ b/internal/usercommands/look.go @@ -6,6 +6,7 @@ import ( "github.com/volte6/gomud/internal/buffs" "github.com/volte6/gomud/internal/gametime" + "github.com/volte6/gomud/internal/items" "github.com/volte6/gomud/internal/keywords" "github.com/volte6/gomud/internal/mobs" "github.com/volte6/gomud/internal/rooms" @@ -165,10 +166,43 @@ func Look(rest string, user *users.UserRecord, room *rooms.Room) (bool, error) { chestStuff = append(chestStuff, item.DisplayName()) } + if len(container.Recipes) > 0 { + + user.SendText(``) + user.SendText(fmt.Sprintf(`You can use the %s if you put the following objects inside:`, containerName)) + + for finalItemId, recipeList := range container.Recipes { + + neededItems := map[int]int{} + + for _, inputItemId := range recipeList { + neededItems[inputItemId] += 1 + } + + user.SendText(``) + + finalItem := items.New(finalItemId) + user.SendText(fmt.Sprintf(` To receive 1 %s: `, finalItem.DisplayName())) + + for inputItemId, qtyNeeded := range neededItems { + tmpItem := items.New(inputItemId) + totalContained := container.Count(inputItemId) + colorClass := "9" + if totalContained == qtyNeeded { + colorClass = "14" + } + user.SendText(fmt.Sprintf(` [%d/%d] %s`, colorClass, totalContained, qtyNeeded, tmpItem.DisplayName())) + } + + } + + } + textOut, _ := templates.Process("descriptions/insidecontainer", chestStuff) user.SendText(``) user.SendText(textOut) + user.SendText(``) return true, nil } diff --git a/internal/usercommands/use.go b/internal/usercommands/use.go index c3e152b6..53b82f34 100644 --- a/internal/usercommands/use.go +++ b/internal/usercommands/use.go @@ -13,6 +13,54 @@ import ( func Use(rest string, user *users.UserRecord, room *rooms.Room) (bool, error) { + containerName := room.FindContainerByName(rest) + if containerName != `` { + + container := room.Containers[containerName] + + if len(container.Recipes) > 0 { + + if container.Lock.IsLocked() { + user.SendText(``) + user.SendText(fmt.Sprintf(`The %s is locked.`, containerName)) + user.SendText(``) + return true, nil + } + + recipeReadyItemId := container.RecipeReady() + + if recipeReadyItemId == 0 { + user.SendText("") + user.SendText(fmt.Sprintf(`The %s seems to be missing something.`, containerName)) + user.SendText("") + return true, nil + } + + for _, removeItem := range container.Recipes[recipeReadyItemId] { + if matchItem, found := container.FindItemById(removeItem); found { + container.RemoveItem(matchItem) + } + } + + newItem := items.New(recipeReadyItemId) + + container.AddItem(newItem) + room.Containers[containerName] = container + + room.PlaySound(`sound/other/change.mp3`, `other`) + + user.SendText(``) + user.SendText(fmt.Sprintf(`The %s produces a %s!`, containerName, newItem.DisplayName())) + user.SendText(``) + + room.SendText(fmt.Sprintf(`%s does something with the %s.`, user.Character.Name, containerName), user.UserId) + + return true, nil + + } + + } + // Check whether the user has an item in their inventory that matches matchItem, found := user.Character.FindInBackpack(rest)