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.
Mods introducing new content into the game.
Augmented or new ways of transporting materials - belts, inserters, pipes!
Related to roboports and logistic robots.
More than just chests.
Hi,
I tried using this on Space Exploration with Alien Loot Economy.
Firstly, it wasn't using surfaces correctly - it used the chest surface. The other thing is the extreme lag it gives every 10 seconds during the on_tick event.
I was able to modify my local copy to completely eliminate the on_tick handler, by modifying the on_entity_died event as follows:
script.on_event(defines.events.on_research_finished, function(event)
auto_cons_check(event.research.force)
end)
-- When an entity dies, we add its position to the table of positions
-- if we have the automated construction tech and if the mod is enabled
script.on_event(defines.events.on_entity_died, function(event)
artifactList = {}
if auto_cons_researched then
if not global.lootChestPos then
global.lootChestPos = {}
end
if string.find(event.entity.name,"spitter") or string.find(event.entity.name, "biter") or string.find(event.entity.name, "worm") or string.find(event.entity.name, "nest") then
entityLoot = event.loot.get_contents() -- gives LuaInventory
log("[LCP]: entity loot: "..serpent.block(entityLoot))
test = entityLoot["artifact-ore"]
if test and test > 0 then
log("[LCP]: we found "..tostring(entityLoot["artifact-ore"]).." artifacts")
table.insert(artifactList, {name = "artifact-ore", count = test})
end
end
end
--Read artifactList and insert into Loot Chest
if #artifactList ~= 0 then
local chest = global.lootChest
local cannotInsert = false
for _, itemStack in pairs(artifactList) do
if(chest.can_insert(itemStack)) then
chest.insert(itemStack)
event.loot.clear()
else
cannotInsert = true
end
end
if cannotInsert then
for _, plr in pairs(chest.force.players) do
plr.print("Cannot insert loot. Artifact loot chest is full.")
end
end
end
end)
there's some limitations, mostly that i'm only searching for artifact-ore type, but i'm sure it would be easy enough for you to adapt this.
now the mod doesn't consume any UPS on my map, and the global table doesn't grow forever (resolves the save/load times).
Hi, nice work there. Although it might sound crazy, but I like that "feature" from my version that you could plonk down the chest and if there were some loots from the same session, it got tranfered nonetheless. So I'm unsure wether to change and what.
On first "fiddeling-around" with it, it seems I would have to add a big block for each loot, or am I missing something?
So for example a mod has alien-ore-1, alien-ore-2, and alien-ore-3 I can't just search for "ore".
Do I need one of these for each loot then?
if string.find(event.entity.name,"spitter") or string.find(event.entity.name, "biter") or string.find(event.entity.name, "worm") or string.find(event.entity.name, "nest") then
entityLoot = event.loot.get_contents() -- gives LuaInventory
log("[LCP]: entity loot: "..serpent.block(entityLoot))
test = entityLoot["artifact-ore"]
if test and test > 0 then
log("[LCP]: we found "..tostring(entityLoot["artifact-ore"]).." artifacts")
table.insert(artifactList, {name = "artifact-ore", count = test})
end
end
thanks, i thought it was like this from the beginning (I recall reading it's event-driven somewhere) so I was surprised when I finally got around to testing it and found extreme UPS drops.
the other thing I noticed was the huge size of its global table because I've had entities dying for a long time without having a single LootChest+ placed.
so, the changes I made, can actually be greatly simplified; because we're getting the Loot directly from the entity obituary, we don't need to search for it, or even validate the name.
i'll work on a newer version for you to take a look at.
Hm thinking about the global table problem... if the loot chest would be unlocked much earlier, like it was before IIRC with steel, then problem solved...somewhat at least.
But also I'm excited to see what you come up with. Sounds interesting and has that huge benefit of being very cheap UPS wise.
script.on_event(defines.events.on_entity_died, function(event)
local foundLoot = false
if not global.artifactList then
log("[LootChestUPS] Initialise artifactList")
global.artifactList = {}
end
if string.find(event.entity.name,"spitter") or string.find(event.entity.name, "biter") or string.find(event.entity.name, "worm") or string.find(event.entity.name, "nest") then
entityLoot = event.loot.get_contents() -- gives LuaInventory
lootCount = 0
for key,value in pairs(entityLoot) do
lootCount = entityLoot[key]
itemName = key
if lootCount and lootCount > 0 then
foundLoot = true
if not global.artifactList[itemName] then
global.artifactList[itemName] = 0
end
global.artifactList[itemName] = global.artifactList[itemName] + lootCount
extraText = ""
event.loot.clear()
extraText = " Uncollected loot has accumulated."
end
end
else
return
end
if not foundLoot or global.artifactList == {} then
return
end
--Read global.artifactList and insert into Loot Chest
--log("[LootChestUPS] artifactList: "..serpent.block(global.artifactList))
local chest = global.lootChest
if not chest.valid then
local errorMsg = "[LootChestUPS] No loot chest is placed, loot can not be collected."
if not global.validChestCheckCount then
global.validChestCheckCount = 0
game.print(errorMsg)
end
if global.validChestCheckCount > 3000 then
global.validChestCheckCount = 0
game.print(errorMsg)
else
global.validChestCheckCount = global.validChestCheckCount + 1
end
return
end
local cannotInsert = false
for _, itemStack in pairs(global.artifactList) do
if itemStack > 0 then
parameters = {}
parameters["name"] = _
parameters["count"] = itemStack
if(chest.valid and chest.can_insert(parameters)) then
chest.insert(parameters)
global.artifactList[parameters["name"]] = 0
event.loot.clear()
else
cannotInsert = true
end
end
end
if chest.valid and cannotInsert then
for _, plr in pairs(chest.force.players) do
plr.print("Cannot insert loot. Artifact loot chest is full."..extraText)
end
end
end)
i've modified it so that it just grabs ALL loot.
so my solution is to keep a dictionary of the loots and increment the count instead of storing an ever-growing number of parameters, it will build the parameters on the spot when attempting insertion.
i've tested this with full chests, i've also ensured that there's a periodic notice to the player that it's unable to add to a chest, since none exist.
the main problem with this is that there's no handling for multiple player forces. everyone uses one loot chest.
Am testing it right now and so far looking pretty awesome! Pretty good solution to destroy the loots if no chest is found.
Not sure about the multiple forces stuff.. Solo-engineer here.. Is that working when everyone has a loot chest?
Anyways, I go and test some more now. Big thanks for your contributions.
yeah i play solo as well, so i'm not concerned about PvP until someone complains.
i'm working on having it print warnings to the user depending on whether or not they want the warnings.
i've tested with a plague rocket in K2+SE on a 100% threat planet, it really does a lot better when pulling everything into the chest.
I've uploaded my modifications as LootChestUPS mod, feel free to take them and integrate to yours.
Thanks a lot for your effort, very appreciated!
Instead of nuking the loots if no chest is found, could they be marked for deconstruction? would that make a difference?
In my short testing the mod is almost non existent, script-update wise - love it!
in the latest version it has an optimised method of storing the uncollected loots.
instead of:
{..{name: .. count: ...}, { name: ..., count: ...}}
it's:
{
"name" = "count",
"name" = "count"
}
and the counts are incremented every time we find loot, set to 0 every time we insert some into the chest.
so if you're producing loot faster than you can pull it out, there will be some potential rounding errors if you have, say, 1000 in the queue and space for 980, i think the game just deletes the 20 that didn't fit.
it was possible to search the chest for free slots, and subtract what can fit from what's in the queue, but that requires a lot of compute power for a death rate that probably is already hurting UPS. i didn't see the point - this is what would be required to deconstruct the remaining ground items.
another UPS optimisation is to enable the choice to have the chest use active provider chest prototype instead of passive, which eliminates the need for an inserter to empty the chest.
not worth it then. ok but not really a problem in my eyes. In a normal run you don't lose much loot. In my last vanilla run, I maybe fought 10 bases until I researched the chest.
Ah another weird thing, a chest placed by nanobots isn't working. Does that need some revive or so?
it also has a problem with GhostPlacerExpress, if you figure that one out, let me know. it seems the event doesn't fire to handle loot chest assignment.
Will do! Until then I'll plonk it down myself.
Thanks again for your work!
no problem, thanks for the starting point. learned a lot. struggled with schall pickup towers for too long but space exploration's multiple surface thing just finally got to me