forked from oerkki/voxelands
add hunger, enable for survival mode
This commit is contained in:
parent
f542cfa84e
commit
3266833cb9
|
@ -546,7 +546,7 @@ void Client::step(float dtime)
|
|||
}else if (event.type == CEE_PLAYER_DAMAGE) {
|
||||
if (m_ignore_damage_timer <= 0) {
|
||||
s8 damage = event.player_damage.amount;
|
||||
sendDamage(damage,0);
|
||||
sendDamage(damage,0,0);
|
||||
|
||||
// Add to ClientEvent queue
|
||||
ClientEvent event;
|
||||
|
@ -557,16 +557,33 @@ void Client::step(float dtime)
|
|||
}else if (event.type == CEE_PLAYER_SUFFOCATE) {
|
||||
if (m_ignore_damage_timer <= 0) {
|
||||
s8 damage = event.player_damage.amount;
|
||||
sendDamage(0,damage);
|
||||
sendDamage(0,damage,0);
|
||||
|
||||
// Add to ClientEvent queue
|
||||
ClientEvent event;
|
||||
event.type = CE_PLAYER_SUFFOCATE;
|
||||
// this will cause the damage screen to flash
|
||||
// when suffocation starts effecting damage
|
||||
if (getAir() < 1 && damage > 0)
|
||||
event.type = CE_PLAYER_DAMAGE;
|
||||
event.player_damage.amount = damage;
|
||||
m_client_event_queue.push_back(event);
|
||||
}
|
||||
}else if (event.type == CEE_PLAYER_HUNGER) {
|
||||
if (m_ignore_damage_timer <= 0) {
|
||||
s8 damage = event.player_damage.amount;
|
||||
sendDamage(0,0,damage);
|
||||
|
||||
// Add to ClientEvent queue
|
||||
ClientEvent event;
|
||||
event.type = CE_PLAYER_HUNGER;
|
||||
// this will cause the damage screen to flash
|
||||
// when hunger starts effecting damage
|
||||
if (getHunger() < 1 && damage > 0)
|
||||
event.type = CE_PLAYER_DAMAGE;
|
||||
event.player_damage.amount = damage;
|
||||
m_client_event_queue.push_back(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1131,8 +1148,10 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
|
|||
assert(player != NULL);
|
||||
u8 hp = readU8(is);
|
||||
u8 air = readU8(is);
|
||||
u8 hunger = readU8(is);
|
||||
player->hp = hp;
|
||||
player->air = air;
|
||||
player->hunger = hunger;
|
||||
}
|
||||
else if(command == TOCLIENT_INVENTORY)
|
||||
{
|
||||
|
@ -1732,7 +1751,7 @@ void Client::sendChangePassword(const std::wstring oldpassword,
|
|||
}
|
||||
|
||||
|
||||
void Client::sendDamage(s8 damage,s8 suffocate)
|
||||
void Client::sendDamage(s8 damage,s8 suffocate,s8 hunger)
|
||||
{
|
||||
DSTACK(__FUNCTION_NAME);
|
||||
std::ostringstream os(std::ios_base::binary);
|
||||
|
@ -1740,6 +1759,7 @@ void Client::sendDamage(s8 damage,s8 suffocate)
|
|||
writeU16(os, TOSERVER_PLAYERDAMAGE);
|
||||
writeS8(os, damage);
|
||||
writeS8(os, suffocate);
|
||||
writeS8(os, hunger);
|
||||
|
||||
// Make data buffer
|
||||
std::string s = os.str();
|
||||
|
@ -2108,6 +2128,13 @@ u16 Client::getAir()
|
|||
return player->air;
|
||||
}
|
||||
|
||||
u16 Client::getHunger()
|
||||
{
|
||||
Player *player = m_env.getLocalPlayer();
|
||||
assert(player != NULL);
|
||||
return player->hunger;
|
||||
}
|
||||
|
||||
void Client::setTempMod(v3s16 p, NodeMod mod)
|
||||
{
|
||||
//JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
|
||||
|
|
|
@ -120,6 +120,7 @@ enum ClientEventType
|
|||
CE_NONE,
|
||||
CE_PLAYER_DAMAGE,
|
||||
CE_PLAYER_SUFFOCATE,
|
||||
CE_PLAYER_HUNGER,
|
||||
CE_PLAYER_FORCE_MOVE,
|
||||
CE_DEATHSCREEN,
|
||||
};
|
||||
|
@ -208,7 +209,7 @@ public:
|
|||
void sendChatMessage(const std::wstring &message);
|
||||
void sendChangePassword(const std::wstring oldpassword,
|
||||
const std::wstring newpassword);
|
||||
void sendDamage(s8 damage, s8 suffocate);
|
||||
void sendDamage(s8 damage, s8 suffocate, s8 hunger);
|
||||
void sendRespawn();
|
||||
void sendWantCookie();
|
||||
|
||||
|
@ -262,6 +263,7 @@ public:
|
|||
|
||||
u16 getHP();
|
||||
u16 getAir();
|
||||
u16 getHunger();
|
||||
|
||||
void setTempMod(v3s16 p, NodeMod mod);
|
||||
void clearTempMod(v3s16 p);
|
||||
|
|
|
@ -85,8 +85,9 @@ enum ToClientCommand
|
|||
TOCLIENT_PLAYERHP = 0x26,
|
||||
/*
|
||||
u16 command
|
||||
u8 hp
|
||||
|
||||
s8 hp
|
||||
s8 air
|
||||
s8 hunger
|
||||
*/
|
||||
|
||||
TOCLIENT_INVENTORY = 0x27,
|
||||
|
@ -287,8 +288,9 @@ enum ToServerCommand
|
|||
TOSERVER_PLAYERDAMAGE = 0x29,
|
||||
/*
|
||||
u16 command
|
||||
u8 damage_amount
|
||||
u8 suffocate_amount
|
||||
s8 damage_amount
|
||||
s8 suffocate_amount
|
||||
s8 hunger_amount
|
||||
*/
|
||||
|
||||
TOSERVER_SIGNTEXT = 0x30, // Old signs
|
||||
|
|
|
@ -153,6 +153,7 @@ void set_creative_defaults(Settings *settings)
|
|||
settings->setDefault("droppable_inventory", "false");
|
||||
settings->setDefault("enable_damage", "false");
|
||||
settings->setDefault("enable_suffocation", "false");
|
||||
settings->setDefault("enable_hunger", "false");
|
||||
settings->setDefault("max_mob_level", "passive");
|
||||
settings->setDefault("initial_inventory", "false");
|
||||
settings->setDefault("tool_wear","false");
|
||||
|
@ -164,6 +165,7 @@ void set_adventure_defaults(Settings *settings)
|
|||
settings->setDefault("droppable_inventory", "true");
|
||||
settings->setDefault("enable_damage", "true");
|
||||
settings->setDefault("enable_suffocation", "false");
|
||||
settings->setDefault("enable_hunger", "false");
|
||||
settings->setDefault("max_mob_level", "aggressive");
|
||||
settings->setDefault("initial_inventory", "true");
|
||||
settings->setDefault("tool_wear","true");
|
||||
|
@ -175,6 +177,7 @@ void set_survival_defaults(Settings *settings)
|
|||
settings->setDefault("droppable_inventory", "true");
|
||||
settings->setDefault("enable_damage", "true");
|
||||
settings->setDefault("enable_suffocation", "true");
|
||||
settings->setDefault("enable_hunger", "true");
|
||||
settings->setDefault("max_mob_level", "aggressive");
|
||||
settings->setDefault("initial_inventory", "false");
|
||||
settings->setDefault("tool_wear","true");
|
||||
|
|
|
@ -4045,6 +4045,25 @@ void ClientEnvironment::step(float dtime)
|
|||
event.type = CEE_PLAYER_SUFFOCATE;
|
||||
event.player_damage.amount = -20;
|
||||
m_client_event_queue.push_back(event);
|
||||
}else{
|
||||
f32 speed = lplayer->getSpeed().getLength();
|
||||
s8 hungry = 0;
|
||||
s32 chance = 100;
|
||||
if (speed > 1.0) {
|
||||
chance = 10;
|
||||
if (speed > 50.0) {
|
||||
chance = 0;
|
||||
hungry = 1;
|
||||
}
|
||||
}
|
||||
if (chance && myrand()%chance == 0)
|
||||
hungry = 1;
|
||||
if (hungry) {
|
||||
ClientEnvEvent event;
|
||||
event.type = CEE_PLAYER_HUNGER;
|
||||
event.player_damage.amount = hungry;
|
||||
m_client_event_queue.push_back(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -337,7 +337,8 @@ enum ClientEnvEventType
|
|||
{
|
||||
CEE_NONE,
|
||||
CEE_PLAYER_DAMAGE,
|
||||
CEE_PLAYER_SUFFOCATE
|
||||
CEE_PLAYER_SUFFOCATE,
|
||||
CEE_PLAYER_HUNGER
|
||||
};
|
||||
|
||||
struct ClientEnvEvent
|
||||
|
|
33
src/game.cpp
33
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, s32 halfbubblecount)
|
||||
Inventory *inventory, s32 halfheartcount, s32 halfbubblecount, s32 halfhungercount)
|
||||
{
|
||||
InventoryList *mainlist = inventory->getList("main");
|
||||
if(mainlist == NULL)
|
||||
|
@ -286,7 +286,7 @@ void draw_hotbar(video::IVideoDriver *driver, gui::IGUIFont *font,
|
|||
} barData[3] = {
|
||||
{halfheartcount/2,halfheartcount,"heart.png",true},
|
||||
{halfbubblecount/2,halfbubblecount,"bubble.png",false},
|
||||
{10,0,"heart.png",false},
|
||||
{halfhungercount/2,halfhungercount,"harvested_carrot.png",true},
|
||||
};
|
||||
v2s32 bar_base(0,-25);
|
||||
for (s32 k=0; k<3; k++) {
|
||||
|
@ -319,33 +319,6 @@ void draw_hotbar(video::IVideoDriver *driver, gui::IGUIFont *font,
|
|||
}
|
||||
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);
|
||||
|
@ -2414,7 +2387,7 @@ void the_game(
|
|||
if (show_hud) {
|
||||
draw_hotbar(driver, font, v2s32(displaycenter.X, screensize.Y),
|
||||
hotbar_imagesize, hotbar_itemcount, &local_inventory,
|
||||
client.getHP(), client.getAir());
|
||||
client.getHP(), client.getAir(), client.getHunger());
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -249,10 +249,22 @@ bool CraftItem::use(ServerEnvironment *env, Player *player)
|
|||
if (content_craftitem_features(m_content).edible) {
|
||||
u16 result_count = getCount() - 1; // Eat one at a time
|
||||
s16 hp_change = content_craftitem_features(m_content).edible;
|
||||
if(player->hp + hp_change > 20)
|
||||
player->hp = 20;
|
||||
else
|
||||
player->hp += hp_change;
|
||||
if (hp_change) {
|
||||
if (player->hunger < 20) {
|
||||
if (player->hunger + hp_change > 20) {
|
||||
hp_change -= 20-player->hunger;
|
||||
player->hunger = 20;
|
||||
}else{
|
||||
player->hunger += hp_change;
|
||||
hp_change = 0;
|
||||
}
|
||||
}
|
||||
if (player->hp + hp_change > 20) {
|
||||
player->hp = 20;
|
||||
}else{
|
||||
player->hp += hp_change;
|
||||
}
|
||||
}
|
||||
|
||||
if(result_count < 1)
|
||||
return true;
|
||||
|
|
|
@ -38,6 +38,8 @@ Player::Player():
|
|||
inventory_backup(NULL),
|
||||
craftresult_is_preview(true),
|
||||
hp(20),
|
||||
air(20),
|
||||
hunger(20),
|
||||
peer_id(PEER_ID_INEXISTENT),
|
||||
m_selected_item(0),
|
||||
m_pitch(0),
|
||||
|
@ -119,6 +121,8 @@ void Player::serialize(std::ostream &os)
|
|||
args.setV3F("position", m_position);
|
||||
args.setBool("craftresult_is_preview", craftresult_is_preview);
|
||||
args.setS32("hp", hp);
|
||||
args.setS32("air", air);
|
||||
args.setS32("hunger", hunger);
|
||||
if (m_hashome)
|
||||
args.setV3F("home",m_home);
|
||||
|
||||
|
@ -170,6 +174,16 @@ void Player::deSerialize(std::istream &is)
|
|||
}catch(SettingNotFoundException &e){
|
||||
hp = 20;
|
||||
}
|
||||
try{
|
||||
air = args.getS32("air");
|
||||
}catch(SettingNotFoundException &e){
|
||||
air = 20;
|
||||
}
|
||||
try{
|
||||
hunger = args.getS32("hunger");
|
||||
}catch(SettingNotFoundException &e){
|
||||
hunger = 20;
|
||||
}
|
||||
try{
|
||||
m_home = args.getV3F("home");
|
||||
m_hashome = true;
|
||||
|
@ -407,8 +421,7 @@ 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;
|
||||
hunger = 0;
|
||||
}
|
||||
|
||||
LocalPlayer::~LocalPlayer()
|
||||
|
|
|
@ -173,6 +173,7 @@ public:
|
|||
|
||||
u16 hp;
|
||||
u16 air;
|
||||
u16 hunger;
|
||||
|
||||
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, 0);
|
||||
HandlePlayerHP(player, 0, 0, 0);
|
||||
|
||||
/*
|
||||
Print out action
|
||||
|
@ -2381,17 +2381,17 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
actionstream<<player->getName()<<" right clicks object "
|
||||
<<obj->getId()<<std::endl;
|
||||
|
||||
// Track hp changes super-crappily
|
||||
// Track changes super-crappily
|
||||
u16 oldhp = player->hp;
|
||||
u16 oldair = player->air;
|
||||
u16 oldhunger = player->hunger;
|
||||
|
||||
// Do stuff
|
||||
obj->rightClick(player);
|
||||
|
||||
// Send back stuff
|
||||
if(player->hp != oldhp)
|
||||
{
|
||||
if (player->hp != oldhp || player->air != oldair || player->hunger != oldhunger)
|
||||
SendPlayerHP(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(command == TOSERVER_GROUND_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,0);
|
||||
HandlePlayerHP(player,4,0,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,0);
|
||||
HandlePlayerHP(player,4,0,0);
|
||||
UpdateCrafting(player->peer_id);
|
||||
SendInventory(player->peer_id);
|
||||
}
|
||||
|
@ -4281,6 +4281,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
std::istringstream is(datastring, std::ios_base::binary);
|
||||
s8 damage = readS8(is);
|
||||
s8 suffocate = readS8(is);
|
||||
s8 hunger = readS8(is);
|
||||
|
||||
if (damage && g_settings->getBool("enable_damage")) {
|
||||
actionstream<<player->getName()<<" damaged by "
|
||||
|
@ -4296,11 +4297,18 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
}else{
|
||||
suffocate = 0;
|
||||
}
|
||||
if (hunger && g_settings->getBool("enable_hunger")) {
|
||||
actionstream<<player->getName()<<" lost "
|
||||
<<(int)hunger<<" hunger at "<<PP(player->getPosition()/BS)
|
||||
<<std::endl;
|
||||
}else{
|
||||
hunger = 0;
|
||||
}
|
||||
|
||||
if (!damage && !suffocate) {
|
||||
if (!damage && !suffocate && !hunger) {
|
||||
SendPlayerHP(player);
|
||||
}else{
|
||||
HandlePlayerHP(player, damage, suffocate);
|
||||
HandlePlayerHP(player, damage, suffocate, hunger);
|
||||
}
|
||||
}
|
||||
else if(command == TOSERVER_SIGNTEXT)
|
||||
|
@ -4612,7 +4620,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
<<(int)damage<<" hp at "<<PP(player->getPosition()/BS)
|
||||
<<std::endl;
|
||||
|
||||
HandlePlayerHP(player, damage, 0);
|
||||
HandlePlayerHP(player, damage, 0, 0);
|
||||
}else{
|
||||
SendPlayerHP(player);
|
||||
}
|
||||
|
@ -4913,7 +4921,7 @@ void Server::deletingPeer(con::Peer *peer, bool timeout)
|
|||
Static send methods
|
||||
*/
|
||||
|
||||
void Server::SendHP(con::Connection &con, u16 peer_id, u8 hp, u8 air)
|
||||
void Server::SendHP(con::Connection &con, u16 peer_id, u8 hp, u8 air, u8 hunger)
|
||||
{
|
||||
DSTACK(__FUNCTION_NAME);
|
||||
std::ostringstream os(std::ios_base::binary);
|
||||
|
@ -4921,6 +4929,7 @@ void Server::SendHP(con::Connection &con, u16 peer_id, u8 hp, u8 air)
|
|||
writeU16(os, TOCLIENT_PLAYERHP);
|
||||
writeU8(os, hp);
|
||||
writeU8(os, air);
|
||||
writeU8(os, hunger);
|
||||
|
||||
// Make data buffer
|
||||
std::string s = os.str();
|
||||
|
@ -5171,7 +5180,7 @@ void Server::BroadcastChatMessage(const std::wstring &message)
|
|||
|
||||
void Server::SendPlayerHP(Player *player)
|
||||
{
|
||||
SendHP(m_con, player->peer_id, player->hp, player->air);
|
||||
SendHP(m_con, player->peer_id, player->hp, player->air,player->hunger);
|
||||
}
|
||||
|
||||
void Server::SendPlayerCookie(Player *player)
|
||||
|
@ -5451,7 +5460,7 @@ void Server::SendBlocks(float dtime)
|
|||
Something random
|
||||
*/
|
||||
|
||||
void Server::HandlePlayerHP(Player *player, s16 damage, s16 suffocate)
|
||||
void Server::HandlePlayerHP(Player *player, s16 damage, s16 suffocate, s16 hunger)
|
||||
{
|
||||
if (player->air > suffocate) {
|
||||
player->air -= suffocate;
|
||||
|
@ -5461,6 +5470,14 @@ void Server::HandlePlayerHP(Player *player, s16 damage, s16 suffocate)
|
|||
player->air = 0;
|
||||
damage += suffocate-player->air;
|
||||
}
|
||||
if (player->hunger > hunger) {
|
||||
player->hunger -= hunger;
|
||||
if (player->hunger > 20)
|
||||
player->hunger = 20;
|
||||
}else{
|
||||
player->hunger = 0;
|
||||
damage += hunger-player->hunger;
|
||||
}
|
||||
if (player->hp > damage) {
|
||||
player->hp -= damage;
|
||||
if (player->hp > 20)
|
||||
|
@ -5502,6 +5519,7 @@ void Server::RespawnPlayer(Player *player)
|
|||
player->setPosition(pos);
|
||||
player->hp = 20;
|
||||
player->air = 20;
|
||||
player->hunger = 20;
|
||||
SendMovePlayer(player);
|
||||
SendPlayerHP(player);
|
||||
}
|
||||
|
|
|
@ -513,7 +513,7 @@ private:
|
|||
Static send methods
|
||||
*/
|
||||
|
||||
static void SendHP(con::Connection &con, u16 peer_id, u8 hp, u8 air);
|
||||
static void SendHP(con::Connection &con, u16 peer_id, u8 hp, u8 air, u8 hunger);
|
||||
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, s16 suffocate);
|
||||
void HandlePlayerHP(Player *player, s16 damage, s16 suffocate, s16 hunger);
|
||||
void RespawnPlayer(Player *player);
|
||||
|
||||
void UpdateCrafting(u16 peer_id);
|
||||
|
|
Loading…
Reference in New Issue