Jump to content

Recommended Posts

Hi,

at the moment I'm improving the "Multifunctional Carpet" mod https://steamcommunity.com/sharedfiles/filedetails/?id=506553597
Therefore I implemented, that the bonusses only work, if near to some base buildings: http://forums.kleientertainment.com/topic/68964-check-for-structure-within-range-and-add-light/

I would like to add components to the turf-items, so the "ShowMe" Mod will show the values of the Carpet Mod in tooltip.

I looked in the api-examples found in this forum and found:

Quote

-----------------------------------
-- Prefab mod example
--
--  AddPrefabPostInit("prefabname", initfn)
--        Use this to modify a prefab by adding, removing, or editing its properties
--        and components.
-----------------------------------

local function BetterCarrotInit(prefab)
    prefab.components.edible.hungervalue = 200 -- carrots are the best food ever!!
end
AddPrefabPostInit("carrot", BetterCarrotInit)

But for some reason this does not work =/ the function is not called.
I have the following written in my modmain.lua file, the mod is a server_only mod:

Quote

local function TurfBoostDesc(prefab)
    print("HELLO")
    if prefab=="turf_woodfloor" then
        prefab.components.insulator.insulation = GetModConfigData("insulation_time_wooden")   -- insulation
        prefab.components.dapperness.dapperness = GLOBAL.TUNING.DAPPERNESS_MED                 -- sanity
        prefab.components.waterproofer.effectiveness = 1-GetModConfigData("rain_reduction_wooden") -- rainproof
    end

end
AddPrefabPostInit("turf_woodfloor", TurfBoostDesc)

But there is no "HELLO" in the client_log. So this means that this function is never called. Why?
And do you think adding this components will work? Or might there be an table error, because e.g prefab.components.insulator does not exist ?

 

edit:
I'm assuming that the function should be called right at the start of the game. Isn't it? I also tried to set all_clients_require_mod= true, but did not change anything =/

Edited by Serpens

Okay, I found out that the prefab function is only called, after the item as beend initialized (so that's why it is called "PostInit" :D)

Now I have the error
attempt to index field 'insulator' (a nil value)
like I expected... but what to do now? how can I give the turf an insulator?

And what about the other bonusses?
 

Tried AddComponent("insulator") ? :p

 

Every prefab has "fn" function in the end of it, you may find that if you surf "prefabs/" folder. That's where prefabs get their components and that is where those components get modified.

This "fn" function is actually something that initializes the prefab. Your AddPrefabPostInit code runs right after "fn" is. If you need an example on how to add some specific component, you're better off looking at at example aka some component that has this component. Just inst:AddComponent("{component_name}") sometimes is not enough, as components may require external event handlers/prop field values.

Also note that if you want to write a solid code. Don't just blindly add component, first check that inst.components.{component_name} is nil, because some other mod may have already added this component.

Edited by IvanX

the addcomponent example is:

Quote

-----------------------------------
-- Component mod example
--
--  AddComponentPostInit("componentname", initfn)
--        Use this to modify a component's properties or behavior
-----------------------------------

local function DoubleHealthDeltaInit(component)
    local original_dodelta = component.DoDelta
    component.DoDelta = function(self, amount, overtime, cause, ignore_invincible)
        local double_amount = amount*2
        original_dodelta(self, double_amount, overtime, cause, ignore_invincible)
    end
end
AddComponentPostInit("health", DoubleHealthDeltaInit)

ok... I searched for " amount, overtime, cause, ignore_invincible " in all lua files of the game and I found out, that I can search the scripts/components folder to find out how a specific component works :)

But... I don't think this is the way it should be down. It looks like the AddComponent is made for adding general new rules for a component. Not for adding a component to an item.

 

In scripts/components/insulation.lua I see that the insulator is a class with some functions:

Quote

local Insulator = Class(function(self, inst)
    self.inst = inst
    self.insulation = 0
    self.type = SEASONS.WINTER
end)

My first idea was to write:

Quote

prefab.components["insulator"] = {}
prefab.components.insulator["insulation"] = GetModConfigData("insulation_time_wooden")
prefab.components.insulator["type"] =  GLOBAL.SEASONS.WINTER

but of course with that way the functions like "GetInsulation()" were missing.

So I need a way to assign the whole class Insulator... sth like:

Quote

prefab.components["insulator"] = GLOBAL.Insulator()
prefab.components.insulator:SetInsulation(GetModConfigData("insulation_time_wooden"))

but that doesn't work either, cause "variable 'Insulator' is not declared" or without the GLOBAL "attempt to call global 'Insulator' (a nil value)" ....
So how to assign the class?

 

 

edit:

I also tried:

Quote

prefab.components["insulator"] = Class(Insulator)

prefab.components["insulator"] = GLOBAL.Class(Insulator)

this did not throw an error, but prefab.components.insulator:SetInsulation(v) still did not work (cause SetInsulation is nil) =/

Edited by Serpens

No, it's literally prefab:AddComponent("insulator") :p I never said anything about AddComponentPostInit

AddComponentPostInit is as said above used to modify component's prototype, the class itself

AddComponent on the other hand is used to give prefab an instance of insulator class, thus making prefab.components.insulator available and initialized via component constructor. You may then modify prefab.components.insulator props and functions to change a single instance of the component.

 

I believe you're thinking you can Add Component to the Great Class of The Prefab, but that's not how it works. In reality your Prefab is just a class, and you add components separately as instances after the prefab instance is created. Thus you use AddPrefabPostInit -- which should be actually called ModifyPrefabInstancePostInit' And inside of that function create your component instance and modify them.

local function TurfBoostDesc(prefab)
   if not prefab.components.insulator then  prefab:AddComponent("insulator")  end
   prefab.components.insulator.insulation = GetModConfigData("insulation_time_wooden")   -- insulation

   if not prefab.components.dapperness then  prefab:AddComponent("dapperness")  end
   prefab.components.dapperness.dapperness = GLOBAL.TUNING.DAPPERNESS_MED          -- sanity

   if not prefab.components.waterproofer then  prefab:AddComponent("waterproofer")  end
   prefab.components.waterproofer.effectiveness = 1-GetModConfigData("rain_reduction_wooden") -- rainproof
end
AddPrefabPostInit("turf_woodfloor", TurfBoostDesc)

 

Edited by IvanX

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