diff --git a/engine/assets/langs/en.txt b/engine/assets/langs/en.txt index ed0ec41..6ef7dcc 100644 --- a/engine/assets/langs/en.txt +++ b/engine/assets/langs/en.txt @@ -103,6 +103,101 @@ ITEM_STICK_SHORTNAME=Stick ITEM_STICK_DESCRIPTION=* "Stick" - Weapon AT 0\n* Its bark is worse than\n its bite. ITEM_STICK_USE=* You threw the stick away.[wait:5]\n* Then picked it back up. +ITEM_MONSTER_CANDY_NAME=Monster Candy +ITEM_MONSTER_CANDY_SHORTNAME=MnstrCndy +ITEM_MONSTER_CANDY_DESCRIPTION=* "Monster Candy" - Heals 10 HP\n* Has a distinct,[wait:5] \n non-licorice flavor. +ITEM_MONSTER_CANDY_DESCRIPTION_SHOP=Heals 10 HP\n(Licorice-\nfree\nguaranteed.) +ITEM_MONSTER_CANDY_USE=\n* Very un-licorice-like. +ITEM_MONSTER_CANDY_USE_2=\n* ... tastes like licorice. + +ITEM_SPIDER_DONUT_NAME=Spider Donut +ITEM_SPIDER_DONUT_SHORTNAME=SpidrDont +ITEM_SPIDER_DONUT_SHORTNAME2=SpdrDonut +ITEM_SPIDER_DONUT_DESCRIPTION=* "Spider Donut" - Heals 12 HP\n* A donut made with Spider\n Cider in the batter. +ITEM_SPIDER_DONUT_DESCRIPTION_SHOP=undefined +ITEM_SPIDER_DONUT_USE=* Don't worry,[wait:5] Spider didn't. + +ITEM_SPIDER_CIDER_NAME=Spider Cider +ITEM_SPIDER_CIDER_SHORTNAME=SpidrCidr +ITEM_SPIDER_CIDER_SHORTNAME2=SpdrCider +ITEM_SPIDER_CIDER_DESCRIPTION=* "Spider Cider" - Heals 24 HP\n* Made with whole spiders,[wait:5]\n not just the juice. +ITEM_SPIDER_CIDER_DESCRIPTION_SHOP=undefined + +ITEM_BUTTERSCOTCH_PIE_NAME=Butterscotch Pie +ITEM_BUTTERSCOTCH_PIE_SHORTNAME=ButtsPie +ITEM_BUTTERSCOTCH_PIE_SHORTNAME2=Pie +ITEM_BUTTERSCOTCH_PIE_DESCRIPTION=* "Butterscotch Pie" - All HP\n* Butterscotch-cinnamon\n pie,[wait:5] one slice. +ITEM_BUTTERSCOTCH_PIE_DESCRIPTION_SHOP=undefined + +ITEM_SNOWMAN_PIECE_NAME=Snowman Piece +ITEM_SNOWMAN_PIECE_SHORTNAME=SnowPiece +ITEM_SNOWMAN_PIECE_SHORTNAME2=SnowPiece +ITEM_SNOWMAN_PIECE_DESCRIPTION=* "Snowman Piece" - Heals 45 HP\n* Please take this to the\n ends of the earth. +ITEM_SNOWMAN_PIECE_DESCRIPTION_SHOP=undefined + +ITEM_NICE_CREAM_NAME=Nice Cream +ITEM_NICE_CREAM_SHORTNAME=NiceCream +ITEM_NICE_CREAM_SHORTNAME2=NiceCream +ITEM_NICE_CREAM_DESCRIPTION=* "Nice Cream" - Heals 15 HP\n* Instead of a joke,[wait:5] the\n wrapper says something nice. +ITEM_NICE_CREAM_DESCRIPTION_SHOP=undefined +ITEM_NICE_CREAM_USE=* You're just great! +ITEM_NICE_CREAM_USE_2=* You look nice today! +ITEM_NICE_CREAM_USE_3=* Are those claws natural? +ITEM_NICE_CREAM_USE_4=* You're super spiffy! +ITEM_NICE_CREAM_USE_5=* Have a wonderful day! +ITEM_NICE_CREAM_USE_6=* Is this as sweet as you? +ITEM_NICE_CREAM_USE_7=* (An illustration of a hug.) +ITEM_NICE_CREAM_USE_8=* Love yourself! I love you! + +ITEM_BISICLE_NAME=Bisicle +ITEM_BISICLE_SHORTNAME=Bisicle +ITEM_BISICLE_SHORTNAME2=Bisicle +ITEM_BISICLE_DESCRIPTION=* "Bisicle" - Heals 11 HP\n* It's a two-pronged popsicle,[wait:5]\n so you can eat it twice. +ITEM_BISICLE_DESCRIPTION_SHOP=Heals 11HP x 2\nEat it twice! +ITEM_BISICLE_USE=* You eat one half of\n the Bisicle. + +ITEM_UNISICLE_NAME=Unisicle +ITEM_UNISICLE_SHORTNAME=Unisicle +ITEM_UNISICLE_SHORTNAME2=Popsicle +ITEM_UNISICLE_DESCRIPTION=* "Unisicle" - Heals 11 HP\n* It's a SINGLE-pronged popsicle.[wait:5]\n* Wait,[wait:5] that's just normal... +ITEM_UNISICLE_DESCRIPTION_SHOP=undefined + +ITEM_CINNAMON_BUNNY_NAME=Cinnamon Bunny +ITEM_CINNAMON_BUNNY_SHORTNAME=CinnaBun +ITEM_CINNAMON_BUNNY_SHORTNAME2=C. Bun +ITEM_CINNAMON_BUNNY_DESCRIPTION=* "Cinnamon Bunny" - Heals 22 HP\n* A cinnamon roll in the shape\n of a bunny. +ITEM_CINNAMON_BUNNY_DESCRIPTION_SHOP=Heals 22HP\nIt's my own\nrecipe. + +ITEM_TEMMIE_FLAKES_NAME=Temmie Flakes +ITEM_TEMMIE_FLAKES_SHORTNAME=TemFlakes +ITEM_TEMMIE_FLAKES_SHORTNAME2=TemFlakes +ITEM_TEMMIE_FLAKES_DESCRIPTION=* "Temmie Flakes" - Heals 2 HP\n* It's just torn up pieces\n of colored construction paper. +ITEM_TEMMIE_FLAKES_DESCRIPTION_SHOP=Heals 2HP\nfood of\ntem + +ITEM_ABANDONED_QUICHE_NAME=Abandoned Quiche +ITEM_ABANDONED_QUICHE_SHORTNAME=Ab Quiche +ITEM_ABANDONED_QUICHE_SHORTNAME2=Quiche +ITEM_ABANDONED_QUICHE_DESCRIPTION=* "Abandoned Quiche" Heals 34 HP\n* A psychologically damaged\n spinach egg pie. +ITEM_ABANDONED_QUICHE_DESCRIPTION_SHOP=undefined +ITEM_ABANDONED_QUICHE_DROP=* You leave the Quiche on the\n ground and tell it you'll\n be right back. +ITEM_ABANDONED_QUICHE_USE=* You eat the quiche. + +ITEM_DOG_RESIDUE_NAME=Dog Residue +ITEM_DOG_RESIDUE_SHORTNAME=DogResidu +ITEM_DOG_RESIDUE_SHORTNAME2=D.Residue +ITEM_DOG_RESIDUE_DESCRIPTION=* "Dog Residue" - Dog Item\n* Shiny trail left\n behind by a dog. +ITEM_DOG_RESIDUE_DESCRIPTION_2=* "Dog Residue" - Dog Item\n* Dog-shaped husk shed\n from a dog's carapace. +ITEM_DOG_RESIDUE_DESCRIPTION_3=* "Dog Residue" - Dog Item\n* Dirty dishes left\n unwashed by a dog. +ITEM_DOG_RESIDUE_DESCRIPTION_4=* "Dog Residue" - Dog Item\n* Glowing crystals secreted\n by a dog. +ITEM_DOG_RESIDUE_DESCRIPTION_5=* "Dog Residue" - Dog Item\n* Jigsaw puzzle left\n unfinished by a dog. +ITEM_DOG_RESIDUE_DESCRIPTION_6=* "Dog Residue" - Dog Item\n* Web spun by a dog\n to ensnare prey. +ITEM_DOG_RESIDUE_DESCRIPTION_SHOP=undefined +ITEM_DOG_RESIDUE_USE=* You used the Dog Residue. +ITEM_DOG_RESIDUE_USE_SUCCESS=* The rest of your inventory\n filled up with Dog Residue. +ITEM_DOG_RESIDUE_USE_FAIL=* ... +ITEM_DOG_RESIDUE_USE_FAIL_2=* You finished using it. +ITEM_DOG_RESIDUE_USE_FAIL_3=* An uneasy atmosphere fills\n the room. + # World shop WORLD_SHOP_ACTION_BUY=Buy WORLD_SHOP_ACTION_SELL=Sell diff --git a/engine/assets/sounds/dogresidue.wav b/engine/assets/sounds/dogresidue.wav new file mode 100644 index 0000000..055029b Binary files /dev/null and b/engine/assets/sounds/dogresidue.wav differ diff --git a/engine/item/consumable.lua b/engine/item/consumable.lua index 534b08d..de76564 100644 --- a/engine/item/consumable.lua +++ b/engine/item/consumable.lua @@ -28,16 +28,20 @@ function ItemConsumable:setType(type) self.type = type end ---- Uses the consumable item -function ItemConsumable:use() - if type(self.onBeforeUse) == "function" then - self:onBeforeUse() - end - +--- Gets the item's heal text +--- @return Dummy.Text.Text +function ItemConsumable:getHealText() local heal_text = Lang.translate("BATTLE_ITEM_HEAL", self:getHeal()) if self:getHeal() + Player.getHP() >= Player.getMaxHP() then heal_text = Lang.translate("BATTLE_ITEM_HEAL_MAX") end + return heal_text +end + +--- (Override) Gets the item's final dialogue text when used +--- @return Dummy.Text.Text[] +function ItemConsumable:getDialogueTexts() + local heal_text = self:getHealText() local dialogue_text = heal_text local use_texts = self:getUseTexts() @@ -46,6 +50,16 @@ function ItemConsumable:use() end local texts = { dialogue_text, table.unpack(use_texts, 2) } + return texts +end + +--- Uses the consumable item +function ItemConsumable:use() + if type(self.onBeforeUse) == "function" then + self:onBeforeUse() + end + + local texts = self:getDialogueTexts() if World.isInBattle() then Battle.playDialogueText(table.unpack(texts)) else diff --git a/engine/item/equipment.lua b/engine/item/equipment.lua index 4480b61..3f51511 100644 --- a/engine/item/equipment.lua +++ b/engine/item/equipment.lua @@ -28,16 +28,22 @@ function ItemEquipment:setType(type) self.type = type end +--- (Override) Gets the item's final dialogue text when used +--- @return Dummy.Text.Text[] +function ItemEquipment:getDialogueTexts() + local texts = self:getUseTexts() + if #texts <= 0 then + texts = { { "BATTLE_ITEM_EQUIPMENT_USE", Lang.translate(self:getName()) } } + end + return texts +end --- Uses the equipment item function ItemEquipment:use() if type(self.onBeforeUse) == "function" then self:onBeforeUse() end - local texts = self:getUseTexts() - if #texts <= 0 then - texts = { { "BATTLE_ITEM_EQUIPMENT_USE", Lang.translate(self:getName()) } } - end + local texts = self:getDialogueTexts() if World.isInBattle() then Battle.playDialogueText(table.unpack(texts)) else diff --git a/engine/item/item.lua b/engine/item/item.lua index 789888b..626b411 100644 --- a/engine/item/item.lua +++ b/engine/item/item.lua @@ -91,6 +91,11 @@ function Item:setDropText(text, ...) self.drop_texts = { text, ... } end +--- (Override) Gets the item's final dialogue text when used +--- @return Dummy.Text.Text[] +function Item:getDialogueTexts() + return self:getUseTexts() +end --- Gets the item's buy price --- @return integer function Item:getBuyPrice() @@ -123,12 +128,12 @@ function Item:use() end if not can_use then return end - local use_texts = self:getUseTexts() - if #use_texts > 0 then + local dialogue_texts = self:getDialogueTexts() + if #dialogue_texts > 0 then if World.isInBattle() then - Battle.playDialogueText(table.unpack(use_texts)) + Battle.playDialogueText(table.unpack(dialogue_texts)) else - World.playDialogue(use_texts) + World.playDialogue(dialogue_texts) end end diff --git a/engine/items/abandoned_quiche.lua b/engine/items/abandoned_quiche.lua new file mode 100644 index 0000000..9816231 --- /dev/null +++ b/engine/items/abandoned_quiche.lua @@ -0,0 +1,30 @@ +--- @class Item.AbandonedQuiche : Dummy.Item.Consumable +local AbandonedQuicheItem = Class(ItemConsumable, "Item.AbandonedQuiche") + +--- Creates an abandoned quiche +--- @return Item.AbandonedQuiche +function AbandonedQuicheItem:new() + self = Class:new(AbandonedQuicheItem, { + "abandoned_quiche", -- item identifier + "ITEM_ABANDONED_QUICHE_NAME", -- item name + "ITEM_ABANDONED_QUICHE_SHORTNAME", -- item short name + "ITEM_ABANDONED_QUICHE_DESCRIPTION", -- item description + 34, + "food" + }) + + -- the price the player will pay to buy the item in the shop + self:setBuyPrice(1) + -- the price at which the item will be sold in the shop + self:setSellPrice(76) + -- the text that will appear in the shop item info at the top right on the buy menu when hovering an item + self:setShopDescription("ITEM_ABANDONED_QUICHE_DESCRIPTION_SHOP") + -- the text that will appear when the item is dropped on the ground + self:setDropText("ITEM_ABANDONED_QUICHE_DROP") + -- the text that will appear when the item is used + self:setUseText("ITEM_ABANDONED_QUICHE_USE") + + return self +end + +return AbandonedQuicheItem diff --git a/engine/items/bisicle.lua b/engine/items/bisicle.lua new file mode 100644 index 0000000..e0a7ab4 --- /dev/null +++ b/engine/items/bisicle.lua @@ -0,0 +1,36 @@ +--- @class Item.Bisicle : Dummy.Item.Consumable +local BisicleItem = Class(ItemConsumable, "Item.Bisicle") + +--- Creates a bisicle +--- @return Item.Bisicle +function BisicleItem:new() + self = Class:new(BisicleItem, { + "bisicle", -- item identifier + "ITEM_BISICLE_NAME", -- item name + "ITEM_BISICLE_SHORTNAME", -- item short name + "ITEM_BISICLE_DESCRIPTION", -- item description + 11, + "food" + }) + + -- the price the player will pay to buy the item in the shop + self:setBuyPrice(15) + -- the price at which the item will be sold in the shop + self:setSellPrice(5) + -- the text that will appear in the shop item info at the top right on the buy menu when hovering an item + self:setShopDescription("ITEM_BISICLE_DESCRIPTION_SHOP") + -- the main text that will appear when the item is used. + self.use_texts = { + "ITEM_BISICLE_USE" + } + + return self +end + +function BisicleItem:onUse() + -- Add a unisicle to the player's inventory when the bisicle is used. + local unisicle = require("items.unisicle"):new() + Player.addItem(unisicle) +end + +return BisicleItem diff --git a/engine/mods/world_example/scripts/items/blanket.lua b/engine/items/blanket.lua similarity index 79% rename from engine/mods/world_example/scripts/items/blanket.lua rename to engine/items/blanket.lua index 6e4003b..bdc7db3 100644 --- a/engine/mods/world_example/scripts/items/blanket.lua +++ b/engine/items/blanket.lua @@ -1,8 +1,8 @@ ---- @class WorldExample.Item.Blanket : Dummy.Item.Consumable -local BlanketItem = Class(ItemEquipment, "WorldExample.Item.Blanket") +--- @class Item.Blanket : Dummy.Item.Consumable +local BlanketItem = Class(ItemEquipment, "Item.Blanket") ---- Creates a monster candy ---- @return WorldExample.Item.Blanket +--- Creates a blanket +--- @return Item.Blanket function BlanketItem:new() self = Class:new(BlanketItem, { "blanket", -- item identifier diff --git a/engine/items/butterscotch_pie.lua b/engine/items/butterscotch_pie.lua new file mode 100644 index 0000000..f5264bb --- /dev/null +++ b/engine/items/butterscotch_pie.lua @@ -0,0 +1,26 @@ +--- @class Item.ButterScotchPie : Dummy.Item.Consumable +local ButterScotchPieItem = Class(ItemConsumable, "Item.ButterScotchPie") + +--- Creates a butterscotch pie +--- @return Item.ButterScotchPie +function ButterScotchPieItem:new() + self = Class:new(ButterScotchPieItem, { + "butterscotch_pie", -- item identifier + "ITEM_BUTTERSCOTCH_PIE_NAME", -- item name + "ITEM_BUTTERSCOTCH_PIE_SHORTNAME", -- item short name + "ITEM_BUTTERSCOTCH_PIE_DESCRIPTION", -- item description + Player.getMaxHP(), + "food" + }) + + -- the price the player will pay to buy the item in the shop + self:setBuyPrice(1) + -- the price at which the item will be sold in the shop + self:setSellPrice(180) + -- the text that will appear in the shop item info at the top right on the buy menu when hovering an item + self:setShopDescription("ITEM_BUTTERSCOTCH_PIE_DESCRIPTION_SHOP") + + return self +end + +return ButterScotchPieItem diff --git a/engine/items/cinnamon_bunny.lua b/engine/items/cinnamon_bunny.lua new file mode 100644 index 0000000..33aa7aa --- /dev/null +++ b/engine/items/cinnamon_bunny.lua @@ -0,0 +1,26 @@ +--- @class Item.CinnamonBunny : Dummy.Item.Consumable +local CinnamonBunnyItem = Class(ItemConsumable, "Item.CinnamonBunny") + +--- Creates a cinnamon bunny +--- @return Item.CinnamonBunny +function CinnamonBunnyItem:new() + self = Class:new(CinnamonBunnyItem, { + "cinnamon_bunny", -- item identifier + "ITEM_CINNAMON_BUNNY_NAME", -- item name + "ITEM_CINNAMON_BUNNY_SHORTNAME", -- item short name + "ITEM_CINNAMON_BUNNY_DESCRIPTION", -- item description + 22, + "food" + }) + + -- the price the player will pay to buy the item in the shop + self:setBuyPrice(25) + -- the price at which the item will be sold in the shop + self:setSellPrice(8) + -- the text that will appear in the shop item info at the top right on the buy menu when hovering an item + self:setShopDescription("ITEM_CINNAMON_BUNNY_DESCRIPTION_SHOP") + + return self +end + +return CinnamonBunnyItem diff --git a/engine/items/dog_residue.lua b/engine/items/dog_residue.lua new file mode 100644 index 0000000..fa1d38d --- /dev/null +++ b/engine/items/dog_residue.lua @@ -0,0 +1,65 @@ +--- @class Item.DogResidue : Dummy.Item.Consumable +local DogResidueItem = Class(Item, "Item.DogResidue") + +--- Creates a dog residue +--- @return Item.DogResidue +function DogResidueItem:new() + self = Class:new(DogResidueItem, { + "dog_residue", -- item identifier + "ITEM_DOG_RESIDUE_NAME", -- item name + "ITEM_DOG_RESIDUE_SHORTNAME", -- item short name + "ITEM_DOG_RESIDUE_DESCRIPTION" -- item description + }) + + -- the price the player will pay to buy the item in the shop + self:setBuyPrice(1) + -- the price at which the item will be sold in the shop + self:setSellPrice(love.math.random(4)) + -- the text that will appear in the shop item info at the top right on the buy menu when hovering an item + self:setShopDescription("ITEM_DOG_RESIDUE_DESCRIPTION_SHOP") + -- the text that will appear when the item is used + self:setUseText("ITEM_DOG_RESIDUE_USE") + -- descriptions for each dog residue type + self.descriptions = { + "ITEM_DOG_RESIDUE_DESCRIPTION", + "ITEM_DOG_RESIDUE_DESCRIPTION_2", + "ITEM_DOG_RESIDUE_DESCRIPTION_3", + "ITEM_DOG_RESIDUE_DESCRIPTION_4", + "ITEM_DOG_RESIDUE_DESCRIPTION_5", + "ITEM_DOG_RESIDUE_DESCRIPTION_6" + } + -- Random description when a new version of the object is added (copies will retain the same description) + self.random_description = love.math.random(6) + + return self +end + +function DogResidueItem:getDialogueTexts() + -- define dialogue_text as an empty table because it keeps adding to it if we don't. For some reason. + local dialogue_text = {} + table.insert(dialogue_text, self:getUseTexts()) + -- Show mini-cutscene depending on if the item can create clones + if #Player.getItems() == Player.getMaxItems() then + table.insert(dialogue_text, Lang.translate("ITEM_DOG_RESIDUE_USE_FAIL")) + table.insert(dialogue_text, Lang.translate("ITEM_DOG_RESIDUE_USE_FAIL_2")) + table.insert(dialogue_text, Lang.translate("ITEM_DOG_RESIDUE_USE_FAIL_3")) + else + table.insert(dialogue_text, Lang.translate("ITEM_DOG_RESIDUE_USE_SUCCESS")) + end + return dialogue_text +end + +function DogResidueItem:onUse() + -- Clone the item to all empty slots in the player's inventory + Assets.playSound("dogresidue") + for i = 1, Player.getMaxItems() - #Player.getItems() do + local dog_residue = require("items.dog_residue"):new() + Player.addItem(dog_residue) + end +end + +function DogResidueItem:getDescription() + return Lang.translate(self.descriptions[self.random_description]) +end + +return DogResidueItem diff --git a/engine/items/monster_candy.lua b/engine/items/monster_candy.lua new file mode 100644 index 0000000..47199b9 --- /dev/null +++ b/engine/items/monster_candy.lua @@ -0,0 +1,52 @@ +--- @class Item.MonsterCandy : Dummy.Item.Consumable +local MonsterCandyItem = Class(ItemConsumable, "Item.MonsterCandy") + +--- Creates a monster candy +--- @return Item.MonsterCandy +function MonsterCandyItem:new() + self = Class:new(MonsterCandyItem, { + "monster_candy", -- item identifier + "ITEM_MONSTER_CANDY_NAME", -- item name + "ITEM_MONSTER_CANDY_SHORTNAME", -- item short name + "ITEM_MONSTER_CANDY_DESCRIPTION", -- item description + 10, + "food" + }) + + -- the price the player will pay to buy the item in the shop + self:setBuyPrice(15) + -- the price at which the item will be sold in the shop + self:setSellPrice(25) + -- the text that will appear in the shop item info at the top right on the buy menu when hovering an item + self:setShopDescription("ITEM_MONSTER_CANDY_DESCRIPTION_SHOP") + -- Random comments on use + self.use_comments = { + "ITEM_MONSTER_CANDY_USE", + "ITEM_MONSTER_CANDY_USE_2" + } + + return self +end + +function MonsterCandyItem:getDialogueTexts() + -- Generate a random number + local rand = love.math.random(0, 15) + -- Set the comment to initially be empty + local usecomment = "" + -- Set Default Dialogue Text + local dialogue_text = { Lang.translate(self:getUseTexts()[1], Lang.translate(self:getName())) .. + "\n" .. self:getHealText() } + -- Change use comment based on random number + if rand <= 2 then + usecomment = self.use_comments[1] + elseif rand == 15 then + usecomment = self.use_comments[2] + end + -- If the use comment is not empty, change the dialogue text to include the use comment + if usecomment ~= "" then + dialogue_text = { Lang.translate(self:getUseTexts()[1], Lang.translate(self:getName())) .. Lang.translate(usecomment) .. "\n" .. self:getHealText() } + end + return { dialogue_text, table.unpack(self:getUseTexts(), 2) } +end + +return MonsterCandyItem diff --git a/engine/items/nice_cream.lua b/engine/items/nice_cream.lua new file mode 100644 index 0000000..e330b9f --- /dev/null +++ b/engine/items/nice_cream.lua @@ -0,0 +1,50 @@ +--- @class Item.NiceCream : Dummy.Item.Consumable +local NiceCreamItem = Class(ItemConsumable, "Item.NiceCream") + +--- Creates a nice cream +--- @return Item.NiceCream +function NiceCreamItem:new() + self = Class:new(NiceCreamItem, { + "nice_cream", -- item identifier + "ITEM_NICE_CREAM_NAME", -- item name + "ITEM_NICE_CREAM_SHORTNAME", -- item short name + "ITEM_NICE_CREAM_DESCRIPTION", -- item description + 15, + "food" + }) + + -- the price the player will pay to buy the item in the shop + self:setBuyPrice(15) + -- the price at which the item will be sold in the shop + self:setSellPrice(2) + -- the text that will appear in the shop item info at the top right on the buy menu when hovering an item + self:setShopDescription("ITEM_NICE_CREAM_DESCRIPTION_SHOP") + -- Random comments on use + self.use_comments = { + "ITEM_NICE_CREAM_USE", + "ITEM_NICE_CREAM_USE_2", + "ITEM_NICE_CREAM_USE_3", + "ITEM_NICE_CREAM_USE_4", + "ITEM_NICE_CREAM_USE_5", + "ITEM_NICE_CREAM_USE_6", + "ITEM_NICE_CREAM_USE_7", + "ITEM_NICE_CREAM_USE_8" + } + + return self +end + +function NiceCreamItem:getDialogueTexts() + -- Generate a random number + local rand = love.math.random(9) + -- Set Default Dialogue Text + local dialogue_text = Lang.translate(self:getUseTexts()[1], Lang.translate(self:getName())) .. + "\n" .. self:getHealText() + -- Override dialogue text with a random comment based on the random number + if rand < 9 then + dialogue_text = Lang.translate(self.use_comments[rand]) + end + return { dialogue_text, table.unpack(self:getUseTexts(), 2) } +end + +return NiceCreamItem diff --git a/engine/items/snowman_piece.lua b/engine/items/snowman_piece.lua new file mode 100644 index 0000000..1ff4749 --- /dev/null +++ b/engine/items/snowman_piece.lua @@ -0,0 +1,26 @@ +--- @class Item.SnowManPiece : Dummy.Item.Consumable +local SnowManPieceItem = Class(ItemConsumable, "Item.SnowManPiece") + +--- Creates a snowman piece +--- @return Item.SnowManPiece +function SnowManPieceItem:new() + self = Class:new(SnowManPieceItem, { + "snowman_piece", -- item identifier + "ITEM_SNOWMAN_PIECE_NAME", -- item name + "ITEM_SNOWMAN_PIECE_SHORTNAME", -- item short name + "ITEM_SNOWMAN_PIECE_DESCRIPTION", -- item description + 45, + "food" + }) + + -- the price the player will pay to buy the item in the shop + self:setBuyPrice(1) + -- the price at which the item will be sold in the shop + self:setSellPrice(40) + -- the text that will appear in the shop item info at the top right on the buy menu when hovering an item + self:setShopDescription("ITEM_SNOWMAN_PIECE_DESCRIPTION_SHOP") + + return self +end + +return SnowManPieceItem diff --git a/engine/items/spider_cider.lua b/engine/items/spider_cider.lua new file mode 100644 index 0000000..9fe0b43 --- /dev/null +++ b/engine/items/spider_cider.lua @@ -0,0 +1,26 @@ +--- @class Item.SpiderCider : Dummy.Item.Consumable +local SpiderCiderItem = Class(ItemConsumable, "Item.SpiderCider") + +--- Creates a spider Cider +--- @return Item.SpiderCider +function SpiderCiderItem:new() + self = Class:new(SpiderCiderItem, { + "spider_cider", -- item identifier + "ITEM_SPIDER_CIDER_NAME", -- item name + "ITEM_SPIDER_CIDER_SHORTNAME", -- item short name + "ITEM_SPIDER_CIDER_DESCRIPTION", -- item description + 24, + "drink" + }) + + -- the price the player will pay to buy the item in the shop + self:setBuyPrice(18) + -- the price at which the item will be sold in the shop + self:setSellPrice(60) + -- the text that will appear in the shop item info at the top right on the buy menu when hovering an item + self:setShopDescription("ITEM_SPIDER_CIDER_DESCRIPTION_SHOP") + + return self +end + +return SpiderCiderItem diff --git a/engine/items/spider_donut.lua b/engine/items/spider_donut.lua new file mode 100644 index 0000000..f9ccc1b --- /dev/null +++ b/engine/items/spider_donut.lua @@ -0,0 +1,41 @@ +--- @class Item.SpiderDonut : Dummy.Item.Consumable +local SpiderDonutItem = Class(ItemConsumable, "Item.SpiderDonut") + +--- Creates a spider donut +--- @return Item.SpiderDonut +function SpiderDonutItem:new() + self = Class:new(SpiderDonutItem, { + "spider_donut", -- item identifier + "ITEM_SPIDER_DONUT_NAME", -- item name + "ITEM_SPIDER_DONUT_SHORTNAME", -- item short name + "ITEM_SPIDER_DONUT_DESCRIPTION", -- item description + 12, + "food" + }) + + -- the price the player will pay to buy the item in the shop + self:setBuyPrice(7) + -- the price at which the item will be sold in the shop + self:setSellPrice(30) + -- the text that will appear in the shop item info at the top right on the buy menu when hovering an item + self:setShopDescription("ITEM_SPIDER_DONUT_DESCRIPTION_SHOP") + + return self +end + +function SpiderDonutItem:getDialogueTexts() + -- Set Default Dialogue Text + local dialogue_text = Lang.translate(self:getUseTexts()[1], Lang.translate(self:getName())) .. "\n" .. self:getHealText() + -- Check if the player is in a battle + if World.isInBattle() then + -- Generate a random number + local rand = love.math.random(0, 10) + -- Override dialogue text with a comment based on the random number + if rand > 9 then + dialogue_text = Lang.translate("ITEM_SPIDER_DONUT_USE") + end + end + return { dialogue_text, table.unpack(self:getUseTexts(), 2) } +end + +return SpiderDonutItem diff --git a/engine/items/temmie_flakes.lua b/engine/items/temmie_flakes.lua new file mode 100644 index 0000000..6027da7 --- /dev/null +++ b/engine/items/temmie_flakes.lua @@ -0,0 +1,26 @@ +--- @class Item.TemmieFlakes : Dummy.Item.Consumable +local TemmieFlakesItem = Class(ItemConsumable, "Item.TemmieFlakes") + +--- Creates a temmie flakes +--- @return Item.TemmieFlakes +function TemmieFlakesItem:new() + self = Class:new(TemmieFlakesItem, { + "temmie_flakes", -- item identifier + "ITEM_TEMMIE_FLAKES_NAME", -- item name + "ITEM_TEMMIE_FLAKES_SHORTNAME", -- item short name + "ITEM_TEMMIE_FLAKES_DESCRIPTION", -- item description + 2, + "food" + }) + + -- the price the player will pay to buy the item in the shop + self:setBuyPrice(1) + -- the price at which the item will be sold in the shop + self:setSellPrice(2) + -- the text that will appear in the shop item info at the top right on the buy menu when hovering an item + self:setShopDescription("ITEM_TEMMIE_FLAKES_DESCRIPTION_SHOP") + + return self +end + +return TemmieFlakesItem diff --git a/engine/items/unisicle.lua b/engine/items/unisicle.lua new file mode 100644 index 0000000..fd93a2e --- /dev/null +++ b/engine/items/unisicle.lua @@ -0,0 +1,26 @@ +--- @class Item.Unisicle : Dummy.Item.Consumable +local UnisicleItem = Class(ItemConsumable, "Item.Unisicle") + +--- Creates a unisicle +--- @return Item.Unisicle +function UnisicleItem:new() + self = Class:new(UnisicleItem, { + "unisicle", -- item identifier + "ITEM_UNISICLE_NAME", -- item name + "ITEM_UNISICLE_SHORTNAME", -- item short name + "ITEM_UNISICLE_DESCRIPTION", -- item description + 11, + "food" + }) + + -- the price the player will pay to buy the item in the shop + self:setBuyPrice(1) + -- the price at which the item will be sold in the shop + self:setSellPrice(2) + -- the text that will appear in the shop item info at the top right on the buy menu when hovering an item + self:setShopDescription("ITEM_UNISICLE_DESCRIPTION_SHOP") + + return self +end + +return UnisicleItem diff --git a/engine/mods/froggit/mod.lua b/engine/mods/froggit/mod.lua index c67eb32..1e0d1ee 100644 --- a/engine/mods/froggit/mod.lua +++ b/engine/mods/froggit/mod.lua @@ -19,14 +19,7 @@ function mod:load() Player.setLV(1) -- add items - Player.addItem(ItemConsumable:new( - "monster_candy", - "FROGGIT_MOD_MONSTER_CANDY_NAME", - "FROGGIT_MOD_MONSTER_CANDY_SHORTNAME", - "", - 50, - "food" - )) + Player.addItem(require("items.monster_candy"):new()) Player.addItem(ItemEquipment:new( "toy_knife", "FROGGIT_MOD_TOY_KNIFE_NAME", diff --git a/engine/mods/world_example/assets/langs/en.txt b/engine/mods/world_example/assets/langs/en.txt index 45ed427..2bae46f 100644 --- a/engine/mods/world_example/assets/langs/en.txt +++ b/engine/mods/world_example/assets/langs/en.txt @@ -81,11 +81,15 @@ WORLD_EXAMPLE_MOD_WORLD_SHOP_DUMMY_TALK_PAT_TEXT_2=* (...but it doesn't respond. WORLD_EXAMPLE_MOD_WORLD_SHOP_DUMMY_TALK_SIDE_TEXT=. . . # Items -WORLD_EXAMPLE_MOD_ITEM_MONSTER_CANDY_NAME=Monster Candy -WORLD_EXAMPLE_MOD_ITEM_MONSTER_CANDY_SHORTNAME=MnstrCndy -WORLD_EXAMPLE_MOD_ITEM_MONSTER_CANDY_DESCRIPTION=* "Monster Candy" - Heals 10 HP\n* Has a distinct,[wait:5] \n non-licorice flavor. -WORLD_EXAMPLE_MOD_ITEM_MONSTER_CANDY_DESCRIPTION_SHOP=Heals 10 HP\n(Licorice-\nfree\nguaranteed.) WORLD_EXAMPLE_MOD_ITEM_BLANKET_NAME=Blanket WORLD_EXAMPLE_MOD_ITEM_BLANKET_SHORTNAME=Blanket WORLD_EXAMPLE_MOD_ITEM_BLANKET_DESCRIPTION=* "Blanket" - Armor DF 1\n* The fabric is very soft. -WORLD_EXAMPLE_MOD_ITEM_BLANKET_DESCRIPTION_SHOP=Armor: 1DF\n({} DF)\n(It makes\nyou sleepy...) \ No newline at end of file +WORLD_EXAMPLE_MOD_ITEM_BLANKET_DESCRIPTION_SHOP=Armor: 1DF\n({} DF)\n(It makes\nyou sleepy...) + +# This overrides engine content +ITEM_BISICLE_NAME=Bisicle SP +ITEM_BISICLE_SHORTNAME=BscleSP +ITEM_BISICLE_SHORTNAME2=BscleSP +ITEM_BISICLE_DESCRIPTION=* "Bisicle SP" - Heals 11 HP\n* It's like a regular bisicle,[wait:5]\n but local to a mod! +ITEM_BISICLE_DESCRIPTION_SHOP=Heals 11HP x 2\nspecil +BATTLE_BISICLE_USE=* You eat one half of it.[wait:5]\n* You feel special. \ No newline at end of file diff --git a/engine/mods/world_example/mod.lua b/engine/mods/world_example/mod.lua index 121a317..0c0c185 100644 --- a/engine/mods/world_example/mod.lua +++ b/engine/mods/world_example/mod.lua @@ -85,14 +85,14 @@ function WorldExampleMod:loadSaveData() -- equipped weapon if save_data.weapon ~= nil then if save_data.weapon ~= "stick" then - Player.setWeapon(modRequire("scripts.items." .. save_data.weapon):new()) + Player.setWeapon(tryRequire("scripts.items." .. save_data.weapon, "items." .. save_data.weapon):new()) end end -- equipped armor if save_data.armor ~= nil then if save_data.armor ~= "bandage" then - Player.setArmor(modRequire("scripts.items." .. save_data.armor):new()) + Player.setArmor(tryRequire("scripts.items." .. save_data.armor, "items." .. save_data.armor):new()) end end @@ -134,7 +134,7 @@ function WorldExampleMod:loadItem(item_id) item = bandage end else - item = modRequire("scripts.items." .. item_id):new() + item = tryRequire("scripts.items." .. item_id, "items." .. item_id):new() end return item end diff --git a/engine/mods/world_example/scripts/items/bisicle.lua b/engine/mods/world_example/scripts/items/bisicle.lua new file mode 100644 index 0000000..f719602 --- /dev/null +++ b/engine/mods/world_example/scripts/items/bisicle.lua @@ -0,0 +1,35 @@ +--- @class Item.Bisicle : Dummy.Item.Consumable +local BisicleItem = Class(ItemConsumable, "Item.Bisicle") + +--- Creates a bisicle +--- @return Item.Bisicle +function BisicleItem:new() + self = Class:new(BisicleItem, { + "bisicle", -- item identifier + "ITEM_BISICLE_NAME", -- item name + "ITEM_BISICLE_SHORTNAME", -- item short name + "ITEM_BISICLE_DESCRIPTION", -- item description + 11, + "food" + }) + + -- the price the player will pay to buy the item in the shop + self:setBuyPrice(15) + -- the price at which the item will be sold in the shop + self:setSellPrice(5) + -- the text that will appear in the shop item info at the top right on the buy menu when hovering an item + self:setShopDescription("ITEM_BISICLE_DESCRIPTION_SHOP") + + self.use_texts = { + "ITEM_BISICLE_USE" + } + + return self +end + +function BisicleItem:onUse() + local unisicle = require("items.unisicle"):new() + Player.addItem(unisicle) +end + +return BisicleItem diff --git a/engine/mods/world_example/scripts/items/monster_candy.lua b/engine/mods/world_example/scripts/items/monster_candy.lua deleted file mode 100644 index 79460d9..0000000 --- a/engine/mods/world_example/scripts/items/monster_candy.lua +++ /dev/null @@ -1,26 +0,0 @@ ---- @class WorldExample.Item.MonsterCandy : Dummy.Item.Consumable -local MonsterCandyItem = Class(ItemConsumable, "WorldExample.Item.MonsterCandy") - ---- Creates a monster candy ---- @return WorldExample.Item.MonsterCandy -function MonsterCandyItem:new() - self = Class:new(MonsterCandyItem, { - "monster_candy", -- item identifier - "WORLD_EXAMPLE_MOD_ITEM_MONSTER_CANDY_NAME", -- item name - "WORLD_EXAMPLE_MOD_ITEM_MONSTER_CANDY_SHORTNAME", -- item short name - "WORLD_EXAMPLE_MOD_ITEM_MONSTER_CANDY_DESCRIPTION", -- item description - 10, - "food" - }) - - -- the price the player will pay to buy the item in the shop - self:setBuyPrice(15) - -- the price at which the item will be sold in the shop - self:setSellPrice(5) - -- the text that will appear in the shop item info at the top right on the buy menu when hovering an item - self:setShopDescription("WORLD_EXAMPLE_MOD_ITEM_MONSTER_CANDY_DESCRIPTION_SHOP") - - return self -end - -return MonsterCandyItem diff --git a/engine/mods/world_example/scripts/world/shop/dummy_shop.lua b/engine/mods/world_example/scripts/world/shop/dummy_shop.lua index 49f6c9a..558af90 100644 --- a/engine/mods/world_example/scripts/world/shop/dummy_shop.lua +++ b/engine/mods/world_example/scripts/world/shop/dummy_shop.lua @@ -41,11 +41,19 @@ end --- Prepares the shop items function DummyShop:prepareItems() - local MonsterCandy = modRequire("scripts.items.monster_candy") + local MonsterCandy = require("items.monster_candy") + local SpiderDonut = require("items.spider_donut") + local bisicle = tryRequire("scripts.items.bisicle", "items.bisicle") + local nice_cream = require("items.nice_cream") + local quiche = require("items.abandoned_quiche") + local dog_residue = require("items.dog_residue") -- amount `-1` for infinite stock self:addItem(MonsterCandy, -1) + self:addItem(bisicle, -1) + self:addItem(quiche, -1) + self:addItem(dog_residue, -1) - local BlanketItem = modRequire("scripts.items.blanket") + local BlanketItem = require("items.blanket") local blanket_amount = 1 -- track wether the blanket has been bought if WorldExampleMod.flag["dummy_shop_blanket"] == 1 then diff --git a/engine/utils/utils.lua b/engine/utils/utils.lua index df08acd..315f2e7 100644 --- a/engine/utils/utils.lua +++ b/engine/utils/utils.lua @@ -7,6 +7,19 @@ function modRequire(modname) return require("mods." .. mod:getId() .. "." .. modname) end +--- Tries to require a module from the current mod, or the base game if it fails. +--- @param modname string +--- @param altname string +--- @return unknown +function tryRequire(modname, altname) + local mod = ModList.getCurrentMod() + local success, result = pcall(modRequire, modname) + if success then + return result + else + return require(altname) + end +end -- table -- -- https://gist.github.com/revolucas/dd1ecccfca32d558fddf70ddb39eb8a6