Jump to content

Finding items on the ground in a radius


Recommended Posts

Hi guys! So I'm well on my way to finishing my first mod. I have the structure all made, and the art and animations working in game. The mod I'm working on is a Vacuum Chest, it checks the area around it for loot on the ground, and if it is not full /is able to add to a stack, picks up the loot automatically. It's chest functionality is all working as expected. 


Right now I'm working on the custom functionality of my structure. I know the basic logic that I need to implement to make this work. However, I'm new to the Don't Starve game files and I'm having difficulty where the functions I need are defined and so I can see their names, their parameters, etc. 


basically I need help finding existing game logic so that I can use it, and advice on the best method to accomplish this. I've been combing through components and prefabs for hours and I've helped myself a long a lot but now the going is slowing down, so a little help on this function would be appreciated! I'm going to continue working on it as I wait for replies to this thread



Here's the function at time of posting:

	inst:DoPeriodicTask(0.5, function ()    	--print "Ran function"    	local SEARCH_RADIUS = 20    	local has_tags = {}    	local ignore_tags = {}    	--find entities    	local entities = TheSim:FindEntities(inst, SEARCH_RADIUS, has_tags, ignore_tags)    	--filter entities by those storable in inventory (by tags?)    	-- if invetory is full, ignore    	-- Else if can pick up, pick up object, store in inventory, play sound    	end)

So right now my question is:


Is TheSim:FindEntities the best way to locate the items around the chest? Do items around the chest have tags I can check? If so what tag do storable items have in common? I'm not very familiar with what exactly tags are and how I can use them to sort results. I pulled this function from the 'follow the leader' example, and I'm not 100% sure if it's actually what I need. (Also I've done something to implement it wrong here in the first place, it gives an error saying i've called it on a 'bad self')


Or is there an alternate/better way I can do this based on filtering objects by components or prefabs? What kinda of function could I use to find entities that are inventoryitems only? or cangoincontainer only? As specified in the inventoryitem component.


tldr: I need to locate items in a radius around the chest and select only those that can be picked up.

Link to comment
Share on other sites


i would use

item=FindEntity(inst, 15, function(item) return item.components.inventoryitem and item.components.inventoryitem.cangoincontainer end)
this only returns 1 item, but u can give it a function to make complicated checks on the item, i already added the check that u probably wanna use. also, this might look good if u add the effect of the dragonfly vaccuming up ashes^^
Link to comment
Share on other sites

@Taryn, If you want to see an example of this in action, I have a mod that does this(though not for ALL items)





Specifically, the magnechest prefab in that mod.  Here's what that looks like:


You wouldn't need to use a component like I do, but some of the stuff in there should be useful for figuring it out.

Link to comment
Share on other sites

@Seiai,@Corrosive, Thank you both so much! With your examples I have the mod working in the most basic way. You guys are both amazing. Thanks so much for your help.


(And Corrosive is that mod not in the workshop?! If it is, I haven't seen it there! It's awesome! I'll definitely be keeping it in my mod library)


Currently I'm working on adding more checks to the chest, because at the moment it's acting more like a black hole than a vacuum. If I get stuck on anything I will be sure to report back! 


Thanks so much, again! 

Link to comment
Share on other sites

Its all in ornage amulet prefab. Sliding items toward the chest looks nice, but its lot of objects constantly changing positions, it cab be heavy operation, will increase memory and cpu usage for sure.

Link to comment
Share on other sites

Alright so I'm running into one more error with my code. I'm hoping a second set of eyes will help me uncover it x.x maybe I've just been staring at it too long!

local function suckit(inst)		local x,y,z = inst.Transform:GetWorldPosition()		local SEARCH_RADIUS = 8		local item = FindEntity(inst, SEARCH_RADIUS, function(item) 			local check = item.components.inventoryitem and item.components.inventoryitem.canbepickedup and item.components.inventoryitem.cangoincontainer			return check			end)		if item and not inst.components.container:IsFull() then			-- container is not full, it can pick up the item			inst.AnimState:PlayAnimation("hit")			inst.SoundEmitter:PlaySound("dontstarve/wilson/chest_open")			inst.components.container:GiveItem(item)			return		elseif item.components.stackable then			-- if the inventory is full, but the item stacks, and exists in the container, and the stack is not full			local stack = inst.components.container:FindItem(function(i) return (i.prefab == item.prefab and not i.components.stackable:IsFull()) end)						if stack then				inst.AnimState:PlayAnimation("hit")			    inst.SoundEmitter:PlaySound("dontstarve/wilson/chest_open")				inst.components.container:GiveItem(item)				return			end		end	end

The log says 'attempt to index a nil value' (item) on this line:

elseif item.components.stackable then

But I did declare the variable earlier in the function, and it worked for the first if statement. I'm not sure why it's not working for the elseif statement. I pulled it from the exampled in the orange amulet prebfab. I'm just getting blocked up on this. Thanks for taking a look!


(I realize it's a lot of work to put in just one function. I'm newer to lua so I'm keeping it all in one place while I test and then I'm gonna clean up the code a bit more later)



Link to comment
Share on other sites

@Taryn Simplifying your code:

if item and not SomeBool then	-- Here, you're saying "If the item exists, and SomeBool is false"	-- Do somethingelseif item.child then	-- Here, you're saying "If the previous corresponding if-statement(s) are false"	-- "Then check item.child"	-- The previous statement will be false if:	-- - Item is nil or false	-- OR	-- - SomeBool is nil or false		-- Do something elseend

I think what you want is something like this.

if item then	-- Item has to be valid for either of these to work:	if not SomeBool then		-- Do something	elseif item.child then		-- Do something else	endend
Link to comment
Share on other sites

@Blueberrys, Aha! Thanks so much. I feel like a dumbie now. haha. Of coarse it would crash, it kept trying to run that part of the function when no valid items existed! Thanks so much! My code is done and working perfectly. 


I've also simplified the code and cleaned it up a little, and now I'm going to test every possible situation in game about 10 more times to make sure no more unexpected bugs pop up ^^


Thanks again to everyone who helped me out with this and gave me tons of examples! It's a very simple mod but I feel like I'm starting to shake off the rust I've accumulated since I last did OOP. 


I might try adding some configuration options to it in the future, for things like radius, etc.

Link to comment
Share on other sites


This topic is now archived and is closed to further replies.

Please be aware that the content of this thread may be outdated and no longer applicable.

  • Create New...