Jump to content

Recommended Posts

Hi, I've looked everywhere but I can't see to find some code that can change the size of a backpack, or more specifically, the Chef Pouch that Warly has. I am making a mod that improves Warly, and I want the Chef Pouch to be viable. The code I am using always crashes. It says the number of slots is read-only, but I can't figure out how to change it.

Code to change it:

function spicepackpostinit(inst)
	inst.components.container:SetNumSlots(10)
end

AddPrefabPostInit("spicepack", spicepackpostinit)

End of log:

[00:01:40]: error calling PrefabPostInit: spicepack in mod balancedwarly (Balanced Warly WIP): 
[string "scripts/class.lua"]:38: Cannot change read only property
LUA ERROR stack traceback:
        =[C] in function 'assert'
        scripts/class.lua(38,1) in function '?'
        scripts/class.lua(30,1)
        scripts/components/container.lua(85,1) in function 'SetNumSlots'
        ../mods/balancedwarly/modmain.lua(35,1)
        =(tail call) ?
        =[C] in function 'xpcall'
        scripts/mods.lua(162,1) in function 'mod'
        scripts/mainfunctions.lua(267,1)
        =[C] in function 'SpawnPrefab'
        scripts/mainfunctions.lua(306,1) in function 'SpawnPrefab'
        scripts/components/builder.lua(440,1)
        =(tail call) ?
        scripts/bufferedaction.lua(25,1) in function 'Do'
        scripts/entityscript.lua(1313,1) in function 'PerformBufferedAction'
        scripts/stategraphs/SGwilson.lua(5040,1) in function 'ontimeout'
        scripts/stategraph.lua(554,1) in function 'UpdateState'
        scripts/stategraph.lua(611,1) in function 'Update'
        scripts/stategraph.lua(128,1) in function 'Update'
        scripts/update.lua(228,1)	
[00:01:40]: Disabling balancedwarly (Balanced Warly WIP) because it had an error.	
[00:01:40]: [string "scripts/class.lua"]:38: Cannot change read only property
LUA ERROR stack traceback:
        =[C] in function 'assert'
        scripts/class.lua(38,1) in function '?'
        scripts/class.lua(30,1)
        scripts/components/container.lua(85,1) in function 'SetNumSlots'
        ../mods/balancedwarly/modmain.lua(35,1)
        =(tail call) ?
        =[C] in function 'xpcall'
        scripts/mods.lua(162,1) in function 'mod'
        scripts/mainfunctions.lua(267,1)
        =[C] in function 'SpawnPrefab'
        scripts/mainfunctions.lua(306,1) in function 'SpawnPrefab'
        scripts/components/builder.lua(440,1)
        =(tail call) ?
        scripts/bufferedaction.lua(25,1) in function 'Do'
        scripts/entityscript.lua(1313,1) in function 'PerformBufferedAction'
        scripts/stategraphs/SGwilson.lua(5040,1) in function 'ontimeout'
        scripts/stategraph.lua(554,1) in function 'UpdateState'
        scripts/stategraph.lua(611,1) in function 'Update'
        scripts/stategraph.lua(128,1) in function 'Update'
        scripts/update.lua(228,1)
[00:01:40]: [string "scripts/class.lua"]:38: Cannot change read only property
LUA ERROR stack traceback:
        =[C] in function 'assert'
        scripts/class.lua(38,1) in function '?'
        scripts/class.lua(30,1)
        scripts/components/container.lua(85,1) in function 'SetNumSlots'
        ../mods/balancedwarly/modmain.lua(35,1)
        =(tail call) ?
        =[C] in function 'xpcall'
        scripts/mods.lua(162,1) in function 'mod'
        scripts/mainfunctions.lua(267,1)
        =[C] in function 'SpawnPrefab'
        scripts/mainfunctions.lua(306,1) in function 'SpawnPrefab'
        scripts/components/builder.lua(440,1)
        =(tail call) ?
        scripts/bufferedaction.lua(25,1) in function 'Do'
        scripts/entityscript.lua(1313,1) in function 'PerformBufferedAction'
        scripts/stategraphs/SGwilson.lua(5040,1) in function 'ontimeout'
        scripts/stategraph.lua(554,1) in function 'UpdateState'
        scripts/stategraph.lua(611,1) in function 'Update'
        scripts/stategraph.lua(128,1) in function 'Update'
        scripts/update.lua(228,1)	
[00:01:40]: Warning: Widget:SetFocusFromChild is happening on a widget outside of the screen/widget hierachy. This will cause focus moves to fail. Is 	ScriptErrorWidget	not a screen?	
[00:01:40]: stack traceback:
	scripts/widgets/widget.lua:605 in (method) SetFocusFromChild (Lua) <602-627>
	scripts/widgets/widget.lua:624 in (method) SetFocusFromChild (Lua) <602-627>
	scripts/widgets/widget.lua:624 in (method) SetFocusFromChild (Lua) <602-627>
	scripts/widgets/widget.lua:656 in (method) SetFocus (Lua) <629-665>
	scripts/widgets/menu.lua:83 in (method) SetFocus (Lua) <74-85>
	scripts/widgets/scripterrorwidget.lua:109 in (method) OnUpdate (Lua) <102-119>
	scripts/update.lua:90 in () ? (Lua) <33-129>	

 

