Bosoca

[Help] Saving component data?

Recommended Posts

Bosoca    1

I have created a component that allows me to poison a target temporarily, the function for poisoning the target is on the component.
So that whenever I give this component to a weapon, I'm able to tip it with poison.

However when I reload my game, it doesn't save the component.

This is the code I have located at the bottom of the code, I have it to set self.mod_data to nil on default but I'm unsure of what I'm supposed to do after that, I tried to set the mod_data variable to the prefab of the weapon it's set on

function poison_trait:OnSave()
    return self.mod_data
end

function poison_trait:OnLoad(data)
    if data and data.mod_data ~= nil then
        self.mod_data = data.mod_data
    end
end

 

Share this post


Link to post
Share on other sites
Monti18    337

The reason this is not working is because you save the data in a wrong way.

Have a look at the save function of the component fueled:

function Fueled:OnSave()
    if self.currentfuel ~= self.maxfuel then
        return {fuel = self.currentfuel}
    end
end

It returns a table, which you are not doing. 

You could do it like this:

function poison_trait:OnSave()
    local data = {}
    data.mod_data = self.mod_data
    return data
end

This is the same as

function poison_trait:OnSave()
    return {mod_data = self.mod_data}
end

If you change your onsave function to one of these, it should work.

  • Like 1

Share this post


Link to post
Share on other sites
Bosoca    1
1 hour ago, Monti18 said:

The reason this is not working is because you save the data in a wrong way.

Have a look at the save function of the component fueled:


function Fueled:OnSave()
    if self.currentfuel ~= self.maxfuel then
        return {fuel = self.currentfuel}
    end
end

It returns a table, which you are not doing. 

You could do it like this:


function poison_trait:OnSave()
    local data = {}
    data.mod_data = self.mod_data
    return data
end

This is the same as


function poison_trait:OnSave()
    return {mod_data = self.mod_data}
end

If you change your onsave function to one of these, it should work.

Well I tried your saving method, Nothing has changed, the load function still does not run and the component vanishes from the item when reloading.

Share this post


Link to post
Share on other sites
Monti18    337

Ah ok, you add this component to a weapon during the game? Then your component will always disappear, as the game doesn't know that this weapon had it last game. All components are reapplied on load. I would add this component in a AddPrefabPostInit to the weapon if it's a base game weapon or directly add it to the weapon if it's your own and then run a function when you want it to be poisonous.

  • Like 1

Share this post


Link to post
Share on other sites
Bosoca    1
5 minutes ago, Monti18 said:

Ah ok, you add this component to a weapon during the game? Then your component will always disappear, as the game doesn't know that this weapon had it last game. All components are reapplied on load. I would add this component in a AddPrefabPostInit to the weapon if it's a base game weapon or directly add it to the weapon if it's your own and then run a function when you want it to be poisonous.

Would you mind giving me a bit of guidance on this?

So I need to add this component all weapons, because it can be applied to all weapons.
then save the data that toggles the poison via a function that activated the poison component.

Share this post


Link to post
Share on other sites
Monti18    337

You can add this to your modmain and change your_component to the name of your component. This will add the component to all prefabs that have the tag weapon. If some are missing or there are some you don't want there, you will need to change this check to your liking.

AddPrefabPostInitAny(function(inst)
    if not inst:HasTag("weapon") then 
      	return
    end
    if not GLOBAL.TheWorld.ismastersim then
		return
	end
    inst:AddComponent("your_component")
end

I don't know what your component looks like, so I will make a small example of what I mean:

local Your_Component = Class(function(self, inst)
    self.inst = inst
    self.poisonous = false
end)

function Your_Component:AddPoisonous()
  --your code to add the poisonous effect
  self.poisonous = true
end

function Your_Component:OnSave()
  if self.poisonous == true then
    return {poisonous = self.poisonous}
  end
end

function Your_Component:OnLoad()
  if data and data.poisonous == true then 
	self:AddPoisonous()
end

return Your_Component

If you want a weapon to have the poisonous effect, you run AddPoisonous(). Then, if the weapon is poisonous, this is saved and when the game is loaded, it checks if it was poisonous and if yes, it applies the poisonous buff.

If you have more questions let me know!

  • Like 1

Share this post


Link to post
Share on other sites
Bosoca    1
10 minutes ago, Monti18 said:

You can add this to your modmain and change your_component to the name of your component. This will add the component to all prefabs that have the tag weapon. If some are missing or there are some you don't want there, you will need to change this check to your liking.


AddPrefabPostInitAny(function(inst)
    if not inst:HasTag("weapon") then 
      	return
    end
    if not GLOBAL.TheWorld.ismastersim then
		return
	end
    inst:AddComponent("your_component")
end

I don't know what your component looks like, so I will make a small example of what I mean:


local Your_Component = Class(function(self, inst)
    self.inst = inst
    self.poisonous = false
end)

function Your_Component:AddPoisonous()
  --your code to add the poisonous effect
  self.poisonous = true
end

function Your_Component:OnSave()
  if self.poisonous == true then
    return {poisonous = self.poisonous}
  end
end

function Your_Component:OnLoad()
  if data and data.poisonous == true then 
	self:AddPoisonous()
end

return Your_Component

If you want a weapon to have the poisonous effect, you run AddPoisonous(). Then, if the weapon is poisonous, this is saved and when the game is loaded, it checks if it was poisonous and if yes, it applies the poisonous buff.

If you have more questions let me know!

So I have these 2 lines of code in the component class function where self.poisonous exists.

    local owner = inst.components.inventoryitem.owner
    owner:ListenForEvent("onattackother", function(inst, data) self:OnAttack(inst, data) end)

Is this ineffective to have there, I mean it works but I haven't tested with multiple players yet.

 

Share this post


Link to post
Share on other sites
Bosoca    1

ok after about 2 hours of reconfiguring everything to be primarily in the modmain, it now works :DD thank you Monti

  • Like 1

Share this post


Link to post
Share on other sites

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