Jump to content

Mod Help - Fixing the vacuum chest


Recommended Posts

Hi guys, so I need help with part of .lua code, as I am not very experienced and I am having a hard time understanding a few things on how to get this mod to work correctly.

Basically I want this mod called Vacuum Chest to ignore things like Tooth Traps, while picking up other valid items. It currently works this way in Don't Starve Together, but not in Don't Starve Alone.

Below I've posted the vacuum_chest.lua files, and I've marked the part that I need help with. The first one shows the current DS version that picks up set traps, and the second one shows the working DST version that doesn't pickup set traps.

If anyone can help me port this functionality to DS, and maybe even understand how it works, that would be absolutely amazing.

Thanks for your time!

-Amnesiac

Here's the code for the current vacuum_chest.lua:

require "prefabutil"
require "scheduler"
require "simutil"
require "behaviours/doaction"

local assets =
{
	Asset("ANIM", "anim/VacuumChest.zip"),
	Asset("ATLAS", "images/inventoryimages/vacuum_chest.xml"),
	Asset("IMAGE", "images/inventoryimages/vacuum_chest.tex")

}


local function onopen(inst) 
	inst.AnimState:PlayAnimation("open") 
	inst.SoundEmitter:PlaySound("dontstarve/wilson/chest_open")		
end 

local function onclose(inst) 
	inst.AnimState:PlayAnimation("close") 
	inst.SoundEmitter:PlaySound("dontstarve/wilson/chest_close")		
end 

local function onhammered(inst, worker)
	inst.components.lootdropper:DropLoot()
	inst.components.container:DropEverything()
	SpawnPrefab("collapse_small").Transform:SetPosition(inst.Transform:GetWorldPosition())
	inst.SoundEmitter:PlaySound("dontstarve/common/destroy_wood")
	
	inst:Remove()
end

local function onhit(inst, worker)
	inst.AnimState:PlayAnimation("hit")
	inst.components.container:DropEverything()
	inst.AnimState:PushAnimation("closed", false)
	inst.components.container:Close()
end


local function onbuilt(inst)
	inst.AnimState:PlayAnimation("place")
	inst.AnimState:PushAnimation("closed", false)
end



local slotpos = {}

for y = 2, 0, -1 do
	for x = 0, 2 do
		table.insert(slotpos, Vector3(80*x-80*2+80, 80*y-80*2+80,0))
	end
end

