diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/camera.cpp | 56 | ||||
-rw-r--r-- | src/camera.h | 9 | ||||
-rw-r--r-- | src/client.cpp | 10 | ||||
-rw-r--r-- | src/content_cao.cpp | 35 | ||||
-rw-r--r-- | src/content_nodemeta.cpp | 23 | ||||
-rw-r--r-- | src/defaultsettings.cpp | 21 | ||||
-rw-r--r-- | src/environment.cpp | 19 | ||||
-rw-r--r-- | src/game.cpp | 393 | ||||
-rw-r--r-- | src/inventorymanager.h | 1 | ||||
-rw-r--r-- | src/light.cpp | 56 | ||||
-rw-r--r-- | src/player.cpp | 16 | ||||
-rw-r--r-- | src/player.h | 2 | ||||
-rw-r--r-- | src/profiler.h | 19 | ||||
-rw-r--r-- | src/scriptapi.cpp | 9 | ||||
-rw-r--r-- | src/scriptapi.h | 2 | ||||
-rw-r--r-- | src/server.cpp | 82 | ||||
-rw-r--r-- | src/server.h | 4 | ||||
-rw-r--r-- | src/serverobject.h | 2 | ||||
-rw-r--r-- | src/serverremoteplayer.cpp | 16 | ||||
-rw-r--r-- | src/serverremoteplayer.h | 1 | ||||
-rw-r--r-- | src/utility.cpp | 2 | ||||
-rw-r--r-- | src/utility.h | 44 |
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 |