summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/camera.cpp56
-rw-r--r--src/camera.h9
-rw-r--r--src/client.cpp10
-rw-r--r--src/content_cao.cpp35
-rw-r--r--src/content_nodemeta.cpp23
-rw-r--r--src/defaultsettings.cpp21
-rw-r--r--src/environment.cpp19
-rw-r--r--src/game.cpp393
-rw-r--r--src/inventorymanager.h1
-rw-r--r--src/light.cpp56
-rw-r--r--src/player.cpp16
-rw-r--r--src/player.h2
-rw-r--r--src/profiler.h19
-rw-r--r--src/scriptapi.cpp9
-rw-r--r--src/scriptapi.h2
-rw-r--r--src/server.cpp82
-rw-r--r--src/server.h4
-rw-r--r--src/serverobject.h2
-rw-r--r--src/serverremoteplayer.cpp16
-rw-r--r--src/serverremoteplayer.h1
-rw-r--r--src/utility.cpp2
-rw-r--r--src/utility.h44
22 files changed, 584 insertions, 238 deletions
diff --git a/src/camera.cpp b/src/camera.cpp
index 066208569..b36daf1d7 100644
--- a/src/camera.cpp
+++ b/src/camera.cpp
@@ -40,8 +40,6 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control):
m_wieldlight(0),
m_draw_control(draw_control),
- m_viewing_range_min(5.0),
- m_viewing_range_max(5.0),
m_camera_position(0,0,0),
m_camera_direction(0,0,0),
@@ -50,7 +48,6 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control):
m_fov_x(1.0),
m_fov_y(1.0),
- m_wanted_frametime(0.0),
m_added_frametime(0),
m_added_frames(0),
m_range_old(0),
@@ -79,8 +76,6 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control):
m_wieldmgr = smgr->createNewSceneManager();
m_wieldmgr->addCameraSceneNode();
m_wieldnode = m_wieldmgr->addMeshSceneNode(createCubeMesh(v3f(1,1,1)), NULL); // need a dummy mesh
-
- updateSettings();
}
Camera::~Camera()
@@ -259,14 +254,17 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize)
// *100.0 helps in large map coordinates
m_cameranode->setTarget(m_camera_position + 100 * m_camera_direction);
- // FOV and and aspect ratio
+ // Get FOV setting
+ f32 fov_degrees = g_settings->getFloat("fov");
+ fov_degrees = MYMAX(fov_degrees, 10.0);
+ fov_degrees = MYMIN(fov_degrees, 170.0);
+
+ // FOV and aspect ratio
m_aspect = (f32)screensize.X / (f32) screensize.Y;
+ m_fov_y = fov_degrees * PI / 180.0;
m_fov_x = 2 * atan(0.5 * m_aspect * tan(m_fov_y));
m_cameranode->setAspectRatio(m_aspect);
m_cameranode->setFOV(m_fov_y);
- // Just so big a value that everything rendered is visible
- // Some more allowance that m_viewing_range_max * BS because of active objects etc.
- m_cameranode->setFarValue(m_viewing_range_max * BS * 10);
// Position the wielded item
v3f wield_position = v3f(45, -35, 65);
@@ -343,7 +341,18 @@ void Camera::updateViewingRange(f32 frametime_in)
<<m_draw_control.blocks_would_have_drawn
<<std::endl;*/
- m_draw_control.wanted_min_range = m_viewing_range_min;
+ // Get current viewing range and FPS settings
+ f32 viewing_range_min = g_settings->getS16("viewing_range_nodes_min");
+ viewing_range_min = MYMAX(5.0, viewing_range_min);
+
+ f32 viewing_range_max = g_settings->getS16("viewing_range_nodes_max");
+ viewing_range_max = MYMAX(viewing_range_min, viewing_range_max);
+
+ f32 wanted_fps = g_settings->getFloat("wanted_fps");
+ wanted_fps = MYMAX(wanted_fps, 1.0);
+ f32 wanted_frametime = 1.0 / wanted_fps;
+
+ m_draw_control.wanted_min_range = viewing_range_min;
m_draw_control.wanted_max_blocks = (2.0*m_draw_control.blocks_would_have_drawn)+1;
if (m_draw_control.wanted_max_blocks < 10)
m_draw_control.wanted_max_blocks = 10;
@@ -362,13 +371,13 @@ void Camera::updateViewingRange(f32 frametime_in)
m_added_frametime = 0.0;
m_added_frames = 0;
- f32 wanted_frametime_change = m_wanted_frametime - frametime;
+ f32 wanted_frametime_change = wanted_frametime - frametime;
//dstream<<"wanted_frametime_change="<<wanted_frametime_change<<std::endl;
// If needed frametime change is small, just return
// This value was 0.4 for many months until 2011-10-18 by c55;
// Let's see how this works out.
- if (fabs(wanted_frametime_change) < m_wanted_frametime*0.33)
+ if (fabs(wanted_frametime_change) < wanted_frametime*0.33)
{
//dstream<<"ignoring small wanted_frametime_change"<<std::endl;
return;
@@ -421,8 +430,8 @@ void Camera::updateViewingRange(f32 frametime_in)
new_range += wanted_range_change;
//f32 new_range_unclamped = new_range;
- new_range = MYMAX(new_range, m_viewing_range_min);
- new_range = MYMIN(new_range, m_viewing_range_max);
+ new_range = MYMAX(new_range, viewing_range_min);
+ new_range = MYMIN(new_range, viewing_range_max);
/*dstream<<"new_range="<<new_range_unclamped
<<", clamped to "<<new_range<<std::endl;*/
@@ -430,24 +439,11 @@ void Camera::updateViewingRange(f32 frametime_in)
m_range_old = new_range;
m_frametime_old = frametime;
-}
-
-void Camera::updateSettings()
-{
- m_viewing_range_min = g_settings->getS16("viewing_range_nodes_min");
- m_viewing_range_min = MYMAX(5.0, m_viewing_range_min);
- m_viewing_range_max = g_settings->getS16("viewing_range_nodes_max");
- m_viewing_range_max = MYMAX(m_viewing_range_min, m_viewing_range_max);
-
- f32 fov_degrees = g_settings->getFloat("fov");
- fov_degrees = MYMAX(fov_degrees, 10.0);
- fov_degrees = MYMIN(fov_degrees, 170.0);
- m_fov_y = fov_degrees * PI / 180.0;
+ // Just so big a value that everything rendered is visible
+ // Some more allowance than viewing_range_max * BS because of active objects etc.
+ m_cameranode->setFarValue(viewing_range_max * BS * 10);
- f32 wanted_fps = g_settings->getFloat("wanted_fps");
- wanted_fps = MYMAX(wanted_fps, 1.0);
- m_wanted_frametime = 1.0 / wanted_fps;
}
void Camera::setDigging(s32 button)
diff --git a/src/camera.h b/src/camera.h
index 56c99d101..7be8162b5 100644
--- a/src/camera.h
+++ b/src/camera.h
@@ -110,9 +110,6 @@ public:
// Render distance feedback loop
void updateViewingRange(f32 frametime_in);
- // Update settings from g_settings
- void updateSettings();
-
// Start digging animation
// Pass 0 for left click, 1 for right click
void setDigging(s32 button);
@@ -139,11 +136,6 @@ private:
// draw control
MapDrawControl& m_draw_control;
- // viewing_range_min_nodes setting
- f32 m_viewing_range_min;
- // viewing_range_max_nodes setting
- f32 m_viewing_range_max;
-
// Absolute camera position
v3f m_camera_position;
// Absolute camera direction
@@ -155,7 +147,6 @@ private:
f32 m_fov_y;
// Stuff for viewing range calculations
- f32 m_wanted_frametime;
f32 m_added_frametime;
s16 m_added_frames;
f32 m_range_old;
diff --git a/src/client.cpp b/src/client.cpp
index 0463aa81c..bc303bc4b 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -1171,8 +1171,18 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
std::istringstream is(datastring, std::ios_base::binary);
Player *player = m_env.getLocalPlayer();
assert(player != NULL);
+ u8 oldhp = player->hp;
u8 hp = readU8(is);
player->hp = hp;
+
+ if(hp < oldhp)
+ {
+ // Add to ClientEvent queue
+ ClientEvent event;
+ event.type = CE_PLAYER_DAMAGE;
+ event.player_damage.amount = oldhp - hp;
+ m_client_event_queue.push_back(event);
+ }
}
else if(command == TOCLIENT_MOVE_PLAYER)
{
diff --git a/src/content_cao.cpp b/src/content_cao.cpp
index a2708674b..3c30a0819 100644
--- a/src/content_cao.cpp
+++ b/src/content_cao.cpp
@@ -2067,6 +2067,7 @@ private:
bool m_is_local_player;
LocalPlayer *m_local_player;
float m_damage_visual_timer;
+ bool m_dead;
public:
PlayerCAO(IGameDef *gamedef, ClientEnvironment *env):
@@ -2078,7 +2079,8 @@ public:
m_yaw(0),
m_is_local_player(false),
m_local_player(NULL),
- m_damage_visual_timer(0)
+ m_damage_visual_timer(0),
+ m_dead(false)
{
if(gamedef == NULL)
ClientActiveObject::registerType(getType(), create);
@@ -2100,6 +2102,8 @@ public:
m_position = readV3F1000(is);
// yaw
m_yaw = readF1000(is);
+ // dead
+ m_dead = readU8(is);
pos_translator.init(m_position);
@@ -2129,6 +2133,8 @@ public:
{
if(m_is_local_player)
return NULL;
+ if(m_dead)
+ return NULL;
return &m_selection_box;
}
v3f getPosition()
@@ -2204,6 +2210,7 @@ public:
m_text->setPosition(v3f(0, (f32)BS*2.1, 0));
updateTextures("");
+ updateVisibility();
updateNodePos();
}
@@ -2221,11 +2228,11 @@ public:
if(m_node == NULL)
return;
- m_node->setVisible(true);
-
u8 li = decode_light(light_at_pos);
video::SColor color(255,li,li,li);
setMeshColor(m_node->getMesh(), color);
+
+ updateVisibility();
}
v3s16 getLightPosition()
@@ -2233,6 +2240,14 @@ public:
return floatToInt(m_position+v3f(0,BS*1.5,0), BS);
}
+ void updateVisibility()
+ {
+ if(m_node == NULL)
+ return;
+
+ m_node->setVisible(!m_dead);
+ }
+
void updateNodePos()
{
if(m_node == NULL)
@@ -2248,6 +2263,7 @@ public:
void step(float dtime, ClientEnvironment *env)
{
pos_translator.translate(dtime);
+ updateVisibility();
updateNodePos();
if(m_damage_visual_timer > 0){
@@ -2279,13 +2295,16 @@ public:
{
// damage
s16 damage = readS16(is);
-
- if(m_is_local_player)
- m_env->damageLocalPlayer(damage, false);
-
- m_damage_visual_timer = 0.5;
+ m_damage_visual_timer = 0.05;
+ if(damage >= 2)
+ m_damage_visual_timer += 0.05 * damage;
updateTextures("^[brighten");
}
+ else if(cmd == 2) // died or respawned
+ {
+ m_dead = readU8(is);
+ updateVisibility();
+ }
}
void updateTextures(const std::string &mod)
diff --git a/src/content_nodemeta.cpp b/src/content_nodemeta.cpp
index 9fb5450cf..b36d57c89 100644
--- a/src/content_nodemeta.cpp
+++ b/src/content_nodemeta.cpp
@@ -441,6 +441,10 @@ bool FurnaceNodeMetadata::step(float dtime)
{
if(dtime > 60.0)
infostream<<"Furnace stepping a long time ("<<dtime<<")"<<std::endl;
+
+ InventoryList *dst_list = m_inventory->getList("dst");
+ assert(dst_list);
+
// Update at a fixed frequency
const float interval = 2.0;
m_step_accumulator += dtime;
@@ -452,8 +456,7 @@ bool FurnaceNodeMetadata::step(float dtime)
//infostream<<"Furnace step dtime="<<dtime<<std::endl;
- InventoryList *dst_list = m_inventory->getList("dst");
- assert(dst_list);
+ bool changed_this_loop = false;
// Check
// 1. if the source item is cookable
@@ -473,7 +476,7 @@ bool FurnaceNodeMetadata::step(float dtime)
bool burning = (m_fuel_time < m_fuel_totaltime);
if(burning)
{
- changed = true;
+ changed_this_loop = true;
m_fuel_time += dtime;
}
@@ -483,7 +486,7 @@ bool FurnaceNodeMetadata::step(float dtime)
float burntime;
if(burning)
{
- changed = true;
+ changed_this_loop = true;
m_src_time += dtime;
m_src_totaltime = cooktime;
infotext = "Furnace is cooking";
@@ -491,7 +494,7 @@ bool FurnaceNodeMetadata::step(float dtime)
else if(getBurnResult(true, burntime))
{
// Fuel inserted
- changed = true;
+ changed_this_loop = true;
m_fuel_time = 0;
m_fuel_totaltime = burntime;
//m_src_time += dtime;
@@ -507,7 +510,7 @@ bool FurnaceNodeMetadata::step(float dtime)
if(m_src_totaltime > 0.001 && m_src_time >= m_src_totaltime)
{
// One item fully cooked
- changed = true;
+ changed_this_loop = true;
dst_list->addItem(cookresult_item);
getCookResult(true, cookresult, cooktime); // decrement source
m_src_totaltime = 0;
@@ -541,7 +544,7 @@ bool FurnaceNodeMetadata::step(float dtime)
if(infotext != m_infotext)
{
m_infotext = infotext;
- changed = true;
+ changed_this_loop = true;
}
if(burning && m_fuel_time >= m_fuel_totaltime)
@@ -550,7 +553,11 @@ bool FurnaceNodeMetadata::step(float dtime)
m_fuel_totaltime = 0;
}
- if(!changed)
+ if(changed_this_loop)
+ {
+ changed = true;
+ }
+ else
{
m_step_accumulator = 0;
break;
diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp
index 4de854dd8..3f6901e8f 100644
--- a/src/defaultsettings.cpp
+++ b/src/defaultsettings.cpp
@@ -43,18 +43,30 @@ void set_default_settings(Settings *settings)
settings->setDefault("keymap_rangeselect", "KEY_KEY_R");
settings->setDefault("keymap_freemove", "KEY_KEY_K");
settings->setDefault("keymap_fastmove", "KEY_KEY_J");
- settings->setDefault("keymap_frametime_graph", "KEY_F1");
settings->setDefault("keymap_screenshot", "KEY_F12");
- settings->setDefault("keymap_toggle_profiler", "KEY_F2");
+ settings->setDefault("keymap_toggle_hud", "KEY_F1");
+ settings->setDefault("keymap_toggle_chat", "KEY_F2");
settings->setDefault("keymap_toggle_force_fog_off", "KEY_F3");
settings->setDefault("keymap_toggle_update_camera", "KEY_F4");
+ settings->setDefault("keymap_toggle_debug", "KEY_F5");
+ settings->setDefault("keymap_toggle_profiler", "KEY_F6");
+ settings->setDefault("keymap_increase_viewing_range_min", "KEY_PRIOR");
+ settings->setDefault("keymap_decrease_viewing_range_min", "KEY_NEXT");
// Some (temporary) keys for debugging
settings->setDefault("keymap_print_debug_stacks", "KEY_KEY_P");
+ // Show debug info by default?
+ #ifdef NDEBUG
+ settings->setDefault("show_debug", "false");
+ #else
+ settings->setDefault("show_debug", "true");
+ #endif
+
settings->setDefault("wanted_fps", "30");
settings->setDefault("fps_max", "60");
- settings->setDefault("viewing_range_nodes_max", "300");
- settings->setDefault("viewing_range_nodes_min", "15");
+ // A bit more than the server will send around the player, to make fog blend well
+ settings->setDefault("viewing_range_nodes_min", "35");
+ settings->setDefault("viewing_range_nodes_max", "128");
settings->setDefault("screenW", "800");
settings->setDefault("screenH", "600");
settings->setDefault("address", "");
@@ -66,7 +78,6 @@ void set_default_settings(Settings *settings)
settings->setDefault("new_style_water", "false");
settings->setDefault("new_style_leaves", "false");
settings->setDefault("smooth_lighting", "true");
- settings->setDefault("frametime_graph", "false");
settings->setDefault("enable_texture_atlas", "true");
settings->setDefault("texture_path", "");
settings->setDefault("video_driver", "opengl");
diff --git a/src/environment.cpp b/src/environment.cpp
index 7c2aef272..6f1d8ff55 100644
--- a/src/environment.cpp
+++ b/src/environment.cpp
@@ -797,6 +797,8 @@ void ServerEnvironment::clearAllObjects()
i.atEnd()==false; i++)
{
ServerActiveObject* obj = i.getNode()->getValue();
+ if(obj->getType() == ACTIVEOBJECT_TYPE_PLAYER)
+ continue;
u16 id = i.getNode()->getKey();
v3f objectpos = obj->getBasePosition();
// Delete static object if block is loaded
@@ -1983,16 +1985,7 @@ void ClientEnvironment::step(float dtime)
{
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;
-
- ClientEnvEvent event;
- event.type = CEE_PLAYER_DAMAGE;
- event.player_damage.amount = damage;
- event.player_damage.send_to_server = true;
- m_client_event_queue.push_back(event);
+ damageLocalPlayer(damage, true);
}
}
}
@@ -2022,11 +2015,7 @@ void ClientEnvironment::step(float dtime)
if(damage_per_second != 0)
{
- ClientEnvEvent event;
- event.type = CEE_PLAYER_DAMAGE;
- event.player_damage.amount = damage_per_second;
- event.player_damage.send_to_server = true;
- m_client_event_queue.push_back(event);
+ damageLocalPlayer(damage_per_second, true);
}
}
diff --git a/src/game.cpp b/src/game.cpp
index 47a0e6afe..670148a44 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -574,7 +574,7 @@ void update_skybox(video::IVideoDriver* driver, ITextureSource *tsrc,
if(g_settings->getBool("enable_farmesh"))
return;*/
- if(brightness >= 0.5)
+ if(brightness >= 0.7)
{
skybox = smgr->addSkyBoxSceneNode(
tsrc->getTextureRaw("skybox2.png"),
@@ -634,6 +634,36 @@ void draw_load_screen(const std::wstring &text,
//return guitext;
}
+/* Profiler display */
+
+void update_profiler_gui(gui::IGUIStaticText *guitext_profiler,
+ gui::IGUIFont *font, u32 text_height,
+ u32 show_profiler, u32 show_profiler_max)
+{
+ if(show_profiler == 0)
+ {
+ guitext_profiler->setVisible(false);
+ }
+ else
+ {
+
+ std::ostringstream os(std::ios_base::binary);
+ g_profiler->printPage(os, show_profiler, show_profiler_max);
+ std::wstring text = narrow_to_wide(os.str());
+ guitext_profiler->setText(text.c_str());
+ guitext_profiler->setVisible(true);
+
+ s32 w = font->getDimension(text.c_str()).Width;
+ if(w < 400)
+ w = 400;
+ core::rect<s32> rect(6, 4+(text_height+5)*2, 12+w,
+ 8+(text_height+5)*2 +
+ font->getDimension(text.c_str()).Height);
+ guitext_profiler->setRelativePosition(rect);
+ guitext_profiler->setVisible(true);
+ }
+}
+
void the_game(
bool &kill,
bool random_input,
@@ -932,6 +962,16 @@ void the_game(
core::rect<s32>(0,0,400,text_height+5) + v2s32(100,200),
false, false);
+ // Status text (displays info when showing and hiding GUI stuff, etc.)
+ gui::IGUIStaticText *guitext_status = guienv->addStaticText(
+ L"<Status>",
+ core::rect<s32>(0,0,0,0),
+ false, false);
+ guitext_status->setVisible(false);
+
+ std::wstring statustext;
+ float statustext_time = 0;
+
// Chat text
gui::IGUIStaticText *guitext_chat = guienv->addStaticText(
L"",
@@ -944,8 +984,7 @@ void the_game(
// Profiler text (size is updated when text is updated)
gui::IGUIStaticText *guitext_profiler = guienv->addStaticText(
L"<Profiler>",
- core::rect<s32>(6, 4+(text_height+5)*2, 400,
- (text_height+5)*2 + text_height*35),
+ core::rect<s32>(0,0,0,0),
false, false);
guitext_profiler->setBackgroundColor(video::SColor(80,0,0,0));
guitext_profiler->setVisible(false);
@@ -968,11 +1007,6 @@ void the_game(
(new GUIPauseMenu(guienv, guiroot, -1, g_gamecallback,
&g_menumgr))->drop();
- // Enable texts
- /*guitext2->setVisible(true);
- guitext_info->setVisible(true);
- guitext_chat->setVisible(true);*/
-
//s32 guitext_chat_pad_bottom = 70;
/*
@@ -1008,9 +1042,14 @@ void the_game(
bool respawn_menu_active = false;
bool update_wielded_item_trigger = false;
- bool show_profiler = false;
+ bool show_hud = true;
+ bool show_chat = true;
bool force_fog_off = false;
bool disable_camera_update = false;
+ bool show_debug = g_settings->getBool("show_debug");
+ bool show_debug_frametime = false;
+ u32 show_profiler = 0;
+ u32 show_profiler_max = 3; // Number of pages
/*
Main loop
@@ -1247,20 +1286,10 @@ void the_game(
g_profiler->print(infostream);
}
- std::ostringstream os(std::ios_base::binary);
- g_profiler->print(os);
- std::wstring text = narrow_to_wide(os.str());
- guitext_profiler->setText(text.c_str());
+ update_profiler_gui(guitext_profiler, font, text_height,
+ show_profiler, show_profiler_max);
g_profiler->clear();
-
- s32 w = font->getDimension(text.c_str()).Width;
- if(w < 400)
- w = 400;
- core::rect<s32> rect(6, 4+(text_height+5)*2, 12+w,
- 8+(text_height+5)*2 +
- font->getDimension(text.c_str()).Height);
- guitext_profiler->setRelativePosition(rect);
}
/*
@@ -1349,12 +1378,14 @@ void the_game(
if(g_settings->getBool("free_move"))
{
g_settings->set("free_move","false");
- chat_lines.push_back(ChatLine(L"free_move disabled"));
+ statustext = L"free_move disabled";
+ statustext_time = 0;
}
else
{
g_settings->set("free_move","true");
- chat_lines.push_back(ChatLine(L"free_move enabled"));
+ statustext = L"free_move enabled";
+ statustext_time = 0;
}
}
else if(input->wasKeyDown(getKeySetting("keymap_fastmove")))
@@ -1362,25 +1393,14 @@ void the_game(
if(g_settings->getBool("fast_move"))
{
g_settings->set("fast_move","false");
- chat_lines.push_back(ChatLine(L"fast_move disabled"));
+ statustext = L"fast_move disabled";
+ statustext_time = 0;
}
else
{
g_settings->set("fast_move","true");
- chat_lines.push_back(ChatLine(L"fast_move enabled"));
- }
- }
- else if(input->wasKeyDown(getKeySetting("keymap_frametime_graph")))
- {
- if(g_settings->getBool("frametime_graph"))
- {
- g_settings->set("frametime_graph","false");
- chat_lines.push_back(ChatLine(L"frametime_graph disabled"));
- }
- else
- {
- g_settings->set("frametime_graph","true");
- chat_lines.push_back(ChatLine(L"frametime_graph enabled"));
+ statustext = L"fast_move enabled";
+ statustext_time = 0;
}
}
else if(input->wasKeyDown(getKeySetting("keymap_screenshot")))
@@ -1395,37 +1415,120 @@ void the_game(
std::wstringstream sstr;
sstr<<"Saved screenshot to '"<<filename<<"'";
infostream<<"Saved screenshot to '"<<filename<<"'"<<std::endl;
- chat_lines.push_back(ChatLine(sstr.str()));
+ statustext = sstr.str();
+ statustext_time = 0;
} else{
infostream<<"Failed to save screenshot '"<<filename<<"'"<<std::endl;
}
image->drop();
}
}
- else if(input->wasKeyDown(getKeySetting("keymap_toggle_profiler")))
+ else if(input->wasKeyDown(getKeySetting("keymap_toggle_hud")))
+ {
+ show_hud = !show_hud;
+ if(show_hud)
+ statustext = L"HUD shown";
+ else
+ statustext = L"HUD hidden";
+ statustext_time = 0;
+ }
+ else if(input->wasKeyDown(getKeySetting("keymap_toggle_chat")))
{
- show_profiler = !show_profiler;
- guitext_profiler->setVisible(show_profiler);
- if(show_profiler)
- chat_lines.push_back(ChatLine(L"Profiler disabled"));
+ show_chat = !show_chat;
+ if(show_chat)
+ statustext = L"Chat shown";
else
- chat_lines.push_back(ChatLine(L"Profiler enabled"));
+ statustext = L"Chat hidden";
+ statustext_time = 0;
}
else if(input->wasKeyDown(getKeySetting("keymap_toggle_force_fog_off")))
{
force_fog_off = !force_fog_off;
if(force_fog_off)
- chat_lines.push_back(ChatLine(L"Fog disabled"));
+ statustext = L"Fog disabled";
else
- chat_lines.push_back(ChatLine(L"Fog enabled"));
+ statustext = L"Fog enabled";
+ statustext_time = 0;
}
else if(input->wasKeyDown(getKeySetting("keymap_toggle_update_camera")))
{
disable_camera_update = !disable_camera_update;
if(disable_camera_update)
- chat_lines.push_back(ChatLine(L"Camera update disabled"));
+ statustext = L"Camera update disabled";
+ else
+ statustext = L"Camera update enabled";
+ statustext_time = 0;
+ }
+ else if(input->wasKeyDown(getKeySetting("keymap_toggle_debug")))
+ {
+ // Initial / 3x toggle: Chat only
+ // 1x toggle: Debug text with chat
+ // 2x toggle: Debug text with frametime
+ if(!show_debug)
+ {
+ show_debug = true;
+ show_debug_frametime = false;
+ statustext = L"Debug info shown";
+ statustext_time = 0;
+ }
+ else if(show_debug_frametime)
+ {
+ show_debug = false;
+ show_debug_frametime = false;
+ statustext = L"Debug info and frametime graph hidden";
+ statustext_time = 0;
+ }
+ else
+ {
+ show_debug_frametime = true;
+ statustext = L"Frametime graph shown";
+ statustext_time = 0;
+ }
+ }
+ else if(input->wasKeyDown(getKeySetting("keymap_toggle_profiler")))
+ {
+ show_profiler = (show_profiler + 1) % (show_profiler_max + 1);
+
+ // FIXME: This updates the profiler with incomplete values
+ update_profiler_gui(guitext_profiler, font, text_height,
+ show_profiler, show_profiler_max);
+
+ if(show_profiler != 0)
+ {
+ std::wstringstream sstr;
+ sstr<<"Profiler shown (page "<<show_profiler
+ <<" of "<<show_profiler_max<<")";
+ statustext = sstr.str();
+ statustext_time = 0;
+ }
else
- chat_lines.push_back(ChatLine(L"Camera update enabled"));
+ {
+ statustext = L"Profiler hidden";
+ statustext_time = 0;
+ }
+ }
+ else if(input->wasKeyDown(getKeySetting("keymap_increase_viewing_range_min")))
+ {
+ s16 range = g_settings->getS16("viewing_range_nodes_min");
+ s16 range_new = range + 10;
+ g_settings->set("viewing_range_nodes_min", itos(range_new));
+ statustext = narrow_to_wide(
+ "Minimum viewing range changed to "
+ + itos(range_new));
+ statustext_time = 0;
+ }
+ else if(input->wasKeyDown(getKeySetting("keymap_decrease_viewing_range_min")))
+ {
+ s16 range = g_settings->getS16("viewing_range_nodes_min");
+ s16 range_new = range - 10;
+ if(range_new < 0)
+ range_new = range;
+ g_settings->set("viewing_range_nodes_min",
+ itos(range_new));
+ statustext = narrow_to_wide(
+ "Minimum viewing range changed to "
+ + itos(range_new));
+ statustext_time = 0;
}
// Item selection with mouse wheel
@@ -1470,15 +1573,18 @@ void the_game(
// Viewing range selection
if(input->wasKeyDown(getKeySetting("keymap_rangeselect")))
{
+ draw_control.range_all = !draw_control.range_all;
if(draw_control.range_all)
{
- draw_control.range_all = false;
- infostream<<"Disabled full viewing range"<<std::endl;
+ infostream<<"Enabled full viewing range"<<std::endl;
+ statustext = L"Enabled full viewing range";
+ statustext_time = 0;
}
else
{
- draw_control.range_all = true;
- infostream<<"Enabled full viewing range"<<std::endl;
+ infostream<<"Disabled full viewing range"<<std::endl;
+ statustext = L"Disabled full viewing range";
+ statustext_time = 0;
}
}
@@ -2011,14 +2117,21 @@ void the_game(
u32 daynight_ratio = client.getDayNightRatio();
u8 light8 = decode_light((daynight_ratio * LIGHT_SUN) / 1000);
brightness = (float)light8/255.0;
- video::SColor bgcolor = video::SColor(
- 255,
- bgcolor_bright.getRed() * brightness,
- bgcolor_bright.getGreen() * brightness,
- bgcolor_bright.getBlue() * brightness);
- /*skycolor.getRed() * brightness,
- skycolor.getGreen() * brightness,
- skycolor.getBlue() * brightness);*/
+ // Make night look good
+ brightness = brightness * 1.15 - 0.15;
+ video::SColor bgcolor;
+ if(brightness >= 0.2 && brightness < 0.7)
+ bgcolor = video::SColor(
+ 255,
+ bgcolor_bright.getRed() * brightness,
+ bgcolor_bright.getGreen() * brightness*0.7,
+ bgcolor_bright.getBlue() * brightness*0.5);
+ else
+ bgcolor = video::SColor(
+ 255,
+ bgcolor_bright.getRed() * brightness,
+ bgcolor_bright.getGreen() * brightness,
+ bgcolor_bright.getBlue() * brightness);
/*
Update skybox
@@ -2033,7 +2146,7 @@ void the_game(
{
clouds->step(dtime);
clouds->update(v2f(player_position.X, player_position.Z),
- 0.05+brightness*0.95);
+ brightness);
}
/*
@@ -2049,7 +2162,7 @@ void the_game(
farmesh->step(dtime);
farmesh->update(v2f(player_position.X, player_position.Z),
- 0.05+brightness*0.95, farmesh_range);
+ brightness, farmesh_range);
}
// Store brightness value
@@ -2068,7 +2181,7 @@ void the_game(
}
else
{
- range = draw_control.wanted_range*BS + MAP_BLOCKSIZE*BS*1.5;
+ range = draw_control.wanted_range*BS + 0.0*MAP_BLOCKSIZE*BS;
range *= 0.9;
if(draw_control.range_all)
range = 100000*BS;
@@ -2105,55 +2218,110 @@ void the_game(
//TimeTaker guiupdatetimer("Gui updating");
+ const char program_name_and_version[] =
+ "Minetest-c55 " VERSION_STRING;
+
+ if(show_debug)
{
static float drawtime_avg = 0;
drawtime_avg = drawtime_avg * 0.95 + (float)drawtime*0.05;
- static float beginscenetime_avg = 0;
+ /*static float beginscenetime_avg = 0;
beginscenetime_avg = beginscenetime_avg * 0.95 + (float)beginscenetime*0.05;
static float scenetime_avg = 0;
scenetime_avg = scenetime_avg * 0.95 + (float)scenetime*0.05;
static float endscenetime_avg = 0;
- endscenetime_avg = endscenetime_avg * 0.95 + (float)endscenetime*0.05;
+ endscenetime_avg = endscenetime_avg * 0.95 + (float)endscenetime*0.05;*/
char temptext[300];
- snprintf(temptext, 300, "Minetest-c55 %s ("
+ snprintf(temptext, 300, "%s ("
"R: range_all=%i"
")"
- " drawtime=%.0f, beginscenetime=%.0f"
- ", scenetime=%.0f, endscenetime=%.0f",
- VERSION_STRING,
+ " drawtime=%.0f, dtime_jitter = % .1f %%"
+ ", v_range = %.1f, RTT = %.3f",
+ program_name_and_version,
draw_control.range_all,
drawtime_avg,
- beginscenetime_avg,
- scenetime_avg,
- endscenetime_avg
+ dtime_jitter1_max_fraction * 100.0,
+ draw_control.wanted_range,
+ client.getRTT()
);
guitext->setText(narrow_to_wide(temptext).c_str());
+ guitext->setVisible(true);
+ }
+ else if(show_hud || show_chat)
+ {
+ guitext->setText(narrow_to_wide(program_name_and_version).c_str());
+ guitext->setVisible(true);
+ }
+ else
+ {
+ guitext->setVisible(false);
}
+ if(show_debug)
{
char temptext[300];
snprintf(temptext, 300,
"(% .1f, % .1f, % .1f)"
- " (% .3f < btime_jitter < % .3f"
- ", dtime_jitter = % .1f %%"
- ", v_range = %.1f, RTT = %.3f)",
+ " (yaw = %.1f)",
player_position.X/BS,
player_position.Y/BS,
player_position.Z/BS,
- busytime_jitter1_min_sample,
- busytime_jitter1_max_sample,
- dtime_jitter1_max_fraction * 100.0,
- draw_control.wanted_range,
- client.getRTT()
- );
+ wrapDegrees_0_360(camera_yaw));
guitext2->setText(narrow_to_wide(temptext).c_str());
+ guitext2->setVisible(true);
+ }
+ else
+ {
+ guitext2->setVisible(false);
}
{
guitext_info->setText(infotext.c_str());
+ guitext_info->setVisible(show_hud);
+ }
+
+ {
+ float statustext_time_max = 3.0;
+ if(!statustext.empty())
+ {
+ statustext_time += dtime;
+ if(statustext_time >= statustext_time_max)
+ {
+ statustext = L"";
+ statustext_time = 0;
+ }
+ }
+ guitext_status->setText(statustext.c_str());
+ guitext_status->setVisible(!statustext.empty());
+
+ if(!statustext.empty())
+ {
+ s32 status_y = screensize.Y - 130;
+ core::rect<s32> rect(
+ 10,
+ status_y - guitext_status->getTextHeight(),
+ screensize.X - 10,
+ status_y
+ );
+ guitext_status->setRelativePosition(rect);
+
+ // Fade out
+ video::SColor initial_color(255,0,0,0);
+ if(guienv->getSkin())
+ initial_color = guienv->getSkin()->getColor(gui::EGDC_BUTTON_TEXT);
+ video::SColor final_color = initial_color;
+ final_color.setAlpha(0);
+ video::SColor fade_color =
+ initial_color.getInterpolated_quadratic(
+ initial_color,
+ final_color,
+ statustext_time / (float) statustext_time_max);
+ guitext_status->setOverrideColor(fade_color);
+ guitext_status->enableOverrideColor(true);
+ }
}
/*
@@ -2224,20 +2392,22 @@ void the_game(
screensize.X - 10,
screensize.Y - guitext_chat_pad_bottom
);*/
+
+ s32 chat_y = 5+(text_height+5);
+ if(show_debug)
+ chat_y += (text_height+5);
core::rect<s32> rect(
10,
- 50,
+ chat_y,
screensize.X - 10,
- 50 + guitext_chat->getTextHeight()
+ chat_y + guitext_chat->getTextHeight()
);
guitext_chat->setRelativePosition(rect);
- // Don't show chat if empty or profiler is enabled
- if(chat_lines.size() == 0 || show_profiler)
- guitext_chat->setVisible(false);
- else
- guitext_chat->setVisible(true);
+ // Don't show chat if empty or profiler or debug is enabled
+ guitext_chat->setVisible(chat_lines.size() != 0
+ && show_chat && show_profiler == 0);
}
/*
@@ -2275,7 +2445,7 @@ void the_game(
{
TimeTaker timer("beginScene");
- driver->beginScene(true, true, bgcolor);
+ driver->beginScene(false, true, bgcolor);
//driver->beginScene(false, true, bgcolor);
beginscenetime = timer.stop(true);
}
@@ -2305,20 +2475,24 @@ void the_game(
driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
- for(core::list< core::aabbox3d<f32> >::Iterator i=hilightboxes.begin();
- i != hilightboxes.end(); i++)
+ if(show_hud)
{
- /*infostream<<"hilightbox min="
- <<"("<<i->MinEdge.X<<","<<i->MinEdge.Y<<","<<i->MinEdge.Z<<")"
- <<" max="
- <<"("<<i->MaxEdge.X<<","<<i->MaxEdge.Y<<","<<i->MaxEdge.Z<<")"
- <<std::endl;*/
- driver->draw3DBox(*i, video::SColor(255,0,0,0));
+ for(core::list<aabb3f>::Iterator i=hilightboxes.begin();
+ i != hilightboxes.end(); i++)
+ {
+ /*infostream<<"hilightbox min="
+ <<"("<<i->MinEdge.X<<","<<i->MinEdge.Y<<","<<i->MinEdge.Z<<")"
+ <<" max="
+ <<"("<<i->MaxEdge.X<<","<<i->MaxEdge.Y<<","<<i->MaxEdge.Z<<")"
+ <<std::endl;*/
+ driver->draw3DBox(*i, video::SColor(255,0,0,0));
+ }
}
/*
Wielded tool
*/
+ if(show_hud)
{
// Warning: This clears the Z buffer.
camera.drawWieldedTool();
@@ -2334,16 +2508,17 @@ void the_game(
/*
Frametime log
*/
- if(g_settings->getBool("frametime_graph") == true)
+ if(show_debug_frametime)
{
s32 x = 10;
+ s32 y = screensize.Y - 10;
for(core::list<float>::Iterator
i = frametime_log.begin();
i != frametime_log.end();
i++)
{
- driver->draw2DLine(v2s32(x,50),
- v2s32(x,50+(*i)*1000),
+ driver->draw2DLine(v2s32(x,y),
+ v2s32(x,y-(*i)*1000),
video::SColor(255,255,255,255));
x++;
}
@@ -2352,12 +2527,15 @@ void the_game(
/*
Draw crosshair
*/
- driver->draw2DLine(displaycenter - core::vector2d<s32>(10,0),
- displaycenter + core::vector2d<s32>(10,0),
- video::SColor(255,255,255,255));
- driver->draw2DLine(displaycenter - core::vector2d<s32>(0,10),
- displaycenter + core::vector2d<s32>(0,10),
- video::SColor(255,255,255,255));
+ if(show_hud)
+ {
+ driver->draw2DLine(displaycenter - core::vector2d<s32>(10,0),
+ displaycenter + core::vector2d<s32>(10,0),
+ video::SColor(255,255,255,255));
+ driver->draw2DLine(displaycenter - core::vector2d<s32>(0,10),
+ displaycenter + core::vector2d<s32>(0,10),
+ video::SColor(255,255,255,255));
+ }
} // timer
@@ -2373,6 +2551,7 @@ void the_game(
/*
Draw hotbar
*/
+ if(show_hud)
{
draw_hotbar(driver, font, gamedef,
v2s32(displaycenter.X, screensize.Y),
diff --git a/src/inventorymanager.h b/src/inventorymanager.h
index 55e8f8402..52377f9a4 100644
--- a/src/inventorymanager.h
+++ b/src/inventorymanager.h
@@ -103,6 +103,7 @@ struct InventoryAction
virtual void apply(InventoryManager *mgr, ServerActiveObject *player,
IGameDef *gamedef) = 0;
virtual void clientApply(InventoryManager *mgr, IGameDef *gamedef) = 0;
+ virtual ~InventoryAction() {};
};
struct IMoveAction : public InventoryAction
diff --git a/src/light.cpp b/src/light.cpp
index f214d6ea0..89bddb1c4 100644
--- a/src/light.cpp
+++ b/src/light.cpp
@@ -20,6 +20,58 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "light.h"
#if 1
+/*
+Made using this and:
+- adding 220 as the second last one
+- replacing the third last one (212) with 195
+
+#!/usr/bin/python
+
+from math import *
+from sys import stdout
+
+# We want 0 at light=0 and 255 at light=LIGHT_MAX
+LIGHT_MAX = 14
+#FACTOR = 0.69
+#FACTOR = 0.75
+FACTOR = 0.83
+START_FROM_ZERO = False
+
+L = []
+if START_FROM_ZERO:
+ for i in range(1,LIGHT_MAX+1):
+ L.append(int(round(255.0 * FACTOR ** (i-1))))
+ L.append(0)
+else:
+ for i in range(1,LIGHT_MAX+1):
+ L.append(int(round(255.0 * FACTOR ** (i-1))))
+ L.append(255)
+
+L.reverse()
+for i in L:
+ stdout.write(str(i)+",\n")
+*/
+u8 light_decode_table[LIGHT_MAX+1] =
+{
+23,
+27,
+33,
+40,
+48,
+57,
+69,
+83,
+100,
+121,
+146,
+176,
+195,
+220,
+255,
+};
+#endif
+
+#if 0
// This is good
// a_n+1 = a_n * 0.786
// Length of LIGHT_MAX+1 means LIGHT_MAX is the last value.
@@ -42,7 +94,9 @@ u8 light_decode_table[LIGHT_MAX+1] =
200,
255,
};
-#else
+#endif
+
+#if 0
// Use for debugging in dark
u8 light_decode_table[LIGHT_MAX+1] =
{
diff --git a/src/player.cpp b/src/player.cpp
index 688be5d98..068b51790 100644
--- a/src/player.cpp
+++ b/src/player.cpp
@@ -156,10 +156,6 @@ void Player::deSerialize(std::istream &is)
setPitch(args.getFloat("pitch"));
setYaw(args.getFloat("yaw"));
setPosition(args.getV3F("position"));
- bool craftresult_is_preview = true;
- try{
- craftresult_is_preview = args.getBool("craftresult_is_preview");
- }catch(SettingNotFoundException &e){}
try{
hp = args.getS32("hp");
}catch(SettingNotFoundException &e){
@@ -173,6 +169,9 @@ void Player::deSerialize(std::istream &is)
// Convert players without craftpreview
inventory.addList("craftpreview", 1);
+ bool craftresult_is_preview = true;
+ if(args.exists("craftresult_is_preview"))
+ craftresult_is_preview = args.getBool("craftresult_is_preview");
if(craftresult_is_preview)
{
// Clear craftresult
@@ -714,14 +713,17 @@ void LocalPlayer::applyControl(float dtime)
}
else if(touching_ground)
{
- v3f speed = getSpeed();
/*
NOTE: The d value in move() affects jump height by
raising the height at which the jump speed is kept
at its starting value
*/
- speed.Y = 6.5*BS;
- setSpeed(speed);
+ v3f speed = getSpeed();
+ if(speed.Y >= -0.5*BS)
+ {
+ speed.Y = 6.5*BS;
+ setSpeed(speed);
+ }
}
// Use the oscillating value for getting out of water
// (so that the player doesn't fly on the surface)
diff --git a/src/player.h b/src/player.h
index 085a4a15a..d62fb6111 100644
--- a/src/player.h
+++ b/src/player.h
@@ -30,7 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
class Map;
class IGameDef;
-class CollisionInfo;
+struct CollisionInfo;
class Player
{
diff --git a/src/profiler.h b/src/profiler.h
index 129118ef6..7bb3b3750 100644
--- a/src/profiler.h
+++ b/src/profiler.h
@@ -100,11 +100,30 @@ public:
void print(std::ostream &o)
{
+ printPage(o, 1, 1);
+ }
+
+ void printPage(std::ostream &o, u32 page, u32 pagecount)
+ {
JMutexAutoLock lock(m_mutex);
+
+ u32 minindex, maxindex;
+ paging(m_data.size(), page, pagecount, minindex, maxindex);
+
for(core::map<std::string, float>::Iterator
i = m_data.getIterator();
i.atEnd() == false; i++)
{
+ if(maxindex == 0)
+ break;
+ maxindex--;
+
+ if(minindex != 0)
+ {
+ minindex--;
+ continue;
+ }
+
std::string name = i.getNode()->getKey();
int avgcount = 1;
core::map<std::string, int>::Node *n = m_avgcounts.find(name);
diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp
index a064cd688..8350c75f1 100644
--- a/src/scriptapi.cpp
+++ b/src/scriptapi.cpp
@@ -3560,6 +3560,14 @@ static int l_get_modpath(lua_State *L)
return 1;
}
+// get_worldpath()
+static int l_get_worldpath(lua_State *L)
+{
+ std::string worldpath = get_server(L)->getWorldPath();
+ lua_pushstring(L, worldpath.c_str());
+ return 1;
+}
+
static const struct luaL_Reg minetest_f [] = {
{"debug", l_debug},
{"log", l_log},
@@ -3576,6 +3584,7 @@ static const struct luaL_Reg minetest_f [] = {
{"get_hitting_properties", l_get_hitting_properties},
{"get_current_modname", l_get_current_modname},
{"get_modpath", l_get_modpath},
+ {"get_worldpath", l_get_worldpath},
{NULL, NULL}
};
diff --git a/src/scriptapi.h b/src/scriptapi.h
index 500a9ab99..df8ae344e 100644
--- a/src/scriptapi.h
+++ b/src/scriptapi.h
@@ -30,7 +30,7 @@ class ServerActiveObject;
class ServerRemotePlayer;
typedef struct lua_State lua_State;
struct LuaEntityProperties;
-class ItemStack;
+struct ItemStack;
struct PointedThing;
//class IGameDef;
diff --git a/src/server.cpp b/src/server.cpp
index a0c8a0092..bf90b2aa7 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -1270,7 +1270,8 @@ void Server::AsyncRunStep()
/*
Handle player HPs (die if hp=0)
*/
- HandlePlayerHP(player, 0);
+ if(player->hp == 0 && player->m_hp_not_sent)
+ DiePlayer(player);
/*
Send player inventories and HPs if necessary
@@ -1284,9 +1285,9 @@ void Server::AsyncRunStep()
}
/*
- Add to environment if is not in respawn screen
+ Add to environment
*/
- if(!player->m_is_in_environment && !player->m_respawn_active){
+ if(!player->m_is_in_environment){
player->m_removed = false;
player->setId(0);
m_env->addActiveObject(player);
@@ -2129,6 +2130,10 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
// Send HP
SendPlayerHP(player);
+ // Show death screen if necessary
+ if(player->hp == 0)
+ SendDeathscreen(m_con, player->peer_id, false, v3f(0,0,0));
+
// Send time of day
{
SharedBuffer<u8> data = makePacket_TOCLIENT_TIME_OF_DAY(
@@ -2160,11 +2165,6 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
}
/*
- Check HP, respawn if necessary
- */
- HandlePlayerHP(player, 0);
-
- /*
Print out action
*/
{
@@ -2662,16 +2662,25 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
std::istringstream is(datastring, std::ios_base::binary);
u8 damage = readU8(is);
+ ServerRemotePlayer *srp = static_cast<ServerRemotePlayer*>(player);
+
if(g_settings->getBool("enable_damage"))
{
actionstream<<player->getName()<<" damaged by "
<<(int)damage<<" hp at "<<PP(player->getPosition()/BS)
<<std::endl;
-
- HandlePlayerHP(player, damage);
+
+ srp->setHP(srp->getHP() - damage);
+
+ if(srp->getHP() == 0 && srp->m_hp_not_sent)
+ DiePlayer(srp);
+
+ if(srp->m_hp_not_sent)
+ SendPlayerHP(player);
}
else
{
+ // Force send (to correct the client's predicted HP)
SendPlayerHP(player);
}
}
@@ -2751,8 +2760,6 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
if(player->hp != 0)
return;
- srp->m_respawn_active = false;
-
RespawnPlayer(player);
actionstream<<player->getName()<<" respawns at "
@@ -2811,6 +2818,13 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
infostream<<"TOSERVER_INTERACT: action="<<(int)action<<", item="<<item_i<<", pointed="<<pointed.dump()<<std::endl;
+ if(player->hp == 0)
+ {
+ infostream<<"TOSERVER_INTERACT: "<<srp->getName()
+ <<" tried to interact, but is dead!"<<std::endl;
+ return;
+ }
+
v3f player_pos = srp->m_last_good_position;
// Update wielded item
@@ -3968,26 +3982,14 @@ void Server::SendTexturesRequested(u16 peer_id,core::list<TextureRequest> tosend
Something random
*/
-void Server::HandlePlayerHP(Player *player, s16 damage)
+void Server::DiePlayer(Player *player)
{
ServerRemotePlayer *srp = static_cast<ServerRemotePlayer*>(player);
- if(srp->m_respawn_active)
- return;
-
- if(player->hp > damage)
- {
- if(damage != 0){
- player->hp -= damage;
- SendPlayerHP(player);
- }
- return;
- }
-
- infostream<<"Server::HandlePlayerHP(): Player "
+ infostream<<"Server::DiePlayer(): Player "
<<player->getName()<<" dies"<<std::endl;
- player->hp = 0;
+ srp->setHP(0);
// Trigger scripted stuff
scriptapi_on_dieplayer(m_lua, srp);
@@ -3999,24 +4001,13 @@ void Server::HandlePlayerHP(Player *player, s16 damage)
}
SendPlayerHP(player);
-
- RemoteClient *client = getClient(player->peer_id);
- if(client->net_proto_version >= 3)
- {
- SendDeathscreen(m_con, player->peer_id, false, v3f(0,0,0));
- srp->m_removed = true;
- srp->m_respawn_active = true;
- }
- else
- {
- RespawnPlayer(player);
- }
+ SendDeathscreen(m_con, player->peer_id, false, v3f(0,0,0));
}
void Server::RespawnPlayer(Player *player)
{
- player->hp = 20;
ServerRemotePlayer *srp = static_cast<ServerRemotePlayer*>(player);
+ srp->setHP(20);
bool repositioned = scriptapi_on_respawnplayer(m_lua, srp);
if(!repositioned){
v3f pos = findSpawnPos(m_env->getServerMap());
@@ -4268,6 +4259,14 @@ ServerRemotePlayer *Server::emergePlayer(const char *name, u16 peer_id)
// Got one.
player->peer_id = peer_id;
+ // Re-add player to environment
+ if(player->m_removed)
+ {
+ player->m_removed = false;
+ player->setId(0);
+ m_env->addActiveObject(player);
+ }
+
// Reset inventory to creative if in creative mode
if(g_settings->getBool("creative_mode"))
{
@@ -4305,12 +4304,13 @@ ServerRemotePlayer *Server::emergePlayer(const char *name, u16 peer_id)
v3f pos = findSpawnPos(m_env->getServerMap());
player = new ServerRemotePlayer(m_env, pos, peer_id, name);
+ ServerRemotePlayer *srp = static_cast<ServerRemotePlayer*>(player);
/* Add player to environment */
m_env->addPlayer(player);
+ m_env->addActiveObject(srp);
/* Run scripts */
- ServerRemotePlayer *srp = static_cast<ServerRemotePlayer*>(player);
scriptapi_on_newplayer(m_lua, srp);
/* Add stuff to inventory */
diff --git a/src/server.h b/src/server.h
index 4fdb60065..04bd61a87 100644
--- a/src/server.h
+++ b/src/server.h
@@ -525,6 +525,8 @@ public:
IWritableCraftDefManager* getWritableCraftDefManager();
const ModSpec* getModSpec(const std::string &modname);
+
+ std::string getWorldPath(){ return m_mapsavedir; }
private:
@@ -592,7 +594,7 @@ private:
Something random
*/
- void HandlePlayerHP(Player *player, s16 damage);
+ void DiePlayer(Player *player);
void RespawnPlayer(Player *player);
void UpdateCrafting(u16 peer_id);
diff --git a/src/serverobject.h b/src/serverobject.h
index 94ceb4895..380bf7302 100644
--- a/src/serverobject.h
+++ b/src/serverobject.h
@@ -42,7 +42,7 @@ Some planning
*/
class ServerEnvironment;
-class ItemStack;
+struct ItemStack;
class Player;
struct ToolDiggingProperties;
diff --git a/src/serverremoteplayer.cpp b/src/serverremoteplayer.cpp
index b4dbbdb1b..728ffe026 100644
--- a/src/serverremoteplayer.cpp
+++ b/src/serverremoteplayer.cpp
@@ -34,7 +34,6 @@ ServerRemotePlayer::ServerRemotePlayer(ServerEnvironment *env):
m_wield_index(0),
m_inventory_not_sent(false),
m_hp_not_sent(false),
- m_respawn_active(false),
m_is_in_environment(false),
m_time_from_last_punch(0),
m_position_not_sent(false)
@@ -159,6 +158,8 @@ std::string ServerRemotePlayer::getClientInitializationData()
writeV3F1000(os, getPosition());
// yaw
writeF1000(os, getYaw());
+ // dead
+ writeU8(os, getHP() == 0);
return os.str();
}
@@ -247,6 +248,19 @@ void ServerRemotePlayer::setHP(s16 hp_)
if(hp != oldhp)
m_hp_not_sent = true;
+
+ // On death or reincarnation send an active object message
+ if((hp == 0) != (oldhp == 0))
+ {
+ std::ostringstream os(std::ios::binary);
+ // command (2 = update death state)
+ writeU8(os, 2);
+ // dead?
+ writeU8(os, hp == 0);
+ // create message and add to list
+ ActiveObjectMessage aom(getId(), false, os.str());
+ m_messages_out.push_back(aom);
+ }
}
s16 ServerRemotePlayer::getHP()
{
diff --git a/src/serverremoteplayer.h b/src/serverremoteplayer.h
index 9d9437646..94926c824 100644
--- a/src/serverremoteplayer.h
+++ b/src/serverremoteplayer.h
@@ -90,7 +90,6 @@ public:
int m_wield_index;
bool m_inventory_not_sent;
bool m_hp_not_sent;
- bool m_respawn_active;
bool m_is_in_environment;
// Incremented by step(), read and reset by Server
float m_time_from_last_punch;
diff --git a/src/utility.cpp b/src/utility.cpp
index 06b60884f..7c87b9ae4 100644
--- a/src/utility.cpp
+++ b/src/utility.cpp
@@ -208,7 +208,7 @@ bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir,
return true;
// If block is far away, it's not in sight
- if(d > range * BS)
+ if(d > range)
return false;
// Maximum radius of a block
diff --git a/src/utility.h b/src/utility.h
index 50f27c11b..f4c7c3017 100644
--- a/src/utility.h
+++ b/src/utility.h
@@ -1757,6 +1757,50 @@ protected:
float m_accumulator;
};
+/*
+ Splits a list into "pages". For example, the list [1,2,3,4,5] split
+ into two pages would be [1,2,3],[4,5]. This function computes the
+ minimum and maximum indices of a single page.
+
+ length: Length of the list that should be split
+ page: Page number, 1 <= page <= pagecount
+ pagecount: The number of pages, >= 1
+ minindex: Receives the minimum index (inclusive).
+ maxindex: Receives the maximum index (exclusive).
+
+ Ensures 0 <= minindex <= maxindex <= length.
+*/
+inline void paging(u32 length, u32 page, u32 pagecount, u32 &minindex, u32 &maxindex)
+{
+ if(length < 1 || pagecount < 1 || page < 1 || page > pagecount)
+ {
+ // Special cases or invalid parameters
+ minindex = maxindex = 0;
+ }
+ else if(pagecount <= length)
+ {
+ // Less pages than entries in the list:
+ // Each page contains at least one entry
+ minindex = (length * (page-1) + (pagecount-1)) / pagecount;
+ maxindex = (length * page + (pagecount-1)) / pagecount;
+ }
+ else
+ {
+ // More pages than entries in the list:
+ // Make sure the empty pages are at the end
+ if(page < length)
+ {
+ minindex = page-1;
+ maxindex = page;
+ }
+ else
+ {
+ minindex = 0;
+ maxindex = 0;
+ }
+ }
+}
+
std::string translatePassword(std::string playername, std::wstring password);
enum PointedThingType