Sign in to follow this  
blubuild

How to change the maximum stack size of one prefab to a custom size via a mod

Recommended Posts

blubuild    37

As the title says, I want to give a specific item a new maximum stack size in a mod. While this is joyfully (or maybe ridiculously) simple to do in Don't Starve:

modmain.lua:

local function changestackA(inst)
	inst.components.stackable.maxsize = 12
end

local function changestackB(inst)
	inst.components.stackable.maxsize = 53
end


AddPrefabPostInit("poop",changestackA) --manure now stacks up to 12
AddPrefabPostInit("cutgrass",changestackB) --cut grass now stacks up to 53

 

...I can't manage to do the same in Don't Starve Together. Whatever I thought to attempt only caused an error related to stackable_replica.lua or just had no discernible effect.  I tried to look into it and it appears that in DST item stack sizes may be based on predefined amounts in a local table in stackable_replica.lua. I'm quite stumped, as I'm not sure how to go about dealing with that, or if netcode is related to my problems...

Does anyone know how to accomplish this?

Thanks for any help. :)

Share this post


Link to post
Share on other sites
DarkXero    2886
local function GetTableFromFunction(tablename, func)
	local debug = GLOBAL.debug
	local i = 1
	while true do
		local n, v = debug.getupvalue(func, i)
		if not n then
			return nil
		end
		if n == tablename then
			return v
		end
		i = i + 1
	end
end

local stackable_replica = GLOBAL.require("components/stackable_replica")

-- if another mod touches the constructor to do the same, game could break
-- lets hope people use variables that can hold MORE values, instead of LESS (who would do this???)
-- if they do, then we are good, all values (ours and theirs) can be represented by the net variables
stackable_replica._ctor = function(self, inst)
	self.inst = inst
	-- net_byte allows 0..255 different stack values
	-- this holds the number of items in the stack
	self._stacksize = GLOBAL.net_byte(inst.GUID, "stackable._stacksize", "stacksizedirty")
	-- net_smallbyte allows 0..63 different max values
	-- max sizes are encoded, this variable holds the key to the max size in the table
	self._maxsize = GLOBAL.net_smallbyte(inst.GUID, "stackable._maxsize")
end

-- these tables are available via upvalue hacking
local STACK_SIZES = GetTableFromFunction("STACK_SIZES", stackable_replica.MaxSize)
local STACK_SIZE_CODES = GetTableFromFunction("STACK_SIZE_CODES", stackable_replica.SetMaxSize)

-- my new max sizes, ready to encode
-- these should be used when doing
-- inst.components.stackable.maxsize = 12
local my_new_maxsizes = {12, 53}

-- add my values to the max stack sizes
for k, v in pairs(my_new_maxsizes) do
	table.insert(STACK_SIZES, v)
end

-- clean the inverted table
for k, v in pairs(STACK_SIZE_CODES) do
	STACK_SIZE_CODES[k] = nil
end

-- now invert sizes into codes
for k, v in pairs(STACK_SIZES) do
	STACK_SIZE_CODES[v] = k
end


-- now we do stuff
-- clients don't have stackable component, so the game would crash
-- the AddPrefabPostInit should be inside a if that checks that TheNet is server
-- or you add the stackable component check

local function changestackA(inst)
	if inst.components.stackable then
		inst.components.stackable.maxsize = 12
	end
end

local function changestackB(inst)
	if inst.components.stackable then
		inst.components.stackable.maxsize = 53
	end
end

AddPrefabPostInit("poop", changestackA) --manure now stacks up to 12
AddPrefabPostInit("cutgrass", changestackB) --cut grass now stacks up to 53

As simple as that, baybeeeeee, as simple as that.

Edited by DarkXero

Share this post


Link to post
Share on other sites
blubuild    37

Whoa! Yeah, simple indeed.:D


That's pretty ingenious, using the debug function to access a local table like that.
Much thanks!!! The required method here is pretty involved! I definitely wouldn't have been able to figure all of this out. Well-commented, too. Needless to say, you're awesome.

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
Sign in to follow this