Jump to content

Recommended Posts

So I'm working on giving a container to a critter and it doesn't index the wdiget, besides that the critter works but the container part is broken. Could someone point me out to where I went wrong?

--modmain code

local containers = require "containers"

local Vector3 = G.Vector3
local params = {}

params.hellpuppy3storage =
{
    widget =
    {
        slotpos =
        {
            Vector3(0, 64 + 32 + 8 + 4, 0),
            Vector3(0, 32 + 4, 0),
            Vector3(0, -(32 + 4), 0),
            Vector3(0, -(64 + 32 + 8 + 4), 0),
        },
        animbank = "ui_lamp_1x4",
        animbuild = "ui_lamp_1x4",
        pos = Vector3(0, 200, 0),
        side_align_tip = 160,
    },
    type = "chest",
}

local containers = G.require("containers")

containers.MAXITEMSLOTS = math.max(containers.MAXITEMSLOTS, params.hellpuppy3storage.widget.slotpos ~= nil and #params.hellpuppy3storage.widget.slotpos or 0)

local old_wsetup = containers.widgetsetup

function containers.widgetsetup(container, prefab, data)
    if params[prefab or container.inst.prefab] and not data then
        data = params[prefab or container.inst.prefab]
    end
    old_wsetup(container, prefab, data)
end
 

hellpuppy3.lua

This seems like an old way to do it? I've had success with just this :

local containers = require "containers"
local Vector3 = G.Vector3

local hellpuppy3storage =
{
    widget =
    {
        slotpos =
        {
            Vector3(0, 64 + 32 + 8 + 4, 0),
            Vector3(0, 32 + 4, 0),
            Vector3(0, -(32 + 4), 0),
            Vector3(0, -(64 + 32 + 8 + 4), 0),
        },
        animbank = "ui_lamp_1x4",
        animbuild = "ui_lamp_1x4",
        pos = Vector3(0, 200, 0),
        side_align_tip = 160,
    },
    type = "chest",
} 
containers.params.hellpuppy3storage = hellpuppy3storage

I am a little confused as to what hooking into the widgetsetup function would do here, but I could be missing something there.

Also, not to nitpick part of your code that you weren't asking about but, you shouldn't be trying to replace a function of a component like you are in hellpuppy3.lua for the GetAllItems function as this could break other things that use said function. The GetAllItems function returns a table of the all items anyway, you can just use that table to separate items in stacks in a new function. However, beyond that the current way you're doing that is just making copies of the entire item (not separated) into the table, so when you inevitably do item:remove() its going to remove that plus the entire stack, leaving data pointers in the table that now lead to no where that you are still looping through which can cause a crash. Sorry if this is overbearing it was just something I noticed that could cause further issues even with the above code.

 

47 minutes ago, Merkyrrie said:

This seems like an old way to do it? I've had success with just this :

local containers = require "containers"
local Vector3 = G.Vector3

local hellpuppy3storage =
{
    widget =
    {
        slotpos =
        {
            Vector3(0, 64 + 32 + 8 + 4, 0),
            Vector3(0, 32 + 4, 0),
            Vector3(0, -(32 + 4), 0),
            Vector3(0, -(64 + 32 + 8 + 4), 0),
        },
        animbank = "ui_lamp_1x4",
        animbuild = "ui_lamp_1x4",
        pos = Vector3(0, 200, 0),
        side_align_tip = 160,
    },
    type = "chest",
} 
containers.params.hellpuppy3storage = hellpuppy3storage

I am a little confused as to what hooking into the widgetsetup function would do here, but I could be missing something there.

Also, not to nitpick part of your code that you weren't asking about but, you shouldn't be trying to replace a function of a component like you are in hellpuppy3.lua for the GetAllItems function as this could break other things that use said function. The GetAllItems function returns a table of the all items anyway, you can just use that table to separate items in stacks in a new function. However, beyond that the current way you're doing that is just making copies of the entire item (not separated) into the table, so when you inevitably do item:remove() its going to remove that plus the entire stack, leaving data pointers in the table that now lead to no where that you are still looping through which can cause a crash. Sorry if this is overbearing it was just something I noticed that could cause further issues even with the above code.

Hey, no worries, this is my first time trying to make something a container. As for the function I'm just using that as a way to get the critter to eat food that it might be carrying at that moment, but I'll get rid of it. I can send the modmain if you want but it keeps giving me the 'attempt to index local widget' a nil value, with the new code you sent me.

1 hour ago, Meepenator said:

 

Hey, no worries, this is my first time trying to make something a container. As for the function I'm just using that as a way to get the critter to eat food that it might be carrying at that moment, but I'll get rid of it. I can send the modmain if you want but it keeps giving me the 'attempt to index local widget' a nil value, with the new code you sent me.

You could probably use the eater component to make it eat food out of its inventory periodically, depending on how often you want that to occur. Though eater wouldn't absolutely be necessary to get that effect.

And yeah you can send modmain so I can see what the issue might be, maybe the relevant snippet from the crash log too. My guess is there's a mismatch between the name in modmain and the name in hellpuppy3.lua. The 'inst.components.container:WidgetSetup()' should have the same thing as 'containers.params' (in this case, 'hellpuppy3storage')

  • Like 1
53 minutes ago, Merkyrrie said:

You could probably use the eater component to make it eat food out of its inventory periodically, depending on how often you want that to occur. Though eater wouldn't absolutely be necessary to get that effect.

And yeah you can send modmain so I can see what the issue might be, maybe the relevant snippet from the crash log too. My guess is there's a mismatch between the name in modmain and the name in hellpuppy3.lua. The 'inst.components.container:WidgetSetup()' should have the same thing as 'containers.params' (in this case, 'hellpuppy3storage')

Ok, I'll look into the eater component then, also ty for checking it out!

Screenshot_515.png

modmain.lua

47 minutes ago, Meepenator said:

Ok, I'll look into the eater component then, also ty for checking it out!

Screenshot_515.png

modmain.lua 19.78 kB · 1 download

I was struggling a bit to fully replicate this issue myself to find the solution but I apparently lucked myself around whatever weird coding issue this is by naming my test container widget the same as my prefab, which somehow bypasses whatever is going on with the replica container component. I did not realize how much some of my tests were holding on by a literal string.

There's two ways to fix this, one is to change all 'hellpuppy3storage' in modmain and hellpuppy3.lua to 'hellpuppy3' and theoretically that should be good (its also the convention all vanilla containers seem to use.) But in case that doesn't work, or to just be more thorough in making sure it doesn't break..

You have two 'if not TheWorld.ismastersim' in your prefab file, take the second one and paste it over the first one while removing the original second one so it should look like this

        inst.entity:SetPristine()

        if not TheWorld.ismastersim then
  			inst:DoTaskInTime(0, function()
				inst.replica.container:WidgetSetup("hellpuppy3")
			end)
            return inst
        end

		inst.favoritefood = data.favoritefood

        inst.GetPeepChance = GetPeepChance
        inst.IsAffectionate = IsAffectionate
        inst.IsSuperCute = IsSuperCute
        inst.IsPlayful = IsPlayful
        
		inst.playmatetags = {"critter"}
		if data ~= nil and data.playmatetags ~= nil then
			inst.playmatetags = JoinArrays(inst.playmatetags, data.playmatetags)
		end
	
        inst:AddComponent("inspectable")

        inst:AddComponent("follower")
        inst.components.follower:KeepLeaderOnAttacked()
        inst.components.follower.keepdeadleader = true

        inst:AddComponent("knownlocations")

        inst:AddComponent("sleeper")
        inst.components.sleeper:SetResistance(3)
        inst.components.sleeper.testperiod = GetRandomWithVariance(6, 2)
        inst.components.sleeper:SetSleepTest(ShouldSleep)
        inst.components.sleeper:SetWakeTest(ShouldWakeUp)

		inst:AddComponent("container")
		inst.components.container:WidgetSetup("hellpuppy3")
		inst.components.container.skipclosesnd = true
		inst.components.container.skipopensnd = true
		inst.components.container.onopenfn = function(inst)
        inst.SoundEmitter:PlaySound("dontstarve/wilson/chest_open")
		end
  • Like 1
5 hours ago, Merkyrrie said:

I was struggling a bit to fully replicate this issue myself to find the solution but I apparently lucked myself around whatever weird coding issue this is by naming my test container widget the same as my prefab, which somehow bypasses whatever is going on with the replica container component. I did not realize how much some of my tests were holding on by a literal string.

There's two ways to fix this, one is to change all 'hellpuppy3storage' in modmain and hellpuppy3.lua to 'hellpuppy3' and theoretically that should be good (its also the convention all vanilla containers seem to use.) But in case that doesn't work, or to just be more thorough in making sure it doesn't break..

You have two 'if not TheWorld.ismastersim' in your prefab file, take the second one and paste it over the first one while removing the original second one so it should look like this

        inst.entity:SetPristine()

        if not TheWorld.ismastersim then
  			inst:DoTaskInTime(0, function()
				inst.replica.container:WidgetSetup("hellpuppy3")
			end)
            return inst
        end

		inst.favoritefood = data.favoritefood

        inst.GetPeepChance = GetPeepChance
        inst.IsAffectionate = IsAffectionate
        inst.IsSuperCute = IsSuperCute
        inst.IsPlayful = IsPlayful
        
		inst.playmatetags = {"critter"}
		if data ~= nil and data.playmatetags ~= nil then
			inst.playmatetags = JoinArrays(inst.playmatetags, data.playmatetags)
		end
	
        inst:AddComponent("inspectable")

        inst:AddComponent("follower")
        inst.components.follower:KeepLeaderOnAttacked()
        inst.components.follower.keepdeadleader = true

        inst:AddComponent("knownlocations")

        inst:AddComponent("sleeper")
        inst.components.sleeper:SetResistance(3)
        inst.components.sleeper.testperiod = GetRandomWithVariance(6, 2)
        inst.components.sleeper:SetSleepTest(ShouldSleep)
        inst.components.sleeper:SetWakeTest(ShouldWakeUp)

		inst:AddComponent("container")
		inst.components.container:WidgetSetup("hellpuppy3")
		inst.components.container.skipclosesnd = true
		inst.components.container.skipopensnd = true
		inst.components.container.onopenfn = function(inst)
        inst.SoundEmitter:PlaySound("dontstarve/wilson/chest_open")
		end

So the first one didn't do anything but the second one(or the combo of both) did! Thanks so much! I didn't think this was gonna be such a hassle but clearly I was wrong lol.

  • Like 1

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