forked from oerkki/voxelands
add suffocation and drowning, enable for survival mode
This commit is contained in:
parent
27adeddd1f
commit
f542cfa84e
Binary file not shown.
After Width: | Height: | Size: 619 B |
Binary file not shown.
Before Width: | Height: | Size: 250 B After Width: | Height: | Size: 247 B |
|
@ -539,19 +539,14 @@ void Client::step(float dtime)
|
|||
/*
|
||||
Get events
|
||||
*/
|
||||
for(;;)
|
||||
{
|
||||
for (;;) {
|
||||
ClientEnvEvent event = m_env.getClientEvent();
|
||||
if(event.type == CEE_NONE)
|
||||
{
|
||||
if (event.type == CEE_NONE) {
|
||||
break;
|
||||
}
|
||||
else if(event.type == CEE_PLAYER_DAMAGE)
|
||||
{
|
||||
if(m_ignore_damage_timer <= 0)
|
||||
{
|
||||
u8 damage = event.player_damage.amount;
|
||||
sendDamage(damage);
|
||||
}else if (event.type == CEE_PLAYER_DAMAGE) {
|
||||
if (m_ignore_damage_timer <= 0) {
|
||||
s8 damage = event.player_damage.amount;
|
||||
sendDamage(damage,0);
|
||||
|
||||
// Add to ClientEvent queue
|
||||
ClientEvent event;
|
||||
|
@ -559,6 +554,19 @@ void Client::step(float dtime)
|
|||
event.player_damage.amount = damage;
|
||||
m_client_event_queue.push_back(event);
|
||||
}
|
||||
}else if (event.type == CEE_PLAYER_SUFFOCATE) {
|
||||
if (m_ignore_damage_timer <= 0) {
|
||||
s8 damage = event.player_damage.amount;
|
||||
sendDamage(0,damage);
|
||||
|
||||
// Add to ClientEvent queue
|
||||
ClientEvent event;
|
||||
event.type = CE_PLAYER_SUFFOCATE;
|
||||
if (getAir() < 1 && damage > 0)
|
||||
event.type = CE_PLAYER_DAMAGE;
|
||||
event.player_damage.amount = damage;
|
||||
m_client_event_queue.push_back(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1115,46 +1123,16 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
|||
|
||||
player->updateAnim(anim_id);
|
||||
}
|
||||
else if(command == TOCLIENT_SECTORMETA)
|
||||
else if(command == TOCLIENT_PLAYERHP)
|
||||
{
|
||||
infostream<<"Client received DEPRECATED TOCLIENT_SECTORMETA"<<std::endl;
|
||||
#if 0
|
||||
/*
|
||||
[0] u16 command
|
||||
[2] u8 sector count
|
||||
[3...] v2s16 pos + sector metadata
|
||||
*/
|
||||
if(datasize < 3)
|
||||
return;
|
||||
|
||||
//infostream<<"Client received TOCLIENT_SECTORMETA"<<std::endl;
|
||||
|
||||
{ //envlock
|
||||
//JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
|
||||
|
||||
std::string datastring((char*)&data[2], datasize-2);
|
||||
std::istringstream is(datastring, std::ios_base::binary);
|
||||
|
||||
u8 buf[4];
|
||||
|
||||
is.read((char*)buf, 1);
|
||||
u16 sector_count = readU8(buf);
|
||||
|
||||
//infostream<<"sector_count="<<sector_count<<std::endl;
|
||||
|
||||
for(u16 i=0; i<sector_count; i++)
|
||||
{
|
||||
// Read position
|
||||
is.read((char*)buf, 4);
|
||||
v2s16 pos = readV2S16(buf);
|
||||
/*infostream<<"Client: deserializing sector at "
|
||||
<<"("<<pos.X<<","<<pos.Y<<")"<<std::endl;*/
|
||||
// Create sector
|
||||
assert(m_env.getMap().mapType() == MAPTYPE_CLIENT);
|
||||
((ClientMap&)m_env.getMap()).deSerializeSector(pos, is);
|
||||
}
|
||||
} //envlock
|
||||
#endif
|
||||
std::string datastring((char*)&data[2], datasize-2);
|
||||
std::istringstream is(datastring, std::ios_base::binary);
|
||||
Player *player = m_env.getLocalPlayer();
|
||||
assert(player != NULL);
|
||||
u8 hp = readU8(is);
|
||||
u8 air = readU8(is);
|
||||
player->hp = hp;
|
||||
player->air = air;
|
||||
}
|
||||
else if(command == TOCLIENT_INVENTORY)
|
||||
{
|
||||
|
@ -1413,6 +1391,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
|||
}
|
||||
else if(command == TOCLIENT_HP)
|
||||
{
|
||||
infostream<<"Client received DEPRECATED TOCLIENT_HP"<<std::endl;
|
||||
std::string datastring((char*)&data[2], datasize-2);
|
||||
std::istringstream is(datastring, std::ios_base::binary);
|
||||
Player *player = m_env.getLocalPlayer();
|
||||
|
@ -1753,13 +1732,14 @@ void Client::sendChangePassword(const std::wstring oldpassword,
|
|||
}
|
||||
|
||||
|
||||
void Client::sendDamage(u8 damage)
|
||||
void Client::sendDamage(s8 damage,s8 suffocate)
|
||||
{
|
||||
DSTACK(__FUNCTION_NAME);
|
||||
std::ostringstream os(std::ios_base::binary);
|
||||
|
||||
writeU16(os, TOSERVER_DAMAGE);
|
||||
writeU8(os, damage);
|
||||
writeU16(os, TOSERVER_PLAYERDAMAGE);
|
||||
writeS8(os, damage);
|
||||
writeS8(os, suffocate);
|
||||
|
||||
// Make data buffer
|
||||
std::string s = os.str();
|
||||
|
@ -2121,6 +2101,13 @@ u16 Client::getHP()
|
|||
return player->hp;
|
||||
}
|
||||
|
||||
u16 Client::getAir()
|
||||
{
|
||||
Player *player = m_env.getLocalPlayer();
|
||||
assert(player != NULL);
|
||||
return player->air;
|
||||
}
|
||||
|
||||
void Client::setTempMod(v3s16 p, NodeMod mod)
|
||||
{
|
||||
//JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
|
||||
|
|
|
@ -119,6 +119,7 @@ enum ClientEventType
|
|||
{
|
||||
CE_NONE,
|
||||
CE_PLAYER_DAMAGE,
|
||||
CE_PLAYER_SUFFOCATE,
|
||||
CE_PLAYER_FORCE_MOVE,
|
||||
CE_DEATHSCREEN,
|
||||
};
|
||||
|
@ -130,7 +131,7 @@ struct ClientEvent
|
|||
struct{
|
||||
} none;
|
||||
struct{
|
||||
u8 amount;
|
||||
s8 amount;
|
||||
} player_damage;
|
||||
struct{
|
||||
f32 pitch;
|
||||
|
@ -207,7 +208,7 @@ public:
|
|||
void sendChatMessage(const std::wstring &message);
|
||||
void sendChangePassword(const std::wstring oldpassword,
|
||||
const std::wstring newpassword);
|
||||
void sendDamage(u8 damage);
|
||||
void sendDamage(s8 damage, s8 suffocate);
|
||||
void sendRespawn();
|
||||
void sendWantCookie();
|
||||
|
||||
|
@ -260,6 +261,7 @@ public:
|
|||
u32 getDayNightRatio();
|
||||
|
||||
u16 getHP();
|
||||
u16 getAir();
|
||||
|
||||
void setTempMod(v3s16 p, NodeMod mod);
|
||||
void clearTempMod(v3s16 p);
|
||||
|
|
|
@ -22,7 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
|
||||
#include "utility.h"
|
||||
|
||||
#define PROTOCOL_VERSION 5
|
||||
#define PROTOCOL_VERSION 6
|
||||
/* 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
|
||||
|
@ -82,11 +82,11 @@ enum ToClientCommand
|
|||
[4] u8 animation_id
|
||||
*/
|
||||
|
||||
TOCLIENT_SECTORMETA = 0x26, // Obsolete
|
||||
TOCLIENT_PLAYERHP = 0x26,
|
||||
/*
|
||||
[0] u16 command
|
||||
[2] u8 sector count
|
||||
[3...] v2s16 pos + sector metadata
|
||||
u16 command
|
||||
u8 hp
|
||||
|
||||
*/
|
||||
|
||||
TOCLIENT_INVENTORY = 0x27,
|
||||
|
@ -284,7 +284,12 @@ enum ToServerCommand
|
|||
3: digging completed
|
||||
*/
|
||||
|
||||
TOSERVER_RELEASE = 0x29, // Obsolete
|
||||
TOSERVER_PLAYERDAMAGE = 0x29,
|
||||
/*
|
||||
u16 command
|
||||
u8 damage_amount
|
||||
u8 suffocate_amount
|
||||
*/
|
||||
|
||||
TOSERVER_SIGNTEXT = 0x30, // Old signs
|
||||
/*
|
||||
|
@ -324,7 +329,7 @@ enum ToServerCommand
|
|||
[5] u16 item
|
||||
*/
|
||||
|
||||
TOSERVER_DAMAGE = 0x35,
|
||||
TOSERVER_DAMAGE = 0x35, // obsolete, see TOSERVER_PLAYERDAMAGE
|
||||
/*
|
||||
u16 command
|
||||
u8 amount
|
||||
|
|
|
@ -152,6 +152,7 @@ void set_creative_defaults(Settings *settings)
|
|||
settings->setDefault("infinite_inventory", "true");
|
||||
settings->setDefault("droppable_inventory", "false");
|
||||
settings->setDefault("enable_damage", "false");
|
||||
settings->setDefault("enable_suffocation", "false");
|
||||
settings->setDefault("max_mob_level", "passive");
|
||||
settings->setDefault("initial_inventory", "false");
|
||||
settings->setDefault("tool_wear","false");
|
||||
|
@ -162,6 +163,7 @@ void set_adventure_defaults(Settings *settings)
|
|||
settings->setDefault("infinite_inventory", "false");
|
||||
settings->setDefault("droppable_inventory", "true");
|
||||
settings->setDefault("enable_damage", "true");
|
||||
settings->setDefault("enable_suffocation", "false");
|
||||
settings->setDefault("max_mob_level", "aggressive");
|
||||
settings->setDefault("initial_inventory", "true");
|
||||
settings->setDefault("tool_wear","true");
|
||||
|
@ -172,6 +174,7 @@ void set_survival_defaults(Settings *settings)
|
|||
settings->setDefault("infinite_inventory", "false");
|
||||
settings->setDefault("droppable_inventory", "true");
|
||||
settings->setDefault("enable_damage", "true");
|
||||
settings->setDefault("enable_suffocation", "true");
|
||||
settings->setDefault("max_mob_level", "aggressive");
|
||||
settings->setDefault("initial_inventory", "false");
|
||||
settings->setDefault("tool_wear","true");
|
||||
|
|
|
@ -4033,6 +4033,18 @@ void ClientEnvironment::step(float dtime)
|
|||
event.type = CEE_PLAYER_DAMAGE;
|
||||
event.player_damage.amount = damage_per_second;
|
||||
m_client_event_queue.push_back(event);
|
||||
}else if (!content_features(n3).air_equivalent) {
|
||||
ClientEnvEvent event;
|
||||
event.type = CEE_PLAYER_SUFFOCATE;
|
||||
event.player_damage.amount = 2;
|
||||
if (content_features(n3).liquid_type == LIQUID_NONE)
|
||||
event.player_damage.amount = 4;
|
||||
m_client_event_queue.push_back(event);
|
||||
}else if (lplayer->air < 20) {
|
||||
ClientEnvEvent event;
|
||||
event.type = CEE_PLAYER_SUFFOCATE;
|
||||
event.player_damage.amount = -20;
|
||||
m_client_event_queue.push_back(event);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -336,7 +336,8 @@ private:
|
|||
enum ClientEnvEventType
|
||||
{
|
||||
CEE_NONE,
|
||||
CEE_PLAYER_DAMAGE
|
||||
CEE_PLAYER_DAMAGE,
|
||||
CEE_PLAYER_SUFFOCATE
|
||||
};
|
||||
|
||||
struct ClientEnvEvent
|
||||
|
|
95
src/game.cpp
95
src/game.cpp
|
@ -223,7 +223,7 @@ public:
|
|||
*/
|
||||
void draw_hotbar(video::IVideoDriver *driver, gui::IGUIFont *font,
|
||||
v2s32 centerlowerpos, s32 imgsize, s32 itemcount,
|
||||
Inventory *inventory, s32 halfheartcount)
|
||||
Inventory *inventory, s32 halfheartcount, s32 halfbubblecount)
|
||||
{
|
||||
InventoryList *mainlist = inventory->getList("main");
|
||||
if(mainlist == NULL)
|
||||
|
@ -278,36 +278,74 @@ void draw_hotbar(video::IVideoDriver *driver, gui::IGUIFont *font,
|
|||
/*
|
||||
Draw hearts
|
||||
*/
|
||||
{
|
||||
video::ITexture *heart_texture =
|
||||
driver->getTexture(getTexturePath("heart.png").c_str());
|
||||
v2s32 p = pos + v2s32(0, -25);
|
||||
for(s32 i=0; i<halfheartcount/2; i++)
|
||||
{
|
||||
struct {
|
||||
s32 count;
|
||||
s32 halfcount;
|
||||
const char* texture;
|
||||
bool show_full;
|
||||
} barData[3] = {
|
||||
{halfheartcount/2,halfheartcount,"heart.png",true},
|
||||
{halfbubblecount/2,halfbubblecount,"bubble.png",false},
|
||||
{10,0,"heart.png",false},
|
||||
};
|
||||
v2s32 bar_base(0,-25);
|
||||
for (s32 k=0; k<3; k++) {
|
||||
if (barData[k].count == 10 && !barData[k].show_full)
|
||||
continue;
|
||||
video::ITexture *texture = driver->getTexture(getTexturePath(barData[k].texture).c_str());
|
||||
v2s32 p = pos + bar_base;
|
||||
for (s32 i=0; i<barData[k].count; i++) {
|
||||
const video::SColor color(255,255,255,255);
|
||||
const video::SColor colors[] = {color,color,color,color};
|
||||
core::rect<s32> rect(0,0,16,16);
|
||||
rect += p;
|
||||
driver->draw2DImage(heart_texture, rect,
|
||||
driver->draw2DImage(texture, rect,
|
||||
core::rect<s32>(core::position2d<s32>(0,0),
|
||||
core::dimension2di(heart_texture->getOriginalSize())),
|
||||
core::dimension2di(texture->getOriginalSize())),
|
||||
NULL, colors, true);
|
||||
p += v2s32(16,0);
|
||||
}
|
||||
if(halfheartcount % 2 == 1)
|
||||
{
|
||||
if (barData[k].halfcount % 2 == 1) {
|
||||
const video::SColor color(255,255,255,255);
|
||||
const video::SColor colors[] = {color,color,color,color};
|
||||
core::rect<s32> rect(0,0,16/2,16);
|
||||
rect += p;
|
||||
core::dimension2di srcd(heart_texture->getOriginalSize());
|
||||
core::dimension2di srcd(texture->getOriginalSize());
|
||||
srcd.Width /= 2;
|
||||
driver->draw2DImage(heart_texture, rect,
|
||||
driver->draw2DImage(texture, rect,
|
||||
core::rect<s32>(core::position2d<s32>(0,0), srcd),
|
||||
NULL, colors, true);
|
||||
p += v2s32(16,0);
|
||||
}
|
||||
bar_base.Y -= 20;
|
||||
}
|
||||
//if (halfbubblecount < 20) {
|
||||
//video::ITexture *bubble_texture = driver->getTexture(getTexturePath("bubble.png").c_str());
|
||||
//v2s32 p = pos + v2s32(0, -40);
|
||||
//for (s32 i=0; i<halfbubblecount/2; i++) {
|
||||
//const video::SColor color(255,255,255,255);
|
||||
//const video::SColor colors[] = {color,color,color,color};
|
||||
//core::rect<s32> rect(0,0,16,16);
|
||||
//rect += p;
|
||||
//driver->draw2DImage(bubble_texture, rect,
|
||||
//core::rect<s32>(core::position2d<s32>(0,0),
|
||||
//core::dimension2di(bubble_texture->getOriginalSize())),
|
||||
//NULL, colors, true);
|
||||
//p += v2s32(16,0);
|
||||
//}
|
||||
//if (halfbubblecount % 2 == 1) {
|
||||
//const video::SColor color(255,255,255,255);
|
||||
//const video::SColor colors[] = {color,color,color,color};
|
||||
//core::rect<s32> rect(0,0,16/2,16);
|
||||
//rect += p;
|
||||
//core::dimension2di srcd(bubble_texture->getOriginalSize());
|
||||
//srcd.Width /= 2;
|
||||
//driver->draw2DImage(bubble_texture, rect,
|
||||
//core::rect<s32>(core::position2d<s32>(0,0), srcd),
|
||||
//NULL, colors, true);
|
||||
//p += v2s32(16,0);
|
||||
//}
|
||||
//}
|
||||
if (selected != "") {
|
||||
v2u32 dim = font->getDimension(narrow_to_wide(selected).c_str());
|
||||
v2s32 sdim(dim.X,dim.Y);
|
||||
|
@ -1622,28 +1660,20 @@ void the_game(
|
|||
|
||||
{
|
||||
// Read client events
|
||||
for(;;)
|
||||
{
|
||||
for(;;) {
|
||||
ClientEvent event = client.getClientEvent();
|
||||
if(event.type == CE_NONE)
|
||||
{
|
||||
if (event.type == CE_NONE) {
|
||||
break;
|
||||
}
|
||||
else if(event.type == CE_PLAYER_DAMAGE)
|
||||
{
|
||||
}else if (event.type == CE_PLAYER_DAMAGE) {
|
||||
damage_flash_timer = 0.05;
|
||||
if(event.player_damage.amount >= 2){
|
||||
damage_flash_timer += 0.05 * event.player_damage.amount;
|
||||
}
|
||||
}
|
||||
else if(event.type == CE_PLAYER_FORCE_MOVE)
|
||||
{
|
||||
}else if (event.type == CE_PLAYER_FORCE_MOVE) {
|
||||
camera_yaw = event.player_force_move.yaw;
|
||||
camera_pitch = event.player_force_move.pitch;
|
||||
}
|
||||
else if(event.type == CE_DEATHSCREEN)
|
||||
{
|
||||
if(respawn_menu_active)
|
||||
}else if (event.type == CE_DEATHSCREEN) {
|
||||
if (respawn_menu_active)
|
||||
continue;
|
||||
|
||||
MainRespawnInitiator *respawner =
|
||||
|
@ -2361,8 +2391,7 @@ void the_game(
|
|||
/*
|
||||
Draw crosshair
|
||||
*/
|
||||
if(show_hud)
|
||||
{
|
||||
if (show_hud) {
|
||||
driver->draw2DLine(displaycenter - core::vector2d<s32>(10,0),
|
||||
displaycenter + core::vector2d<s32>(10,0),
|
||||
video::SColor(255,255,255,255));
|
||||
|
@ -2382,18 +2411,16 @@ void the_game(
|
|||
/*
|
||||
Draw hotbar
|
||||
*/
|
||||
if(show_hud)
|
||||
{
|
||||
if (show_hud) {
|
||||
draw_hotbar(driver, font, v2s32(displaycenter.X, screensize.Y),
|
||||
hotbar_imagesize, hotbar_itemcount, &local_inventory,
|
||||
client.getHP());
|
||||
client.getHP(), client.getAir());
|
||||
}
|
||||
|
||||
/*
|
||||
Damage flash
|
||||
*/
|
||||
if(damage_flash_timer > 0.0)
|
||||
{
|
||||
if (damage_flash_timer > 0.0) {
|
||||
damage_flash_timer -= dtime;
|
||||
|
||||
video::SColor color(128,255,0,0);
|
||||
|
|
|
@ -407,6 +407,8 @@ LocalPlayer::LocalPlayer():
|
|||
// Initialize hp to 0, so that no hearts will be shown if server
|
||||
// doesn't support health points
|
||||
hp = 0;
|
||||
// Likewise, initialize air to 20, so that no bubbles will be shown
|
||||
air = 20;
|
||||
}
|
||||
|
||||
LocalPlayer::~LocalPlayer()
|
||||
|
|
|
@ -172,6 +172,7 @@ public:
|
|||
bool craftresult_is_preview;
|
||||
|
||||
u16 hp;
|
||||
u16 air;
|
||||
|
||||
u16 peer_id;
|
||||
|
||||
|
|
|
@ -2130,7 +2130,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
/*
|
||||
Check HP, respawn if necessary
|
||||
*/
|
||||
HandlePlayerHP(player, 0);
|
||||
HandlePlayerHP(player, 0, 0);
|
||||
|
||||
/*
|
||||
Print out action
|
||||
|
@ -3489,7 +3489,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
|| tool->getContent() != CONTENT_TOOLITEM_STEELBUCKET
|
||||
) {
|
||||
mlist->deleteItem(item_i);
|
||||
HandlePlayerHP(player,4);
|
||||
HandlePlayerHP(player,4,0);
|
||||
}else{
|
||||
std::string dug_s = std::string("ToolItem ") + tool->getToolName() + "_lava 1";
|
||||
std::istringstream is(dug_s, std::ios::binary);
|
||||
|
@ -4084,7 +4084,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
}
|
||||
}else{
|
||||
ilist->deleteItem(item_i);
|
||||
HandlePlayerHP(player,4);
|
||||
HandlePlayerHP(player,4,0);
|
||||
UpdateCrafting(player->peer_id);
|
||||
SendInventory(player->peer_id);
|
||||
}
|
||||
|
@ -4275,19 +4275,34 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
<<action<<std::endl;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
else if(command == TOSERVER_RELEASE)
|
||||
else if(command == TOSERVER_PLAYERDAMAGE)
|
||||
{
|
||||
if(datasize < 3)
|
||||
return;
|
||||
/*
|
||||
length: 3
|
||||
[0] u16 command
|
||||
[2] u8 button
|
||||
*/
|
||||
infostream<<"TOSERVER_RELEASE ignored"<<std::endl;
|
||||
std::string datastring((char*)&data[2], datasize-2);
|
||||
std::istringstream is(datastring, std::ios_base::binary);
|
||||
s8 damage = readS8(is);
|
||||
s8 suffocate = readS8(is);
|
||||
|
||||
if (damage && g_settings->getBool("enable_damage")) {
|
||||
actionstream<<player->getName()<<" damaged by "
|
||||
<<(int)damage<<" hp at "<<PP(player->getPosition()/BS)
|
||||
<<std::endl;
|
||||
}else{
|
||||
damage = 0;
|
||||
}
|
||||
if (suffocate && g_settings->getBool("enable_suffocation")) {
|
||||
actionstream<<player->getName()<<" lost "
|
||||
<<(int)suffocate<<" air at "<<PP(player->getPosition()/BS)
|
||||
<<std::endl;
|
||||
}else{
|
||||
suffocate = 0;
|
||||
}
|
||||
|
||||
if (!damage && !suffocate) {
|
||||
SendPlayerHP(player);
|
||||
}else{
|
||||
HandlePlayerHP(player, damage, suffocate);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else if(command == TOSERVER_SIGNTEXT)
|
||||
{
|
||||
infostream<<"Server: TOSERVER_SIGNTEXT not supported anymore"
|
||||
|
@ -4590,17 +4605,15 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
std::string datastring((char*)&data[2], datasize-2);
|
||||
std::istringstream is(datastring, std::ios_base::binary);
|
||||
u8 damage = readU8(is);
|
||||
infostream<<"TOSERVER_DAMAGE: using deprecated command"<<std::endl;
|
||||
|
||||
if(g_settings->getBool("enable_damage"))
|
||||
{
|
||||
if (g_settings->getBool("enable_damage")) {
|
||||
actionstream<<player->getName()<<" damaged by "
|
||||
<<(int)damage<<" hp at "<<PP(player->getPosition()/BS)
|
||||
<<std::endl;
|
||||
|
||||
HandlePlayerHP(player, damage);
|
||||
}
|
||||
else
|
||||
{
|
||||
HandlePlayerHP(player, damage, 0);
|
||||
}else{
|
||||
SendPlayerHP(player);
|
||||
}
|
||||
}
|
||||
|
@ -4900,13 +4913,14 @@ void Server::deletingPeer(con::Peer *peer, bool timeout)
|
|||
Static send methods
|
||||
*/
|
||||
|
||||
void Server::SendHP(con::Connection &con, u16 peer_id, u8 hp)
|
||||
void Server::SendHP(con::Connection &con, u16 peer_id, u8 hp, u8 air)
|
||||
{
|
||||
DSTACK(__FUNCTION_NAME);
|
||||
std::ostringstream os(std::ios_base::binary);
|
||||
|
||||
writeU16(os, TOCLIENT_HP);
|
||||
writeU16(os, TOCLIENT_PLAYERHP);
|
||||
writeU8(os, hp);
|
||||
writeU8(os, air);
|
||||
|
||||
// Make data buffer
|
||||
std::string s = os.str();
|
||||
|
@ -5157,7 +5171,7 @@ void Server::BroadcastChatMessage(const std::wstring &message)
|
|||
|
||||
void Server::SendPlayerHP(Player *player)
|
||||
{
|
||||
SendHP(m_con, player->peer_id, player->hp);
|
||||
SendHP(m_con, player->peer_id, player->hp, player->air);
|
||||
}
|
||||
|
||||
void Server::SendPlayerCookie(Player *player)
|
||||
|
@ -5437,15 +5451,22 @@ void Server::SendBlocks(float dtime)
|
|||
Something random
|
||||
*/
|
||||
|
||||
void Server::HandlePlayerHP(Player *player, s16 damage)
|
||||
void Server::HandlePlayerHP(Player *player, s16 damage, s16 suffocate)
|
||||
{
|
||||
if(player->hp > damage)
|
||||
{
|
||||
player->hp -= damage;
|
||||
SendPlayerHP(player);
|
||||
if (player->air > suffocate) {
|
||||
player->air -= suffocate;
|
||||
if (player->air > 20)
|
||||
player->air = 20;
|
||||
}else{
|
||||
player->air = 0;
|
||||
damage += suffocate-player->air;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (player->hp > damage) {
|
||||
player->hp -= damage;
|
||||
if (player->hp > 20)
|
||||
player->hp = 20;
|
||||
SendPlayerHP(player);
|
||||
}else{
|
||||
infostream<<"Server::HandlePlayerHP(): Player "
|
||||
<<player->getName()<<" dies"<<std::endl;
|
||||
|
||||
|
@ -5480,6 +5501,7 @@ void Server::RespawnPlayer(Player *player)
|
|||
pos = findSpawnPos(m_env.getServerMap());
|
||||
player->setPosition(pos);
|
||||
player->hp = 20;
|
||||
player->air = 20;
|
||||
SendMovePlayer(player);
|
||||
SendPlayerHP(player);
|
||||
}
|
||||
|
|
|
@ -513,7 +513,7 @@ private:
|
|||
Static send methods
|
||||
*/
|
||||
|
||||
static void SendHP(con::Connection &con, u16 peer_id, u8 hp);
|
||||
static void SendHP(con::Connection &con, u16 peer_id, u8 hp, u8 air);
|
||||
static void SendAccessDenied(con::Connection &con, u16 peer_id,
|
||||
const std::wstring &reason);
|
||||
static void SendDeathscreen(con::Connection &con, u16 peer_id,
|
||||
|
@ -558,7 +558,7 @@ private:
|
|||
Something random
|
||||
*/
|
||||
|
||||
void HandlePlayerHP(Player *player, s16 damage);
|
||||
void HandlePlayerHP(Player *player, s16 damage, s16 suffocate);
|
||||
void RespawnPlayer(Player *player);
|
||||
|
||||
void UpdateCrafting(u16 peer_id);
|
||||
|
|
|
@ -76,6 +76,11 @@ inline void writeU8(u8 *data, u8 i)
|
|||
data[0] = ((i>> 0)&0xff);
|
||||
}
|
||||
|
||||
inline void writeS8(u8 *data, s8 i)
|
||||
{
|
||||
data[0] = ((i>> 0)&0xff);
|
||||
}
|
||||
|
||||
inline uint64_t readU64(u8 *data)
|
||||
{
|
||||
return ((uint64_t)data[0]<<56) | ((uint64_t)data[1]<<48)
|
||||
|
@ -99,6 +104,11 @@ inline u8 readU8(u8 *data)
|
|||
return (data[0]<<0);
|
||||
}
|
||||
|
||||
inline s8 readS8(u8 *data)
|
||||
{
|
||||
return ((s8)data[0]<<0);
|
||||
}
|
||||
|
||||
inline void writeS32(u8 *data, s32 i){
|
||||
writeU32(data, (u32)i);
|
||||
}
|
||||
|
@ -204,12 +214,24 @@ inline void writeU8(std::ostream &os, u8 p)
|
|||
writeU8((u8*)buf, p);
|
||||
os.write(buf, 1);
|
||||
}
|
||||
inline void writeS8(std::ostream &os, s8 p)
|
||||
{
|
||||
char buf[1];
|
||||
writeS8((u8*)buf, p);
|
||||
os.write(buf, 1);
|
||||
}
|
||||
inline u8 readU8(std::istream &is)
|
||||
{
|
||||
char buf[1];
|
||||
is.read(buf, 1);
|
||||
return readU8((u8*)buf);
|
||||
}
|
||||
inline s8 readS8(std::istream &is)
|
||||
{
|
||||
char buf[1];
|
||||
is.read(buf, 1);
|
||||
return readS8((u8*)buf);
|
||||
}
|
||||
|
||||
inline void writeU16(std::ostream &os, u16 p)
|
||||
{
|
||||
|
|
|
@ -135,6 +135,13 @@
|
|||
#enable_damage = true
|
||||
# survival
|
||||
#enable_damage = true
|
||||
# Enable players suffocating/drowning and dying
|
||||
# creative
|
||||
#enable_suffocation = false
|
||||
# adventure
|
||||
#enable_suffocation = false
|
||||
# survival
|
||||
#enable_suffocation = true
|
||||
# The maximum 'level' of mobs to spawn: passive, aggressive, destructive
|
||||
# roughly: passive = rats, aggressive = oerkki, destructive = DM
|
||||
# creative
|
||||
|
|
Loading…
Reference in New Issue