Skip to content

Commit f567449

Browse files
authored
Add more information in PlayerHPChangeReason (#16024)
1) Add `node` and `node_pos` field for the `drown` field (analog to `node_damage` type) 2) Add `custom_type` field to allow a standardized way to report more details of the HP change 3) Make `builtin` report a `custom_type` for the HP changes caused by the `/kill` command and `core.do_item_eat` 4) Move the documentation of `PlayerHPChangeReason` to its own section 5) Fill in missing information of said documentation
1 parent 9c37b46 commit f567449

File tree

5 files changed

+43
-20
lines changed

5 files changed

+43
-20
lines changed

builtin/game/chat.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1348,7 +1348,7 @@ local function handle_kill_command(killer, victim)
13481348
core.log("action", string.format("%s killed %s", killer, victim))
13491349
end
13501350
-- Kill victim
1351-
victimref:set_hp(0)
1351+
victimref:set_hp(0, {type="set_hp", custom_type="__builtin:kill_command"})
13521352
return true, S("@1 has been killed.", victim)
13531353
end
13541354

builtin/game/item.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ function core.do_item_eat(hp_change, replace_with_item, itemstack, user, pointed
435435
core.add_item(pos, replace_with_item)
436436
end
437437

438-
user:set_hp(user:get_hp() + hp_change)
438+
user:set_hp(user:get_hp() + hp_change, {type="set_hp", custom_type="__builtin:item_eat"})
439439

440440
return nil -- don't overwrite wield item a second time
441441
end

doc/lua_api.md

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6226,26 +6226,14 @@ Call these functions only at load time!
62266226
* Historically, the new HP value was clamped to [0, 65535] before
62276227
calculating the HP change. This clamping has been removed as of
62286228
version 5.10.0
6229-
* `reason`: a PlayerHPChangeReason table.
6230-
* The `type` field will have one of the following values:
6231-
* `set_hp`: A mod or the engine called `set_hp` without
6232-
giving a type - use this for custom damage types.
6233-
* `punch`: Was punched. `reason.object` will hold the puncher, or nil if none.
6234-
* `fall`
6235-
* `node_damage`: `damage_per_second` from a neighboring node.
6236-
`reason.node` will hold the node name or nil.
6237-
`reason.node_pos` will hold the position of the node
6238-
* `drown`
6239-
* `respawn`
6240-
* Any of the above types may have additional fields from mods.
6241-
* `reason.from` will be `mod` or `engine`.
6229+
* `reason`: a `PlayerHPChangeReason` table.
62426230
* `modifier`: when true, the function should return the actual `hp_change`.
62436231
Note: modifiers only get a temporary `hp_change` that can be modified by later modifiers.
62446232
Modifiers can return true as a second argument to stop the execution of further functions.
62456233
Non-modifiers receive the final HP change calculated by the modifiers.
62466234
* `core.register_on_dieplayer(function(ObjectRef, reason))`
62476235
* Called when a player dies
6248-
* `reason`: a PlayerHPChangeReason table, see register_on_player_hpchange
6236+
* `reason`: a `PlayerHPChangeReason` table
62496237
* For customizing the death screen, see `core.show_death_screen`.
62506238
* `core.register_on_respawnplayer(function(ObjectRef))`
62516239
* Called when player is to be respawned
@@ -6986,7 +6974,7 @@ Formspec functions
69866974
* `"VAL"`: not changed
69876975
* `core.show_death_screen(player, reason)`
69886976
* Called when the death screen should be shown.
6989-
* `player` is an ObjectRef, `reason` is a PlayerHPChangeReason table or nil.
6977+
* `player` is an ObjectRef, `reason` is a `PlayerHPChangeReason` table or nil.
69906978
* By default, this shows a simple formspec with the option to respawn.
69916979
Respawning is done via `ObjectRef:respawn`.
69926980
* You can override this to show a custom death screen.
@@ -8495,7 +8483,7 @@ child will follow movement and rotation of that bone.
84958483
* note: this is called `right_click` for historical reasons only
84968484
* `get_hp()`: returns number of health points
84978485
* `set_hp(hp, reason)`: set number of health points
8498-
* See reason in register_on_player_hpchange
8486+
* reason: A `PlayerHPChangeReason` table (optional)
84998487
* Is limited to the range of 0 ... 65535 (2^16 - 1)
85008488
* For players: HP are also limited by `hp_max` specified in object properties
85018489
* `get_inventory()`: returns an `InvRef` for players, otherwise returns `nil`
@@ -11314,6 +11302,40 @@ See [Decoration types](#decoration-types). Used by `core.register_decoration`.
1131411302
}
1131511303
```
1131611304

11305+
`PlayerHPChangeReason` table definition
11306+
---------------------------------------
11307+
11308+
The `PlayerHPChangeReason` table specifies a reason for player health changes.
11309+
11310+
* The `type` field is for providing one of the possible damage types
11311+
supported natively by the engine. It will have one of the following values:
11312+
* `set_hp`: A mod, builtin or the engine called `set_hp`, either
11313+
without giving a damage type, or by setting `set_hp`
11314+
as damage type explicitly
11315+
* `punch`: Was punched. `reason.object` will hold the puncher, or nil if none.
11316+
* `fall`: Fall damage.
11317+
* `node_damage`: `damage_per_second` from a neighboring node.
11318+
`reason.node` will hold the node name or nil.
11319+
`reason.node_pos` will hold the position of the node
11320+
* `drown`: Drowning damage from a node with the `drowning` field set.
11321+
`reason.node` and `reason.node_pos` are same as for `node_damage`
11322+
* `respawn`: HP restored by respawning.
11323+
* The `custom_type` field may optionally be used to provide a reason that is not
11324+
supported by the engine, as a string. It will be ignored by the engine,
11325+
but it can be used to communicate to other mods about custom damage types.
11326+
If provided, it must be a string. It's recommended to follow the
11327+
`modname:reason` naming convention.
11328+
These custom types exist by default:
11329+
* `__builtin:item_eat`: HP change caused by `core.do_item_eat`
11330+
* `__builtin:kill_command`: `/kill` command
11331+
* The `from` field denotes the origin of the HP change:
11332+
* `engine`: Engine
11333+
* `mod`: Mod or builtin
11334+
* Mods may add additional fields
11335+
11336+
Note: The `from` is ignored by `ObjectRef:set_hp`, the engine will always
11337+
set it to `mod`.
11338+
1131711339
Chat command definition
1131811340
-----------------------
1131911341

src/server/player_sao.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,8 @@ void PlayerSAO::step(float dtime, bool send_recommended)
159159

160160
// No more breath, damage player
161161
if (m_breath == 0) {
162-
PlayerHPChangeReason reason(PlayerHPChangeReason::DROWNING);
162+
std::string nodename = c.name;
163+
PlayerHPChangeReason reason(PlayerHPChangeReason::DROWNING, nodename, p);
163164
setHP(m_hp - c.drowning, reason);
164165
}
165166
}

src/server/player_sao.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ struct PlayerHPChangeReason
250250

251251
// For PLAYER_PUNCH
252252
ServerActiveObject *object = nullptr;
253-
// For NODE_DAMAGE
253+
// For NODE_DAMAGE and DROWNING
254254
std::string node;
255255
v3s16 node_pos;
256256

0 commit comments

Comments
 (0)