可入锅
参考:cooking.lua
先来看一下官方代码
--names:{"prefab1", "prefab2", ...} 预设物名字表
-- tags: 食物标签,肉度,菜度等。{meat=1, fruit=1}
--fruit, monster, sweetener, veggie, meat, fish,
--egg, decoration, fat, dairy, inedible, seed, magic
--cancook:是否可烹饪,true时把tags拷贝一份
--candry:是否可凉干,true时把tags拷贝一份
--因为return的表里有ingredients,使用可以用require("cooking").ingredients自己修改tags
local ingredients = {}
function AddIngredientValues(names, tags, cancook, candry)
for _,name in pairs(names) do
ingredients[name] = { tags= {}}
if cancook then
ingredients[name.."_cooked"] = {tags={}}
end
if candry then
ingredients[name.."_dried"] = {tags={}}
end
for tagname,tagval in pairs(tags) do
ingredients[name].tags[tagname] = tagval
--print(name,tagname,tagval,ingtable[name].tags[tagname])
if cancook then
ingredients[name.."_cooked"].tags.precook = 1
ingredients[name.."_cooked"].tags[tagname] = tagval
end
if candry then
ingredients[name.."_dried"].tags.dried = 1
ingredients[name.."_dried"].tags[tagname] = tagval
end
end
end
end
return {..., ingredients = ingredients, ...}
要让自己的预设物可入锅可以在modmian.lua中只需一行代码
--modmain.lua
--AddIngredientValues(names, tags, cancook, candry) cooking.lua下中也有例子
AddIngredientValues({"prefabname"}, {meat=1})
我们要修改凉干/烹饪后的标签就可以这么写
--modmain.lua
local ingredients = require("cooking").ingredients
ingredients[name.."_cooked"].tags[tagname] = tagval
ingredients[name.."_dried"].tags[tagname] = tagval
require的lua文件中的非local的函数和变量可以直接访问,修改,赋值(不建议赋值=)。
而local的函数和变量可以作为return值,在reuire时返回,然后我们就可以间接访问函数,或者修改表的数据。
菜谱
烹饪锅菜谱在scripts/preparedfoods.lua
烹饪锅菜的预设物在prefabs/preparedfoods.lua
厨师的scripts/preparedfoods_warly.lua prefabs/preparedfoods_warly.lua
其中test函数的参数 names={prefabname = num} tags = {meat=num}
可烹饪
组件:cookable
先来看看组件代码
--components/cookable.lua
local Cookable = Class(function(self, inst)
...
--推荐在inst.entity:SetPristine()之前添加该标签,让客户端也有这个标签
inst:AddTag("cookable")
end)
...
--核心代码在这,根据self.product来生成预设物实体,所以我们设置以下self.product的值即可
function Cookable:Cook(cooker, chef)
...
if self.product ~= nil then
--生成预设物实体
local prod = SpawnPrefab(
type(self.product) ~= "function" and
self.product or
self.product(self.inst, cooker, chef)
)
...
return prod
end
end
return Cookable
在我们的预设物的构建函数中,添加cookable组件和标签,简单设置下它的product即可
local function fn()
--服务器和客户端都运行
...
inst:AddTag("cookable") --来自cookable组件
inst.entity:SetPristine()
if not TheWorld.ismastersim then
--if里面仅客户端运行,客户端到这里直接返回了
return inst
end
--下面是仅服务器运行,大部分component都写在这
inst:AddComponent("cookable")
--prefabname,一般是 _cooked结尾(烤大肉是个例外),你也可以设置为mod的预设物
inst.components.cookable.product = "cookedmeat"
end
可凉干
制作凉干的食物需要格外制作动画,稍微有点复杂,先看下组件怎么写的。
组件:dryable
--components/dryable.lua
local Dryable = Class(function(self, inst)
...
--推荐在inst.entity:SetPristine()之前添加该标签,让客户端也有这个标签
inst:AddTag("dryable")
end)
--product:凉干后的预设物名,一般以_dried结尾
function Dryable:SetProduct(product)
self.product = product
end
--time:凉干所需时间,可以用TUNING.DRY_FAST等表示
function Dryable:SetDryTime(time)
self.drytime = time
end
--设置凉干中的动画scml名 prefab同名文件夹,并设置好锚点,悬挂的点
function Dryable:SetBuildFile(buildfile)
self.buildfile = buildfile
end
--设置凉干后的动画scml名 product同名的文件夹,并设置锚点,悬挂的点
function Dryable:SetDriedBuildFile(dried_buildfile)
self.dried_buildfile = dried_buildfile
end
return Dryable
例如我们有mymeat和mymeat_dried两个普通食物预设物,
凉肉架的动画不需要做,不过需要prefab(这里是mymeat)、product(这里是mymeat_dried)同名的文件夹,并设置好里面图片(横的)的锚点。
我们需要做的只有扔地上的动画,之前也说过了scml名是build,右下角第一层是bank,在下面是anim。例如这里的
anim: mymeat
bank: mymeat
anim: idle
之前地上的动画推荐是把x,y设置为0,0,这样锚点的位置就刚好是落地点的位置(十字线交叉点),不过这里的锚点需要设置为凉肉架上绳子挂的地方,x,y就不强制要求为0,0了。
为了避免贴图重复打包占空间,我们在mymeat.scml中把mymeat_dried地上的动画做了
anim: mymeat
bank: mymeat_dried
anim: idle
游戏内的,左边凉干后的,右边刚凉的(凉肉架自动寻找build中的文件夹图片,自动旋转)
预设物 mymeat 的代码
--mymeat.lua
local assets = {
Asset("ANIM", "anim/mymeat.zip")
Asset("IMAGE", "images/inventoryimages/mymeat.tex"), --物品栏贴图
Asset("ATLAS", "images/inventoryimages/mymeat.xml"),
}
local function fn()
--服务器和客户端都运行
...
inst:AddTag("dryable") --来自cookable组件
inst.entity:SetPristine()
if not TheWorld.ismastersim then
--if里面仅客户端运行,客户端到这里直接返回了
return inst
end
--下面是仅服务器运行,大部分component都写在这
-- 可吃
inst:AddComponent("edible")
--可凉干
inst:AddComponent("dryable")
inst.components.dryable:SetProduct("mymeat_dried")
inst.components.dryable:SetDryTime(TUNING.DRY_FAST)
inst.components.dryable:SetBuildFile("mymeat") --scml name
inst.components.dryable:SetDriedBuildFile("mymeat") --scml name
-- 物品栏
inst:AddComponent("inventoryitem")
inst.components.inventoryitem.atlasname = "images/inventoryimages/mymeat.xml"
end
return Prefab("mymeat", fn, assets)
mymeat_dried 的代码,简单的食物
--mymeat.lua
local assets = {
Asset("ANIM", "anim/mymeat.zip")
Asset("IMAGE", "images/inventoryimages/mymeat_dried.tex"), --物品栏贴图
Asset("ATLAS", "images/inventoryimages/mymeat_dried.xml"),
}
local function fn()
--服务器和客户端都运行
...
inst.entity:SetPristine()
if not TheWorld.ismastersim then
--if里面仅客户端运行,客户端到这里直接返回了
return inst
end
--下面是仅服务器运行,大部分component都写在这
-- 可吃
inst:AddComponent("edible")
-- 物品栏
inst:AddComponent("inventoryitem")
inst.components.inventoryitem.atlasname = "images/inventoryimages/mymeat_dried.xml"
end
return Prefab("mymeat_dried", fn, assets)