Code: Select all
script.on_event(defines.events.on_entity_damaged, on_entity_damaged, {
{filter = "final-damage-amount", comparison = ">", value = 0},
{filter = "damage-type", type = WT.steam_damage_name, mode = "and"},
{filter = "final-damage-amount", comparison = ">", value = 0, mode = "or"},
{filter = "damage-type", type = WT.water_damage_name, mode = "and"},
})
Now I've just found a bug in one of my mods. It didn't work as expected because I've messed up the conditions for a surface search:
Code: Select all
local not_burning_types = { "character", "lamp", "electric-pole" } -- Just some random prototype types…
local e_type -- Result of an operation that returns either a valid prototype type or nil
local entities = surface.find_entities_filtered{
force = force_name,
type = e_type or not_burning_types,
limit = 1000,
invert = e_type and false or true
}
The code above gives me the expected results if e_type is not nil. But if it is nil, the filter is intrinsically broken: To get the correct types, I need to search for the types I want to ignore and invert the search. However, "invert" applies to all filters (see here: "If the filters should be inverted. These filters are: name, type, ghost_name, ghost_type, direction, collision_mask, force."), so this would give me all entities that are not listed in not_burning_types -- but none of these entities would belong to the correct force!
Of course, I could work around it, for example this way:
Code: Select all
local inv_forces = { player = {"enemy", "neutral"}, "enemy" = {"player", "neutral"}, "neutral = {"player", "enemy"} }
local not_burning_types = { "character", "lamp", "electric-pole" } -- Just some random prototype types…
local e_type -- Result of an operation that returns either a valid prototype type or nil
local entities = surface.find_entities_filtered{
force = e_type and force_name or inv_forces[force_name],
type = e_type or not_burning_types,
limit = 1000,
invert = e_type and false or true
}
Code: Select all
local entities = surface.find_entities_filtered{
{ filter = "force", force = force_name },
{ filter = "type", type = e_type or not_burning_types, invert = true, mode = "and" }
}
- It's easy and intuitive to combine even contradicting conditions.
- Therefore it could encourage leaner code (e.g. instead of making two surface searches and filter out entities that are found by both searches, we could reduce that to just one search with clever filtering).
- It would make the code more readable. (find_entities_filtered takes the arguments area, position, radius, to_be_upgraded, limit AND name, type, ghost_name, ghost_type, direction, collision_mask, force. Of these, only the latter are actual filters that can be inverted. It's easy to overlook that a particular argument is or isn't a filter, so it's easy to introduce bugs -- just as it happened to me.)