Add drowning

master
PilzAdam 2013-06-19 14:30:22 +00:00
parent e65ac4d626
commit 53066024f6
15 changed files with 67 additions and 5 deletions

View File

@ -1710,6 +1710,7 @@ Node definition (register_node)
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 B

View File

@ -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)

View File

@ -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); }

View File

@ -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
*/

View File

@ -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;
};

View File

@ -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());
}
/*

View File

@ -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));
}

View File

@ -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();

View File

@ -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) {};
}

View File

@ -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;

View File

@ -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;
}

View File

@ -232,6 +232,7 @@ public:
float physics_override_gravity;
u16 hp;
u16 breath;
float hurt_tilt_timer;
float hurt_tilt_strength;

View File

@ -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);

View File

@ -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},
};