Loot Chest+

by hanes

Automagically collects all the loot, on all surfaces. Useful in combination with artillery. Convenient for mods that add loot when aliens die, like Bob's mods, Necromant, Reika's EndgameCombat, Alien Loot Economy and Alien Space Science. The chest acts now as a passive provider chest and gets unlocked with logistic-robotics tech.

11 months ago
0.16 - 1.1
37082

i Compatibilty suggestion

11 months ago

could it be set to pick up science packs that are dropped by this:
https://mods.factorio.com/mod/DropSciencePack ?

11 months ago

My mod will pick up all stuff that is loot. That means stuff that gets dropped when an enemy or a spawner/turret dies.

If I'm getting this right on a quick loot at your mod it uses spill item stack. So alas the answer to your question is no. You should talk with the mod author from DropSciencePack.

11 months ago

the way theirs works is incompatible with all event-driven drop mods.

11 months ago

After a second look, problem is that it outputs as item-on-ground because of surface.spill_item_stack. it has event on entity died but uses drops table not loot.

11 months ago

thank you for the response/clarification!

3 months ago

After a second look, problem is that it outputs as item-on-ground because of surface.spill_item_stack. it has event on entity died but uses drops table not loot.

Hello, please tell me what can I change in this code so that your mod works with Pollution Solutions Fix? This is part of the control.lua, where, as I understand, is the problem.

--====================--
-- Loot Functionality --
--====================--

function EntityDied(event)
local alien = event.entity
--log(alien.name .. " died in force " .. alien.force.name)
if alien.force ~= game.forces.enemy or not event.force then return end
if global.nestsKilled == nil then global.nestsKilled = 0 end
if global.spilledLoot == nil then global.spilledLoot = {} end
if global.lootToCheck == nil then global.lootToCheck = {} end

local loot = {name="", count=0}
local quantity = 0.0

if alien.type == "unit" then
    local blueAverage = settings.global["zpollution-blue-per-alien"].value
    --[[
    if game.active_mods["Rampant"] ~= nil then
        blueAverage = blueAverage * 0.5
    end
    --]]
    if blueAverage >= 1 then
        quantity = 2*math.random() * blueAverage
        loot = {name="blue-xenomass", count=math.floor(quantity+0.5)}
    elseif blueAverage > math.random() then
        loot = {name="blue-xenomass", count=1}
    end

elseif alien.type == "turret" then
    quantity = 2*math.random() * 20
    loot = {name="blue-xenomass", count=math.floor(quantity+0.5)}
elseif alien.type == "unit-spawner" then
    global.nestsKilled = global.nestsKilled + 1
    quantity = settings.global["zpollution-red-per-alien"].value / global.nestsKilled
    loot = {name="red-xenomass", count=math.ceil(quantity)}
end

--log(create " .. quantity .. " xenomass")
local safetyRadius = settings.global["zpollution-pickup-safety-radius"].value
local isArtillery = (event.cause ~= nil) and (event.cause.type == "artillery-wagon" or event.cause.type == "artillery-turret" or event.cause.type == "artillery-projectile")

if loot.count >= 1 then
    if safetyRadius == 0 or isArtillery then
        if isArtillery then
            log(event.cause.type.." from force "..event.force.name.." killed "..alien.name..".")
        end
        alien.surface.spill_item_stack(alien.position, loot, true, event.force)
        return
    else
        alien.surface.spill_item_stack(alien.position, loot, true)
        -- remember my loot
        local nearItems = alien.surface.find_entities_filtered{
                position=alien.position,
                radius=5,
                name="item-on-ground"
        }
        for _,checkLoot in pairs(nearItems) do
            if checkLoot.stack.name == loot.name and checkLoot.to_be_deconstructed(event.force) == false then
                if global.spilledLoot[checkLoot] == nil then
                    checkLoot.to_be_looted = true
                    global.spilledLoot[checkLoot] = {force=event.force}
                end
            end
        end
    end
end

if safetyRadius == 0 or IsEnemyNear(alien, 2 * safetyRadius) then return end

--log(alien.name .. " died as last survivor.")
for checkLoot,info in pairs(global.spilledLoot) do
    if not checkLoot.valid then
        --log("manually looted")
        global.spilledLoot[checkLoot] = nil
    else
        if Distance(alien, checkLoot) < safetyRadius then
            checkLoot.to_be_looted = true
            checkLoot.order_deconstruction(info.force)
            global.spilledLoot[checkLoot] = nil
        end
    end
end
-- check loot spilled outside my safety-radius
global.lootToCheck = {}
for checkLoot,_ in pairs(global.spilledLoot) do
    global.lootToCheck[checkLoot] = true
end
for checkLoot,_ in pairs(global.lootToCheck) do
    if global.lootToCheck[checkLoot] == true then
        AttemptMarkForPickup(checkLoot, safetyRadius)
    end
end

end

New response