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

insert image description here

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.

  1. The material should be placed in the swap_hat folder
    insert image description here

  2. 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.
    insert image description here

  3. 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.

insert image description here

insert image description here

  1. 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里右下角的第二层名字

insert image description here

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)

Guess you like

Origin blog.csdn.net/weixin_46068322/article/details/127701854