Jump to content

Recommended Posts

I am making a food, that when eaten, reduces fire damage taken.

liquor =
	{	
        test = function(cooker, names, tags) return tags.frozen and (names.pepper or names.pepper_cooked) == 2 and (names.tomato or names.tomato_cooked) end,
        priority = 30,
        foodtype = FOODTYPE.VEGGIE,
        health = -TUNING.HEALING_SMALL,
        hunger = TUNING.CALORIES_MED,
        sanity = TUNING.SANITY_SMALL,
        perishtime = TUNING.PERISH_SLOW,
        cooktime = 0.75,
        potlevel = "low",
        tags = { "masterfood" },
        prefabs = { "buff_fireimmunity" },
        oneatenfn = function(inst, eater)
            if eater.components.debuffable ~= nil and eater.components.debuffable:IsEnabled() and
                not (eater.components.health ~= nil and eater.components.health:IsDead()) and
                not eater:HasTag("playerghost") then
                eater.components.debuffable:AddDebuff("buff_fireimmunity", "buff_fireimmunity")
            end
       	end,
    --floater = {nil, 0.1, 0.7},
	},

This is my code for the crockpot recipe.

 

In modmain:

local function fire_attach(inst, target)
    if target.components.health ~= nil then
        target.components.health.fire_damage_scale = 0.1
    end
end

local function fire_detach(inst, target)
    if target.components.health ~= nil then
        target.components.health.fire_damage_scale = 1
    end
end

local function create_fire_buff(inst)
    MakeBuff("fireimmunity", fire_attach, nil, fire_detach, TUNING.BUFF_MOISTUREIMMUNITY_DURATION, 2)
end

AddPrefabPostInit("foodbuffs", create_fire_buff)

When I cook the food, it has no texture, and when I harvest the crockpot, it disappears.

Edited by decduck3
Link to comment
https://forums.kleientertainment.com/forums/topic/120775-custom-food-buff/
Share on other sites

I got it to work. Here is my code for anyone that needs it:

liquor.lua

local assets =
{
    Asset("ANIM", "anim/liquor.zip"),
	Asset("IMAGE", "images/inventoryimages/liquor.tex"),
	Asset("ATLAS", "images/inventoryimages/liquor.xml"),
}

local prefabs =
{
    "buff_fireimmunity",
}

local function fn()
    local inst = CreateEntity()

    inst.entity:AddTransform()
    inst.entity:AddAnimState()
    inst.entity:AddNetwork()

    MakeInventoryPhysics(inst)

    inst.AnimState:SetBank("liquor")
    inst.AnimState:SetBuild("liquor")
    inst.AnimState:PlayAnimation("idle")
	
    inst.entity:SetPristine()

    if not TheWorld.ismastersim then
        return inst
    end

	inst:AddComponent("stackable")
	inst.components.stackable.maxsize = TUNING.STACK_SIZE_MEDITEM

	inst:AddComponent("tradable")

    inst:AddComponent("inspectable")
    
    inst:AddComponent("edible")
    inst.components.edible.healthvalue = -TUNING.HEALING_SMALL
    inst.components.edible.hungervalue = TUNING.CALORIES_LARGE
    inst.components.edible.sanityvalue = TUNING.SANITY_MED
    inst.components.edible.foodtype = FOODTYPE.VEGGIE
    inst.components.edible.oneaten = function(inst, eater)
        if eater.components.debuffable ~= nil and eater.components.debuffable:IsEnabled() and
            not (eater.components.health ~= nil and eater.components.health:IsDead()) and
            not eater:HasTag("playerghost") then
            eater.components.debuffable:AddDebuff("buff_fireimmunity", "buff_fireimmunity")
        end
    end

    inst:AddComponent("perishable")
    inst.components.perishable.perishtime = TUNING.PERISH_SUPERSLOW
    inst.components.perishable.onperishreplacement = "spoiled_food"

	inst:AddComponent("inventoryitem")
	inst.components.inventoryitem.atlasname = "images/inventoryimages/liquor.xml"

	MakeHauntableLaunchAndPerish(inst)
    MakeSmallPropagator(inst)
    return inst
