aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client.cpp7
-rw-r--r--src/client.h1
-rw-r--r--src/environment.cpp40
-rw-r--r--src/environment.h2
-rw-r--r--src/game.cpp2
-rw-r--r--src/hud.cpp5
-rw-r--r--src/hud.h3
-rw-r--r--src/nodedef.cpp3
-rw-r--r--src/nodedef.h1
-rw-r--r--src/player.cpp4
-rw-r--r--src/player.h1
-rw-r--r--src/script/common/c_content.cpp1
-rw-r--r--src/script/lua_api/l_object.cpp1
13 files changed, 66 insertions, 5 deletions
diff --git a/src/client.cpp b/src/client.cpp
index 6b1789fe0..5f53e14f7 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -2680,6 +2680,13 @@ u16 Client::getHP()
return player->hp;
}
+u16 Client::getBreath()
+{
+ Player *player = m_env.getLocalPlayer();
+ assert(player != NULL);
+ return player->breath;
+}
+
bool Client::getChatMessage(std::wstring &message)
{
if(m_chat_queue.size() == 0)
diff --git a/src/client.h b/src/client.h
index f0cc55868..1d231a5a3 100644
--- a/src/client.h
+++ b/src/client.h
@@ -349,6 +349,7 @@ public:
void setCrack(int level, v3s16 pos);
u16 getHP();
+ u16 getBreath();
bool checkPrivilege(const std::string &priv)
{ return (m_privileges.count(priv) != 0); }
diff --git a/src/environment.cpp b/src/environment.cpp
index a97a9bd08..99da5190c 100644
--- a/src/environment.cpp
+++ b/src/environment.cpp
@@ -2227,7 +2227,45 @@ void ClientEnvironment::step(float dtime)
damageLocalPlayer(damage_per_second, true);
}
}
-
+
+ /*
+ Drowning
+ */
+ if(m_drowning_interval.step(dtime, 2.0))
+ {
+ v3f pf = lplayer->getPosition();
+
+ // head
+ v3s16 p = floatToInt(pf + v3f(0, BS*1.6, 0), BS);
+ MapNode n = m_map->getNodeNoEx(p);
+ ContentFeatures c = m_gamedef->ndef()->get(n);
+
+ if(c.isLiquid() && c.drowning){
+ if(lplayer->breath > 10)
+ lplayer->breath = 11;
+ if(lplayer->breath > 0)
+ lplayer->breath -= 1;
+ }
+
+ if(lplayer->breath == 0){
+ damageLocalPlayer(1, true);
+ }
+ }
+ if(m_breathing_interval.step(dtime, 0.5))
+ {
+ v3f pf = lplayer->getPosition();
+
+ // head
+ v3s16 p = floatToInt(pf + v3f(0, BS*1.6, 0), BS);
+ MapNode n = m_map->getNodeNoEx(p);
+ ContentFeatures c = m_gamedef->ndef()->get(n);
+
+ if(!c.isLiquid() || !c.drowning){
+ if(lplayer->breath <= 10)
+ lplayer->breath += 1;
+ }
+ }
+
/*
Stuff that can be done in an arbitarily large dtime
*/
diff --git a/src/environment.h b/src/environment.h
index a62173a11..ac479999c 100644
--- a/src/environment.h
+++ b/src/environment.h
@@ -494,6 +494,8 @@ private:
Queue<ClientEnvEvent> m_client_event_queue;
IntervalLimiter m_active_object_light_update_interval;
IntervalLimiter m_lava_hurt_interval;
+ IntervalLimiter m_drowning_interval;
+ IntervalLimiter m_breathing_interval;
std::list<std::string> m_player_names;
};
diff --git a/src/game.cpp b/src/game.cpp
index 30d9c7faf..88be47b39 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -3310,7 +3310,7 @@ void the_game(
if (show_hud)
{
hud.drawHotbar(v2s32(displaycenter.X, screensize.Y),
- client.getHP(), client.getPlayerItem());
+ client.getHP(), client.getPlayerItem(), client.getBreath());
}
/*
diff --git a/src/hud.cpp b/src/hud.cpp
index a3ae38bcb..9404ed997 100644
--- a/src/hud.cpp
+++ b/src/hud.cpp
@@ -278,7 +278,7 @@ void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture, s
}
-void Hud::drawHotbar(v2s32 centerlowerpos, s32 halfheartcount, u16 playeritem) {
+void Hud::drawHotbar(v2s32 centerlowerpos, s32 halfheartcount, u16 playeritem, s32 breath) {
InventoryList *mainlist = inventory->getList("main");
if (mainlist == NULL) {
errorstream << "draw_hotbar(): mainlist == NULL" << std::endl;
@@ -295,6 +295,9 @@ void Hud::drawHotbar(v2s32 centerlowerpos, s32 halfheartcount, u16 playeritem) {
if (player->hud_flags & HUD_FLAG_HEALTHBAR_VISIBLE)
drawStatbar(pos - v2s32(0, 4), HUD_CORNER_LOWER, HUD_DIR_LEFT_RIGHT,
"heart.png", halfheartcount, v2s32(0, 0));
+ if (player->hud_flags & HUD_FLAG_BREATHBAR_VISIBLE && breath <= 10)
+ drawStatbar(pos - v2s32(-180, 4), HUD_CORNER_LOWER, HUD_DIR_LEFT_RIGHT,
+ "bubble.png", breath*2, v2s32(0, 0));
}
diff --git a/src/hud.h b/src/hud.h
index fa9d33f8b..c7289f7c4 100644
--- a/src/hud.h
+++ b/src/hud.h
@@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define HUD_FLAG_HEALTHBAR_VISIBLE (1 << 1)
#define HUD_FLAG_CROSSHAIR_VISIBLE (1 << 2)
#define HUD_FLAG_WIELDITEM_VISIBLE (1 << 3)
+#define HUD_FLAG_BREATHBAR_VISIBLE (1 << 4)
#define HUD_PARAM_HOTBAR_ITEMCOUNT 1
@@ -122,7 +123,7 @@ public:
void drawStatbar(v2s32 pos, u16 corner, u16 drawdir,
std::string texture, s32 count, v2s32 offset);
- void drawHotbar(v2s32 centerlowerpos, s32 halfheartcount, u16 playeritem);
+ void drawHotbar(v2s32 centerlowerpos, s32 halfheartcount, u16 playeritem, s32 breath);
void resizeHotbar();
void drawCrosshair();
diff --git a/src/nodedef.cpp b/src/nodedef.cpp
index ba3e42e98..7d8ce70d3 100644
--- a/src/nodedef.cpp
+++ b/src/nodedef.cpp
@@ -211,6 +211,7 @@ void ContentFeatures::reset()
liquid_alternative_source = "";
liquid_viscosity = 0;
liquid_renewable = true;
+ drowning = true;
light_source = 0;
damage_per_second = 0;
node_box = NodeBox();
@@ -279,6 +280,7 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version)
writeU8(os, rightclickable);
// Stuff below should be moved to correct place in a version that otherwise changes
// the protocol version
+ writeU8(os, drowning);
}
void ContentFeatures::deSerialize(std::istream &is)
@@ -343,6 +345,7 @@ void ContentFeatures::deSerialize(std::istream &is)
try{
// Stuff below should be moved to correct place in a version that
// otherwise changes the protocol version
+ drowning = readU8(is);
}catch(SerializationError &e) {};
}
diff --git a/src/nodedef.h b/src/nodedef.h
index 2691aca33..e397d20e0 100644
--- a/src/nodedef.h
+++ b/src/nodedef.h
@@ -219,6 +219,7 @@ struct ContentFeatures
u8 liquid_viscosity;
// Is liquid renewable (new liquid source will be created between 2 existing)
bool liquid_renewable;
+ bool drowning;
// Amount of light the node emits
u8 light_source;
u32 damage_per_second;
diff --git a/src/player.cpp b/src/player.cpp
index 4eb5955c0..a199c9a6c 100644
--- a/src/player.cpp
+++ b/src/player.cpp
@@ -36,6 +36,7 @@ Player::Player(IGameDef *gamedef):
camera_barely_in_ceiling(false),
inventory(gamedef->idef()),
hp(PLAYER_MAX_HP),
+ breath(-1),
peer_id(PEER_ID_INEXISTENT),
// protected
m_gamedef(gamedef),
@@ -80,7 +81,8 @@ Player::Player(IGameDef *gamedef):
physics_override_gravity = 1;
hud_flags = HUD_FLAG_HOTBAR_VISIBLE | HUD_FLAG_HEALTHBAR_VISIBLE |
- HUD_FLAG_CROSSHAIR_VISIBLE | HUD_FLAG_WIELDITEM_VISIBLE;
+ HUD_FLAG_CROSSHAIR_VISIBLE | HUD_FLAG_WIELDITEM_VISIBLE |
+ HUD_FLAG_BREATHBAR_VISIBLE;
hud_hotbar_itemcount = HUD_HOTBAR_ITEMCOUNT_DEFAULT;
}
diff --git a/src/player.h b/src/player.h
index d3738fd52..517bd354d 100644
--- a/src/player.h
+++ b/src/player.h
@@ -232,6 +232,7 @@ public:
float physics_override_gravity;
u16 hp;
+ u16 breath;
float hurt_tilt_timer;
float hurt_tilt_strength;
diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp
index c7966a0be..64c76ef7c 100644
--- a/src/script/common/c_content.cpp
+++ b/src/script/common/c_content.cpp
@@ -389,6 +389,7 @@ ContentFeatures read_content_features(lua_State *L, int index)
f.liquid_viscosity = getintfield_default(L, index,
"liquid_viscosity", f.liquid_viscosity);
getboolfield(L, index, "liquid_renewable", f.liquid_renewable);
+ getboolfield(L, index, "drowning", f.drowning);
// Amount of light the node emits
f.light_source = getintfield_default(L, index,
"light_source", f.light_source);
diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp
index 1e45610a6..f90b59285 100644
--- a/src/script/lua_api/l_object.cpp
+++ b/src/script/lua_api/l_object.cpp
@@ -62,6 +62,7 @@ struct EnumString es_HudBuiltinElement[] =
{HUD_FLAG_HEALTHBAR_VISIBLE, "healthbar"},
{HUD_FLAG_CROSSHAIR_VISIBLE, "crosshair"},
{HUD_FLAG_WIELDITEM_VISIBLE, "wielditem"},
+ {HUD_FLAG_BREATHBAR_VISIBLE, "breathbar"},
{0, NULL},
};