Edited by decduck3
Link to comment
https://forums.kleientertainment.com/forums/topic/119855-expanding-chef-pouch/
Share on other sites

I'm not sure how SetNumSlots works, but you might be able to do another prefabpostinit. In the spicepack prefab, there's a line that looks like this:

inst.components.container:WidgetSetup("spicepack")

In the prefab post init, you could redo that line with backpack instead and that should take care of all the widget and container complications:

inst.components.container:WidgetSetup("backpack")

Since this only alters the container and widget stuff, the other functionality should remain since they're dealt with through tags and components elsewhere.

Would this work?

function spicepackpostinit(inst)
    params.spicepack =
    {
        widget =
        {
            slotpos = {},
            animbank = "ui_backpack_2x4",
            animbuild = "ui_backpack_2x4",
            pos = Vector3(-5, -70, 0),
        },
    issidewidget = true,
    type = "pack",
    }

    for y = 0, 3 do
        table.insert(params.backpack.widget.slotpos, Vector3(-162, -75 * y + 114, 0))
        table.insert(params.backpack.widget.slotpos, Vector3(-162 + 75, -75 * y + 114, 0))
    end
end

AddPrefabPostInit("containers", spicepackpostinit)

 

Edited by decduck3

Now that I think of it, whenever we made a mod that required us to give something a container component, we had to redefine all the widget stuff like you just asked. So if you want to make something use a different widget, you might have to do something similar, in which case, what you have right on top of this should work...

Or at least be similar to what the end result should look like.

Edited by rawii22

Scroll to the bottom of this file where you see params.treasurechest_quantum. This is my quantum chest mod that I made with my brother. It's just a new prefab that has weird interactions with other chests. The full mod is here (not that it helps with widgets but you can mess with the widget stuff if you're curious): https://steamcommunity.com/sharedfiles/filedetails/?id=2056581913&searchtext=quantum+chest

modmain.lua

I can't seem to make it work. DST throws no errors, but the Chef Pouch still only has 6 slots. I "borrowed" your code, and stuck it on the end of my modmain, and changed all the treasurechest_quantaum s to spicepack.

local params = {}

params.spicepack =
{
    widget =
    {
        slotpos = {},
        animbank = "ui_backpack_2x4",
        animbuild = "ui_backpack_2x4",
        pos = GLOBAL.Vector3(-5, -70, 0),
    },
    issidewidget = true,
    type = "pack",
}

for y = 0, 3 do
    table.insert(params.spicepack.widget.slotpos, GLOBAL.Vector3(-162, -75 * y + 114, 0))
    table.insert(params.spicepack.widget.slotpos, GLOBAL.Vector3(-162 + 75, -75 * y + 114, 0))
end