end

return Prefab("liquor", fn, assets, prefabs)

foodbuffs.lua

-------------------------------------------------------------------------
---------------------- Attach and dettach functions ---------------------
-------------------------------------------------------------------------

local function playerabsorption_attach(inst, target)
    if target.components.health ~= nil then
        target.components.health.externalabsorbmodifiers:SetModifier(inst, TUNING.BUFF_PLAYERABSORPTION_MODIFIER)
    end
end

local function playerabsorption_detach(inst, target)
    if target.components.health ~= nil then
        target.components.health.externalabsorbmodifiers:RemoveModifier(inst)
    end
end

local function attack_attach(inst, target)
    if target.components.combat ~= nil then
        target.components.combat.externaldamagemultipliers:SetModifier(inst, TUNING.BUFF_ATTACK_MULTIPLIER)
    end
end

local function attack_detach(inst, target)
    if target.components.combat ~= nil then
        target.components.combat.externaldamagemultipliers:RemoveModifier(inst)
    end
end

local function work_attach(inst, target)
    if target.components.workmultiplier ~= nil then
        target.components.workmultiplier:AddMultiplier(ACTIONS.CHOP,   TUNING.BUFF_WORKEFFECTIVENESS_MODIFIER, inst)
        target.components.workmultiplier:AddMultiplier(ACTIONS.MINE,   TUNING.BUFF_WORKEFFECTIVENESS_MODIFIER, inst)
        target.components.workmultiplier:AddMultiplier(ACTIONS.HAMMER, TUNING.BUFF_WORKEFFECTIVENESS_MODIFIER, inst)
    end
end

local function work_detach(inst, target)
    if target.components.workmultiplier ~= nil then
        target.components.workmultiplier:RemoveMultiplier(ACTIONS.CHOP,   inst)
        target.components.workmultiplier:RemoveMultiplier(ACTIONS.MINE,   inst)
        target.components.workmultiplier:RemoveMultiplier(ACTIONS.HAMMER, inst)
    end
end

local function moisture_attach(inst, target)
    if target.components.moisture ~= nil then
        target.components.moisture:ForceDry(true, inst)
        target.components.moisture:SetWaterproofInventory(true)
    end
end

local function moisture_detach(inst, target)
    if target.components.moisture ~= nil then
        target.components.moisture:ForceDry(false, inst)
        target.components.moisture:SetWaterproofInventory(false)
    end
end

local function electric_attach(inst, target)
    if target.components.electricattacks == nil then
        target:AddComponent("electricattacks")
    end
    target.components.electricattacks:AddSource(inst)
    if inst._onattackother == nil then
        inst._onattackother = function(attacker, data)
            if data.weapon ~= nil then
                if data.projectile == nil then
                    --in combat, this is when we're just launching a projectile, so don't do FX yet
                    if data.weapon.components.projectile ~= nil then
                        return
                    elseif data.weapon.components.complexprojectile ~= nil then
                        return
                    elseif data.weapon.components.weapon:CanRangedAttack() then
                        return
                    end
                end
                if data.weapon.components.weapon ~= nil and data.weapon.components.weapon.stimuli == "electric" then
                    --weapon already has electric stimuli, so probably does its own FX
                    return
                end
            end
            if data.target ~= nil and data.target:IsValid() and attacker:IsValid() then
                SpawnPrefab("electrichitsparks"):AlignToTarget(data.target, data.projectile ~= nil and data.projectile:IsValid() and data.projectile or attacker, true)
            end
        end
        inst:ListenForEvent("onattackother", inst._onattackother, target)
    end
    SpawnPrefab("electricchargedfx"):SetTarget(target)
end

local function electric_extend(inst, target)
    SpawnPrefab("electricchargedfx"):SetTarget(target)
end

