TheSAguy wrote: ↑Tue Jun 27, 2023 4:47 pm
Code: Select all
--- Look for Alien Artifacts from Loot Drops
if event.loot and event.loot.valid then
for i = 1, #event.loot do
…
To begin with, the if-condition doesn't make sense because event.loot isn't optional, so it will always exist and always be valid. Basically, event.loot is a dynamically generated inventory that has just as many slots as necessary to accommodate all the loot -- if the killed entity didn't leave any loot behind, it will have 0 slots. So you could change this condition to
However, this is redundant as the for-loop will only run iff #event.loot > 0.
Code: Select all
for i = 1, #event.loot do
if event.loot[i].valid_for_read and event.loot[i].name == "small-alien-artifact" then
In this loop, you go over all slots in the loot-inventory. Each slot is a
LuaItemStack, and its name is the name of the item prototype that is placed in this slot.
Code: Select all
writeDebug("Loot Trigger is Small Artifact")
local loot_entities = {}
local loot_entities = event.entity.surface.find_entities_filtered({
position = event.entity.position,
type = "item-on-ground",
radius = 10
})
Before, you've looked for items, now you've looked for real entities. However, this won't find anything because you've mixed up entity.type ("item-entity") and entity.name("item-on-ground"). This should actually find something:
Code: Select all
writeDebug("Loot Trigger is Small Artifact")
local loot_entities = {}
local loot_entities = event.entity.surface.find_entities_filtered({
position = event.entity.position,
name = "item-on-ground",
radius = 10
})
Entities of type item-on-ground are a kind of dummy or container; they have a property entity.stack, which describes what item it contains (name and amount). There may be anything in it, not just your artifacts, so this also won't work as expected:
Code: Select all
writeDebug("Number of small artifacts found = " ..#loot_entities)
if #loot_entities > 0 then
for i = 1, #loot_entities do
writeDebug("got here")
for i, Small_Artifacts in pairs(loot_entities) do
--- Add EACH small Artifict found to a Global Table
--[[
if Small_Artifacts and Small_Artifacts.valid then
global.small_alien_artifact_created[Small_Artifacts.unit_number] = {
artifact = entity,
time = event.tick,
surface = entity.surface,
position = event.entity.position
}
writeDebug("Small Artifact Added")
writeDebug(table_size(global.small_alien_artifact_created))
end
]]
end
end
end
Even worse: Although an item-entity is a LuaEntity, it doesn't have a unit_number, so your scheme for storing the artifacts won't work.
I'm not sure what exactly you want to achieve. My guess is that you want the artifacts to be automatically removed if they haven't been picked up or destroyed after a certain time. If that assumption is correct, it would make sense to store them in tables indexed by event.tick (or event.tick + TICKS_TO_EXPIRE). Then you could check in on_tick whether there a table for that tick exists and destroy all item-entities that are still valid (i.e. they have not been picked up yet).
I've also noticed that only occasionally (some) of the loot will be found in on_entity_died. DaveMcW seems to be right: It seems that all loot items will be item-on-ground by the time that on_post_entity_died triggers. So you should add defines.events.on_post_entity_died to death_events. When your event handler is entered for on_entity_died, check if the loot contains any of your artifacts and just create a new table (indexed by tick). On the next run, look for item-on-ground entities that contain your artifacts and insert them into the appropriate table. Your search radius is rather big (10 tiles), so you may find loot that has been left behind by another entity. But this really shouldn't matter if all you want to do is destroying uncollected loot after a certain time.
Here's my take on your On_Death function, plus the clean-up code for on_tick:
Code: Select all
local reverse_events = {}
for e_name, e in pairs(defines.events) do
reverse_events[e] = e_name
end
LOOT_EXPIRE_TICKS = 60*30 -- 30 seconds, should probably be longer!
--------------------------------------------------------------------
local function On_Death(event)
writeDebug(string.format("Entered handler for event %s: %s", reverse_events[event.name], serpent.line(event)))
local post_event = (event.name == defines.events.on_post_entity_died)
-- Exists only in on_entity_died!
local entity = event.entity
-- on_post_entity_died provides surface_index
local surface = post_event and game.surfaces[event.surface_index] or
entity.surface
-- Only relevant for on_entity_died!
local force = entity and entity.force
-- on_post_entity_died provides position
local pos = post_event and event.position or entity.position
local loot_expires_on_tick = event.tick + LOOT_EXPIRE_TICKS
-- Code for on_post_entity_died
if post_event then
local tick = loot_expires_on_tick
-- Tables have been created in on_entity_died if artifacts were found in loot!
if global.small_alien_artifact_created[tick] or
global.big_alien_artifact_created[tick] then
-- Look for items on ground around position where entity died
local loot_entities = surface.find_entities_filtered({
position = pos,
name = "item-on-ground",
--~ type = "item-entity",
radius = 10
})
log("loot_entities: "..serpent.block(loot_entities))
-- Look for the items on ground that contain artifacts
for e, entity in pairs(loot_entities) do
log(string.format("e: %s\titem in entity: %s (%s)",
e, entity.stack.name, entity.stack.count))
if entity.stack.valid and entity.stack.valid_for_read then
-- Add small artifacts to table
if entity.stack.name == "small-alien-artifact" and
global.small_alien_artifact_created[tick] then
writeDebug("Loot Trigger is Small Artifact")
log("entity: "..serpent.line(entity and entity.valid and entity.name))
table.insert(global.small_alien_artifact_created[tick], entity)
-- Add big artifacts to table
elseif entity.stack.name == "alien-artifact" and
global.big_alien_artifact_created[tick] then
writeDebug("Loot Trigger is Big Artifact")
table.insert(global.big_alien_artifact_created[tick], entity)
end
end
end
writeDebug(string.format("Added %s small and %s big artifacts!",
global.small_alien_artifact_created[tick] and
#global.small_alien_artifact_created[tick] or 0,
global.big_alien_artifact_created[tick] and
#global.big_alien_artifact_created[tick] or 0))
end
-- Nothing more to do for on_post_entity_died!
return
end
--------------------------------------------------------------------
-- Code for on_entity_died
--- If you remove a rocket silo, the tech levle lowers again.
if entity.valid and entity.type == "rocket-silo" and
settings.startup["NE_Challenge_Mode"].value then
…
end
--- Unit Launcher Mine Detinated
if entity.valid and NELandmine(entity) == "landmine" then
…
end
--- Look for Alien Artifacts from Loot Drops
local loot = event.loot.get_contents()
for i_name, i_count in pairs(loot) do
log(string.format("name: %s\tcount: %s", i_name, i_count))
end
-- Create tables
if loot["small-alien-artifact"] then
global.small_alien_artifact_created[loot_expires_on_tick] = {}
end
if loot["alien-artifact"] then
global.big_alien_artifact_created[loot_expires_on_tick] = {}
end
…
end
local function on_tick()
if global.big_alien_artifact_created[game.tick] then
local cnt = 0
for e, entity in pairs(global.big_alien_artifact_created[game.tick]) do
if entity.valid then
cnt = cnt + 1
entity.destroy()
end
end
global.big_alien_artifact_created[game.tick] = nil
log(string.format("Removed %s big artifacts!", cnt))
end
if global.small_alien_artifact_created[game.tick] then
local cnt = 0
for e, entity in pairs(global.small_alien_artifact_created[game.tick] or {}) do
if entity.valid then
entity.destroy()
end
end
global.small_alien_artifact_created[game.tick] = nil
log(string.format("Removed %s small artifacts!", cnt))
end
…
end