Skip to content

Commit f7d50a8

Browse files
SmallJokernerzhul
authored andcommittedAug 23, 2017
Respect object property hp_max field for players (#6287)
* Respect object property hp_max field for players This allows modders to configure the maximal HP per player * Statbars: Downscale bar to full 20 HP when exceeding this value Add default max HP for players and breath constants to builtin Document the constants * Rename PLAYER_MAX_HP -> PLAYER_MAX_HP_DEFAULT
1 parent d01b65a commit f7d50a8

File tree

9 files changed

+51
-27
lines changed

9 files changed

+51
-27
lines changed
 

Diff for: ‎builtin/game/constants.lua

+4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ core.EMERGE_GENERATED = 4
2121
-- constants.h
2222
-- Size of mapblocks in nodes
2323
core.MAP_BLOCKSIZE = 16
24+
-- Default maximal HP of a player
25+
core.PLAYER_MAX_HP_DEFAULT = 20
26+
-- Maximal breath of a player
27+
core.PLAYER_MAX_BREATH = 11
2428

2529
-- light.h
2630
-- Maximum value for node 'light_source' parameter

Diff for: ‎builtin/game/statbars.lua

+30-19
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ local health_bar_definition =
66
hud_elem_type = "statbar",
77
position = { x=0.5, y=1 },
88
text = "heart.png",
9-
number = 20,
9+
number = core.PLAYER_MAX_HP_DEFAULT,
1010
direction = 0,
1111
size = { x=24, y=24 },
1212
offset = { x=(-10*24)-25, y=-(48+24+16)},
@@ -37,39 +37,45 @@ local function initialize_builtin_statbars(player)
3737
return
3838
end
3939

40-
if (hud_ids[name] == nil) then
40+
if not hud_ids[name] then
4141
hud_ids[name] = {}
4242
-- flags are not transmitted to client on connect, we need to make sure
4343
-- our current flags are transmitted by sending them actively
4444
player:hud_set_flags(player:hud_get_flags())
4545
end
46+
local hud = hud_ids[name]
4647

4748
if player:hud_get_flags().healthbar and enable_damage then
48-
if hud_ids[name].id_healthbar == nil then
49-
health_bar_definition.number = player:get_hp()
50-
hud_ids[name].id_healthbar = player:hud_add(health_bar_definition)
49+
if hud.id_healthbar == nil then
50+
local hp = player:get_hp()
51+
local max_display_hp = math.max(core.PLAYER_MAX_HP_DEFAULT,
52+
math.max(player:get_properties().hp_max, hp))
53+
-- Limit width of health bar: Scale to the default maximal HP
54+
health_bar_definition.number =
55+
hp / max_display_hp * core.PLAYER_MAX_HP_DEFAULT
56+
hud.id_healthbar = player:hud_add(health_bar_definition)
5157
end
5258
else
53-
if hud_ids[name].id_healthbar ~= nil then
54-
player:hud_remove(hud_ids[name].id_healthbar)
55-
hud_ids[name].id_healthbar = nil
59+
if hud.id_healthbar ~= nil then
60+
player:hud_remove(hud.id_healthbar)
61+
hud.id_healthbar = nil
5662
end
5763
end
5864

59-
if (player:get_breath() < 11) then
65+
if player:get_breath() < core.PLAYER_MAX_BREATH then
6066
if player:hud_get_flags().breathbar and enable_damage then
61-
if hud_ids[name].id_breathbar == nil then
62-
hud_ids[name].id_breathbar = player:hud_add(breath_bar_definition)
67+
if hud.id_breathbar == nil then
68+
hud.id_breathbar = player:hud_add(breath_bar_definition)
6369
end
6470
else
65-
if hud_ids[name].id_breathbar ~= nil then
66-
player:hud_remove(hud_ids[name].id_breathbar)
67-
hud_ids[name].id_breathbar = nil
71+
if hud.id_breathbar ~= nil then
72+
player:hud_remove(hud.id_breathbar)
73+
hud.id_breathbar = nil
6874
end
6975
end
70-
elseif hud_ids[name].id_breathbar ~= nil then
71-
player:hud_remove(hud_ids[name].id_breathbar)
72-
hud_ids[name].id_breathbar = nil
76+
elseif hud.id_breathbar ~= nil then
77+
player:hud_remove(hud.id_breathbar)
78+
hud.id_breathbar = nil
7379
end
7480
end
7581

@@ -101,7 +107,12 @@ local function player_event_handler(player,eventname)
101107
initialize_builtin_statbars(player)
102108

103109
if hud_ids[name].id_healthbar ~= nil then
104-
player:hud_change(hud_ids[name].id_healthbar,"number",player:get_hp())
110+
local hp = player:get_hp()
111+
local max_display_hp = math.max(core.PLAYER_MAX_HP_DEFAULT,
112+
math.max(player:get_properties().hp_max, hp))
113+
-- Limit width of health bar: Scale to the default maximal HP
114+
local hp_count = hp / max_display_hp * core.PLAYER_MAX_HP_DEFAULT
115+
player:hud_change(hud_ids[name].id_healthbar, "number", hp_count)
105116
return true
106117
end
107118
end
@@ -110,7 +121,7 @@ local function player_event_handler(player,eventname)
110121
initialize_builtin_statbars(player)
111122

112123
if hud_ids[name].id_breathbar ~= nil then
113-
player:hud_change(hud_ids[name].id_breathbar,"number",player:get_breath()*2)
124+
player:hud_change(hud_ids[name].id_breathbar, "number", player:get_breath() * 2)
114125
return true
115126
end
116127
end

Diff for: ‎doc/lua_api.txt

+2
Original file line numberDiff line numberDiff line change
@@ -3276,6 +3276,7 @@ This is basically a reference to a C++ `ServerActiveObject`
32763276
* `0`: player is drowning,
32773277
* `1`-`10`: remaining number of bubbles
32783278
* `11`: bubbles bar is not shown
3279+
* See constant: `minetest.PLAYER_MAX_BREATH`
32793280
* `set_attribute(attribute, value)`:
32803281
* Sets an extra attribute with value on player.
32813282
* `value` must be a string.
@@ -3980,6 +3981,7 @@ Definition tables
39803981

39813982
{
39823983
hp_max = 1,
3984+
-- ^ For players, the maximal HP defaults to `minetest.PLAYER_MAX_HP_DEFAULT`
39833985
physical = true,
39843986
collide_with_objects = true, -- collide with other objects if physical = true
39853987
weight = 5,

Diff for: ‎src/constants.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
9090
#define PLAYER_INVENTORY_SIZE (8 * 4)
9191

9292
// Maximum hit points of a player
93-
#define PLAYER_MAX_HP 20
93+
#define PLAYER_MAX_HP_DEFAULT 20
9494

9595
// Maximal breath of a player
9696
#define PLAYER_MAX_BREATH 11

Diff for: ‎src/content_sao.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,7 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, u16 peer_id
782782
{
783783
assert(m_peer_id != 0); // pre-condition
784784

785-
m_prop.hp_max = PLAYER_MAX_HP;
785+
m_prop.hp_max = PLAYER_MAX_HP_DEFAULT;
786786
m_prop.physical = false;
787787
m_prop.weight = 75;
788788
m_prop.collisionbox = aabb3f(-0.3f, 0.0f, -0.3f, 0.3f, 1.77f, 0.3f);
@@ -799,7 +799,7 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, u16 peer_id
799799
m_prop.is_visible = true;
800800
m_prop.makes_footstep_sound = true;
801801
m_prop.stepheight = PLAYER_DEFAULT_STEPHEIGHT * BS;
802-
m_hp = PLAYER_MAX_HP;
802+
m_hp = m_prop.hp_max;
803803
}
804804

805805
PlayerSAO::~PlayerSAO()
@@ -1235,8 +1235,8 @@ void PlayerSAO::setHP(s16 hp)
12351235

12361236
if (hp < 0)
12371237
hp = 0;
1238-
else if (hp > PLAYER_MAX_HP)
1239-
hp = PLAYER_MAX_HP;
1238+
else if (hp > m_prop.hp_max)
1239+
hp = m_prop.hp_max;
12401240

12411241
if (hp < oldhp && !g_settings->getBool("enable_damage")) {
12421242
return;

Diff for: ‎src/remoteplayer.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ void RemotePlayer::deSerialize(std::istream &is, const std::string &playername,
100100
try {
101101
sao->setHPRaw(args.getS32("hp"));
102102
} catch(SettingNotFoundException &e) {
103-
sao->setHPRaw(PLAYER_MAX_HP);
103+
sao->setHPRaw(PLAYER_MAX_HP_DEFAULT);
104104
}
105105

106106
try {

Diff for: ‎src/script/common/c_content.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,9 @@ void read_object_properties(lua_State *L, int index,
183183
if(!lua_istable(L, index))
184184
return;
185185

186-
prop->hp_max = getintfield_default(L, -1, "hp_max", 10);
186+
int hp_max = 0;
187+
if (getintfield(L, -1, "hp_max", hp_max))
188+
prop->hp_max = (s16)rangelim(hp_max, 0, S16_MAX);
187189

188190
getboolfield(L, -1, "physical", prop->physical);
189191
getboolfield(L, -1, "collide_with_objects", prop->collideWithObjects);

Diff for: ‎src/script/lua_api/l_object.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,11 @@ int ObjectRef::l_set_properties(lua_State *L)
751751
if (!prop)
752752
return 0;
753753
read_object_properties(L, 2, prop, getServer(L)->idef());
754+
if (prop->hp_max < co->getHP()) {
755+
co->setHP(prop->hp_max);
756+
if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER)
757+
getServer(L)->SendPlayerHPOrDie((PlayerSAO *)co);
758+
}
754759
co->notifyObjectPropertiesModified();
755760
return 0;
756761
}

Diff for: ‎src/server.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -2588,7 +2588,7 @@ void Server::RespawnPlayer(u16 peer_id)
25882588
<< playersao->getPlayer()->getName()
25892589
<< " respawns" << std::endl;
25902590

2591-
playersao->setHP(PLAYER_MAX_HP);
2591+
playersao->setHP(playersao->accessObjectProperties()->hp_max);
25922592
playersao->setBreath(PLAYER_MAX_BREATH);
25932593

25942594
bool repositioned = m_script->on_respawnplayer(playersao);

0 commit comments

Comments
 (0)
Please sign in to comment.