local function fn(Sim)
	-- body
	local inst = CreateEntity()

	inst:AddTag("structure")

	inst.entity:AddTransform()
	inst.entity:AddAnimState()
	inst.entity:AddSoundEmitter()

	local minimap = inst.entity:AddMiniMapEntity()
	minimap:SetIcon("vacuum_chest.tex")

	inst.AnimState:SetBank("chest")
	inst.AnimState:SetBuild("VacuumChest")
	inst.AnimState:PlayAnimation("closed")

	inst:AddComponent("inspectable")
	inst:AddComponent("container")
	inst.components.container:SetNumSlots(#slotpos)

	inst.components.container.onopenfn = onopen
	inst.components.container.onclosefn = onclose
		
	inst.components.container.widgetslotpos = slotpos
	inst.components.container.widgetanimbank = "ui_chest_3x3"
	inst.components.container.widgetanimbuild = "ui_chest_3x3"
	inst.components.container.widgetpos = Vector3(0,200,0)
	inst.components.container.side_align_tip = 160

	inst:AddComponent("lootdropper")
	inst:AddComponent("workable")
	inst.components.workable:SetWorkAction(ACTIONS.HAMMER)
	inst.components.workable:SetWorkLeft(2)
	inst.components.workable:SetOnFinishCallback(onhammered)
	inst.components.workable:SetOnWorkCallback(onhit) 
		
	inst:ListenForEvent( "onbuilt", onbuilt)
	MakeSnowCovered(inst, .01)	

	local function suckit(item)   --吸取
		inst.AnimState:PlayAnimation("hit")
		inst.SoundEmitter:PlaySound("dontstarve/wilson/chest_open")
		inst.components.container:GiveItem(item)
	end


	local function vacuum(inst)
		local x,y,z = inst.Transform:GetWorldPosition()
		local SEARCH_RADIUS = TUNING.SEARCH_RADIUS--搜索半径

    --Amnesiac: Here's the part that searches for valid items I believe
    
		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 then
			if not inst.components.container:IsFull() then
			-- container is not full, it can pick up the item
				suckit(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
					suckit(item)
					return
				end
			end
		end
	end

	inst:DoPeriodicTask(0.5, vacuum)


	return inst
end

return Prefab( "common/vacuum_chest", fn, assets), 
		MakePlacer("common/vacuum_chest_placer", "chest", "VacuumChest", "closed")

 

 

And here's the code from Don't Starve Together, note the part that looks for invalid items that is missing from the Don't Starve version.

require "prefabutil"

local assets =
{
    Asset("ANIM", "anim/VacuumChest.zip"),
    Asset("ANIM", "anim/firefighter_placement.zip"),
	Asset("ATLAS", "images/inventoryimages/vacuum_chest.xml"),
	Asset("IMAGE", "images/inventoryimages/vacuum_chest.tex"),
}

local prefabs =
{
    "collapse_small",
}

local function onopen(inst) 
	inst.AnimState:PlayAnimation("open") 
	inst.SoundEmitter:PlaySound("dontstarve/wilson/chest_open")		
end 

local function onclose(inst) 
	inst.AnimState:PlayAnimation("close") 
	inst.SoundEmitter:PlaySound("dontstarve/wilson/chest_close")		
end 

local function onhammered(inst, worker)
	inst.components.lootdropper:DropLoot()
	inst.components.container:DropEverything()
	SpawnPrefab("collapse_small").Transform:SetPosition(inst.Transform:GetWorldPosition())
	inst.SoundEmitter:PlaySound("dontstarve/common/destroy_wood")
	
	inst:Remove()
end

local function onhit(inst, worker)
	inst.AnimState:PlayAnimation("hit")
	inst.components.container:DropEverything()
	inst.AnimState:PushAnimation("closed", false)
	inst.components.container:Close()
end


local function onbuilt(inst)
	inst.AnimState:PlayAnimation("place")
	inst.AnimState:PushAnimation("closed", false)
end

--------------------------------------------------------------------------
--minus or add 0.25 for every 5 range
local PLACER_SCALE = TUNING.VACUUM_RANGE == 10 and 1.255 or TUNING.VACUUM_RANGE == 15 and 1.55 or TUNING.VACUUM_RANGE == 20 and 1.755

local function OnEnableHelper(inst, enabled)
    if enabled then
        if inst.helper == nil then
            inst.helper = CreateEntity()

            --[[Non-networked entity]]
            inst.helper.entity:SetCanSleep(false)
            inst.helper.persists = false

            inst.helper.entity:AddTransform()
            inst.helper.entity:AddAnimState()

            inst.helper:AddTag("CLASSIFIED")
            inst.helper:AddTag("NOCLICK")
            inst.helper:AddTag("placer")

            inst.helper.Transform:SetScale(PLACER_SCALE, PLACER_SCALE, PLACER_SCALE)

            inst.helper.AnimState:SetBank("firefighter_placement")
            inst.helper.AnimState:SetBuild("firefighter_placement")
            inst.helper.AnimState:PlayAnimation("idle")
            inst.helper.AnimState:SetLightOverride(1)
            inst.helper.AnimState:SetOrientation(ANIM_ORIENTATION.OnGround)
            inst.helper.AnimState:SetLayer(LAYER_BACKGROUND)
            inst.helper.AnimState:SetSortOrder(1)
            inst.helper.AnimState:SetAddColour(0, .2, .5, 0)

            inst.helper.entity:SetParent(inst.entity)
        end
    elseif inst.helper ~= nil then
        inst.helper:Remove()
        inst.helper = nil
    end
end

--------------------------------------------------------------------------

local function fn(Sim)
	local inst = CreateEntity()

    inst.entity:AddTransform()
    inst.entity:AddAnimState()
    inst.entity:AddSoundEmitter()
	inst.entity:AddMiniMapEntity()
    inst.entity:AddNetwork()

	inst.MiniMapEntity:SetIcon("vacuum_chest.tex")

	inst.AnimState:SetBank("chest")
	inst.AnimState:SetBuild("VacuumChest")
	inst.AnimState:PlayAnimation("closed")
	
	inst:AddTag("structure")
    inst:AddTag("chest")

    --Dedicated server does not need deployhelper
    if not TheNet:IsDedicated() then
        inst:AddComponent("deployhelper")
        inst.components.deployhelper.onenablehelper = OnEnableHelper
    end
	
	inst.entity:SetPristine()

    if not TheWorld.ismastersim then
		inst.OnEntityReplicated = function(inst) 
			inst.replica.container:WidgetSetup("chester") 
		end
		return inst
	end

	inst:AddComponent("inspectable")

	inst:AddComponent("container")
	inst.components.container:WidgetSetup("chester")
	inst.components.container.onopenfn = onopen
    inst.components.container.onclosefn = onclose

	inst:AddComponent("lootdropper")
	inst:AddComponent("workable")
	inst.components.workable:SetWorkAction(ACTIONS.HAMMER)
	inst.components.workable:SetWorkLeft(2)
	inst.components.workable:SetOnFinishCallback(onhammered)
	inst.components.workable:SetOnWorkCallback(onhit) 
		
	inst:ListenForEvent( "onbuilt", onbuilt)
	MakeSnowCovered(inst, .01)	

	local function suckit(item)
		if inst.AnimState:IsCurrentAnimation("closed") or inst.AnimState:IsCurrentAnimation("close") then
			inst.AnimState:PlayAnimation("hit")
			inst.AnimState:PushAnimation("closed", false)
		end
		inst.SoundEmitter:PlaySound("dontstarve/wilson/chest_open")
		inst.components.container:GiveItem(item)
	end


	local function vacuum(inst)
		local SEARCH_RADIUS = TUNING.VACUUM_RANGE

		local function IsItem(ent)
			return ent.components.inventoryitem and ent.components.inventoryitem.canbepickedup and ent.components.inventoryitem.cangoincontainer and ent or nil
		end
  --Amnesiac: This is the part I'm talking about
    --See how it checks for Mines? I think this also applies to traps, as this verison does't pickup set traps.
    
		local Item = FindEntity(inst, SEARCH_RADIUS, IsItem,{"_inventoryitem"} , {"INLIMBO", "NOCLICK", "catchable", "fire", "minesprung", "mineactive"})
		
		if Item then
			if not inst.components.container:IsFull() then
				suckit(Item)
				return
			elseif Item.components.stackable then
				local stack = inst.components.container:FindItem(function(i) return (i.prefab == Item.prefab and not i.components.stackable:IsFull()) end)
			
				if stack then
					suckit(Item)
					return
				end
			end
		end
	end

	inst:DoPeriodicTask(0.5, vacuum)


	return inst
end

local function placer_postinit_fn(inst)
    --Show the vacuum chest placer on top of the vacuum chest range ground placer

    local placer2 = CreateEntity()

    --[[Non-networked entity]]
    placer2.entity:SetCanSleep(false)
    placer2.persists = false

    placer2.entity:AddTransform()
    placer2.entity:AddAnimState()

    placer2:AddTag("CLASSIFIED")
    placer2:AddTag("NOCLICK")
    placer2:AddTag("placer")

    local s = 1 / PLACER_SCALE
    placer2.Transform:SetScale(s, s, s)

    placer2.AnimState:SetBank("chest")
    placer2.AnimState:SetBuild("VacuumChest")
    placer2.AnimState:PlayAnimation("closed")
    placer2.AnimState:SetLightOverride(1)

    placer2.entity:SetParent(inst.entity)

    inst.components.placer:LinkEntity(placer2)
end

return Prefab( "common/vacuum_chest", fn, assets), 
    	MakePlacer("common/vacuum_chest_placer", "firefighter_placement", "firefighter_placement", "idle", true, nil, nil, PLACER_SCALE, nil, nil, placer_postinit_fn)

 

Link to comment
Share on other sites

Archived

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...