饥荒mod开发——消耗道具通用组件
通用:
组件为主客机通用组件,应该在客机添加,主客机分别配置,可以配置的有:
- 客机配置:
userCheckFn(inst, doer, target)对玩家的检测,为nil则表示任何玩家可使用,默认niltargetCheckFn(inst, doer, target)对目标对象的检测,为nil则表示任何目标都行,默认只能对玩家自己使用state执行的state,默认domediumactionstr需要显示的文本
- 主机配置:
onUseFn使用时执行函数,必须赋值,道具的删除要在里面自己写useSound使用时音效,默认黄金那个清脆的音效
下面示例代码我的mod前缀为lappland_。
1. 组件代码
local componentPre = debug.getinfo(1, 'S').source:match("([^/]+)_consumable%.lua$") --当前文件前缀
local componentName = componentPre .. "_consumable"
local function DefaultTargetCheckFn(inst, doer, target)
return doer == target
end
--- 通用消耗品组件,主客机通用组件
--- 该组件和trader组件功能有些重叠,两者的区别在于trader组件功能强大,但是不够灵活,比如trader必须在给予方添加tradable组件,不能修改动作,
-- 一次只能给一个,不能在客机拦截显示,tradable的东西对所有trader的东西都能互动,即便有时候不想显示文本也不行,也不能修改显示的文本,
-- trader是站在被给予方进行判断的,该组件是站在给予方进行判断的
--- 该组件也有缺点,必须在主客机添加并分别配置,功能单一,有时候想站在被给予方进行判断会比较麻烦,比如让肉类可与一个建筑互动,就得给所有有
-- 肉类标签的对象添加组件并判断(虽然trader也类似,不过判断方是建筑)
local Consumable = Class(function(self, inst)
self.inst = inst
-- 3个限制
inst:AddTag(componentName) --根据标签判断是否可以消耗,默认可以
self.userCheckFn = nil
self.targetCheckFn = DefaultTargetCheckFn --默认只能自己用
self.state = "domediumaction" --使用执行的state,建议give/domediumaction
self.str = nil
if not TheWorld.ismastersim then return end
self.onUseFn = nil --使用时执行函数,必须赋值,道具的删除要在里面自己写
self.useSound = "dontstarve/wilson/equip_item_gold" --使用音效
end)
function Consumable:Use(doer, target)
local status, msg
if self.onUseFn then
status, msg = self.onUseFn(self.inst, doer, target)
else
status, msg = false, "NOT_INIT" --不应该发生
end
if status and self.useSound then
if doer and doer.SoundEmitter then
doer.SoundEmitter:PlaySound(self.useSound)
elseif self.inst.SoundEmitter then
self.inst.SoundEmitter:PlaySound(self.useSound)
end
end
return status, msg
end
return Consumable
2. 使用示例
2.1 创建对应的action
local LAPPLAND_USE_ITEM = Action({ priority = 1 })
LAPPLAND_USE_ITEM.id = "LAPPLAND_USE_ITEM"
LAPPLAND_USE_ITEM.strfn = function(act)
return act.invobject.components.lappland_consumable.str
end
LAPPLAND_USE_ITEM.fn = function(act)
return act.invobject.components.lappland_consumable:Use(act.doer)
end
AddAction(LAPPLAND_USE_ITEM)
-- 可显示的文本
STRINGS.ACTIONS.LAPPLAND_USE_ITEM = {
GENERIC = "使用",
PLANT = "种植"
}
-- 失败原因
STRINGS.CHARACTERS.GENERIC.ACTIONFAIL.LAPPLAND_USE_ITEM = {
EXIST_CAREER = "已经选过职业了。",
}
2.2 添加对应的ComponentAction
local function CheckConsumable(inst, doer, target, actions)
local com = inst.components.lappland_consumable
if com
and inst:HasTag("lappland_consumable") --默认有
and (not com.userCheckFn or com.userCheckFn(inst, doer, target)) --对玩家的检测
and (not com.targetCheckFn or com.targetCheckFn(inst, doer, target)) --对目标单位的检测
then
table.insert(actions, ACTIONS.LAPPLAND_USE_ITEM)
end
end
-- 可以自己使用
AddComponentAction("INVENTORY", "lappland_consumable", function(inst, doer, actions, right)
CheckConsumable(inst, doer, doer, actions)
end)
-- 可以对目标使用
AddComponentAction("USEITEM", "lappland_consumable", function(inst, doer, target, actions, right)
CheckConsumable(inst, doer, target, actions)
end)
2.3 在玩家的sg中添加对应的事件处理
-- 使用消耗品道具
AddStategraphActionHandler("wilson", ActionHandler(ACTIONS.LAPPLAND_USE_ITEM,
function(inst, action)
return action.invobject.components.lappland_consumable.state
end))
AddStategraphActionHandler("wilson_client", ActionHandler(ACTIONS.LAPPLAND_USE_ITEM,
function(inst, action)
return action.invobject.components.lappland_consumable.state
end))
2.4 在预制体中添加组件并配置
-- 使用后执行的操作,在主机执行,actions的返回值别忘了,成功就返回true,失败就返回false和失败原因
local function OnUseFn(inst, doer, target)
inst:Remove()
return true
end
-- 对目标的要求,在客机执行
local function TargetCheck(inst, doer, target)
return target ~= nil
end
local function fn()
-- ...
inst.components.lappland_consumable.targetCheckFn = TargetCheck --其实只在客机设置就行
inst.components.lappland_consumable.str = "PLANT" --显示的文本
if not TheWorld.ismastersim then
return inst
end
inst:AddComponent("lappland_consumable")
inst.components.lappland_consumable.state = "domediumaction"
inst.components.lappland_consumable.onUseFn = OnUseFn
-- ...
end
浙公网安备 33010602011771号