Entity damage mechanism

Damage calculation:

damage = 0
foreach group in cap.damage_groups:
    damage += cap.damage_groups[group]
        * limit(actual_interval / cap.full_punch_interval, 0.0, 1.0)
        * (object.armor_groups[group] / 100.0)
        -- Where object.armor_groups[group] is 0 for inexistent values
return damage

Client predicts damage based on damage groups. Because of this, it is able to give an immediate response when an entity is damaged or dies; the response is pre-defined and a smoke puff will appear when an entity dies.

The group immortal completely disables normal damage.

Entities can define a special armor group, which is punch_operable. This group disables the regular damage mechanism for players punching it by hand or a non-tool item, so that it can do something else than take damage.

On the Lua side, every punch calls:

entity:on_punch(puncher, time_from_last_punch, tool_capabilities, direction,
                damage)

This should never be called directly, because damage is usually not handled by the entity itself.

(see "Registered entities" section for detailed description)

To punch an entity/object in Lua, call:

object:punch(puncher, time_from_last_punch, tool_capabilities, direction)

(see "ObjectRef" section for detailed description)