Jump to content

Recommended Posts

I'm encountering a problem : i have some "debris" prefab i would like to make repairable.

I added the repairable component. But i don't have any "repair" option. However, i have the dialogue "i think i can fix it" when examining the item.

I'm probably missing something obvious but i tried a various things without success.

 

Related code :

local assets =
{
	Asset("ANIM", "anim/debris_plank.zip"),
	Asset("ANIM", "anim/debris_potted_fern.zip"),
}

local prefabs =
{
    "collapse_big",

    --loot:
    "boards",
    "foliage",
	"slurtle_shellpieces",
}

local fern = {"idle_01","idle_02"}

local planks_loot =
{
    "boards",
    "boards",
}
local potted_fern_loot =
{
    "foliage",
    "foliage",
    "foliage",
	"slurtle_shellpieces",
}


local function OnRepaired(inst, doer, repair_item)
		-- local pos = inst:GetPosition()
        -- local pottedfern = SpawnPrefab("pottedfern")
        -- pottedfern.Transform:SetPosition(pos:Get())
        -- SpawnPrefab("collapse_big").Transform:SetPosition(pos:Get())
        inst:Remove()
end

local function onhammered(inst, worker)
    if inst.components.burnable ~= nil and inst.components.burnable:IsBurning() then
        inst.components.burnable:Extinguish()
    end
    inst.components.lootdropper:DropLoot()
    local fx = SpawnPrefab("collapse_big")
    fx.Transform:SetPosition(inst.Transform:GetWorldPosition())
    fx:SetMaterial("wood")
    inst:Remove()
end

local function commonfn()
    local inst = CreateEntity()

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

    MakeObstaclePhysics(inst, 0.6)

    MakeSnowCoveredPristine(inst)

    inst:AddTag("structure")
    inst:AddTag("stone")
	
    inst.entity:SetPristine()

    if not TheWorld.ismastersim then
        return inst
    end

    inst:AddComponent("inspectable")
    inst:AddComponent("lootdropper")
    inst:AddComponent("workable")
    inst.components.workable:SetWorkAction(ACTIONS.HAMMER)
    inst.components.workable:SetWorkLeft(2)
    inst.components.workable:SetMaxWork(4)
    inst.components.workable:SetOnFinishCallback(onhammered)
	
	inst:AddComponent("repairable")
	inst.components.repairable.repairmaterial = MATERIALS.STONE
    inst.components.repairable.onrepaired = OnRepaired

    MakeMediumBurnable(inst, nil, nil, true)
    MakeLargePropagator(inst)


    MakeSnowCovered(inst)

    return inst
end


local function debris_plank()
    local inst = commonfn("debris_plank")

    inst.AnimState:SetBank("debris_plank")
    inst.AnimState:SetBuild("debris_plank")
    inst.AnimState:PlayAnimation("idle")
	
    if not TheWorld.ismastersim then
        return inst
    end

    inst.components.lootdropper:SetLoot(planks_loot)

    return inst
end

local function debris_potted_fern()
    local inst = commonfn("debris_potted_fern")

    inst.AnimState:SetBank("debris_potted_fern")
    inst.AnimState:SetBuild("debris_potted_fern")
    inst.AnimState:PlayAnimation(fern[math.random(#fern)])
	
    if not TheWorld.ismastersim then
        return inst
    end

    inst.components.lootdropper:SetLoot(potted_fern_loot)

    return inst
end


return	Prefab("debris_plank", debris_plank, assets, prefabs),
		Prefab("debris_potted_fern", debris_potted_fern, assets, prefabs)

Screenshots of the problem :

debris01.png.10515a29ddc9f75d6bcb0dd33cc22deb.pngdebris02.png.dfc65b52c928e33fe1429c528c0e5d51.pngdebris03.png.884a82d96a86bf4868bc1498cad6c5f4.png

 

.zip of the mod :

Debris.zip

 

Note : at the moment, the repairable function is shared, and the effect is very basic (for testing purpose). My goal is to make various items repairable in something specific (like a chest for the plank and a potted fern for the broken potted fern), and adding various debris working on the same principle.

 

But since i'm stuck with the same problem i would really like to make this working first.

The error must be something i missed, but i don't see what. I looked at the different prefabs using the repairable component and don't see why mine doesn't have the option. If someone has a clue, it will be welcome :)

 

Also, what i would like is a way to tell the game "if the prefab is "debris_plank" then the repairable item is "treasure chest"" and this for each item without having ton of "if elseif elseif" for each prefab. I know you can use tables for this, i just don't know how.

Thanks in advance for any help.

1 hour ago, Lumina said:

I'm encountering a problem : i have some "debris" prefab i would like to make repairable.

The repairer component has a super-weird implementation. So...

The first strange thing: actioncomponents.lua (this collects all valid actions at current frame):

for k, v in pairs(MATERIALS) do
	if target:HasTag("repairable_"..v) then
		if (inst:HasTag("work_"..v) and target:HasTag("workrepairable"))
			or (inst:HasTag("health_"..v) and target.replica.health ~= nil and not target.replica.health:IsFull())
			or (inst:HasTag("freshen_"..v) and (target:HasTag("fresh") or target:HasTag("stale") or target:HasTag("spoiled"))) 
		then
			table.insert(actions, ACTIONS.REPAIR)
		end
		return
	end
end

inst is an item you use as material and target is a broken thing you want to repair.

Your items doesn't have a health component and they aren't perishable, so you need to adapt it for the first condition:

  1. You have the "workrepairable" tag from the workable component;
  2. Material must have the "work_stone" tag. This is a second strange thing — it doesn't.

Look at the repairer component code:

local function onrepairvalue(self)
    if self.repairmaterial ~= nil then
        onremovematerial(self, self.repairmaterial)
        if self.workrepairvalue > 0 then
            self.inst:AddTag("work_"..self.repairmaterial)
        end
        if self.healthrepairvalue > 0 or self.healthrepairpercent > 0 then
            self.inst:AddTag("health_"..self.repairmaterial)
        end
        if self.perishrepairpercent > 0 then
            self.inst:AddTag("freshen_"..self.repairmaterial)
        end
    end
end

It will add the "work_stone" tag only if repairer.workrepairvalue will be setted for a material-item prefab (stone materials have only healthrepeirvalue).

So you have 3 ways to fix your issue:

  • Set the workrepairvalue for all materials you want to use (good, but maybe It will make some thing repairable with incorrect materials);
  • Push the tag to all materials (unsafe I think);
  • Add the health component and tune the health value (health without combat? not sure).

May be there is a way to fix this weird component with debug-upvalue, but it's a bit complicated.

Edited by ksaab

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