switch player states to true percentages, and add hud indicator of last damage, aka "I should make smaller commits"
After Width: | Height: | Size: 163 B |
After Width: | Height: | Size: 164 B |
After Width: | Height: | Size: 164 B |
After Width: | Height: | Size: 172 B |
After Width: | Height: | Size: 168 B |
After Width: | Height: | Size: 169 B |
After Width: | Height: | Size: 168 B |
After Width: | Height: | Size: 169 B |
|
@ -504,8 +504,10 @@ void Client::step(float dtime)
|
|||
event.type = CE_PLAYER_SUFFOCATE;
|
||||
// this will cause the damage screen to flash
|
||||
// when suffocation starts effecting damage
|
||||
if (getAir() < 1 && damage > 0)
|
||||
if (getAir() < 1 && damage > 0) {
|
||||
event.type = CE_PLAYER_DAMAGE;
|
||||
player->addDamage(PLAYER_HEAD,DAMAGE_AIR,damage);
|
||||
}
|
||||
event.player_damage.amount = damage;
|
||||
m_client_event_queue.push_back(event);
|
||||
}
|
||||
|
@ -519,8 +521,10 @@ void Client::step(float dtime)
|
|||
event.type = CE_PLAYER_HUNGER;
|
||||
// this will cause the damage screen to flash
|
||||
// when hunger starts effecting damage
|
||||
if (getHunger() < 1 && damage > 0)
|
||||
if (getHunger() < 1 && damage > 0) {
|
||||
event.type = CE_PLAYER_DAMAGE;
|
||||
player->addDamage(PLAYER_TORSO,DAMAGE_HUNGER,damage);
|
||||
}
|
||||
event.player_damage.amount = damage;
|
||||
m_client_event_queue.push_back(event);
|
||||
}
|
||||
|
@ -1004,7 +1008,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
|||
player->updateAnim(anim_id,pointed);
|
||||
}
|
||||
break;
|
||||
case TOCLIENT_PLAYERHP:
|
||||
case TOCLIENT_PLAYERSTATE:
|
||||
{
|
||||
std::string datastring((char*)&data[2], datasize-2);
|
||||
std::istringstream is(datastring, std::ios_base::binary);
|
||||
|
@ -1013,14 +1017,17 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
|||
u8 hp = readU8(is);
|
||||
u8 air = readU8(is);
|
||||
u8 hunger = readU8(is);
|
||||
player->dirt = readU8(is);
|
||||
player->wet = readU8(is);
|
||||
player->blood = readU8(is);
|
||||
u16 energy_effect = readU16(is);
|
||||
if (energy_effect > player->energy_effectf)
|
||||
player->energy_effectf = energy_effect;
|
||||
player->cold_effectf += readU16(is);
|
||||
if (m_server_damage) {
|
||||
if (!player->hp)
|
||||
if (!player->health)
|
||||
player->setEnergy(hp);
|
||||
player->hp = hp;
|
||||
player->health = hp;
|
||||
}
|
||||
if (m_server_suffocation)
|
||||
player->air = air;
|
||||
|
@ -2167,7 +2174,7 @@ u16 Client::getHP()
|
|||
Player *player = m_env.getLocalPlayer();
|
||||
if (!player)
|
||||
return 0;
|
||||
return player->hp;
|
||||
return player->health;
|
||||
}
|
||||
|
||||
u16 Client::getAir()
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#include "utility.h"
|
||||
|
||||
#define PROTOCOL_VERSION 10
|
||||
#define PROTOCOL_VERSION 11
|
||||
/* the last protocol version used by 0.3.x minetest-c55 clients */
|
||||
#define PROTOCOL_DOTTHREE 3
|
||||
/* this is the oldest protocol that we will allow to connect
|
||||
|
@ -89,12 +89,17 @@ enum ToClientCommand
|
|||
[4] u8 animation_id
|
||||
*/
|
||||
|
||||
TOCLIENT_PLAYERHP = 0x26,
|
||||
TOCLIENT_PLAYERSTATE = 0x26,
|
||||
/*
|
||||
u16 command
|
||||
s8 hp
|
||||
s8 air
|
||||
s8 hunger
|
||||
u8 dirt
|
||||
u8 water
|
||||
u8 blood
|
||||
u16 energy_effect
|
||||
u16 cold_effect
|
||||
*/
|
||||
|
||||
TOCLIENT_INVENTORY = 0x27,
|
||||
|
|
|
@ -433,7 +433,7 @@ void MobCAO::step(float dtime, ClientEnvironment *env)
|
|||
)
|
||||
) && fabs(m_position.Z - playerpos.Z) < m.attack_player_range.Z*BS
|
||||
) {
|
||||
env->damageLocalPlayerWithArmour(m.attack_player_damage);
|
||||
env->damageLocalPlayer(PLAYER_TORSO,DAMAGE_ATTACK,m.attack_player_damage);
|
||||
m_player_hit_timer = 3.0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -246,8 +246,8 @@ void content_craftitem_init()
|
|||
f->cook_result = CONTENT_CRAFTITEM_ASH;
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-eat";
|
||||
f->hunger_effect = 8;
|
||||
f->health_effect = 4;
|
||||
f->hunger_effect = 40;
|
||||
f->health_effect = 20;
|
||||
lists::add("creative",i);
|
||||
lists::add("cooking",i);
|
||||
|
||||
|
@ -269,8 +269,8 @@ void content_craftitem_init()
|
|||
f->description = wgettext("Apple");
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-eat";
|
||||
f->hunger_effect = 6;
|
||||
f->health_effect = 3;
|
||||
f->hunger_effect = 30;
|
||||
f->health_effect = 15;
|
||||
lists::add("creative",i);
|
||||
|
||||
i = CONTENT_CRAFTITEM_APPLE_IRON;
|
||||
|
@ -281,8 +281,8 @@ void content_craftitem_init()
|
|||
f->description = wgettext("Iron Apple");
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-eat";
|
||||
f->hunger_effect = 16;
|
||||
f->health_effect = 8;
|
||||
f->hunger_effect = 80;
|
||||
f->health_effect = 40;
|
||||
{
|
||||
u16 recipe[9] = {
|
||||
CONTENT_CRAFTITEM_STEEL_INGOT, CONTENT_IGNORE, CONTENT_CRAFTITEM_STEEL_INGOT,
|
||||
|
@ -499,8 +499,8 @@ void content_craftitem_init()
|
|||
f->description = wgettext("Apple Blossoms");
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-eat";
|
||||
f->hunger_effect = 2;
|
||||
f->health_effect = 1;
|
||||
f->hunger_effect = 10;
|
||||
f->health_effect = 5;
|
||||
f->fuel_time = 30/16;
|
||||
lists::add("creative",i);
|
||||
|
||||
|
@ -512,8 +512,8 @@ void content_craftitem_init()
|
|||
f->description = wgettext("Cactus Berry");
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-eat";
|
||||
f->hunger_effect = 6;
|
||||
f->health_effect = 3;
|
||||
f->hunger_effect = 30;
|
||||
f->health_effect = 15;
|
||||
lists::add("creative",i);
|
||||
|
||||
i = CONTENT_CRAFTITEM_MUSH;
|
||||
|
@ -525,7 +525,7 @@ void content_craftitem_init()
|
|||
f->description = wgettext("Mush");
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-eat";
|
||||
f->health_effect = -1;
|
||||
f->health_effect = -5;
|
||||
lists::add("creative",i);
|
||||
|
||||
i = CONTENT_CRAFTITEM_PUMPKINSLICE;
|
||||
|
@ -536,8 +536,8 @@ void content_craftitem_init()
|
|||
f->description = wgettext("Sliced Pumpkin");
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-eat";
|
||||
f->hunger_effect = 6;
|
||||
f->health_effect = 3;
|
||||
f->hunger_effect = 30;
|
||||
f->health_effect = 15;
|
||||
crafting::set1To2Recipe(CONTENT_FARM_PUMPKIN,CONTENT_CRAFTITEM_PUMPKINSLICE);
|
||||
lists::add("craftguide",i);
|
||||
lists::add("creative",i);
|
||||
|
@ -550,8 +550,8 @@ void content_craftitem_init()
|
|||
f->description = wgettext("Pumpkin Pie Slice");
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-eat";
|
||||
f->hunger_effect = 12;
|
||||
f->health_effect = 6;
|
||||
f->hunger_effect = 60;
|
||||
f->health_effect = 30;
|
||||
lists::add("craftguide",i);
|
||||
|
||||
i = CONTENT_CRAFTITEM_APPLE_PIE_SLICE;
|
||||
|
@ -562,8 +562,8 @@ void content_craftitem_init()
|
|||
f->description = wgettext("Apple Pie Slice");
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-eat";
|
||||
f->hunger_effect = 12;
|
||||
f->health_effect = 6;
|
||||
f->hunger_effect = 60;
|
||||
f->health_effect = 30;
|
||||
lists::add("creative",i);
|
||||
|
||||
i = CONTENT_CRAFTITEM_MELONSLICE;
|
||||
|
@ -574,8 +574,8 @@ void content_craftitem_init()
|
|||
f->description = wgettext("Sliced Melon");
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-eat";
|
||||
f->hunger_effect = 8;
|
||||
f->health_effect = 4;
|
||||
f->hunger_effect = 40;
|
||||
f->health_effect = 20;
|
||||
crafting::set1To2Recipe(CONTENT_FARM_MELON,CONTENT_CRAFTITEM_MELONSLICE);
|
||||
lists::add("craftguide",i);
|
||||
lists::add("creative",i);
|
||||
|
@ -588,8 +588,8 @@ void content_craftitem_init()
|
|||
f->description = wgettext("Wheat");
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-eat";
|
||||
f->hunger_effect = 2;
|
||||
f->health_effect = 1;
|
||||
f->hunger_effect = 10;
|
||||
f->health_effect = 5;
|
||||
lists::add("creative",i);
|
||||
|
||||
i = CONTENT_CRAFTITEM_FLOUR;
|
||||
|
@ -600,8 +600,8 @@ void content_craftitem_init()
|
|||
f->description = wgettext("Flour");
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-eat";
|
||||
f->hunger_effect = 2;
|
||||
f->health_effect = 1;
|
||||
f->hunger_effect = 10;
|
||||
f->health_effect = 5;
|
||||
crafting::set1Any2Recipe(CONTENT_CRAFTITEM_WHEAT,CONTENT_CRAFTITEM_WHEAT,CONTENT_CRAFTITEM_FLOUR);
|
||||
lists::add("craftguide",i);
|
||||
lists::add("creative",i);
|
||||
|
@ -615,8 +615,8 @@ void content_craftitem_init()
|
|||
f->cook_result = CONTENT_CRAFTITEM_BREAD;
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-eat";
|
||||
f->hunger_effect = 4;
|
||||
f->health_effect = 2;
|
||||
f->hunger_effect = 20;
|
||||
f->health_effect = 10;
|
||||
crafting::set1Any2Recipe(CONTENT_CRAFTITEM_FLOUR,CONTENT_CRAFTITEM_FLOUR,CONTENT_CRAFTITEM_DOUGH);
|
||||
lists::add("craftguide",i);
|
||||
lists::add("creative",i);
|
||||
|
@ -630,8 +630,8 @@ void content_craftitem_init()
|
|||
f->description = wgettext("Bread");
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-eat";
|
||||
f->hunger_effect = 10;
|
||||
f->health_effect = 5;
|
||||
f->hunger_effect = 50;
|
||||
f->health_effect = 20;
|
||||
lists::add("creative",i);
|
||||
|
||||
i = CONTENT_CRAFTITEM_POTATO;
|
||||
|
@ -643,8 +643,8 @@ void content_craftitem_init()
|
|||
f->cook_result = CONTENT_CRAFTITEM_ROASTPOTATO;
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-eat";
|
||||
f->hunger_effect = 6;
|
||||
f->health_effect = 3;
|
||||
f->hunger_effect = 30;
|
||||
f->health_effect = 15;
|
||||
lists::add("creative",i);
|
||||
lists::add("cooking",i);
|
||||
|
||||
|
@ -666,8 +666,8 @@ void content_craftitem_init()
|
|||
f->description = wgettext("Roast Potato");
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-eat";
|
||||
f->hunger_effect = 12;
|
||||
f->health_effect = 6;
|
||||
f->hunger_effect = 60;
|
||||
f->health_effect = 30;
|
||||
lists::add("creative",i);
|
||||
|
||||
i = CONTENT_CRAFTITEM_CARROT;
|
||||
|
@ -678,8 +678,8 @@ void content_craftitem_init()
|
|||
f->description = wgettext("Carrot");
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-eat";
|
||||
f->hunger_effect = 6;
|
||||
f->health_effect = 4;
|
||||
f->hunger_effect = 30;
|
||||
f->health_effect = 20;
|
||||
lists::add("creative",i);
|
||||
|
||||
i = CONTENT_CRAFTITEM_CARROT_CAKE_RAW;
|
||||
|
@ -691,8 +691,8 @@ void content_craftitem_init()
|
|||
f->cook_result = CONTENT_CRAFTITEM_CARROT_CAKE;
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-eat";
|
||||
f->hunger_effect = 6;
|
||||
f->health_effect = 3;
|
||||
f->hunger_effect = 30;
|
||||
f->health_effect = 20;
|
||||
crafting::set1over1Recipe(CONTENT_CRAFTITEM_CARROT,CONTENT_CRAFTITEM_DOUGH,CONTENT_CRAFTITEM_CARROT_CAKE_RAW);
|
||||
lists::add("craftguide",i);
|
||||
lists::add("cooking",i);
|
||||
|
@ -705,8 +705,8 @@ void content_craftitem_init()
|
|||
f->description = wgettext("Carrot Cake");
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-eat";
|
||||
f->hunger_effect = 12;
|
||||
f->health_effect = 6;
|
||||
f->hunger_effect = 60;
|
||||
f->health_effect = 30;
|
||||
lists::add("creative",i);
|
||||
|
||||
i = CONTENT_CRAFTITEM_BEETROOT;
|
||||
|
@ -717,8 +717,8 @@ void content_craftitem_init()
|
|||
f->description = wgettext("Beetroot");
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-eat";
|
||||
f->hunger_effect = 6;
|
||||
f->health_effect = 3;
|
||||
f->hunger_effect = 30;
|
||||
f->health_effect = 15;
|
||||
lists::add("creative",i);
|
||||
|
||||
i = CONTENT_CRAFTITEM_GRAPE;
|
||||
|
@ -729,8 +729,8 @@ void content_craftitem_init()
|
|||
f->description = wgettext("Bunch of Grapes");
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-eat";
|
||||
f->hunger_effect = 6;
|
||||
f->health_effect = 4;
|
||||
f->hunger_effect = 30;
|
||||
f->health_effect = 20;
|
||||
lists::add("creative",i);
|
||||
|
||||
i = CONTENT_CRAFTITEM_STRING;
|
||||
|
@ -786,8 +786,8 @@ void content_craftitem_init()
|
|||
f->drop_item = CONTENT_MOB_FISH;
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-eat";
|
||||
f->hunger_effect = 1;
|
||||
f->health_effect = -1;
|
||||
f->hunger_effect = 5;
|
||||
f->health_effect = -5;
|
||||
lists::add("creative",i);
|
||||
lists::add("cooking",i);
|
||||
|
||||
|
@ -800,8 +800,8 @@ void content_craftitem_init()
|
|||
f->cook_result = CONTENT_CRAFTITEM_ASH;
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-eat";
|
||||
f->hunger_effect = 8;
|
||||
f->health_effect = 6;
|
||||
f->hunger_effect = 40;
|
||||
f->health_effect = 30;
|
||||
lists::add("creative",i);
|
||||
lists::add("cooking",i);
|
||||
|
||||
|
@ -814,8 +814,8 @@ void content_craftitem_init()
|
|||
f->cook_result = CONTENT_CRAFTITEM_COOKED_MEAT;
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-eat";
|
||||
f->hunger_effect = 1;
|
||||
f->health_effect = -1;
|
||||
f->hunger_effect = 5;
|
||||
f->health_effect = -5;
|
||||
lists::add("creative",i);
|
||||
lists::add("cooking",i);
|
||||
|
||||
|
@ -828,8 +828,8 @@ void content_craftitem_init()
|
|||
f->cook_result = CONTENT_CRAFTITEM_ASH;
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-eat";
|
||||
f->hunger_effect = 10;
|
||||
f->health_effect = 6;
|
||||
f->hunger_effect = 50;
|
||||
f->health_effect = 30;
|
||||
lists::add("creative",i);
|
||||
lists::add("cooking",i);
|
||||
|
||||
|
@ -1348,8 +1348,8 @@ void content_craftitem_init()
|
|||
f->drop_count = 1;
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-drink";
|
||||
f->hunger_effect = 3;
|
||||
f->health_effect = 3;
|
||||
f->hunger_effect = 15;
|
||||
f->health_effect = 15;
|
||||
f->energy_effect = 30;
|
||||
f->onuse_replace_item = CONTENT_CRAFTITEM_GLASS_BOTTLE;
|
||||
crafting::set1over1Recipe(CONTENT_CRAFTITEM_GRAPE,CONTENT_CRAFTITEM_GLASS_BOTTLE,CONTENT_CRAFTITEM_GRAPE_JUICE);
|
||||
|
@ -1366,8 +1366,8 @@ void content_craftitem_init()
|
|||
f->drop_count = 1;
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-drink";
|
||||
f->hunger_effect = 2;
|
||||
f->health_effect = 3;
|
||||
f->hunger_effect = 10;
|
||||
f->health_effect = 15;
|
||||
f->energy_effect = 10;
|
||||
f->onuse_replace_item = CONTENT_CRAFTITEM_GLASS_BOTTLE;
|
||||
crafting::set1over1Recipe(CONTENT_CRAFTITEM_APPLE,CONTENT_CRAFTITEM_GLASS_BOTTLE,CONTENT_CRAFTITEM_APPLE_JUICE);
|
||||
|
@ -1383,8 +1383,8 @@ void content_craftitem_init()
|
|||
f->drop_count = 1;
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-eat";
|
||||
f->hunger_effect = 1;
|
||||
f->health_effect = 2;
|
||||
f->hunger_effect = 5;
|
||||
f->health_effect = 10;
|
||||
lists::add("creative",i);
|
||||
|
||||
i = CONTENT_CRAFTITEM_TEA;
|
||||
|
@ -1397,8 +1397,8 @@ void content_craftitem_init()
|
|||
f->drop_count = 1;
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-drink";
|
||||
f->hunger_effect = 3;
|
||||
f->health_effect = 4;
|
||||
f->hunger_effect = 15;
|
||||
f->health_effect = 20;
|
||||
f->cold_effect = 300;
|
||||
f->energy_effect = 10;
|
||||
f->onuse_replace_item = CONTENT_CRAFTITEM_STEEL_BOTTLE;
|
||||
|
@ -1415,8 +1415,8 @@ void content_craftitem_init()
|
|||
f->drop_count = 1;
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-eat";
|
||||
f->hunger_effect = 2;
|
||||
f->health_effect = 3;
|
||||
f->hunger_effect = 10;
|
||||
f->health_effect = 15;
|
||||
f->energy_effect = 30;
|
||||
lists::add("creative",i);
|
||||
|
||||
|
@ -1430,8 +1430,8 @@ void content_craftitem_init()
|
|||
f->drop_count = 1;
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-drink";
|
||||
f->hunger_effect = 2;
|
||||
f->health_effect = 3;
|
||||
f->hunger_effect = 10;
|
||||
f->health_effect = 15;
|
||||
f->cold_effect = 10;
|
||||
f->energy_effect = 300;
|
||||
f->onuse_replace_item = CONTENT_CRAFTITEM_STEEL_BOTTLE;
|
||||
|
@ -1467,8 +1467,8 @@ void content_craftitem_init()
|
|||
f->drop_count = 1;
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-drink";
|
||||
f->hunger_effect = 1;
|
||||
f->health_effect = 1;
|
||||
f->hunger_effect = 5;
|
||||
f->health_effect = 5;
|
||||
f->onuse_replace_item = CONTENT_CRAFTITEM_GLASS_BOTTLE;
|
||||
lists::add("creative",i);
|
||||
|
||||
|
@ -1482,8 +1482,8 @@ void content_craftitem_init()
|
|||
f->drop_count = 1;
|
||||
f->consumable = true;
|
||||
f->sound_use = "use-drink";
|
||||
f->hunger_effect = 1;
|
||||
f->health_effect = 1;
|
||||
f->hunger_effect = 5;
|
||||
f->health_effect = 8;
|
||||
f->cold_effect = 5;
|
||||
f->onuse_replace_item = CONTENT_CRAFTITEM_STEEL_BOTTLE;
|
||||
lists::add("creative",i);
|
||||
|
|
|
@ -1518,7 +1518,6 @@ void meshgen_dirtlike(MeshMakeData *data, v3s16 p, MapNode &n, SelectedNode &sel
|
|||
}
|
||||
}
|
||||
if (faces[1]) {
|
||||
TileSpec tile = getNodeTile(n,p,v3s16(0,-1,0),selected,NULL);
|
||||
video::S3DVertex v[4] = {
|
||||
video::S3DVertex( 0.5*data->m_BS,-0.5*data->m_BS, 0.5*data->m_BS, 0,0,0, video::SColor(255,255,255,255), basetile.texture.x0(), basetile.texture.y0()),
|
||||
video::S3DVertex(-0.5*data->m_BS,-0.5*data->m_BS, 0.5*data->m_BS, 0,0,0, video::SColor(255,255,255,255), basetile.texture.x1(), basetile.texture.y0()),
|
||||
|
@ -2188,7 +2187,7 @@ void meshgen_plantlike_fern(MeshMakeData *data, v3s16 p, MapNode &n, SelectedNod
|
|||
ContentFeatures *f = &content_features(n);
|
||||
TileSpec tile = getNodeTile(n,p,v3s16(0,-1,0),selected);
|
||||
v3f offset(0,0,0);
|
||||
s16 rot = 0;
|
||||
int rot = 0;
|
||||
bool is_dropped = false;
|
||||
if (data->m_vmanip.getNodeRO(data->m_blockpos_nodes + p + v3s16(0,-1,0)).getContent() == CONTENT_FLOWER_POT) {
|
||||
offset = v3f(0,-0.25*data->m_BS,0);
|
||||
|
@ -2253,7 +2252,7 @@ void meshgen_plantlike_fern(MeshMakeData *data, v3s16 p, MapNode &n, SelectedNod
|
|||
video::S3DVertex(-0.5*data->m_BS, 0.28125*data->m_BS,1.5*data->m_BS, 0,0,0, video::SColor(255,255,255,255), 0.,0.),
|
||||
video::S3DVertex( 0.5*data->m_BS, 0.28125*data->m_BS,1.5*data->m_BS, 0,0,0, video::SColor(255,255,255,255), 1.,0.)
|
||||
};
|
||||
s16 angle[8] = {
|
||||
int angle[8] = {
|
||||
45+rot,
|
||||
-45+rot,
|
||||
135+rot,
|
||||
|
|
|
@ -297,7 +297,7 @@ void content_mapnode_init(bool repeat)
|
|||
f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1";
|
||||
f->type = CMT_STONE;
|
||||
f->hardness = 1.0;
|
||||
f->warmth_per_second = 2;
|
||||
f->warmth_per_second = 10;
|
||||
lists::add("creative",i);
|
||||
|
||||
i = CONTENT_COAL;
|
||||
|
@ -1695,7 +1695,7 @@ void content_mapnode_init(bool repeat)
|
|||
f->dug_item = std::string("CraftItem snow_ball 9");
|
||||
f->type = CMT_DIRT;
|
||||
f->hardness = 0.3;
|
||||
f->warmth_per_second = 2;
|
||||
f->warmth_per_second = 10;
|
||||
crafting::setHardBlockRecipe(CONTENT_CRAFTITEM_SNOW_BALL,CONTENT_SNOW_BLOCK);
|
||||
lists::add("craftguide",i);
|
||||
lists::add("creative",i);
|
||||
|
@ -1784,7 +1784,7 @@ void content_mapnode_init(bool repeat)
|
|||
f->hardness = 0.3;
|
||||
f->pressure_type = CST_CRUSHABLE;
|
||||
f->suffocation_per_second = 0;
|
||||
f->warmth_per_second = 2;
|
||||
f->warmth_per_second = 10;
|
||||
lists::add("creative",i);
|
||||
lists::add("decrafting",i);
|
||||
|
||||
|
@ -2159,8 +2159,8 @@ void content_mapnode_init(bool repeat)
|
|||
f->buildable_to = true;
|
||||
f->air_equivalent = true;
|
||||
f->pressure_type = CST_CRUSHED;
|
||||
f->suffocation_per_second = 15;
|
||||
f->pressure_per_second = 10;
|
||||
f->suffocation_per_second = 75;
|
||||
f->pressure_per_second = 50;
|
||||
|
||||
i = CONTENT_WATER;
|
||||
f = &content_features(i);
|
||||
|
@ -2190,7 +2190,7 @@ void content_mapnode_init(bool repeat)
|
|||
f->post_effect_color = video::SColor(64, 100, 100, 200);
|
||||
#endif
|
||||
f->sound_ambient = "env-water";
|
||||
f->suffocation_per_second = 2;
|
||||
f->suffocation_per_second = 10;
|
||||
|
||||
i = CONTENT_WATERSOURCE;
|
||||
f = &content_features(i);
|
||||
|
@ -2220,7 +2220,7 @@ void content_mapnode_init(bool repeat)
|
|||
f->type = CMT_LIQUID;
|
||||
f->hardness = 0.5;
|
||||
f->pressure_type = CST_CRUSHABLE;
|
||||
f->suffocation_per_second = 2;
|
||||
f->suffocation_per_second = 10;
|
||||
|
||||
i = CONTENT_LAVA;
|
||||
f = &content_features(i);
|
||||
|
@ -2245,7 +2245,7 @@ void content_mapnode_init(bool repeat)
|
|||
f->liquid_alternative_flowing = CONTENT_LAVA;
|
||||
f->liquid_alternative_source = CONTENT_LAVASOURCE;
|
||||
f->liquid_viscosity = LAVA_VISC;
|
||||
f->damage_per_second = 4*2;
|
||||
f->damage_per_second = 40;
|
||||
#ifndef SERVER
|
||||
f->post_effect_color = video::SColor(192, 255, 64, 0);
|
||||
#endif
|
||||
|
@ -2272,7 +2272,7 @@ void content_mapnode_init(bool repeat)
|
|||
f->liquid_alternative_flowing = CONTENT_LAVA;
|
||||
f->liquid_alternative_source = CONTENT_LAVASOURCE;
|
||||
f->liquid_viscosity = LAVA_VISC;
|
||||
f->damage_per_second = 4*2;
|
||||
f->damage_per_second = 40;
|
||||
f->sound_ambient = "env-lava";
|
||||
#ifndef SERVER
|
||||
f->post_effect_color = video::SColor(192, 255, 64, 0);
|
||||
|
|
|
@ -752,7 +752,7 @@ void content_mapnode_plants(bool repeat)
|
|||
f->param_type = CPT_LIGHT;
|
||||
f->light_propagates = true;
|
||||
f->sunlight_propagates = true;
|
||||
f->damage_per_second = 2;
|
||||
f->damage_per_second = 10;
|
||||
f->solidness = 0; // drawn separately, makes no faces
|
||||
f->flammable = 1; // can be replaced by fire if the node under it is set on fire
|
||||
f->fuel_time = 30/4;
|
||||
|
|
|
@ -1042,7 +1042,7 @@ void content_mapnode_special(bool repeat)
|
|||
f->pointable = false;
|
||||
f->diggable = false;
|
||||
f->buildable_to = true;
|
||||
f->damage_per_second = 8;
|
||||
f->damage_per_second = 40;
|
||||
f->sound_ambient = "env-fire";
|
||||
#ifndef SERVER
|
||||
f->post_effect_color = video::SColor(192, 255, 64, 0);
|
||||
|
@ -1063,7 +1063,7 @@ void content_mapnode_special(bool repeat)
|
|||
f->pointable = false;
|
||||
f->diggable = false;
|
||||
f->buildable_to = true;
|
||||
f->damage_per_second = 8;
|
||||
f->damage_per_second = 40;
|
||||
#ifndef SERVER
|
||||
f->post_effect_color = video::SColor(192, 255, 64, 0);
|
||||
#endif
|
||||
|
@ -1757,7 +1757,7 @@ void content_mapnode_special(bool repeat)
|
|||
f->pointable = false;
|
||||
f->diggable = false;
|
||||
f->buildable_to = true;
|
||||
f->damage_per_second = 50;
|
||||
f->damage_per_second = 80;
|
||||
f->pressure_type = CST_CRUSHED;
|
||||
#ifndef SERVER
|
||||
f->setAllTextureTypes(MATERIAL_ALPHA_BLEND);
|
||||
|
@ -1777,7 +1777,7 @@ void content_mapnode_special(bool repeat)
|
|||
f->pointable = false;
|
||||
f->diggable = false;
|
||||
f->buildable_to = true;
|
||||
f->warmth_per_second = 4;
|
||||
f->damage_per_second = 20;
|
||||
f->pressure_type = CST_CRUSHED;
|
||||
#ifndef SERVER
|
||||
f->setAllTextureTypes(MATERIAL_ALPHA_BLEND);
|
||||
|
|
|
@ -273,7 +273,6 @@ void mob_spawn_passive(v3s16 pos, bool water, ServerEnvironment *env)
|
|||
void mob_spawn_hostile(v3s16 pos, bool water, ServerEnvironment *env)
|
||||
{
|
||||
std::vector<content_t> can;
|
||||
int rand = myrand();
|
||||
u8 level = mobLevelI(g_settings->get("max_mob_level"));
|
||||
if (level < MOB_AGGRESSIVE)
|
||||
return;
|
||||
|
@ -416,7 +415,7 @@ void content_mob_init()
|
|||
f->spawn_max_height = 2;
|
||||
f->sound_spawn = "mob-oerkki-spawn";
|
||||
f->notices_player = true;
|
||||
f->attack_player_damage = 3;
|
||||
f->attack_player_damage = 15;
|
||||
f->attack_player_range = v3f(1,1,1);
|
||||
f->lifetime = one_day;
|
||||
f->setCollisionBox(aabb3f(-BS/3.,0.0,-BS/3., BS/3.,BS*2.,BS/3.));
|
||||
|
@ -457,7 +456,7 @@ void content_mob_init()
|
|||
f->glow_light = LIGHT_MAX-1;
|
||||
f->notices_player = true;
|
||||
f->moves_silently = true;
|
||||
f->attack_player_damage = 3;
|
||||
f->attack_player_damage = 15;
|
||||
f->attack_player_range = v3f(2,2,2);
|
||||
f->contact_explosion_diameter = 3;
|
||||
f->spawn_naturally = false;
|
||||
|
@ -514,7 +513,7 @@ void content_mob_init()
|
|||
f->spawn_max_height = 40;
|
||||
f->spawn_chance = 2;
|
||||
f->notices_player = true;
|
||||
f->attack_player_damage = 3;
|
||||
f->attack_player_damage = 15;
|
||||
f->attack_player_range = v3f(1,1,1);
|
||||
f->lifetime = one_week;
|
||||
f->setCollisionBox(aabb3f(-0.7*BS, 0., -0.7*BS, 0.7*BS, 1.5*BS, 0.7*BS));
|
||||
|
@ -591,7 +590,7 @@ void content_mob_init()
|
|||
f->moves_silently = true;
|
||||
f->spawn_water = true;
|
||||
f->notices_player = true;
|
||||
f->attack_player_damage = 3;
|
||||
f->attack_player_damage = 15;
|
||||
f->attack_player_range = v3f(1,1,1);
|
||||
f->lifetime = one_week;
|
||||
f->setCollisionBox(aabb3f(-0.75*BS, 0., -0.75*BS, 0.75*BS, 1.*BS, 0.75*BS));
|
||||
|
@ -621,7 +620,7 @@ void content_mob_init()
|
|||
f->sound_punch = "mob-wolf-hit";
|
||||
f->sound_spawn = "mob-wolf-spawn";
|
||||
f->notices_player = true;
|
||||
f->attack_player_damage = 3;
|
||||
f->attack_player_damage = 15;
|
||||
f->attack_player_range = v3f(1,1,1);
|
||||
f->lifetime = one_day;
|
||||
f->setCollisionBox(aabb3f(-0.5*BS, 0., -0.5*BS, 0.5*BS, 1.*BS, 0.5*BS));
|
||||
|
@ -772,6 +771,9 @@ void content_mob_init()
|
|||
f->sound_random = "mob-kitty-env";
|
||||
f->spawn_min_height = -5;
|
||||
f->spawn_max_height = 40;
|
||||
f->notices_player = true;
|
||||
f->attack_player_damage = 1;
|
||||
f->attack_player_range = v3f(1,1,1);
|
||||
f->lifetime = one_week;
|
||||
f->setCollisionBox(aabb3f(-0.6*BS, 0., -0.6*BS, 0.6*BS, 1.25*BS, 0.6*BS));
|
||||
lists::add("creative",CONTENT_TOOLITEM_MOB_SPAWNER,1,i);
|
||||
|
@ -798,6 +800,9 @@ void content_mob_init()
|
|||
f->sound_random = "mob-kitty-env";
|
||||
f->spawn_min_height = -5;
|
||||
f->spawn_max_height = 40;
|
||||
f->notices_player = true;
|
||||
f->attack_player_damage = 1;
|
||||
f->attack_player_range = v3f(1,1,1);
|
||||
f->lifetime = one_week;
|
||||
f->setCollisionBox(aabb3f(-0.6*BS, 0., -0.6*BS, 0.6*BS, 1.25*BS, 0.6*BS));
|
||||
lists::add("creative",CONTENT_TOOLITEM_MOB_SPAWNER,1,i);
|
||||
|
@ -824,6 +829,9 @@ void content_mob_init()
|
|||
f->sound_random = "mob-kitty-env";
|
||||
f->spawn_min_height = -5;
|
||||
f->spawn_max_height = 40;
|
||||
f->notices_player = true;
|
||||
f->attack_player_damage = 1;
|
||||
f->attack_player_range = v3f(1,1,1);
|
||||
f->lifetime = one_week;
|
||||
f->setCollisionBox(aabb3f(-0.6*BS, 0., -0.6*BS, 0.6*BS, 1.25*BS, 0.6*BS));
|
||||
lists::add("creative",CONTENT_TOOLITEM_MOB_SPAWNER,1,i);
|
||||
|
@ -850,6 +858,9 @@ void content_mob_init()
|
|||
f->sound_random = "mob-kitty-env";
|
||||
f->spawn_min_height = -5;
|
||||
f->spawn_max_height = 40;
|
||||
f->notices_player = true;
|
||||
f->attack_player_damage = 1;
|
||||
f->attack_player_range = v3f(1,1,1);
|
||||
f->lifetime = one_week;
|
||||
f->setCollisionBox(aabb3f(-0.6*BS, 0., -0.6*BS, 0.6*BS, 1.25*BS, 0.6*BS));
|
||||
lists::add("creative",CONTENT_TOOLITEM_MOB_SPAWNER,1,i);
|
||||
|
|
|
@ -603,7 +603,6 @@ void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime)
|
|||
MapNode n = block->getNodeNoEx(p0);
|
||||
MapNode n1 = block->getNodeNoEx(p0+v3s16(0,1,0));
|
||||
MapNode n2 = block->getNodeNoEx(p0+v3s16(0,2,0));
|
||||
u8 light = n1.getLightBlend(getDayNightRatio());
|
||||
if (n1.getContent() == CONTENT_IGNORE || n2.getContent() == CONTENT_IGNORE)
|
||||
continue;
|
||||
if (n.getContent() == CONTENT_WATERSOURCE && n1.getContent() == CONTENT_WATERSOURCE && n2.getContent() == CONTENT_WATERSOURCE) {
|
||||
|
@ -1114,7 +1113,6 @@ void ServerEnvironment::step(float dtime)
|
|||
}
|
||||
|
||||
if (block->last_spawn < m_time_of_day-6000) {
|
||||
MapNode n = block->getNodeNoEx(block->spawn_area);
|
||||
MapNode n1 = block->getNodeNoEx(block->spawn_area+v3s16(0,1,0));
|
||||
MapNode n2 = block->getNodeNoEx(block->spawn_area+v3s16(0,2,0));
|
||||
u8 light = n1.getLightBlend(getDayNightRatio());
|
||||
|
@ -2747,10 +2745,12 @@ void ServerEnvironment::step(float dtime)
|
|||
!searchNearInv(p,v3s16(0,1,0),v3s16(0,16,0),search,NULL)
|
||||
&& !searchNear(p,v3s16(3,3,3),CONTENT_FIRE,NULL)
|
||||
) {
|
||||
n.param1 &= ~0x0F;
|
||||
n.param1 |= 0x04;
|
||||
n.envticks = 0;
|
||||
m_map->addNodeWithEvent(p,n);
|
||||
MapNode nn(CONTENT_SNOW);
|
||||
m_map->addNodeWithEvent(p+v3s16(0,1,0),nn);
|
||||
//n.param1 &= ~0x0F;
|
||||
//n.param1 |= 0x04;
|
||||
//n.envticks = 0;
|
||||
//m_map->addNodeWithEvent(p,n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3782,17 +3782,13 @@ void ClientEnvironment::step(float dtime)
|
|||
if (info.t == COLLISION_FALL) {
|
||||
//f32 tolerance = BS*10; // 2 without damage
|
||||
f32 tolerance = BS*12; // 3 without damage
|
||||
f32 factor = 1;
|
||||
f32 factor = 5;
|
||||
if (info.speed > BS*4)
|
||||
m_client->playStepSound(0);
|
||||
if (info.speed > tolerance) {
|
||||
f32 damage_f = (info.speed - tolerance)/BS*factor;
|
||||
u16 damage = (u16)(damage_f+0.5);
|
||||
if (lplayer->hp > damage) {
|
||||
lplayer->hp -= damage;
|
||||
}else{
|
||||
lplayer->hp = 0;
|
||||
}
|
||||
lplayer->addDamage(PLAYER_FEET|PLAYER_LLEG|PLAYER_RLEG,DAMAGE_FALL,damage);
|
||||
|
||||
ClientEnvEvent event;
|
||||
event.type = CEE_PLAYER_DAMAGE;
|
||||
|
@ -3805,61 +3801,89 @@ void ClientEnvironment::step(float dtime)
|
|||
/* player damage */
|
||||
if (m_damage_interval.step(dtime, 1.0)) {
|
||||
v3f pf = lplayer->getPosition();
|
||||
|
||||
v3s16 pp = floatToInt(pf, BS);
|
||||
// Feet, middle and head
|
||||
v3s16 p0 = floatToInt(pf - v3f(0, BS*0.1, 0), BS);
|
||||
MapNode feet = m_map->getNodeNoEx(p0);
|
||||
v3s16 p1 = floatToInt(pf + v3f(0, BS*0.1, 0), BS);
|
||||
MapNode legs = m_map->getNodeNoEx(p1);
|
||||
v3s16 p2 = floatToInt(pf + v3f(0, BS*0.8, 0), BS);
|
||||
MapNode torso = m_map->getNodeNoEx(p2);
|
||||
v3s16 p3 = floatToInt(pf + v3f(0, BS*1.6, 0), BS);
|
||||
MapNode head = m_map->getNodeNoEx(p3);
|
||||
|
||||
u32 damage_per_second = 0;
|
||||
u32 suffocation_per_second = 0;
|
||||
u32 warmth_per_second = 0;
|
||||
u32 pressure_per_second = 0;
|
||||
damage_per_second = content_features(feet).damage_per_second;
|
||||
damage_per_second = MYMAX(damage_per_second, content_features(legs).damage_per_second);
|
||||
damage_per_second = MYMAX(damage_per_second, content_features(torso).damage_per_second);
|
||||
damage_per_second = MYMAX(damage_per_second, content_features(head).damage_per_second);
|
||||
suffocation_per_second = content_features(head).suffocation_per_second;
|
||||
warmth_per_second = content_features(feet).warmth_per_second;
|
||||
warmth_per_second = MYMAX(warmth_per_second, content_features(legs).warmth_per_second);
|
||||
warmth_per_second = MYMAX(warmth_per_second, content_features(torso).warmth_per_second);
|
||||
warmth_per_second = MYMAX(warmth_per_second, content_features(head).warmth_per_second);
|
||||
pressure_per_second = content_features(feet).pressure_per_second;
|
||||
pressure_per_second = MYMAX(pressure_per_second, content_features(legs).pressure_per_second);
|
||||
pressure_per_second = MYMAX(pressure_per_second, content_features(torso).pressure_per_second);
|
||||
pressure_per_second = MYMAX(pressure_per_second, content_features(head).pressure_per_second);
|
||||
s16 coldzone = 60;
|
||||
bool possible_cold = (pp.Y > coldzone && pp.Y < 1024);
|
||||
|
||||
v3f ps[6] = {
|
||||
v3f(0, BS*-0.1, 0),
|
||||
v3f(0, BS*0.1, 0),
|
||||
v3f(0, BS*0.8, 0),
|
||||
v3f(BS*0.4, BS*0.8, 0),
|
||||
v3f(BS*-0.4, BS*0.8, 0),
|
||||
v3f(0, BS*1.6, 0)
|
||||
};
|
||||
|
||||
u8 area[6] = {
|
||||
PLAYER_FEET,
|
||||
(PLAYER_LLEG|PLAYER_RLEG),
|
||||
PLAYER_TORSO,
|
||||
PLAYER_RARM,
|
||||
PLAYER_LARM,
|
||||
PLAYER_HEAD
|
||||
};
|
||||
ps[3].rotateXZBy(lplayer->getYaw());
|
||||
ps[4].rotateXZBy(lplayer->getYaw());
|
||||
pf.Y += BS;
|
||||
|
||||
for (int i=0; i<6; i++) {
|
||||
v3s16 p = floatToInt(pf+ps[i],BS);
|
||||
MapNode n = m_map->getNodeNoEx(p);
|
||||
u32 damage = content_features(n).damage_per_second;
|
||||
u32 suffocation = content_features(n).suffocation_per_second;
|
||||
u32 warmth = content_features(n).warmth_per_second;
|
||||
u32 pressure = content_features(n).pressure_per_second;
|
||||
if (damage > 0) {
|
||||
u8 t = DAMAGE_UNKNOWN;
|
||||
switch (n.getContent()) {
|
||||
case CONTENT_LAVA:
|
||||
case CONTENT_LAVASOURCE:
|
||||
t = DAMAGE_LAVA;
|
||||
break;
|
||||
case CONTENT_CACTUS:
|
||||
t = DAMAGE_CACTUS;
|
||||
break;
|
||||
case CONTENT_FIRE:
|
||||
case CONTENT_FIRE_SHORTTERM:
|
||||
t = DAMAGE_FIRE;
|
||||
break;
|
||||
case CONTENT_TNT:
|
||||
case CONTENT_FLASH:
|
||||
t = DAMAGE_TNT;
|
||||
break;
|
||||
case CONTENT_STEAM:
|
||||
t = DAMAGE_STEAM;
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
damageLocalPlayer(area[i],t,damage);
|
||||
}
|
||||
if (warmth > 0)
|
||||
damageLocalPlayer(area[i],DAMAGE_COLD,warmth);
|
||||
if (pressure > 0)
|
||||
damageLocalPlayer(area[i],DAMAGE_SPACE,pressure);
|
||||
if (i < 5)
|
||||
continue;
|
||||
if (suffocation > 0) {
|
||||
damageLocalPlayer(area[i],DAMAGE_AIR,suffocation);
|
||||
}else if (lplayer->air < 100) {
|
||||
ClientEnvEvent event;
|
||||
event.type = CEE_PLAYER_SUFFOCATE;
|
||||
event.player_damage.amount = -100;
|
||||
m_client_event_queue.push_back(event);
|
||||
}
|
||||
}
|
||||
|
||||
// cold zone
|
||||
if (warmth_per_second == 0 && pp.Y > 60 && myrand()%10 == 0) {
|
||||
if (pp.Y < 1024) {
|
||||
if (possible_cold) {
|
||||
std::vector<content_t> search;
|
||||
search.push_back(CONTENT_FIRE);
|
||||
if (!searchNear(pp,v3s16(-4,-2,-4),v3s16(5,5,5),search,NULL))
|
||||
warmth_per_second = 1;
|
||||
damageLocalPlayer(PLAYER_ALL,DAMAGE_COLD,5);
|
||||
}
|
||||
}
|
||||
|
||||
if (damage_per_second != 0)
|
||||
damageLocalPlayer(damage_per_second);
|
||||
if (suffocation_per_second != 0) {
|
||||
damageLocalPlayerWithSuffocation(suffocation_per_second);
|
||||
}else if (lplayer->air < 20) {
|
||||
ClientEnvEvent event;
|
||||
event.type = CEE_PLAYER_SUFFOCATE;
|
||||
event.player_damage.amount = -20;
|
||||
m_client_event_queue.push_back(event);
|
||||
}
|
||||
if (pressure_per_second != 0)
|
||||
damageLocalPlayerWithVacuum(pressure_per_second);
|
||||
if (warmth_per_second != 0)
|
||||
damageLocalPlayerWithWarmth(warmth_per_second);
|
||||
}
|
||||
|
||||
if (m_hunger_interval.step(dtime,5.0)) {
|
||||
f32 speed = lplayer->getSpeed().getLength();
|
||||
s8 hungry = 0;
|
||||
|
@ -3876,7 +3900,7 @@ void ClientEnvironment::step(float dtime)
|
|||
if (hungry) {
|
||||
ClientEnvEvent event;
|
||||
event.type = CEE_PLAYER_HUNGER;
|
||||
event.player_damage.amount = hungry;
|
||||
event.player_damage.amount = 3;
|
||||
m_client_event_queue.push_back(event);
|
||||
}
|
||||
// a little discouragement for running around naked
|
||||
|
@ -3897,7 +3921,7 @@ void ClientEnvironment::step(float dtime)
|
|||
safe = true;
|
||||
}
|
||||
if (!safe)
|
||||
damageLocalPlayer(1);
|
||||
damageLocalPlayer((PLAYER_TORSO|PLAYER_RLEG|PLAYER_LLEG),DAMAGE_EXPOSURE,2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4100,152 +4124,20 @@ void ClientEnvironment::processActiveObjectMessage(u16 id,
|
|||
Callbacks for activeobjects
|
||||
*/
|
||||
|
||||
void ClientEnvironment::damageLocalPlayer(u8 damage)
|
||||
void ClientEnvironment::damageLocalPlayer(u8 area, u8 type, u8 damage)
|
||||
{
|
||||
if (!m_client->getServerDamage())
|
||||
return;
|
||||
LocalPlayer *lplayer = getLocalPlayer();
|
||||
assert(lplayer);
|
||||
|
||||
if (lplayer->hp > damage) {
|
||||
lplayer->hp -= damage;
|
||||
}else{
|
||||
lplayer->hp = 0;
|
||||
}
|
||||
|
||||
ClientEnvEvent event;
|
||||
event.type = CEE_PLAYER_DAMAGE;
|
||||
event.player_damage.amount = damage;
|
||||
m_client_event_queue.push_back(event);
|
||||
}
|
||||
|
||||
void ClientEnvironment::damageLocalPlayerWithArmour(u8 damage)
|
||||
{
|
||||
if (!m_client->getServerDamage())
|
||||
return;
|
||||
LocalPlayer *lplayer = getLocalPlayer();
|
||||
assert(lplayer);
|
||||
f32 effect = lplayer->getArmourProtection();
|
||||
f32 effect = lplayer->getProtection(area,type);
|
||||
f32 f_damage = damage;
|
||||
|
||||
if (damage > 0 && effect > 0.0) {
|
||||
f_damage -= f_damage*effect;
|
||||
ClientEnvEvent event;
|
||||
event.type = CEE_PLAYER_WEARCLOTHES;
|
||||
event.player_wear.amount = damage*(500*(2.0-effect));
|
||||
m_client_event_queue.push_back(event);
|
||||
if (f_damage < 1.0 && f_damage > 0.0) {
|
||||
damage = 1.0/f_damage;
|
||||
if (myrand_range(0,damage) == 0)
|
||||
f_damage = 1.0;
|
||||
}
|
||||
damage = f_damage;
|
||||
if (damage < 1)
|
||||
return;
|
||||
}
|
||||
|
||||
if (lplayer->hp > damage) {
|
||||
lplayer->hp -= damage;
|
||||
}else{
|
||||
lplayer->hp = 0;
|
||||
}
|
||||
|
||||
ClientEnvEvent event;
|
||||
event.type = CEE_PLAYER_DAMAGE;
|
||||
event.player_damage.amount = damage;
|
||||
m_client_event_queue.push_back(event);
|
||||
}
|
||||
|
||||
void ClientEnvironment::damageLocalPlayerWithWarmth(u8 damage)
|
||||
{
|
||||
if (!m_client->getServerDamage())
|
||||
return;
|
||||
LocalPlayer *lplayer = getLocalPlayer();
|
||||
assert(lplayer);
|
||||
f32 effect = lplayer->getWarmthProtection();
|
||||
f32 f_damage = damage;
|
||||
if (lplayer->cold_effectf > 0.0)
|
||||
return;
|
||||
|
||||
if (damage > 0 && effect > 0.0) {
|
||||
f_damage -= f_damage*effect;
|
||||
ClientEnvEvent event;
|
||||
event.type = CEE_PLAYER_WEARCLOTHES;
|
||||
event.player_wear.amount = damage*(500*(2.0-effect));
|
||||
m_client_event_queue.push_back(event);
|
||||
if (f_damage < 1.0 && f_damage > 0.0) {
|
||||
damage = 1.0/f_damage;
|
||||
if (myrand_range(0,damage) == 0)
|
||||
f_damage = 1.0;
|
||||
}
|
||||
damage = f_damage;
|
||||
if (damage < 1)
|
||||
return;
|
||||
}
|
||||
|
||||
if (lplayer->hp > damage) {
|
||||
lplayer->hp -= damage;
|
||||
}else{
|
||||
lplayer->hp = 0;
|
||||
}
|
||||
|
||||
ClientEnvEvent event;
|
||||
event.type = CEE_PLAYER_DAMAGE;
|
||||
event.player_damage.amount = damage;
|
||||
m_client_event_queue.push_back(event);
|
||||
}
|
||||
|
||||
void ClientEnvironment::damageLocalPlayerWithVacuum(u8 damage)
|
||||
{
|
||||
if (!m_client->getServerDamage())
|
||||
return;
|
||||
LocalPlayer *lplayer = getLocalPlayer();
|
||||
assert(lplayer);
|
||||
f32 effect = lplayer->getVacuumProtection();
|
||||
f32 f_damage = damage;
|
||||
|
||||
if (damage > 0 && effect > 0.0) {
|
||||
f_damage -= f_damage*effect;
|
||||
ClientEnvEvent event;
|
||||
event.type = CEE_PLAYER_WEARCLOTHES;
|
||||
event.player_wear.amount = damage*(500*(2.0-effect));
|
||||
m_client_event_queue.push_back(event);
|
||||
if (f_damage < 1.0 && f_damage > 0.0) {
|
||||
damage = 1.0/f_damage;
|
||||
if (myrand_range(0,damage) == 0)
|
||||
f_damage = 1.0;
|
||||
}
|
||||
damage = f_damage;
|
||||
if (damage < 1)
|
||||
return;
|
||||
}
|
||||
|
||||
if (lplayer->hp > damage) {
|
||||
lplayer->hp -= damage;
|
||||
}else{
|
||||
lplayer->hp = 0;
|
||||
}
|
||||
|
||||
ClientEnvEvent event;
|
||||
event.type = CEE_PLAYER_DAMAGE;
|
||||
event.player_damage.amount = damage;
|
||||
m_client_event_queue.push_back(event);
|
||||
}
|
||||
|
||||
void ClientEnvironment::damageLocalPlayerWithSuffocation(u8 damage)
|
||||
{
|
||||
if (!m_client->getServerSuffocation())
|
||||
return;
|
||||
LocalPlayer *lplayer = getLocalPlayer();
|
||||
assert(lplayer);
|
||||
f32 effect = lplayer->getSuffocationProtection();
|
||||
f32 f_damage = damage;
|
||||
|
||||
if (damage > 0 && effect > 0.0) {
|
||||
f_damage -= f_damage*effect;
|
||||
ClientEnvEvent event;
|
||||
event.type = CEE_PLAYER_WEARCLOTHES;
|
||||
event.player_wear.amount = damage*(500*(2.0-effect));
|
||||
event.player_wear.amount = damage*(100*(2.0-effect));
|
||||
m_client_event_queue.push_back(event);
|
||||
if (f_damage < 1.0 && f_damage > 0.0) {
|
||||
damage = 1.0/f_damage;
|
||||
|
@ -4258,7 +4150,12 @@ void ClientEnvironment::damageLocalPlayerWithSuffocation(u8 damage)
|
|||
}
|
||||
|
||||
ClientEnvEvent event;
|
||||
if (type == DAMAGE_AIR) {
|
||||
event.type = CEE_PLAYER_SUFFOCATE;
|
||||
}else{
|
||||
lplayer->addDamage(area,type,damage);
|
||||
event.type = CEE_PLAYER_DAMAGE;
|
||||
}
|
||||
event.player_damage.amount = damage;
|
||||
m_client_event_queue.push_back(event);
|
||||
}
|
||||
|
|
|
@ -559,11 +559,7 @@ public:
|
|||
/*
|
||||
Callbacks for activeobjects
|
||||
*/
|
||||
void damageLocalPlayer(u8 damage);
|
||||
void damageLocalPlayerWithArmour(u8 damage);
|
||||
void damageLocalPlayerWithWarmth(u8 damage);
|
||||
void damageLocalPlayerWithVacuum(u8 damage);
|
||||
void damageLocalPlayerWithSuffocation(u8 damage);
|
||||
void damageLocalPlayer(u8 area, u8 type, u8 damage);
|
||||
|
||||
/*
|
||||
Client likes to call these
|
||||
|
|
|
@ -2305,6 +2305,8 @@ void the_game(
|
|||
&local_inventory,
|
||||
client.getServerDamage(),
|
||||
client.getHP(),
|
||||
(p->last_damage&0xFF00)>>8,
|
||||
(p->last_damage&0x00FF),
|
||||
p->cold_effectf,
|
||||
client.getServerSuffocation(),
|
||||
client.getAir(),
|
||||
|
|
85
src/hud.cpp
|
@ -369,12 +369,14 @@ void hud_draw(
|
|||
bool show_index,
|
||||
Inventory *inventory,
|
||||
bool have_health,
|
||||
s32 halfheartcount,
|
||||
s32 health,
|
||||
u8 damage_type,
|
||||
u8 damage_pos,
|
||||
float cold_boost,
|
||||
bool have_suffocation,
|
||||
s32 halfbubblecount,
|
||||
s32 air,
|
||||
bool have_hunger,
|
||||
s32 halfhungercount,
|
||||
s32 hunger,
|
||||
float energy,
|
||||
float energy_boost,
|
||||
int crosshair,
|
||||
|
@ -570,10 +572,10 @@ void hud_draw(
|
|||
|
||||
// health
|
||||
if (have_health) {
|
||||
int c = 55+(halfheartcount*10);
|
||||
int c = 55+(health*2);
|
||||
float e = 0.0;
|
||||
if (halfheartcount > 0.0)
|
||||
e = energy/((float)halfheartcount/100.0);
|
||||
if (health > 0.0)
|
||||
e = energy/((float)health/100.0);
|
||||
if (e > 100.0)
|
||||
e = 100.0;
|
||||
if (e < 0.0)
|
||||
|
@ -601,7 +603,7 @@ void hud_draw(
|
|||
draw_image(driver,texture,color,rect,NULL,NULL);
|
||||
}
|
||||
|
||||
std::wstring txt = itows(halfheartcount*5);
|
||||
std::wstring txt = itows(health);
|
||||
txt += L"%";
|
||||
|
||||
v2u32 dim = font->getDimension(txt.c_str());
|
||||
|
@ -613,16 +615,71 @@ void hud_draw(
|
|||
sdim
|
||||
);
|
||||
font->draw(txt.c_str(), rect2, video::SColor(255,255,255,255), false, false, NULL);
|
||||
|
||||
{
|
||||
char* image[8] = {
|
||||
(char*)"body_feet.png",
|
||||
(char*)"body_lleg.png",
|
||||
(char*)"body_rleg.png",
|
||||
(char*)"body_torso.png",
|
||||
(char*)"body_hands.png",
|
||||
(char*)"body_larm.png",
|
||||
(char*)"body_rarm.png",
|
||||
(char*)"body_head.png"
|
||||
};
|
||||
|
||||
for (int i=0; i<8; i++) {
|
||||
u8 a = (1<<i);
|
||||
u8 c = 255;
|
||||
if ((damage_pos&a) == a)
|
||||
c = 0;
|
||||
const video::SColor color(255,255,c,c);
|
||||
video::ITexture *texture = driver->getTexture(getTexturePath(image[i]).c_str());
|
||||
core::rect<s32> rect(20,screensize.Y-182,52,screensize.Y-118);
|
||||
draw_image(driver,texture,color,rect,NULL,NULL);
|
||||
}
|
||||
}
|
||||
{
|
||||
char* damage_types[] = {
|
||||
(char*)"",
|
||||
gettext("Unknown"),
|
||||
gettext("Fall"),
|
||||
gettext("Exposure"),
|
||||
gettext("Cold"),
|
||||
gettext("Attack"),
|
||||
gettext("Space"),
|
||||
gettext("Hunger"),
|
||||
gettext("Air"),
|
||||
gettext("Lava"),
|
||||
gettext("Cactus"),
|
||||
gettext("Fire"),
|
||||
gettext("TNT"),
|
||||
gettext("Steam"),
|
||||
gettext("Poison")
|
||||
};
|
||||
|
||||
std::wstring t = narrow_to_wide(damage_types[damage_type]);
|
||||
|
||||
v2u32 dim = font->getDimension(t.c_str());
|
||||
v2s32 sdim(dim.X,dim.Y);
|
||||
v2s32 p(52,screensize.Y-150);
|
||||
p.Y -= sdim.Y/2;
|
||||
core::rect<s32> rect2(
|
||||
p,
|
||||
sdim
|
||||
);
|
||||
font->draw(t.c_str(), rect2, video::SColor(255,255,255,255), false, false, NULL);
|
||||
}
|
||||
}
|
||||
// air
|
||||
if (have_suffocation && halfbubblecount<20) {
|
||||
int c = 55+(halfbubblecount*10);
|
||||
if (have_suffocation && air < 100) {
|
||||
int c = 55+(air*2);
|
||||
const video::SColor color(255,255,c,c);
|
||||
video::ITexture *texture = driver->getTexture(getTexturePath("bubble.png").c_str());
|
||||
core::rect<s32> rect(100,screensize.Y-68,132,screensize.Y-36);
|
||||
draw_image(driver,texture,color,rect,NULL,NULL);
|
||||
|
||||
std::wstring txt = itows(halfbubblecount*5);
|
||||
std::wstring txt = itows(air);
|
||||
txt += L"%";
|
||||
|
||||
v2u32 dim = font->getDimension(txt.c_str());
|
||||
|
@ -637,13 +694,13 @@ void hud_draw(
|
|||
}
|
||||
// hunger
|
||||
if (have_hunger) {
|
||||
int c = 55+(halfhungercount*10);
|
||||
int c = 55+(hunger*2);
|
||||
const video::SColor color(255,255,c,c);
|
||||
video::ITexture *texture = driver->getTexture(getTexturePath("harvested_carrot.png").c_str());
|
||||
core::rect<s32> rect(36,screensize.Y-68,68,screensize.Y-36);
|
||||
draw_image(driver,texture,color,rect,NULL,NULL);
|
||||
|
||||
std::wstring txt = itows(halfhungercount*5);
|
||||
std::wstring txt = itows(hunger);
|
||||
txt += L"%";
|
||||
|
||||
v2u32 dim = font->getDimension(txt.c_str());
|
||||
|
@ -833,7 +890,7 @@ void hud_draw(
|
|||
core::rect<s32> rect(x_off+132,screensize.Y-36,x_off+164,screensize.Y-4);
|
||||
draw_image(driver,texture,color,rect,NULL,NULL);
|
||||
|
||||
std::wstring txt = itows(halfhungercount*5);
|
||||
std::wstring txt = itows(hunger);
|
||||
txt += L"%";
|
||||
|
||||
v2u32 dim = font->getDimension(txt.c_str());
|
||||
|
@ -858,7 +915,7 @@ void hud_draw(
|
|||
core::rect<s32> rect(x_off+132,screensize.Y-36,x_off+164,screensize.Y-4);
|
||||
draw_image(driver,texture,color,rect,NULL,NULL);
|
||||
|
||||
std::wstring txt = itows(halfhungercount*5);
|
||||
std::wstring txt = itows(hunger);
|
||||
txt += L"%";
|
||||
|
||||
v2u32 dim = font->getDimension(txt.c_str());
|
||||
|
|
|
@ -71,12 +71,14 @@ void hud_draw(
|
|||
bool show_index,
|
||||
Inventory *inventory,
|
||||
bool have_health,
|
||||
s32 halfheartcount,
|
||||
s32 health,
|
||||
u8 damage_type,
|
||||
u8 damage_pos,
|
||||
float cold_boost,
|
||||
bool have_suffocation,
|
||||
s32 halfbubblecount,
|
||||
s32 air,
|
||||
bool have_hunger,
|
||||
s32 halfhungercount,
|
||||
s32 hunger,
|
||||
float energy,
|
||||
float energy_boost,
|
||||
int crosshair,
|
||||
|
|
|
@ -453,20 +453,16 @@ bool CraftItem::use(ServerEnvironment *env, Player *player)
|
|||
bool used = false;
|
||||
CraftItemFeatures f = content_craftitem_features(m_content);
|
||||
if (f.consumable) {
|
||||
if (f.hunger_effect && (f.health_effect < 1 || player->hunger < 20)) {
|
||||
if (player->hunger + f.hunger_effect > 20) {
|
||||
player->hunger = 20;
|
||||
if (f.hunger_effect && (f.health_effect < 1 || player->hunger < 100)) {
|
||||
if (player->hunger + f.hunger_effect > 100) {
|
||||
player->hunger = 100;
|
||||
}else{
|
||||
player->hunger += f.hunger_effect;
|
||||
}
|
||||
used = true;
|
||||
}
|
||||
if (f.health_effect < 0 || (!used && f.health_effect > 0)) {
|
||||
if (player->hp + f.health_effect > 20) {
|
||||
player->hp = 20;
|
||||
}else{
|
||||
player->hp += f.health_effect;
|
||||
}
|
||||
player->addHealth(f.health_effect);
|
||||
used = true;
|
||||
}
|
||||
if (f.cold_effect) {
|
||||
|
|
|
@ -3795,8 +3795,8 @@ void ClientMap::renderPostFx()
|
|||
|
||||
if (m_client->getServerSuffocation()) {
|
||||
u16 a = m_client->getAir();
|
||||
if (a < 18) {
|
||||
u8 c = 255-(a*14);
|
||||
if (a < 50) {
|
||||
u8 c = 255-(a*5);
|
||||
const video::SColor color(c,255,255,255);
|
||||
const video::SColor colors[] = {color,color,color,color};
|
||||
std::string tex = getTexturePath("low_air.png");
|
||||
|
|
|
@ -1823,7 +1823,6 @@ void make_block(BlockMakeData *data)
|
|||
u32 current_depth = 0;
|
||||
bool air_detected = false;
|
||||
bool water_detected = false;
|
||||
bool have_clay = false;
|
||||
|
||||
// Use fast index incrementing
|
||||
s16 start_y = node_max.Y+2;
|
||||
|
|
|
@ -595,7 +595,7 @@ struct ContentFeatures
|
|||
hardness = 1.0;
|
||||
pressure_type = CST_MOVABLE;
|
||||
damage_per_second = 0;
|
||||
suffocation_per_second = 4;
|
||||
suffocation_per_second = 20;
|
||||
warmth_per_second = 0;
|
||||
pressure_per_second = 0;
|
||||
home_node = -1;
|
||||
|
|
|
@ -51,11 +51,15 @@ Player::Player():
|
|||
in_bed(false),
|
||||
wake_timeout(0.0),
|
||||
craftresult_is_preview(true),
|
||||
hp(20),
|
||||
air(20),
|
||||
hunger(20),
|
||||
health(100),
|
||||
air(100),
|
||||
hunger(100),
|
||||
energy_effect(0),
|
||||
cold_effect(0),
|
||||
dirt(0),
|
||||
wet(0),
|
||||
blood(0),
|
||||
last_damage(0),
|
||||
peer_id(PEER_ID_INEXISTENT),
|
||||
m_selected_item(0),
|
||||
m_pitch(0),
|
||||
|
@ -213,7 +217,7 @@ void Player::serialize(std::ostream &os)
|
|||
args.setFloat("yaw", m_yaw);
|
||||
args.setV3F("position", m_position);
|
||||
args.setBool("craftresult_is_preview", craftresult_is_preview);
|
||||
args.setS32("hp", hp);
|
||||
args.setS32("health", health);
|
||||
args.setS32("air", air);
|
||||
args.setS32("hunger", hunger);
|
||||
if (m_hashome)
|
||||
|
@ -263,20 +267,32 @@ void Player::deSerialize(std::istream &is)
|
|||
}else{
|
||||
craftresult_is_preview = true;
|
||||
}
|
||||
if (args.exists("hp")) {
|
||||
hp = args.getS32("hp");
|
||||
}else{
|
||||
hp = 20;
|
||||
}
|
||||
if (args.exists("health")) {
|
||||
health = args.getS32("health");
|
||||
if (args.exists("air")) {
|
||||
air = args.getS32("air");
|
||||
}else{
|
||||
air = 20;
|
||||
air = 100;
|
||||
}
|
||||
if (args.exists("hunger")) {
|
||||
hunger = args.getS32("hunger");
|
||||
}else{
|
||||
hunger = 20;
|
||||
hunger = 100;
|
||||
}
|
||||
}else if (args.exists("hp")) {
|
||||
health = 5*args.getS32("hp");
|
||||
if (args.exists("air")) {
|
||||
air = 5*args.getS32("air");
|
||||
}else{
|
||||
air = 100;
|
||||
}
|
||||
if (args.exists("hunger")) {
|
||||
hunger = 5*args.getS32("hunger");
|
||||
}else{
|
||||
hunger = 100;
|
||||
}
|
||||
}else{
|
||||
health = 100;
|
||||
}
|
||||
if (args.exists("home")) {
|
||||
m_home = args.getV3F("home");
|
||||
|
@ -1106,11 +1122,11 @@ void LocalPlayer::applyControl(float dtime)
|
|||
}
|
||||
}else{
|
||||
if (energy_effectf) {
|
||||
if (m_energy < hp)
|
||||
m_energy += dtime*5.0;
|
||||
if (m_energy < health)
|
||||
m_energy += dtime*25.0;
|
||||
}else if (control.digging) {
|
||||
m_energy -= dtime*0.2;
|
||||
}else if (m_energy < hp) {
|
||||
m_energy -= dtime;
|
||||
}else if (m_energy < health) {
|
||||
if (speed.X || speed.Y || speed.Z) {
|
||||
m_energy += dtime*((float)hunger/30.0);
|
||||
}else{
|
||||
|
@ -1123,8 +1139,8 @@ void LocalPlayer::applyControl(float dtime)
|
|||
speed = speed.normalize() * walkspeed_max;
|
||||
}
|
||||
}
|
||||
if (m_energy > hp) {
|
||||
m_energy = hp;
|
||||
if (m_energy > health) {
|
||||
m_energy = health;
|
||||
}else if (m_energy < -0.1) {
|
||||
m_can_use_energy = false;
|
||||
m_energy = -0.1;
|
||||
|
@ -1138,7 +1154,7 @@ void LocalPlayer::applyControl(float dtime)
|
|||
|
||||
m_low_energy_effect = g_sound->playSound(snd,true);
|
||||
}
|
||||
}else if (m_energy > 1.8) {
|
||||
}else if (m_energy > 9.8) {
|
||||
m_can_use_energy = true;
|
||||
if (g_sound && m_low_energy_effect) {
|
||||
g_sound->stopSound(m_low_energy_effect);
|
||||
|
|
187
src/player.h
|
@ -65,6 +65,22 @@
|
|||
#define PLAYER_HEAD 0x80
|
||||
#define PLAYER_ALL 0xFF
|
||||
|
||||
#define DAMAGE_NONE 0x00
|
||||
#define DAMAGE_UNKNOWN 0x01
|
||||
#define DAMAGE_FALL 0x02
|
||||
#define DAMAGE_EXPOSURE 0x03
|
||||
#define DAMAGE_COLD 0x04
|
||||
#define DAMAGE_ATTACK 0x05
|
||||
#define DAMAGE_SPACE 0x06
|
||||
#define DAMAGE_HUNGER 0x07
|
||||
#define DAMAGE_AIR 0x08
|
||||
#define DAMAGE_LAVA 0x09
|
||||
#define DAMAGE_CACTUS 0x0A
|
||||
#define DAMAGE_FIRE 0x0B
|
||||
#define DAMAGE_TNT 0x0C
|
||||
#define DAMAGE_STEAM 0x0D
|
||||
#define DAMAGE_POISON 0x0E
|
||||
|
||||
class Map;
|
||||
|
||||
class Player
|
||||
|
@ -213,80 +229,141 @@ public:
|
|||
|
||||
bool craftresult_is_preview;
|
||||
|
||||
u16 hp;
|
||||
u16 health;
|
||||
u16 air;
|
||||
u16 hunger;
|
||||
u16 energy_effect;
|
||||
u16 cold_effect;
|
||||
|
||||
u8 dirt;
|
||||
u8 wet;
|
||||
float wet_dtime;
|
||||
u8 blood;
|
||||
|
||||
void addDirt(u8 area)
|
||||
{
|
||||
dirt |= area;
|
||||
}
|
||||
void addBlood(u8 area)
|
||||
{
|
||||
blood |= area;
|
||||
}
|
||||
void addWater(u8 area)
|
||||
{
|
||||
wet |= area;
|
||||
dirt &= ~area;
|
||||
blood &= ~area;
|
||||
}
|
||||
|
||||
u16 last_damage;
|
||||
void addDamage(u8 area, u8 type, u16 amount)
|
||||
{
|
||||
last_damage = (type<<8)|area;
|
||||
if (amount > health) {
|
||||
health = 0;
|
||||
}else{
|
||||
health -= amount;
|
||||
}
|
||||
}
|
||||
void addHealth(u16 amount)
|
||||
{
|
||||
last_damage = 0;
|
||||
health += amount;
|
||||
if (health > 100)
|
||||
health = 100;
|
||||
}
|
||||
|
||||
u16 peer_id;
|
||||
|
||||
bool getHome(s8 i, v3f &h);
|
||||
void setHome(s8 i, v3f h);
|
||||
void unsetHome(s8 i);
|
||||
|
||||
f32 getArmourProtection()
|
||||
f32 getProtection(u8 area, u8 type)
|
||||
{
|
||||
InventoryList *l;
|
||||
InventoryItem *i;
|
||||
f32 v = 0;
|
||||
const char* list[7] = {"hat","shirt","jacket","decorative","belt","pants","boots"};
|
||||
for (int j=0; j<7; j++) {
|
||||
InventoryList *l = inventory.getList(list[j]);
|
||||
if (l == NULL)
|
||||
continue;
|
||||
InventoryItem *i = l->getItem(0);
|
||||
if (i == NULL)
|
||||
continue;
|
||||
v += content_clothesitem_features(i->getContent()).armour;
|
||||
}
|
||||
if (v > 1.0)
|
||||
return 1.0;
|
||||
return v;
|
||||
}
|
||||
f32 getWarmthProtection()
|
||||
{
|
||||
f32 v = 0;
|
||||
const char* list[7] = {"hat","shirt","jacket","decorative","belt","pants","boots"};
|
||||
if (cold_effect)
|
||||
return 1.0;
|
||||
for (int j=0; j<7; j++) {
|
||||
InventoryList *l = inventory.getList(list[j]);
|
||||
if (l == NULL)
|
||||
continue;
|
||||
InventoryItem *i = l->getItem(0);
|
||||
if (i == NULL)
|
||||
continue;
|
||||
v += content_clothesitem_features(i->getContent()).warmth;
|
||||
}
|
||||
if (v > 1.0)
|
||||
return 1.0;
|
||||
return v;
|
||||
}
|
||||
f32 getVacuumProtection()
|
||||
{
|
||||
f32 v = 0;
|
||||
const char* list[7] = {"hat","shirt","jacket","decorative","belt","pants","boots"};
|
||||
for (int j=0; j<7; j++) {
|
||||
InventoryList *l = inventory.getList(list[j]);
|
||||
if (l == NULL)
|
||||
continue;
|
||||
InventoryItem *i = l->getItem(0);
|
||||
if (i == NULL)
|
||||
continue;
|
||||
v += content_clothesitem_features(i->getContent()).vacuum;
|
||||
}
|
||||
if (v > 1.0)
|
||||
return 1.0;
|
||||
return v;
|
||||
}
|
||||
f32 getSuffocationProtection()
|
||||
{
|
||||
InventoryList *l = inventory.getList("hat");
|
||||
|
||||
switch (type) {
|
||||
case DAMAGE_FALL:
|
||||
l = inventory.getList("boots");
|
||||
if (l == NULL)
|
||||
return 0;
|
||||
InventoryItem *i = l->getItem(0);
|
||||
i = l->getItem(0);
|
||||
if (i == NULL)
|
||||
return 0;
|
||||
return content_clothesitem_features(i->getContent()).armour;
|
||||
break;
|
||||
case DAMAGE_AIR:
|
||||
l = inventory.getList("hat");
|
||||
if (l == NULL)
|
||||
return 0;
|
||||
i = l->getItem(0);
|
||||
if (i == NULL)
|
||||
return 0;
|
||||
return content_clothesitem_features(i->getContent()).suffocate;
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
|
||||
for (int j=0; j<7; j++) {
|
||||
if (area && area != PLAYER_ALL) {
|
||||
switch (area) {
|
||||
case PLAYER_FEET:
|
||||
if (j != 6)
|
||||
continue;
|
||||
break;
|
||||
case PLAYER_LLEG:
|
||||
case PLAYER_RLEG:
|
||||
if (j != 5 && j != 6)
|
||||
continue;
|
||||
break;
|
||||
case PLAYER_TORSO:
|
||||
if (j != 1)
|
||||
continue;
|
||||
break;
|
||||
case PLAYER_HANDS:
|
||||
case PLAYER_LARM:
|
||||
case PLAYER_RARM:
|
||||
if (j != 2)
|
||||
continue;
|
||||
break;
|
||||
case PLAYER_HEAD:
|
||||
if (j != 0)
|
||||
continue;
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
l = inventory.getList(list[j]);
|
||||
if (l == NULL)
|
||||
continue;
|
||||
i = l->getItem(0);
|
||||
if (i == NULL)
|
||||
continue;
|
||||
|
||||
switch (type) {
|
||||
case DAMAGE_TNT:
|
||||
case DAMAGE_FIRE:
|
||||
case DAMAGE_ATTACK:
|
||||
case DAMAGE_CACTUS:
|
||||
v += content_clothesitem_features(i->getContent()).armour;
|
||||
break;
|
||||
case DAMAGE_COLD:
|
||||
v += content_clothesitem_features(i->getContent()).warmth;
|
||||
break;
|
||||
case DAMAGE_SPACE:
|
||||
v += content_clothesitem_features(i->getContent()).vacuum;
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
}
|
||||
if (v > 1.0)
|
||||
return 1.0;
|
||||
return v;
|
||||
}
|
||||
|
||||
// character def used for skin creation and model scaling
|
||||
|
|
101
src/server.cpp
|
@ -1979,7 +1979,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
SendPlayerItems();
|
||||
|
||||
// Send HP
|
||||
SendPlayerHP(player);
|
||||
SendPlayerState(player);
|
||||
|
||||
// Send time of day
|
||||
{
|
||||
|
@ -2170,7 +2170,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
return;
|
||||
|
||||
// Track changes super-crappily
|
||||
u16 oldhp = player->hp;
|
||||
u16 oldhp = player->health;
|
||||
u16 oldair = player->air;
|
||||
u16 oldhunger = player->hunger;
|
||||
|
||||
|
@ -2185,8 +2185,8 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
SendInventory(peer_id);
|
||||
|
||||
// Send back stuff
|
||||
if (player->hp != oldhp || player->air != oldair || player->hunger != oldhunger || player->energy_effect || player->cold_effect)
|
||||
SendPlayerHP(player);
|
||||
if (player->health != oldhp || player->air != oldair || player->hunger != oldhunger || player->energy_effect || player->cold_effect)
|
||||
SendPlayerState(player);
|
||||
}
|
||||
break;
|
||||
case TOSERVER_PLAYERPOS:
|
||||
|
@ -2396,7 +2396,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
<<obj->getId()<<std::endl;
|
||||
|
||||
// Track changes super-crappily
|
||||
u16 oldhp = player->hp;
|
||||
u16 oldhp = player->health;
|
||||
u16 oldair = player->air;
|
||||
u16 oldhunger = player->hunger;
|
||||
|
||||
|
@ -2407,8 +2407,8 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
}
|
||||
|
||||
// Send back stuff
|
||||
if (player->hp != oldhp || player->air != oldair || player->hunger != oldhunger)
|
||||
SendPlayerHP(player);
|
||||
if (player->health != oldhp || player->air != oldair || player->hunger != oldhunger)
|
||||
SendPlayerState(player);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -4183,7 +4183,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
}
|
||||
|
||||
if (!damage && !suffocate && !hunger) {
|
||||
SendPlayerHP(player);
|
||||
SendPlayerState(player);
|
||||
}else{
|
||||
HandlePlayerHP(player, damage, suffocate, hunger);
|
||||
}
|
||||
|
@ -4613,7 +4613,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
break;
|
||||
case TOSERVER_RESPAWN:
|
||||
{
|
||||
if(player->hp != 0)
|
||||
if(player->health != 0)
|
||||
return;
|
||||
|
||||
RespawnPlayer(player);
|
||||
|
@ -4827,15 +4827,29 @@ void Server::deletingPeer(con::Peer *peer, bool timeout)
|
|||
Static send methods
|
||||
*/
|
||||
|
||||
void Server::SendHP(con::Connection &con, u16 peer_id, u8 hp, u8 air, u8 hunger, u16 energy_effect, u16 cold_effect)
|
||||
void Server::SendState(
|
||||
con::Connection &con,
|
||||
u16 peer_id,
|
||||
u8 health,
|
||||
u8 air,
|
||||
u8 hunger,
|
||||
u8 dirt,
|
||||
u8 wet,
|
||||
u8 blood,
|
||||
u16 energy_effect,
|
||||
u16 cold_effect
|
||||
)
|
||||
{
|
||||
DSTACK(__FUNCTION_NAME);
|
||||
std::ostringstream os(std::ios_base::binary);
|
||||
|
||||
writeU16(os, TOCLIENT_PLAYERHP);
|
||||
writeU8(os, hp);
|
||||
writeU16(os, TOCLIENT_PLAYERSTATE);
|
||||
writeU8(os, health);
|
||||
writeU8(os, air);
|
||||
writeU8(os, hunger);
|
||||
writeU8(os, dirt);
|
||||
writeU8(os, wet);
|
||||
writeU8(os, blood);
|
||||
writeU16(os, energy_effect);
|
||||
writeU16(os, cold_effect);
|
||||
|
||||
|
@ -5159,18 +5173,29 @@ void Server::BroadcastChatMessage(const std::wstring &message)
|
|||
}
|
||||
}
|
||||
|
||||
void Server::SendPlayerHP(Player *player)
|
||||
void Server::SendPlayerState(Player *player)
|
||||
{
|
||||
u8 hp = player->hp;
|
||||
u8 hp = player->health;
|
||||
u8 air = player->air;
|
||||
u8 hunger = player->hunger;
|
||||
if (hp < 20 && !g_settings->getBool("enable_damage"))
|
||||
hp = 20;
|
||||
if (air < 20 && !g_settings->getBool("enable_suffocation"))
|
||||
air = 20;
|
||||
if (hunger < 20 && !g_settings->getBool("enable_hunger"))
|
||||
hunger = 20;
|
||||
SendHP(m_con, player->peer_id, hp,air,hunger,player->energy_effect,player->cold_effect);
|
||||
if (hp < 100 && !g_settings->getBool("enable_damage"))
|
||||
hp = 100;
|
||||
if (air < 100 && !g_settings->getBool("enable_suffocation"))
|
||||
air = 100;
|
||||
if (hunger < 100 && !g_settings->getBool("enable_hunger"))
|
||||
hunger = 100;
|
||||
SendState(
|
||||
m_con,
|
||||
player->peer_id,
|
||||
hp,
|
||||
air,
|
||||
hunger,
|
||||
player->dirt,
|
||||
player->wet,
|
||||
player->blood,
|
||||
player->energy_effect,
|
||||
player->cold_effect
|
||||
);
|
||||
player->energy_effect = 0;
|
||||
player->cold_effect = 0;
|
||||
}
|
||||
|
@ -5514,30 +5539,31 @@ void Server::HandlePlayerHP(Player *player, s16 damage, s16 suffocate, s16 hunge
|
|||
{
|
||||
if (player->air > suffocate) {
|
||||
player->air -= suffocate;
|
||||
if (player->air > 20)
|
||||
player->air = 20;
|
||||
if (player->air > 100)
|
||||
player->air = 100;
|
||||
}else{
|
||||
damage += suffocate-player->air;
|
||||
player->air = 0;
|
||||
}
|
||||
if (player->hunger > hunger) {
|
||||
player->hunger -= hunger;
|
||||
if (player->hunger > 20)
|
||||
player->hunger = 20;
|
||||
if (player->hunger > 100)
|
||||
player->hunger = 100;
|
||||
}else{
|
||||
damage += hunger-player->hunger;
|
||||
player->hunger = 0;
|
||||
}
|
||||
if (player->hp > damage) {
|
||||
player->hp -= damage;
|
||||
if (player->hp > 20)
|
||||
player->hp = 20;
|
||||
SendPlayerHP(player);
|
||||
player->addDamage(PLAYER_ALL,DAMAGE_UNKNOWN,damage);
|
||||
if (player->health > 0) {
|
||||
SendPlayerState(player);
|
||||
}else{
|
||||
infostream<<"Server::HandlePlayerHP(): Player "
|
||||
<<player->getName()<<" dies"<<std::endl;
|
||||
|
||||
player->hp = 0;
|
||||
player->health = 0;
|
||||
player->dirt = 0;
|
||||
player->wet = 0;
|
||||
player->blood = 0;
|
||||
|
||||
//TODO: Throw items around
|
||||
if (g_settings->getBool("death_drops_inv")) {
|
||||
|
@ -5636,7 +5662,7 @@ void Server::HandlePlayerHP(Player *player, s16 damage, s16 suffocate, s16 hunge
|
|||
return;
|
||||
}
|
||||
|
||||
SendPlayerHP(player);
|
||||
SendPlayerState(player);
|
||||
|
||||
RemoteClient *client = getClient(player->peer_id);
|
||||
if (client->net_proto_version >= 3) {
|
||||
|
@ -5653,11 +5679,14 @@ void Server::RespawnPlayer(Player *player)
|
|||
if (!player->getHome(PLAYERFLAG_HOME,pos))
|
||||
pos = findSpawnPos(m_env.getServerMap());
|
||||
player->setPosition(pos);
|
||||
player->hp = 20;
|
||||
player->air = 20;
|
||||
player->hunger = 20;
|
||||
player->health = 100;
|
||||
player->air = 100;
|
||||
player->hunger = 100;
|
||||
player->dirt = 0;
|
||||
player->wet = 0;
|
||||
player->blood = 0;
|
||||
SendMovePlayer(player);
|
||||
SendPlayerHP(player);
|
||||
SendPlayerState(player);
|
||||
}
|
||||
|
||||
void Server::UpdateCrafting(u16 peer_id)
|
||||
|
|
17
src/server.h
|
@ -489,7 +489,18 @@ private:
|
|||
Static send methods
|
||||
*/
|
||||
|
||||
static void SendHP(con::Connection &con, u16 peer_id, u8 hp, u8 air, u8 hunger, u16 energy_effect, u16 cold_effect);
|
||||
static void SendState(
|
||||
con::Connection &con,
|
||||
u16 peer_id,
|
||||
u8 health,
|
||||
u8 air,
|
||||
u8 hunger,
|
||||
u8 dirt,
|
||||
u8 wet,
|
||||
u8 blood,
|
||||
u16 energy_effect,
|
||||
u16 cold_effect
|
||||
);
|
||||
static void SendAccessDenied(con::Connection &con, u16 peer_id,
|
||||
const std::wstring &reason);
|
||||
static void SendDeathscreen(con::Connection &con, u16 peer_id,
|
||||
|
@ -511,7 +522,7 @@ private:
|
|||
void SendPlayerItems(Player *player);
|
||||
void SendChatMessage(u16 peer_id, const std::wstring &message);
|
||||
void BroadcastChatMessage(const std::wstring &message);
|
||||
void SendPlayerHP(Player *player);
|
||||
void SendPlayerState(Player *player);
|
||||
// tell the client what kind of game is being played
|
||||
void SendSettings(Player *player);
|
||||
/*
|
||||
|
@ -552,7 +563,7 @@ private:
|
|||
std::string getPlayerName(u16 peer_id)
|
||||
{
|
||||
Player *player = m_env.getPlayer(peer_id);
|
||||
if(player == NULL)
|
||||
if (player == NULL)
|
||||
return "[id="+itos(peer_id);
|
||||
return player->getName();
|
||||
}
|
||||
|
|