local containers = GLOBAL.require("containers")
containers.MAXITEMSLOTS = math.max(containers.MAXITEMSLOTS, params.spicepack.widget.slotpos ~= nil and #params.spicepack.widget.slotpos or 0)
local old_widgetsetup = containers.widgetsetup
function containers.WidgetSetup(container, prefab, data)
    local pref = prefab or container.inst.prefab
    if pref == "spicepack" then
        local t = params[pref]
        for k, v in pairs(t) do
            container[k] = v
        end
        container:SetNumSlots(container.widget.slotpos ~= nil and #container.widget.slotpos or 0)
    else
        return old_widgetsetup(container, prefab)
    end
end

Is there anything else I need to do?

Now that I look again, we have our own prefab file for that special chest and load in a ui anims there. Perhaps since those assets are loaded in the prefab file itself locally it might be impossible to change without duplicating the whole thing and changing it there. That's pretty unconventional in terms of maintenance, and you'll probably have to adjust a bunch of stuff inside the prefab (if that's possible to do successfully) but otherwise I'm not sure what to do yet...

Are you saying that I may have to override Klei's Chef Pouch, and then add in the UI?

 

Also what is different between:

(taken from your mod)

function containers.WidgetSetup(container, prefab, data)
    local pref = prefab or container.inst.prefab
    if pref == "spicepack" then
        local t = params[pref]
        for k, v in pairs(t) do
            container[k] = v
        end
        container:SetNumSlots(container.widget.slotpos ~= nil and #container.widget.slotpos or 0)
    else
        return old_widgetsetup(container, prefab)
    end
end

(taken from containers.lua)

function containers.widgetsetup(container, prefab, data)
    local t = data or params[prefab or container.inst.prefab]
    if t ~= nil then
        for k, v in pairs(t) do
            container[k] = v
        end
        container:SetNumSlots(container.widget.slotpos ~= nil and #container.widget.slotpos or 0)
    end
end

What makes it different? Why did you have to redefine it? Doesn't it do the same thing?

Edited by decduck3
On 7/9/2020 at 12:38 PM, IThatGuyI said:

You need to add this:


function spicepackpostinit(inst)
	if inst.components.container ~= nil then
		inst.components.container:WidgetSetup("backpack")
	end
end

AddPrefabPostInit("spicepack", spicepackpostinit)

That should fix it.

just tested this and worked fine for me, chef pouch inventory was 8 instead of 6

7 hours ago, decduck3 said:

How exactly did you test it? I tried it and it doesn't work.

 

Here's my entire modmain.lua. I dunno why it isn't working

modmain.lua 3.96 kB · 0 downloads

I'm not sure why it doesn't work for you, I didn't make any changes to the code either. Here it is as a mod file with just the spicepack code if you wish to test it yourself, it still works for me

20200714100741_1.thumb.jpg.481509f71f58366884a1ce8ac2e3264c.jpg

 

test.zip

For some reason, it still isn't working. With no other mods active, except for your mod that I quickly chucked into the mods folder. There may be something wrong with my copy of the game.

 

One question. If you extract the scripts.zip in the data folder, does it get recompiled by extracted version of the folder if it's called scripts?

Just reinstalled the game, and it still doesn't work. I have no idea how you got it to work.

Edited by decduck3

About the zipped folders, if you unzip scripts and move it into data, the game will look for the game files in data/scripts instead of data/databundles/scripts, assuming you renamed the original zipped folder.

Also, we seem to be really close here, @maliblues seems to have gotten somewhere. Could you link the client_log whenever you try something as well as the modmain. I know some other people on the forums may not care, but we might as well since we're so close and it really appears to be a simple fix...

@rawii22 have you got it to work yourself?

 

I have tried a couple things, to no avail:

  1. Loop the function until it does the WidgetSetup("backpack"). This got stuck in a infinite loop
  2. inst.AddComponent("container"), and gave me an error

It may be a problem with my version of DST, so I could try to run it on a different computer?

So, I did some research, and by some I mean 2 days of searching, and I managed to make it work.

To start, the container component uses containers.lua. I've looked for some clues there and, yes, there is something that looks like this:

params.spicepack =
{
    widget =
    {
        slotpos = {},
        animbank = "ui_icepack_2x3",
        animbuild = "ui_icepack_2x3",
        pos = Vector3(-5, -70, 0),
    },
    issidewidget = true,
    type = "pack",
}

for y = 0, 2 do
    table.insert(params.spicepack.widget.slotpos, Vector3(-162, -75 * y + 75, 0))
    table.insert(params.spicepack.widget.slotpos, Vector3(-162 + 75, -75 * y + 75, 0))
end

 

So, I figured you could somehow change the values to match these of the backpack:

params.backpack =
{
    widget =
    {
        slotpos = {},
        animbank = "ui_backpack_2x4",
        animbuild = "ui_backpack_2x4",
        pos = Vector3(-5, -70, 0),
    },
    issidewidget = true,
    type = "pack",
}

for y = 0, 3 do
    table.insert(params.backpack.widget.slotpos, Vector3(-162, -75 * y + 114, 0))
    table.insert(params.backpack.widget.slotpos, Vector3(-162 + 75, -75 * y + 114, 0))
end

params.icepack = params.backpack

 

That was not an easy task let me tell you.

After trying myself to make it work I ended up searching for some information on the forum and found this thread:

In there Wolf_EX showed how to add a custom container. I used this code and edited it in a way that only overrides the spicepack code. And here it is (all of it is in the modmain.lua):

local require = GLOBAL.require -- Obviously needs a require
local Vector3 = GLOBAL.Vector3 -- Also needs Vector3
local containers = require "containers" -- And containers.lua

Assets = {
    Asset("ANIM", "anim/ui_backpack_2x4.zip"), -- The anim file for the backpack widget
}

local params = {}

params.spicepack = -- I've kept the name as "spicepack"
{
	widget =
    {
        slotpos = {
			Vector3(-162, -75 * 0 + 114, 0), -- You have to do it this way since you can't really use a "for" loop outside of a function
			Vector3(-162, -75 * 1 + 114, 0), -- Each one represents one slot
			Vector3(-162, -75 * 2 + 114, 0),
			Vector3(-162, -75 * 3 + 114, 0),
			Vector3(-162 + 75, -75 * 0 + 114, 0),
			Vector3(-162 + 75, -75 * 1 + 114, 0),
			Vector3(-162 + 75, -75 * 2 + 114, 0),
			Vector3(-162 + 75, -75 * 3 + 114, 0),
		},
        animbank = "ui_backpack_2x4", -- Setting the bank
        animbuild = "ui_backpack_2x4", -- And the build
        pos = Vector3(-5, -70, 0),
    },
    issidewidget = true,
    type = "pack",
}

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

local containers_widgetsetup_base = containers.widgetsetup
function containers.widgetsetup(container, prefab, data)
    local t = params[prefab or container.inst.prefab]
    if t ~= nil then
        for k, v in pairs(t) do
            container[k] = v
        end
        container:SetNumSlots(container.widget.slotpos ~= nil and #container.widget.slotpos or 0)
    else
        containers_widgetsetup_base(container, prefab, data)
    end
end

I tested it out and it worked for me, I hope it works for you too.

  • Like 3
  • Thanks 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...