PFQNiet wrote: Sun Nov 08, 2020 6:20 am
However, the downside is that you can only have one event handler per event, and therefore only one filter. If you want multiple filters, you will need to go the `if` route. You should still apply a filter collecting all the types you want if possible.
You can make a kind of multi-filter, but it's quite tedious and not intuitive. For example, in Water Turrets I want to act if an entity has been damaged by one of my turrets. It's likely that my turrets have caused the damage if the damage is one of my damage types, so I could filter by that:
Code: Select all
script.on_event(defines.events.on_entity_damaged, on_entity_damaged, {
{filter = "damage-type", type = WT.steam_damage_name},
{filter = "damage-type", type = WT.water_damage_name},
{filter = "damage-type", type = WT.fire_ex_damage_name},
})
This will OR the conditions, so the event will trigger whenever an entity gets my damage. However, there's a catch! WT.fire_ex_damage_name is meant to hurt only the dummies I've defined in my mod, so I've added full resistance against this damage type to all entities but my dummies. But the damage is an area damage, and if any other entity is next to my dummy, it will get "damaged" as well: The event will trigger, but final_damage_amount will be 0. So I want to filter out the cases where no real damage is done. Basically, the condition should be "IF damage > 0 and (type == A or type == B or type == C) THEN trigger event". Seems easy to implement, right?
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 = "damage-type", type = WT.water_damage_name, mode = "or"},
{filter = "damage-type", type = WT.fire_ex_damage_name, mode = "or"},
})
Except this won't work as expected. Instead, the above code translates to "IF (damage > 0 and type == A) or (type == B) or (type == C) THEN trigger event". To get the result I wanted, I had to OR different sets of ANDed conditions:
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"},
{filter = "final-damage-amount", comparison = ">", value = 0, mode = "or"},
{filter = "damage-type", type = WT.fire_ex_damage_name, mode = "and"},
})
So, it is possible to use even more complex filters (Guess what: You can also use "invert = true" to invert a condition!), but you need to take care to set them up correctly.
PFQNiet wrote: Mon Nov 09, 2020 2:52 pm
And, once you're inside the event handler, you still need `if` blocks to handle different cases.
For common events like on_entity_died it really makes a difference whether you'll have to go through the if-blocks for each biter you've killed or whether the event only triggers for the types of entities you're actually interested in. So I'd say filtering out the bulk of unwanted cases via event filtering and fine-tuning the rest inside the event handler is the best solution.