Jump to content

Need help creating a Woodie mod to prevent item drops on transformation!


Recommended Posts

Hiya all,

I'm trying to add to my Woodie mod the ability to prevent Woodie from dropping equipped items upon transformation. Can anyone help me locate the code that initiates this drop in the first place? Bonus points if you can tell me how to actually prevent it in the first place!!

I'm relatively new to lua and I'm having trouble figuring this one out!

Thanks!

Link to comment
Share on other sites

On 1/15/2023 at 1:20 AM, Tyroue said:

Hiya all,

I'm trying to add to my Woodie mod the ability to prevent Woodie from dropping equipped items upon transformation. Can anyone help me locate the code that initiates this drop in the first place? Bonus points if you can tell me how to actually prevent it in the first place!!

I'm relatively new to lua and I'm having trouble figuring this one out!

Thanks!

Bump, because googling the very same brought me here. Any luck on your endeavors? 

Link to comment
Share on other sites

On 1/15/2023 at 1:20 AM, Tyroue said:

Can anyone help me locate the code that initiates this drop in the first place?

In stategraphs\SGwilson.lua, the states "transform_werebeaver", "transform_weremoose" and "transform_weregoose" through the "DropEquipped" function of the "inventory" component.

On 1/15/2023 at 1:20 AM, Tyroue said:

Bonus points if you can tell me how to actually prevent it in the first place!!

This is how I went about doing it, just put this in modmain:

AddComponentPostInit("inventory", function(self)
	local _old_dropequipped = self.DropEquipped
	
	function self:DropEquipped(keepBackpack, ...)
		local state_name = self.inst.sg ~= nil and self.inst.sg.currentstate ~= nil and self.inst.sg.currentstate.name
		
		if state_name ~= nil then
			if state_name == "transform_werebeaver" or state_name == "transform_weremoose" or state_name == "transform_weregoose" then
				return
			end
		end
		
		_old_dropequipped(self, keepBackpack, ...)
	end
end)

I hooked into the DropEquipped function and made it check if the player is in one of those states when the function is called. A bit of a hacky solution, but I can't think of a better alternative right now.

However, this is only the start. I tested it a bit and the items are still equipped with all of their effects which... looks a bit buggy at times. The Moose and Goose lose part of their heads, the Moose and Werebeaver attack with the weapon you're holding and so on. You'd have to look into how to disable the effects of those equipped items too and re-enable them when transforming back to human. I'm not sure how you'd go about doing that, but I haven't looked into it at all yet.

21 hours ago, DinsdaleP said:

Bump

Quoting you too, since you bumped the thread.

  • Thanks 1
Link to comment
Share on other sites

5 hours ago, ariadnesGambit said:

Quoting you too, since you bumped the thread.

Thank you!

Given the information above and with *extremely* rudimentary LUA knowledge (and probably downright horrible code), I think I've managed to nail down what I want to do more or less, messing around with inventory.lua:

function Inventory:DropEquipped(keepBackpack)
	local handitem = self:GetEquippedItem(EQUIPSLOTS.HANDS)			
	if handitem ~= nil then
		if handitem.components.inventoryitem.cangoincontainer then
			self.silentfull = true
			self:GiveItem(handitem, nil)
			self.silentfull = false
		else
			self:DropItem(handitem, true, true)
		end
	end
	local headitem = self:GetEquippedItem(EQUIPSLOTS.HEAD)
	if headitem ~= nil then			
		if headitem.components.inventoryitem.cangoincontainer then
			self.silentfull = true
			self:GiveItem(headitem, nil)
			self.silentfull = false
		else
			self:DropItem(headitem, true, true)
		end
	end
	local bodyitem = self:GetEquippedItem(EQUIPSLOTS.BODY)
    if not (keepBackpack and bodyitem:HasTag("backpack")) then
			self.silentfull = true
			self:GiveItem(bodyitem, nil)
			self.silentfull = false
		else
			self:DropItem(bodyitem, true, true)
    end
end

Basically, unless the inventory is totally full, it'll try and simply unequip items instead of dropping them to the ground... at least that's the basic idea.

I've used the same code as the game does when picking up heavy items (boulders, altars pieces and such), with a bit of trial-and-error tinkering... however, there is one thing I'd like to ask for help in, since I can't get it working properly: backpacks.

The code above checks if your bodyslot item is a backpack and if not, it tries to put in the inventory, and drops it if there aren't any more space - or if it's a backpack, not the most ideal solution. Keeping only the DropItem part and deleting the four lines above allows you to keep your backpack, but drops the bodyslot item if anything other than a backpack is equipped.

Is there any way for it to drop the equipped item if the inventory is full, but always keep the backpack? Sorry, I'm no coder, just someone trying to bodge lua to do what I want to do.

Also, is there a tutorial for how to turn things into mods, instead of just editing things inside scripts.zip? Does not seem like the most elegant solution.

Thank you for all your help and for making this possible!

Link to comment
Share on other sites

I'm at my wits end with this, managed to make the code do what I want to do, but I don't know enough about lua to turn this into a proper mod.

The modmain.lua currently looks like this:

AddComponentPostInit("inventory", function(Inventory, inst)
	local _old_dropequipped = Inventory.DropEquipped

function Inventory:DropEquipped(keepBackpack)
	local handitem = self:GetEquippedItem(EQUIPSLOTS.HANDS)			
	if handitem ~= nil then
		if handitem.components.inventoryitem.cangoincontainer then
			self.silentfull = true
			self:GiveItem(handitem, nil)
			self.silentfull = false
		else
			self:DropItem(handitem, true, true)
		end
	end
	local headitem = self:GetEquippedItem(EQUIPSLOTS.HEAD)
	if headitem ~= nil then			
		if headitem.components.inventoryitem.cangoincontainer then
			self.silentfull = true
			self:GiveItem(headitem, nil)
			self.silentfull = false
		else
			self:DropItem(headitem, true, true)
		end
	end
	local bodyitem = self:GetEquippedItem(EQUIPSLOTS.BODY)
    if not (keepBackpack and bodyitem:HasTag("backpack")) then
		self.silentfull = true
		self:GiveItem(bodyitem, nil)
		self.silentfull = false
	else
		if (keepBackpack and bodyitem:HasTag("backpack")) then
			return
		else
			self:DropItem(bodyitem, true, true)
		end
    end
	_old_dropequipped(inventory, keepBackpack)
end
end)

Server launchers properly with the mod, however, anytime I try to use a kitschy idol, I got the following message:

[string "../mods/Woodie nodrop/modmain.lua"]:5: attempt to index global 'EQUIPSLOTS' (a nil value)

Can anyone help my about what am I missing and how do I fix it?

Link to comment
Share on other sites

10 hours ago, Digi_056 said:

Try adding “GLOBAL.” in front of any use of EQUIPSLOTS 

Thank you very much, it worked! This has finally led me to find another problem in the code, and with a bit of help from ChatGPT (why didn't I think of that sooner?!) I've managed to sort all the issues out and get some code that was about tenth of my original in length, though setting the item dropping order to hands -> head -> body, it did grow into something resembling the horror I've bodged together.

I still need to made a proper mod image, then I'll set the whole thing loose on the world.

Thank you both for your help!

Edited by DinsdaleP
Link to comment
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
 Share

×
  • Create New...