Mod development of the online version of Famine - Two kinds of hats (10)
foreword
In this issue, let’s talk about the hats in Don’t Starve. According to the display, they can be divided into open-headed hats (such as wreaths) and non-exposed hats (such as top hats). The two hats are the same except for the animation display part. In order to save the time of animation, I directly use the animation of wreath and top hat for demonstration.
Overview and Downloads
In addition to the animation and prefabs, others can be covered in previous issues, so I won’t go into details here.
Source files have been added to mods/~myhats.zip
Don't Starve Online Version Development
https://pan.baidu.com/s/1_-TPRdo86z8PNwK084N_3A?pwd=oc74
animation
For the two types of hats, the animation production process is actually the same.
-
The material should be placed in the swap_hat folder
-
The names should correspond , the first three correspond to the front, side, and back textures of the hat in turn, and the last one is the texture on the ground.
-
Double-click the picture in the upper right corner to set the anchor point . The anchor points of the first three cards correspond to the position after wearing the hat. This requires more games and more trials. The anchor point of the last card is the ground landing point.
- Make an animation of throwing on the ground, pay attention to the name, which corresponds to the parameters of the three lines of code.
(It has been involved in the previous issues, I don’t remember, go back and review)
inst.AnimState:SetBuild("mytophat") --scml名字自动打包成同名zip,同时也是这个参数
inst.AnimState:SetBank("mytophat") --对应sprite里右下角的第一层名字
inst.AnimState:PlayAnimation("idle") --第一个参数是动画名,对应sprite里右下角的第二层名字
the code
modmain
Simply declare the preset object file, item name, and item description
GLOBAL.setmetatable(env,{
__index=function(t,k) return GLOBAL.rawget(GLOBAL,k) end})
PrefabFiles = {
"myflowerhat",
"mytophat"
}
STRINGS.NAMES.MYFLOWERHAT = "我的花帽"
STRINGS.CHARACTERS.GENERIC.DESCRIBE.MYFLOWERHAT = "这是花帽?"
STRINGS.NAMES.MYTOPHAT = "我的高礼帽"
STRINGS.CHARACTERS.GENERIC.DESCRIBE.MYTOPHAT = "这是高礼帽?"
Outcropping hat
Basic Prefab Framework
The following code is the most basic code. If you don’t understand it, it is recommended to go back and read the third and fourth issues.
--prefabs/myflowerhat.lua
local assets = {
Asset("ANIM", "anim/myflowerhat.zip"), --动画文件
Asset("IMAGE", "images/inventoryimages/myflowerhat.tex"), --物品栏贴图
Asset("ATLAS", "images/inventoryimages/myflowerhat.xml")
}
local prefabs = {
}
local function fn()
local inst = CreateEntity()
inst.entity:AddTransform()
inst.entity:AddAnimState()
inst.entity:AddNetwork()
MakeInventoryPhysics(inst) --与地面碰撞
MakeInventoryFloatable(inst) --可以飘在水上
inst.AnimState:SetBank("myflowerhat")
inst.AnimState:SetBuild("myflowerhat")
inst.AnimState:PlayAnimation("idle")
inst.entity:SetPristine()
if not TheWorld.ismastersim then
return inst
end
inst:AddComponent("inspectable") --可检查
inst:AddComponent("inventoryitem") --物品组件
inst.components.inventoryitem.imagename = "myflowerhat"
inst.components.inventoryitem.atlasname = "images/inventoryimages/myflowerhat.xml"
MakeHauntableLaunch(inst) --可作祟
return inst
end
return Prefab("myflowerhat", fn, assets, prefabs)
to wear
Of course, it is still impossible to write like this. The core component that controls the wearability of items is equippable . Generally speaking, we only need to add this component, set the position of the equipment, and replace the texture when equipping/uninstalling.
If you observe carefully, you will find that the equipment item is actually a texture change directly after the start action.
local function onequiphat(inst, owner) --装备的函数
owner.AnimState:OverrideSymbol("swap_hat", "myflowerhat", "swap_hat")
owner.AnimState:Show("HAT")
owner.AnimState:Hide("HAIR_HAT")
owner.AnimState:Show("HAIR_NOHAT")
owner.AnimState:Show("HAIR")
owner.AnimState:Show("HEAD")
owner.AnimState:Hide("HEAD_HAT")
--若有耐久组件,则开始扣耐久
if inst.components.fueled ~= nil then
inst.components.fueled:StartConsuming()
end
end
local function onunequiphat(inst, owner) --解除帽子
owner.AnimState:ClearOverrideSymbol("swap_hat")
owner.AnimState:Hide("HAT")
owner.AnimState:Hide("HAIR_HAT")
owner.AnimState:Show("HAIR_NOHAT")
owner.AnimState:Show("HAIR")
if owner:HasTag("player") then
owner.AnimState:Show("HEAD")
owner.AnimState:Hide("HEAD_HAT")
end
--若有耐久组件,则停止扣耐久
if inst.components.fueled ~= nil then
inst.components.fueled:StopConsuming()
end
end
local function fn()
...
if not TheWorld.ismastersim then
return inst
end
...
inst:AddComponent("equippable") --装备组件
inst.components.equippable.equipslot = EQUIPSLOTS.HEAD --装在头上
inst.components.equippable:SetOnEquip(onequiphat) --装备
inst.components.equippable:SetOnUnequip(onunequiphat) --解除装备
end
in
-
owner.AnimState:OverrideSymbol("swap_hat", "myflowerhat", "swap_hat")
indicates that the image in the swap_hat (back) folder in the myflowerhat.sccl animation is used to replace the image in the swap_hat (front) in the owner.
Since the transparent image folder indicated by the first parameter cannot be decompressed, generally we only configure the last two parameters. -
owner.AnimState:Show("HAT")
displays a picture of a folder -
owner.AnimState:Hide("HAT")
hides the image of a folder -
owner.AnimState:ClearOverrideSymbol("swap_hat")
cancels the replacement of the image of a folder, that is, restores it back.
The above equipment and uninstall functions are basically fixed, if there are new functions, just add them later, and copy the previous ones directly.
tradeable
Of course this is just the basic equipping/unmounting, we can add tradable components so that it can be used for pigmen, rabbitmen, etc.
inst:AddComponent("tradable") --可交易,给猪人等
Rotten and Freezer Safe
Secondly, adding rot to the flower hat to make it durable is quite good. When the rot is over we replace it with a flower.
inst:AddComponent("perishable") --腐烂的
inst.components.perishable:SetPerishTime(TUNING.PERISH_FAST) --6天的腐烂时间
inst.components.perishable.onperishreplacement = "flower" --设置腐烂后的替代物
--inst.components.perishable:SetOnPerishFn(inst.Remove) --如果不要替代物,可换为这句,腐烂后直接销毁
inst.components.perishable:StartPerishing() --开始腐烂
Of course, it must be indicated on the client side that the degree of decay should be displayed, and that it can be stored in the refrigerator
...
inst:AddTag("show_spoilage") --加这个就有保鲜度动画
inst:AddTag("icebox_valid") --加这个就可以放进冰箱
inst.entity:SetPristine()
if not TheWorld.ismastersim then
return inst
end
total code
So, the total code is as follows
--prefabs/myflowerhat.lua
local assets = {
Asset("ANIM", "anim/myflowerhat.zip"), --动画文件
Asset("IMAGE", "images/inventoryimages/myflowerhat.tex"), --物品栏贴图
Asset("ATLAS", "images/inventoryimages/myflowerhat.xml")
}
local prefabs = {
}
local function onequiphat(inst, owner) --装备的函数
owner.AnimState:OverrideSymbol("swap_hat", "myflowerhat", "swap_hat")
owner.AnimState:Show("HAT")
owner.AnimState:Hide("HAIR_HAT")
owner.AnimState:Show("HAIR_NOHAT")
owner.AnimState:Show("HAIR")
owner.AnimState:Show("HEAD")
owner.AnimState:Hide("HEAD_HAT")
if inst.components.fueled ~= nil then
inst.components.fueled:StartConsuming()
end
end
local function onunequiphat(inst, owner) --解除帽子
owner.AnimState:ClearOverrideSymbol("swap_hat")
owner.AnimState:Hide("HAT")
owner.AnimState:Hide("HAIR_HAT")
owner.AnimState:Show("HAIR_NOHAT")
owner.AnimState:Show("HAIR")
if owner:HasTag("player") then
owner.AnimState:Show("HEAD")
owner.AnimState:Hide("HEAD_HAT")
end
if inst.components.fueled ~= nil then
inst.components.fueled:StopConsuming()
end
end
local function fn()
local inst = CreateEntity()
inst.entity:AddTransform()
inst.entity:AddAnimState()
inst.entity:AddNetwork()
MakeInventoryPhysics(inst) --与地面碰撞
MakeInventoryFloatable(inst) --可以飘在水上
inst.AnimState:SetBank("myflowerhat")
inst.AnimState:SetBuild("myflowerhat")
inst.AnimState:PlayAnimation("idle")
inst:AddTag("hat")
inst:AddTag("show_spoilage") --加这个就有保鲜度动画
inst:AddTag("icebox_valid") --加这个就可以放进冰箱
inst.entity:SetPristine()
if not TheWorld.ismastersim then
return inst
end
inst:AddComponent("inspectable") --可检查
inst:AddComponent("inventoryitem") --物品组件
inst.components.inventoryitem.imagename = "myflowerhat"
inst.components.inventoryitem.atlasname = "images/inventoryimages/myflowerhat.xml"
inst:AddComponent("equippable") --装备组件
inst.components.equippable.equipslot = EQUIPSLOTS.HEAD --装在头上
inst.components.equippable:SetOnEquip(onequiphat) --装备
inst.components.equippable:SetOnUnequip(onunequiphat) --解除装备
inst.components.equippable.dapperness = TUNING.DAPPERNESS_MED --设置回san值
inst:AddComponent("perishable") --腐烂的
inst.components.perishable:SetPerishTime(TUNING.PERISH_FAST) --6天的腐烂时间
inst.components.perishable.onperishreplacement = "flower" --设置腐烂后的替代物
--inst.components.perishable:SetOnPerishFn(inst.Remove) --如果不要替代物,可换为这句,腐烂后直接销毁
inst.components.perishable:StartPerishing() --开始腐烂
inst:AddComponent("tradable") --可交易,给猪人等
MakeHauntableLaunch(inst) --可作祟
return inst
end
return Prefab("myflowerhat", fn, assets, prefabs)
headless hat
difference
The difference between these two hats is mainly the call display of AnimState in the equipment function, that is, the Show and Hide parts. The uninstall function is the same.
--露头
local function onequiphat(inst, owner) --装备的函数
owner.AnimState:OverrideSymbol("swap_hat", "myflowerhat", "swap_hat")
owner.AnimState:Show("HAT")
owner.AnimState:Hide("HAIR_HAT")
owner.AnimState:Show("HAIR_NOHAT")
owner.AnimState:Show("HAIR")
owner.AnimState:Show("HEAD")
owner.AnimState:Hide("HEAD_HAT")
if inst.components.fueled ~= nil then
inst.components.fueled:StartConsuming()
end
end
--不露头
local function onequiphat(inst, owner) --装备的函数
owner.AnimState:OverrideSymbol("swap_hat", "mytophat", "swap_hat")
owner.AnimState:Show("HAT")
owner.AnimState:Show("HAIR_HAT")
owner.AnimState:Hide("HAIR_NOHAT")
owner.AnimState:Hide("HAIR")
if owner:HasTag("player") then
owner.AnimState:Hide("HEAD")
owner.AnimState:Show("HEAD_HAT")
end
if inst.components.fueled ~= nil then
inst.components.fueled:StartConsuming()
end
end
basic code
So the code for the most basic headless hat is as follows.
local assets = {
Asset("ANIM", "anim/mytophat.zip"), --动画文件
Asset("IMAGE", "images/inventoryimages/mytophat.tex"), --物品栏贴图
Asset("ATLAS", "images/inventoryimages/mytophat.xml")
}
local prefabs = {
}
local function onequiphat(inst, owner) --装备的函数
owner.AnimState:OverrideSymbol("swap_hat", "mytophat", "swap_hat")
owner.AnimState:Show("HAT")
owner.AnimState:Show("HAIR_HAT")
owner.AnimState:Hide("HAIR_NOHAT")
owner.AnimState:Hide("HAIR")
if owner:HasTag("player") then
owner.AnimState:Hide("HEAD")
owner.AnimState:Show("HEAD_HAT")
end
if inst.components.fueled ~= nil then
inst.components.fueled:StartConsuming()
end
end
local function onunequiphat(inst, owner) --解除帽子
owner.AnimState:ClearOverrideSymbol("swap_hat")
owner.AnimState:Hide("HAT")
owner.AnimState:Hide("HAIR_HAT")
owner.AnimState:Show("HAIR_NOHAT")
owner.AnimState:Show("HAIR")
if owner:HasTag("player") then
owner.AnimState:Show("HEAD")
owner.AnimState:Hide("HEAD_HAT")
end
if inst.components.fueled ~= nil then
inst.components.fueled:StopConsuming()
end
end
local function fn()
local inst = CreateEntity()
inst.entity:AddTransform()
inst.entity:AddAnimState()
inst.entity:AddNetwork()
MakeInventoryPhysics(inst)
MakeInventoryFloatable(inst) --可以飘在水上
inst.AnimState:SetBank("mytophat")
inst.AnimState:SetBuild("mytophat")
inst.AnimState:PlayAnimation("idle")
inst:AddTag("hat")
inst.entity:SetPristine()
if not TheWorld.ismastersim then
return inst
end
inst:AddComponent("inspectable") --可检查
inst:AddComponent("inventoryitem") --物品组件
inst.components.inventoryitem.imagename = "mytophat"
inst.components.inventoryitem.atlasname = "images/inventoryimages/mytophat.xml"
inst:AddComponent("equippable") --装备组件
inst.components.equippable.equipslot = EQUIPSLOTS.HEAD --装在头上
inst.components.equippable:SetOnEquip(onequiphat) --装备
inst.components.equippable:SetOnUnequip(onunequiphat) --解除装备
MakeHauntableLaunch(inst) --可作祟
return inst
end
return Prefab("mytophat", fn, assets, prefabs)
Endurance
To add durability, you need to use the fueled component to set the usage and durability, that is, the callback after the durability is over.
inst:AddComponent("fueled") --耐久
inst.components.fueled.fueltype = FUELTYPE.USAGE
inst.components.fueled:InitializeFuelLevel(TUNING.FEATHERHAT_PERISHTIME) --8天
inst.components.fueled:SetDepletedFn(inst.Remove)
Other functions
inst:AddComponent("waterproofer") --防水
inst.components.waterproofer:SetEffectiveness(TUNING.WATERPROOFNESS_SMALL)
inst:AddComponent("insulator") --绝缘
inst.components.insulator:SetInsulation(TUNING.INSULATION_MED)
inst:AddComponent("armor") --防具
inst.components.armor:InitCondition(TUNING.ARMOR_SLURTLEHAT, TUNING.ARMOR_SLURTLEHAT_ABSORPTION)
By the way, the above TUNING.XXX can be found in tuning.lua, usually a number
total code
--prefabs/mytophat.lua
local assets = {
Asset("ANIM", "anim/mytophat.zip"), --动画文件
Asset("IMAGE", "images/inventoryimages/mytophat.tex"), --物品栏贴图
Asset("ATLAS", "images/inventoryimages/mytophat.xml")
}
local prefabs = {
}
local function onequiphat(inst, owner) --装备的函数
owner.AnimState:OverrideSymbol("swap_hat", "mytophat", "swap_hat")
owner.AnimState:Show("HAT")
owner.AnimState:Show("HAIR_HAT")
owner.AnimState:Hide("HAIR_NOHAT")
owner.AnimState:Hide("HAIR")
if owner:HasTag("player") then
owner.AnimState:Hide("HEAD")
owner.AnimState:Show("HEAD_HAT")
end
if inst.components.fueled ~= nil then
inst.components.fueled:StartConsuming()
end
end
local function onunequiphat(inst, owner) --解除帽子
owner.AnimState:ClearOverrideSymbol("swap_hat")
owner.AnimState:Hide("HAT")
owner.AnimState:Hide("HAIR_HAT")
owner.AnimState:Show("HAIR_NOHAT")
owner.AnimState:Show("HAIR")
if owner:HasTag("player") then
owner.AnimState:Show("HEAD")
owner.AnimState:Hide("HEAD_HAT")
end
if inst.components.fueled ~= nil then
inst.components.fueled:StopConsuming()
end
end
local function fn()
local inst = CreateEntity()
inst.entity:AddTransform()
inst.entity:AddAnimState()
inst.entity:AddNetwork()
MakeInventoryPhysics(inst)
MakeInventoryFloatable(inst) --可以飘在水上
inst.AnimState:SetBank("mytophat")
inst.AnimState:SetBuild("mytophat")
inst.AnimState:PlayAnimation("idle")
inst:AddTag("hat")
inst.entity:SetPristine()
if not TheWorld.ismastersim then
return inst
end
inst:AddComponent("inspectable") --可检查
inst:AddComponent("inventoryitem") --物品组件
inst.components.inventoryitem.imagename = "mytophat"
inst.components.inventoryitem.atlasname = "images/inventoryimages/mytophat.xml"
inst:AddComponent("equippable") --装备组件
inst.components.equippable.equipslot = EQUIPSLOTS.HEAD --装在头上
inst.components.equippable:SetOnEquip(onequiphat) --装备
inst.components.equippable:SetOnUnequip(onunequiphat) --解除装备
inst.components.equippable.dapperness = TUNING.DAPPERNESS_LARGE --设置回san值
inst:AddComponent("fueled") --耐久
inst.components.fueled.fueltype = FUELTYPE.USAGE
inst.components.fueled:InitializeFuelLevel(TUNING.FEATHERHAT_PERISHTIME) --8天
inst.components.fueled:SetDepletedFn(inst.Remove)
inst:AddComponent("waterproofer") --防水
inst.components.waterproofer:SetEffectiveness(TUNING.WATERPROOFNESS_SMALL)
inst:AddComponent("insulator") --绝缘
inst.components.insulator:SetInsulation(TUNING.INSULATION_MED)
inst:AddComponent("armor") --防具
inst.components.armor:InitCondition(TUNING.ARMOR_SLURTLEHAT, TUNING.ARMOR_SLURTLEHAT_ABSORPTION)
inst:AddComponent("tradable") --可交易
MakeHauntableLaunch(inst) --可作祟
return inst
end
return Prefab("mytophat", fn, assets, prefabs)
official reference code
prefabs/hats.lua
Portal
→Famine Online Mod Development - Clothes (11)
←Famine Online Mod Development - Production Column (9)