local function electric_detach(inst, target)
    if target.components.electricattacks ~= nil then
        target.components.electricattacks:RemoveSource(inst)
    end
    if inst._onattackother ~= nil then
        inst:RemoveEventCallback("onattackother", inst._onattackother, target)
        inst._onattackother = nil
    end
end

local function fire_attach(inst, target)
    if target.components.health ~= nil then
        target.components.health.fire_damage_scale = 0
    end
end

local function fire_detach(inst, target)
    if target.components.health ~= nil then
        target.components.health.fire_damage_scale = 1
    end
end

-------------------------------------------------------------------------
----------------------- Prefab building functions -----------------------
-------------------------------------------------------------------------

local function OnTimerDone(inst, data)
    if data.name == "buffover" then
        inst.components.debuff:Stop()
    end
end

local function MakeBuff(name, onattachedfn, onextendedfn, ondetachedfn, duration, priority, prefabs)
    local function OnAttached(inst, target)
        inst.entity:SetParent(target.entity)
        inst.Transform:SetPosition(0, 0, 0) --in case of loading
        inst:ListenForEvent("death", function()
            inst.components.debuff:Stop()
        end, target)

        target:PushEvent("foodbuffattached", { buff = "ANNOUNCE_ATTACH_BUFF_"..string.upper(name), priority = priority })
        if onattachedfn ~= nil then
            onattachedfn(inst, target)
        end
    end

    local function OnExtended(inst, target)
        inst.components.timer:StopTimer("buffover")
        inst.components.timer:StartTimer("buffover", duration)

        target:PushEvent("foodbuffattached", { buff = "ANNOUNCE_ATTACH_BUFF_"..string.upper(name), priority = priority })
        if onextendedfn ~= nil then
            onextendedfn(inst, target)
        end
    end

    local function OnDetached(inst, target)
        if ondetachedfn ~= nil then
            ondetachedfn(inst, target)
        end

        target:PushEvent("foodbuffdetached", { buff = "ANNOUNCE_DETACH_BUFF_"..string.upper(name), priority = priority })
        inst:Remove()
    end

    local function fn()
        local inst = CreateEntity()

        if not TheWorld.ismastersim then
            --Not meant for client!
            inst:DoTaskInTime(0, inst.Remove)
            return inst
        end

        inst.entity:AddTransform()

        --[[Non-networked entity]]
        --inst.entity:SetCanSleep(false)
        inst.entity:Hide()
        inst.persists = false

        inst:AddTag("CLASSIFIED")

        inst:AddComponent("debuff")
        inst.components.debuff:SetAttachedFn(OnAttached)
        inst.components.debuff:SetDetachedFn(OnDetached)
        inst.components.debuff:SetExtendedFn(OnExtended)
        inst.components.debuff.keepondespawn = true

        inst:AddComponent("timer")
        inst.components.timer:StartTimer("buffover", duration)
        inst:ListenForEvent("timerdone", OnTimerDone)

        return inst
    end

    return Prefab("buff_"..name, fn, nil, prefabs)
end

return MakeBuff("attack", attack_attach, nil, attack_detach, TUNING.BUFF_ATTACK_DURATION, 1),
       MakeBuff("playerabsorption", playerabsorption_attach, nil, playerabsorption_detach, TUNING.BUFF_PLAYERABSORPTION_DURATION, 1),
       MakeBuff("workeffectiveness", work_attach, nil, work_detach, TUNING.BUFF_WORKEFFECTIVENESS_DURATION, 1),
       MakeBuff("moistureimmunity", moisture_attach, nil, moisture_detach, TUNING.BUFF_MOISTUREIMMUNITY_DURATION, 2),
       MakeBuff("electricattack", electric_attach, electric_extend, electric_detach, TUNING.BUFF_ELECTRICATTACK_DURATION, 2, { "electrichitsparks", "electricchargedfx" }),
       MakeBuff("fireimmunity", fire_attach, nil, fire_detach, TUNING.BUFF_MOISTUREIMMUNITY_DURATION, 2)

 

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
  • Create New...