我想编写一个游戏模组,游戏名是《饥荒联机版》,该游戏英文名是《Don't Starve Together》,该游戏模组由lua语言编写,游戏内有一名叫做沃尔特的角色,英文名是Walter,玩家可以使用该角色在夜晚,用鼠标右键在火坑使用讲故事的能力。请你参考角色沃尔特讲故事的游戏相关代码,帮我编写一个模组,让所有角色,包括模组角色,获得跟沃尔特相同的讲故事能力。故事的内容可以在模组内自定义修改,并且每天晚上都会随机讲多个不同的故事,直到故事列表所有不同的故事都讲完,才能讲之前讲过的故事。并且讲故事时,每句话的语速可以在代码中自行调整,请帮我写一个模组实现以上功能。
好的,我可以帮助你编写一个《Don't Starve Together》的模组,使所有角色都能在夜晚使用讲故事的能力。我们将参考沃尔特的讲故事功能,并扩展到所有角色。以下是一个基本的模组代码框架,你可以根据需要进行自定义。
首先,创建一个新的模组文件夹,并在其中创建以下文件和文件夹结构:
modinfo.lua
modmain.lua
scripts/
components/
storyteller.lua
prefabs/
storybook.lua
modinfo.lua
这是模组的基本信息文件。
name = "Universal Storyteller"
description = "All characters can tell stories at night."
author = "Your Name"
version = "1.0"
forumthread = ""
api_version = 10
dst_compatible = true
all_clients_require_mod = true
client_only_mod = false
icon_atlas = "modicon.xml"
icon = "modicon.tex"
modmain.lua
这是模组的主文件,负责初始化和加载模组功能。
PrefabFiles = {
"storybook",
}
local function AddStorytellerComponent(inst)
if not inst.components.storyteller then
inst:AddComponent("storyteller")
end
end
local function OnPlayerSpawn(inst)
inst:DoTaskInTime(0, function()
AddStorytellerComponent(inst)
end)
end
AddPlayerPostInit(OnPlayerSpawn)
scripts/components/storyteller.lua
这是自定义的讲故事组件。
local Storyteller = Class(function(self, inst)
self.inst = inst
self.stories = {
"Once upon a time...",
"In a land far, far away...",
"There was a brave adventurer...",
-- Add more stories here
}
self.current_story_index = 1
self.story_interval = 2 -- Time between sentences
end)
function Storyteller:TellStory()
if not self.inst.components.talker then
self.inst:AddComponent("talker")
end
local function TellNextSentence()
if self.current_story_index <= #self.stories then
self.inst.components.talker:Say(self.stories[self.current_story_index])
self.current_story_index = self.current_story_index + 1
self.inst:DoTaskInTime(self.story_interval, TellNextSentence)
else
self.current_story_index = 1
end
end
TellNextSentence()
end
function Storyteller:OnRightClick()
if TheWorld.state.isnight then
self:TellStory()
else
self.inst.components.talker:Say("I can only tell stories at night.")
end
end
return Storyteller
scripts/prefabs/storybook.lua
这是一个虚拟的物品,用于触发讲故事功能。
local function OnRightClick(inst, doer, target, actions, right)
if right and doer.components.storyteller then
table.insert(actions, ACTIONS.TELLSTORY)
end
end
local function fn()
local inst = CreateEntity()
inst.entity:AddTransform()
inst.entity:AddNetwork()
inst:AddTag("storybook")
if not TheWorld.ismastersim then
return inst
end
inst.entity:SetPristine()
inst:AddComponent("inspectable")
inst:AddComponent("inventoryitem")
inst.components.inventoryitem.imagename = "storybook"
inst.components.inventoryitem.atlasname = "images/inventoryimages/storybook.xml"
inst:AddComponent("useableitem")
inst.components.useableitem:SetOnUseFn(function(inst, doer)
if doer.components.storyteller then
doer.components.storyteller:OnRightClick()
end
end)
return inst
end
return Prefab("common/inventory/storybook", fn, assets)
images/inventoryimages/storybook.xml
和 images/inventoryimages/storybook.tex
你需要创建一个图标文件用于故事书物品。你可以使用 TexTool
工具将 PNG 图像转换为 .tex
格式,并创建相应的 .xml
文件。
scripts/actions.lua
定义一个新的动作 TELLSTORY
。
local Action = GLOBAL.Action
local ACTIONS = GLOBAL.ACTIONS
ACTIONS.TELLSTORY = Action({ priority = 10, rmb = true })
ACTIONS.TELLSTORY.id = "TELLSTORY"
ACTIONS.TELLSTORY.str = "Tell Story"
ACTIONS.TELLSTORY.fn = function(act)
if act.doer.components.storyteller then
act.doer.components.storyteller:OnRightClick()
return true
end
end
AddAction(ACTIONS.TELLSTORY)
scripts/stategraphs/SGwilson.lua
添加新的状态图以处理讲故事动作。
local State = GLOBAL.State
local EventHandler = GLOBAL.EventHandler
local TimeEvent = GLOBAL.TimeEvent
local function TellStoryAction(inst)
if inst.components.storyteller then
inst.components.storyteller:OnRightClick()
end
end
AddStategraphActionHandler("wilson", GLOBAL.ActionHandler(GLOBAL.ACTIONS.TELLSTORY, "doshortaction"))
AddStategraphState("wilson", State{
name = "tellstory",
tags = { "doing", "busy" },
onenter = function(inst)
inst.components.locomotor:Stop()
inst.AnimState:PlayAnimation("idle")
inst:PerformBufferedAction()
end,
timeline = {
TimeEvent(0, TellStoryAction),
},
events = {
EventHandler("animover", function(inst)
inst.sg:GoToState("idle")
end),
},
})
你可以在 storyteller.lua
文件中自定义故事内容和语速:
self.stories = {
"Once upon a time...",
"In a land far, far away...",
"There was a brave adventurer...",
-- Add more stories here
}
self.story_interval = 2 -- Time between sentences
以上代码提供了一个基本的框架,你可以根据需要进行扩展和修改。希望这能帮助你实现你的模组!