Sorry it has taken me so long to answer -- working on my own mod took way longer than expected (and it's not even ready yet).
I implemented what you suggested, but it doesn't quite work. The problem is I don't know the original health of the damaged entity, and the "final damage" does not account for the entity's original health, so the effect is the explosive shells now heal friendly entities! That seems a bit overpowered, especially as I'd like to do this for all entities, not just rail. Any clever ideas on how to fix that?
You're right, if something was damaged before, you will heal it completely because health will never be smaller than 0. I think nothing can be done about it currently. Any of these would help:
- Allow "entity.health < 0", so adding final_damage_amount to it won't automatically restore all health.
- Get access to the value of entity.health before the damage was applied, perhaps as "entity.original_health" or "entity.health_before_damage".
- Provide access to the current value of entity.lifetime/entity.time_to_live. (That wouldn't affect your mod, but it's something I need for playing with fire, or rather, the "fire" prototype.)
I've just made an interface request. Not sure it will get us any further, as similar requests (e.g. for a new event triggering before damage is applied) have been turned down.
-- TODO: Use an event filter rather than doing all filtering
-- after receiving the event.
There's really nothing much you can filter by except damage type:
script.on_event(defines.events.on_entity_damaged, function(event) … end,
{filter = "damage-type", type = "explosion"}
})
You could register the event in "if … then" and be more precise if only_prevent_friendly_explosive_damage_to_rail is true:
if only_prevent_friendly_explosive_damage_to_rail then
script.on_event(defines.events.on_entity_damaged, function(event) … end,
{filter = "damage-type", type = "explosion"},
{filter = "rail", mode = "and"},
{filter = "rail-signal"},
})
else
script.on_event(defines.events.on_entity_damaged, function(event) … end,
{filter = "damage-type", type = "explosion"}
})
end
The filters will be ORed by default, therefore 'mode = "and"' is needed.