liquid_alternative_source = "", -- Source version of flowing liquid
liquid_viscosity = 0, -- Higher viscosity = slower flow (max. 7)
liquid_renewable = true, -- Can new liquid source be created by placing
+ drowning = true, -- Player will drown in these
two or more sources nearly?
light_source = 0, -- Amount of light emitted by node
damage_per_second = 0, -- If player is inside node, this damage is caused
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)
void setCrack(int level, v3s16 pos);
u16 getHP();
+ u16 getBreath();
bool checkPrivilege(const std::string &priv)
{ return (m_privileges.count(priv) != 0); }
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
*/
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;
};
if (show_hud)
{
hud.drawHotbar(v2s32(displaycenter.X, screensize.Y),
- client.getHP(), client.getPlayerItem());
+ client.getHP(), client.getPlayerItem(), client.getBreath());
}
/*
}
-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;
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));
}
#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
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();
liquid_alternative_source = "";
liquid_viscosity = 0;
liquid_renewable = true;
+ drowning = true;
light_source = 0;
damage_per_second = 0;
node_box = NodeBox();
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)
try{
// Stuff below should be moved to correct place in a version that
// otherwise changes the protocol version
+ drowning = readU8(is);
}catch(SerializationError &e) {};
}
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;
camera_barely_in_ceiling(false),
inventory(gamedef->idef()),
hp(PLAYER_MAX_HP),
+ breath(-1),
peer_id(PEER_ID_INEXISTENT),
// protected
m_gamedef(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;
}
float physics_override_gravity;
u16 hp;
+ u16 breath;
float hurt_tilt_timer;
float hurt_tilt_strength;
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);
{HUD_FLAG_HEALTHBAR_VISIBLE, "healthbar"},
{HUD_FLAG_CROSSHAIR_VISIBLE, "crosshair"},
{HUD_FLAG_WIELDITEM_VISIBLE, "wielditem"},
+ {HUD_FLAG_BREATHBAR_VISIBLE, "breathbar"},
{0, NULL},
};