145 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			145 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| -- luacheck: globals Item Vector2 Character MyModGlobal
 | |
| -- luacheck: max line length 420
 | |
| local dump = require("Cyka.dump")
 | |
| local quickstack = require("Cyka.quickstack")
 | |
| 
 | |
| ---@class ItemLocation
 | |
| ---@field item Barotrauma.Item
 | |
| ---@field distance number
 | |
| 
 | |
| ---@param A Vector2
 | |
| ---@param B Vector2
 | |
| ---@return number
 | |
| local function getDistanceQuick(A, B)
 | |
| 	return math.abs(A.X - B.X) + math.abs(A.Y - B.Y)
 | |
| end
 | |
| 
 | |
| ---@param source Vector2
 | |
| ---@param distanceThreshold number
 | |
| ---@return ItemLocation[]
 | |
| local function getNearbyItems(source, distanceThreshold)
 | |
| 	-- local log = {}
 | |
| 	---@type ItemLocation[]
 | |
| 	local items = {}
 | |
| 	local whitelistedComponents = "Holdable,Pickable,Wearable"
 | |
| 	local blacklistedComponents = "ConnectionPanel"
 | |
| 	for item in Item.ItemList do
 | |
| 		-- log[#log + 1] = string.format("Checking item %s", tostring(item))
 | |
| 		local distance, tags, hasAnyOfComponent
 | |
| 		---@cast item Barotrauma.Item
 | |
| 		local parentInventory = item.ParentInventory
 | |
| 		if parentInventory then
 | |
| 			-- log[#log + 1] = string.format("Item %s is in an inventory", tostring(item))
 | |
| 			goto continue
 | |
| 		end
 | |
| 		tags = tostring(item.Tags)
 | |
| 		if not string.find(tags, "item") then
 | |
| 			-- log[#log + 1] = string.format("Item %s is not an item (but a structure) - %s", tostring(item), tags)
 | |
| 			goto continue
 | |
| 		end
 | |
| 		for component in item.Components do
 | |
| 			-- For some God forsaken reason this does not work
 | |
| 			-- Not that it classifies the incorrect items
 | |
| 			-- But it just literally does not work
 | |
| 			-- The code does not execute
 | |
| 			-- Some of the items vanish into thin air, as if they never existed
 | |
| 			-- I have no idea why
 | |
| 			-- So we'll do this in 2 steps...
 | |
| 			-- if string.find(blacklistedComponents, component.Name) then
 | |
| 			-- 	log[#log + 1] = string.format("Item %s has blacklisted component %s - %s", tostring(item), component.Name, component.Name)
 | |
| 			-- 	goto continue
 | |
| 			-- end
 | |
| 			if string.find(whitelistedComponents, component.Name) then
 | |
| 				hasAnyOfComponent = true
 | |
| 				break
 | |
| 			end
 | |
| 		end
 | |
| 		if not hasAnyOfComponent then
 | |
| 			-- log[#log + 1] = string.format("Item %s is not %s", tostring(item), whitelistedComponents)
 | |
| 			goto continue
 | |
| 		end
 | |
| 
 | |
| 		distance = getDistanceQuick(item.WorldPosition, source)
 | |
| 		if distance > distanceThreshold then
 | |
| 			-- log[#log + 1] = string.format("Item %s is too far away - %s", tostring(item), distance)
 | |
| 			goto continue
 | |
| 		end
 | |
| 		items[#items + 1] = {
 | |
| 			item = item,
 | |
| 			distance = distance,
 | |
| 		}
 | |
| 		::continue::
 | |
| 	end
 | |
| 	-- print(table.concat(log, "\n"))
 | |
| 
 | |
| 	table.sort(items, function(a, b)
 | |
| 		return a.distance < b.distance
 | |
| 	end)
 | |
| 
 | |
| 	-- local str = ""
 | |
| 	-- for _, item in pairs(items) do
 | |
| 	-- 	str = str .. tostring(item.item) .. " " .. item.distance .. " "
 | |
| 	-- 	local tags = tostring(item.item.Tags)
 | |
| 	-- 	str = str .. tags .. " "
 | |
| 	-- 	for component in item.item.Components do
 | |
| 	-- 		str = str .. component.Name .. " "
 | |
| 	-- 	end
 | |
| 	-- 	str = str .. "---" .. "\n"
 | |
| 	-- end
 | |
| 	-- print(str)
 | |
| 
 | |
| 	local filteredItems = {}
 | |
| 	for _, item in pairs(items) do
 | |
| 		for component in item.item.Components do
 | |
| 			if string.find(blacklistedComponents, component.Name) then
 | |
| 				goto continue
 | |
| 			end
 | |
| 		end
 | |
| 		filteredItems[#filteredItems + 1] = item.item
 | |
| 		::continue::
 | |
| 	end
 | |
| 	dump(filteredItems)
 | |
| 
 | |
| 	-- str = ""
 | |
| 	-- for _, item in pairs(filteredItems) do
 | |
| 	-- 	str = str .. tostring(item) .. " "
 | |
| 	-- 	local tags = tostring(item.Tags)
 | |
| 	-- 	str = str .. tags .. " "
 | |
| 	-- 	for component in item.Components do
 | |
| 	-- 		str = str .. component.Name .. " "
 | |
| 	-- 	end
 | |
| 	-- 	str = str .. "---" .. "\n"
 | |
| 	-- end
 | |
| 	-- print(str)
 | |
| 
 | |
| 	return filteredItems
 | |
| end
 | |
| 
 | |
| local function tryAoePickup()
 | |
| 	MyModGlobal.debugPrint("tryAoePickup")
 | |
| 	local character = Character.Controlled
 | |
| 	if not character then
 | |
| 		MyModGlobal.debugPrint("No controlled character")
 | |
| 		return
 | |
| 	end
 | |
| 
 | |
| 	local itemTree, err = quickstack.tryBuildCharacterItemTree(character)
 | |
| 	if err then
 | |
| 		MyModGlobal.debugPrint(err)
 | |
| 		return
 | |
| 	end
 | |
| 
 | |
| 	local distanceThreshold = 2000
 | |
| 	local characterPos = character.WorldPosition
 | |
| 	local nearbyItems = getNearbyItems(characterPos, distanceThreshold)
 | |
| 
 | |
| 	local errors = quickstack.tryMoveItems(nearbyItems, itemTree, true)
 | |
| 	for _, error in pairs(errors) do
 | |
| 		MyModGlobal.debugPrint(string.format("Error moving items: %s", error))
 | |
| 	end
 | |
| end
 | |
| 
 | |
| return {
 | |
| 	tryAoePickup = tryAoePickup,
 | |
| }
 |