]> git.lizzy.rs Git - dragonfireclient.git/commitdiff
Merge branch 'master' of https://github.com/minetest/minetest
authorElias Fleckenstein <eliasfleckenstein@web.de>
Sun, 19 Sep 2021 18:56:13 +0000 (20:56 +0200)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Sun, 19 Sep 2021 18:56:13 +0000 (20:56 +0200)
49 files changed:
1  2 
.gitignore
CMakeLists.txt
README.md
builtin/client/death_formspec.lua
builtin/common/misc_helpers.lua
builtin/game/item.lua
builtin/init.lua
builtin/mainmenu/dlg_contentstore.lua
builtin/mainmenu/dlg_settings_advanced.lua
builtin/settingtypes.txt
doc/client_lua_api.txt
doc/lua_api.txt
src/client/client.cpp
src/client/client.h
src/client/clientmap.cpp
src/client/content_cao.cpp
src/client/game.cpp
src/client/game.h
src/client/gameui.cpp
src/client/gameui.h
src/client/hud.cpp
src/client/inputhandler.cpp
src/client/inputhandler.h
src/client/localplayer.cpp
src/client/mapblock_mesh.cpp
src/client/render/core.cpp
src/client/render/core.h
src/client/renderingengine.cpp
src/defaultsettings.cpp
src/map.cpp
src/map.h
src/network/clientpackethandler.cpp
src/player.h
src/script/common/c_content.cpp
src/script/common/c_content.h
src/script/cpp_api/s_base.cpp
src/script/cpp_api/s_base.h
src/script/cpp_api/s_client.cpp
src/script/cpp_api/s_security.cpp
src/script/lua_api/l_env.cpp
src/script/lua_api/l_env.h
src/script/lua_api/l_item.cpp
src/script/lua_api/l_localplayer.cpp
src/script/lua_api/l_mainmenu.cpp
src/script/lua_api/l_server.cpp
src/script/lua_api/l_util.cpp
src/serverenvironment.cpp
util/buildbot/buildwin32.sh
util/buildbot/buildwin64.sh

diff --cc .gitignore
Simple merge
diff --cc CMakeLists.txt
index e4ec5ea18c3de3a00c9036799770aa3e1dfb0d19,1995f34b88ebc8ea5a6ed20d0095e17329ba4385..deb327c5bc17df45e6c2f4b7d1ce58a80a4e34b9
@@@ -1,8 -1,15 +1,15 @@@
  cmake_minimum_required(VERSION 3.5)
  
+ # Set policies up to 3.9 since we want to enable the IPO option
+ if(${CMAKE_VERSION} VERSION_LESS 3.9)
+       cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
+ else()
+       cmake_policy(VERSION 3.9)
+ endif()
  # This can be read from ${PROJECT_NAME} after project() is called
  project(minetest)
 -set(PROJECT_NAME_CAPITALIZED "Minetest")
 +set(PROJECT_NAME_CAPITALIZED "Dragonfire")
  
  set(CMAKE_CXX_STANDARD 11)
  set(GCC_MINIMUM_VERSION "4.8")
diff --cc README.md
Simple merge
index 6d6fd6fd914456b2dd1b9b5e452efaaa9471e310,c25c799ab7fd3f48d79df208c3718986cf49fde5..ff484b32f6312e62796ebc61ee0364ee2044dc3b
@@@ -1,18 -1,11 +1,18 @@@
 --- CSM death formspec. Only used when clientside modding is enabled, otherwise
 --- handled by the engine.
 +local death_formspec = ""
 +      .. "size[11,5.5]"
 +      .. "bgcolor[#320000b4;true]"
-       .. "label[4.85,1.35;" .. "You died" .. "]"
-       .. "button_exit[2,3;3,0.5;btn_respawn;" .. "Respawn" .. "]"
++      .. "label[4.85,1.35;" .. fgettext("You died") .. "]"
++      .. "button_exit[2,3;3,0.5;btn_respawn;" .. fgettext("Respawn") .. "]"
 +      .. "button_exit[6,3;3,0.5;btn_ghost_mode;" .. "Ghost Mode" .. "]"
 +      .. "set_focus[btn_respawn;true]"
  
  core.register_on_death(function()
 -      local formspec = "size[11,5.5]bgcolor[#320000b4;true]" ..
 -              "label[4.85,1.35;" .. fgettext("You died") ..
 -              "]button_exit[4,3;3,0.5;btn_respawn;".. fgettext("Respawn") .."]"
 -      core.show_formspec("bultin:death", formspec)
 +      core.display_chat_message("You died at " .. core.pos_to_string(vector.round(core.localplayer:get_pos())) .. ".")
 +      if core.settings:get_bool("autorespawn") then
 +              core.send_respawn()
 +      else
 +              core.show_formspec("bultin:death", death_formspec)
 +      end
  end)
  
  core.register_on_formspec_input(function(formname, fields)
Simple merge
Simple merge
Simple merge
index 20a446d5d497214c1b866ede6cf9ee5134572d7f,a3c72aee4e0da28a7f2bc9c9547d7fa8016005a9..790da03bafc3fdcc01c9a4ae6378b6030b585147
@@@ -582,9 -604,10 +604,10 @@@ en
  function store.update_paths()
        local mod_hash = {}
        pkgmgr.refresh_globals()
 -      for _, mod in pairs(pkgmgr.global_mods:get_list()) do
 +      for _, mod in pairs(pkgmgr.clientmods:get_list()) do
                if mod.author and mod.release > 0 then
-                       mod_hash[mod.author:lower() .. "/" .. mod.name] = mod
+                       local id = mod.author:lower() .. "/" .. mod.name
+                       mod_hash[store.aliases[id] or id] = mod
                end
        end
  
Simple merge
Simple merge
diff --cc doc/lua_api.txt
Simple merge
index 57f8e6593400b8a8a99f330229bde1df3cdcdf61,45cc62a33578e4fcef557a27d6b2111ccc5cd2c3..3c4ea5f95f6a2be6d2407f581db91d6fa54458ab
@@@ -1299,14 -1319,19 +1322,27 @@@ void Client::sendPlayerPos(v3f pos
        Send(&pkt);
  }
  
 +void Client::sendPlayerPos()
 +{
 +      LocalPlayer *player = m_env.getLocalPlayer();
 +      if (!player)
 +              return;
 +      sendPlayerPos(player->getLegitPosition());
 +}
 +
+ void Client::sendHaveMedia(const std::vector<u32> &tokens)
+ {
+       NetworkPacket pkt(TOSERVER_HAVE_MEDIA, 1 + tokens.size() * 4);
+       sanity_check(tokens.size() < 256);
+       pkt << static_cast<u8>(tokens.size());
+       for (u32 token : tokens)
+               pkt << token;
+       Send(&pkt);
+ }
  void Client::removeNode(v3s16 p)
  {
        std::map<v3s16, MapBlock*> modified_blocks;
Simple merge
Simple merge
index 3a6ca3e292e827c254c73a2057f766e01fd30847,da78cae7cd5d04a9ed1892a28aee273f899c1684..5d8a597a2c41618c4a8743edd58b5a444fc2e075
@@@ -1011,9 -998,7 +1016,7 @@@ void GenericCAO::step(float dtime, Clie
                        const PlayerControl &controls = player->getPlayerControl();
  
                        bool walking = false;
-                       if ((controls.up || controls.down || controls.left || controls.right ||
-                                       controls.forw_move_joystick_axis != 0.f ||
-                                       controls.sidew_move_joystick_axis != 0.f) && ! g_settings->getBool("freecam"))
 -                      if (controls.movement_speed > 0.001f)
++                      if (controls.movement_speed > 0.001f && ! g_settings->getBool("freecam"))
                                walking = true;
  
                        f32 new_speed = player->local_animation_speed;
                                        (controls.aux1 ||
                                        (!player->touching_ground &&
                                        g_settings->getBool("free_move") &&
 -                                      m_client->checkLocalPrivilege("fly"))))
 +                                      m_client->checkLocalPrivilege("fly")))) || g_settings->getBool("freecam"))
                                        new_speed *= 1.5;
-                       // slowdown speed if sneeking
+                       // slowdown speed if sneaking
 -                      if (controls.sneak && walking)
 +                      if (controls.sneak && walking && ! g_settings->getBool("no_slow"))
                                new_speed /= 2;
+                       new_speed *= controls.movement_speed;
  
                        if (walking && (controls.dig || controls.place)) {
                                new_anim = player->local_animations[3];
index 5bfe55e665e26f16e26d000dd691977514be801f,a24ded844192e331d234d4926201e5c7a6317dab..d2a75104085d59555d1765dabecc77bca05be897
@@@ -3199,16 -3960,6 +3257,16 @@@ void Game::updateFrame(ProfilerGraph *g
        if (m_game_ui->m_flags.show_profiler_graph)
                graph->draw(10, screensize.Y - 10, driver, g_fontengine->getFont());
  
-                       m_cheat_menu->draw(driver, m_game_ui->m_flags.show_debug);
 +      /*
 +              Cheat menu
 +      */
 +
 +      if (! gui_chat_console->isOpen()) {
 +              if (m_game_ui->m_flags.show_cheat_menu)
++                      m_cheat_menu->draw(driver, m_game_ui->m_flags.show_minimal_debug);
 +              if (g_settings->getBool("cheat_hud"))
 +                      m_cheat_menu->drawHUD(driver, dtime);
 +      }
        /*
                Damage flash
        */
index 8197b9a9bdf0c547b98ef0e6607d39df0da5237d,fbbf106db6381455fc93f2812d89da1dcd4ea925..cb40d48904639613ef8ded00282b39137e02ca3a
@@@ -96,821 -43,6 +96,824 @@@ struct CameraOrientation 
        f32 camera_pitch;  // "up/down"
  };
  
 +/*
 +      Text input system
 +*/
 +
 +struct TextDestNodeMetadata : public TextDest
 +{
 +      TextDestNodeMetadata(v3s16 p, Client *client)
 +      {
 +              m_p = p;
 +              m_client = client;
 +      }
 +      // This is deprecated I guess? -celeron55
 +      void gotText(const std::wstring &text)
 +      {
 +              std::string ntext = wide_to_utf8(text);
 +              infostream << "Submitting 'text' field of node at (" << m_p.X << ","
 +                         << m_p.Y << "," << m_p.Z << "): " << ntext << std::endl;
 +              StringMap fields;
 +              fields["text"] = ntext;
 +              m_client->sendNodemetaFields(m_p, "", fields);
 +      }
 +      void gotText(const StringMap &fields)
 +      {
 +              m_client->sendNodemetaFields(m_p, "", fields);
 +      }
 +
 +      v3s16 m_p;
 +      Client *m_client;
 +};
 +
 +struct TextDestPlayerInventory : public TextDest
 +{
 +      TextDestPlayerInventory(Client *client)
 +      {
 +              m_client = client;
 +              m_formname = "";
 +      }
 +      TextDestPlayerInventory(Client *client, const std::string &formname)
 +      {
 +              m_client = client;
 +              m_formname = formname;
 +      }
 +      void gotText(const StringMap &fields)
 +      {
 +              m_client->sendInventoryFields(m_formname, fields);
 +      }
 +
 +      Client *m_client;
 +};
 +
 +struct LocalFormspecHandler : public TextDest
 +{
 +      LocalFormspecHandler(const std::string &formname)
 +      {
 +              m_formname = formname;
 +      }
 +
 +      LocalFormspecHandler(const std::string &formname, Client *client):
 +              m_client(client)
 +      {
 +              m_formname = formname;
 +      }
 +
 +      void gotText(const StringMap &fields)
 +      {
 +              if (m_formname == "MT_PAUSE_MENU") {
 +                      if (fields.find("btn_sound") != fields.end()) {
 +                              g_gamecallback->changeVolume();
 +                              return;
 +                      }
 +
 +                      if (fields.find("btn_key_config") != fields.end()) {
 +                              g_gamecallback->keyConfig();
 +                              return;
 +                      }
 +
 +                      if (fields.find("btn_exit_menu") != fields.end()) {
 +                              g_gamecallback->disconnect();
 +                              return;
 +                      }
 +
 +                      if (fields.find("btn_exit_os") != fields.end()) {
 +                              g_gamecallback->exitToOS();
 +#ifndef __ANDROID__
 +                              RenderingEngine::get_raw_device()->closeDevice();
 +#endif
 +                              return;
 +                      }
 +
 +                      if (fields.find("btn_change_password") != fields.end()) {
 +                              g_gamecallback->changePassword();
 +                              return;
 +                      }
 +
 +                      return;
 +              }
 +
 +              if (m_formname == "MT_DEATH_SCREEN") {
 +                      assert(m_client != 0);
 +                      m_client->sendRespawn();
 +                      return;
 +              }
 +
 +              if (m_client->modsLoaded())
 +                      m_client->getScript()->on_formspec_input(m_formname, fields);
 +      }
 +
 +      Client *m_client = nullptr;
 +};
 +
 +/* Form update callback */
 +
 +class NodeMetadataFormSource: public IFormSource
 +{
 +public:
 +      NodeMetadataFormSource(ClientMap *map, v3s16 p):
 +              m_map(map),
 +              m_p(p)
 +      {
 +      }
 +      const std::string &getForm() const
 +      {
 +              static const std::string empty_string = "";
 +              NodeMetadata *meta = m_map->getNodeMetadata(m_p);
 +
 +              if (!meta)
 +                      return empty_string;
 +
 +              return meta->getString("formspec");
 +      }
 +
 +      virtual std::string resolveText(const std::string &str)
 +      {
 +              NodeMetadata *meta = m_map->getNodeMetadata(m_p);
 +
 +              if (!meta)
 +                      return str;
 +
 +              return meta->resolveString(str);
 +      }
 +
 +      ClientMap *m_map;
 +      v3s16 m_p;
 +};
 +
 +class PlayerInventoryFormSource: public IFormSource
 +{
 +public:
 +      PlayerInventoryFormSource(Client *client):
 +              m_client(client)
 +      {
 +      }
 +
 +      const std::string &getForm() const
 +      {
 +              LocalPlayer *player = m_client->getEnv().getLocalPlayer();
 +              return player->inventory_formspec;
 +      }
 +
 +      Client *m_client;
 +};
 +
 +class NodeDugEvent: public MtEvent
 +{
 +public:
 +      v3s16 p;
 +      MapNode n;
 +
 +      NodeDugEvent(v3s16 p, MapNode n):
 +              p(p),
 +              n(n)
 +      {}
 +      MtEvent::Type getType() const
 +      {
 +              return MtEvent::NODE_DUG;
 +      }
 +};
 +
 +class SoundMaker
 +{
 +      ISoundManager *m_sound;
 +      const NodeDefManager *m_ndef;
 +public:
 +      bool makes_footstep_sound;
 +      float m_player_step_timer;
 +      float m_player_jump_timer;
 +
 +      SimpleSoundSpec m_player_step_sound;
 +      SimpleSoundSpec m_player_leftpunch_sound;
 +      SimpleSoundSpec m_player_rightpunch_sound;
 +
 +      SoundMaker(ISoundManager *sound, const NodeDefManager *ndef):
 +              m_sound(sound),
 +              m_ndef(ndef),
 +              makes_footstep_sound(true),
 +              m_player_step_timer(0.0f),
 +              m_player_jump_timer(0.0f)
 +      {
 +      }
 +
 +      void playPlayerStep()
 +      {
 +              if (m_player_step_timer <= 0 && m_player_step_sound.exists()) {
 +                      m_player_step_timer = 0.03;
 +                      if (makes_footstep_sound)
 +                              m_sound->playSound(m_player_step_sound, false);
 +              }
 +      }
 +
 +      void playPlayerJump()
 +      {
 +              if (m_player_jump_timer <= 0.0f) {
 +                      m_player_jump_timer = 0.2f;
 +                      m_sound->playSound(SimpleSoundSpec("player_jump", 0.5f), false);
 +              }
 +      }
 +
 +      static void viewBobbingStep(MtEvent *e, void *data)
 +      {
 +              SoundMaker *sm = (SoundMaker *)data;
 +              sm->playPlayerStep();
 +      }
 +
 +      static void playerRegainGround(MtEvent *e, void *data)
 +      {
 +              SoundMaker *sm = (SoundMaker *)data;
 +              sm->playPlayerStep();
 +      }
 +
 +      static void playerJump(MtEvent *e, void *data)
 +      {
 +              SoundMaker *sm = (SoundMaker *)data;
 +              sm->playPlayerJump();
 +      }
 +
 +      static void cameraPunchLeft(MtEvent *e, void *data)
 +      {
 +              SoundMaker *sm = (SoundMaker *)data;
 +              sm->m_sound->playSound(sm->m_player_leftpunch_sound, false);
 +      }
 +
 +      static void cameraPunchRight(MtEvent *e, void *data)
 +      {
 +              SoundMaker *sm = (SoundMaker *)data;
 +              sm->m_sound->playSound(sm->m_player_rightpunch_sound, false);
 +      }
 +
 +      static void nodeDug(MtEvent *e, void *data)
 +      {
 +              SoundMaker *sm = (SoundMaker *)data;
 +              NodeDugEvent *nde = (NodeDugEvent *)e;
 +              sm->m_sound->playSound(sm->m_ndef->get(nde->n).sound_dug, false);
 +      }
 +
 +      static void playerDamage(MtEvent *e, void *data)
 +      {
 +              SoundMaker *sm = (SoundMaker *)data;
 +              sm->m_sound->playSound(SimpleSoundSpec("player_damage", 0.5), false);
 +      }
 +
 +      static void playerFallingDamage(MtEvent *e, void *data)
 +      {
 +              SoundMaker *sm = (SoundMaker *)data;
 +              sm->m_sound->playSound(SimpleSoundSpec("player_falling_damage", 0.5), false);
 +      }
 +
 +      void registerReceiver(MtEventManager *mgr)
 +      {
 +              mgr->reg(MtEvent::VIEW_BOBBING_STEP, SoundMaker::viewBobbingStep, this);
 +              mgr->reg(MtEvent::PLAYER_REGAIN_GROUND, SoundMaker::playerRegainGround, this);
 +              mgr->reg(MtEvent::PLAYER_JUMP, SoundMaker::playerJump, this);
 +              mgr->reg(MtEvent::CAMERA_PUNCH_LEFT, SoundMaker::cameraPunchLeft, this);
 +              mgr->reg(MtEvent::CAMERA_PUNCH_RIGHT, SoundMaker::cameraPunchRight, this);
 +              mgr->reg(MtEvent::NODE_DUG, SoundMaker::nodeDug, this);
 +              mgr->reg(MtEvent::PLAYER_DAMAGE, SoundMaker::playerDamage, this);
 +              mgr->reg(MtEvent::PLAYER_FALLING_DAMAGE, SoundMaker::playerFallingDamage, this);
 +      }
 +
 +      void step(float dtime)
 +      {
 +              m_player_step_timer -= dtime;
 +              m_player_jump_timer -= dtime;
 +      }
 +};
 +
 +// Locally stored sounds don't need to be preloaded because of this
 +class GameOnDemandSoundFetcher: public OnDemandSoundFetcher
 +{
 +      std::set<std::string> m_fetched;
 +private:
 +      void paths_insert(std::set<std::string> &dst_paths,
 +              const std::string &base,
 +              const std::string &name)
 +      {
 +              dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".ogg");
 +              dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".0.ogg");
 +              dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".1.ogg");
 +              dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".2.ogg");
 +              dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".3.ogg");
 +              dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".4.ogg");
 +              dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".5.ogg");
 +              dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".6.ogg");
 +              dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".7.ogg");
 +              dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".8.ogg");
 +              dst_paths.insert(base + DIR_DELIM + "sounds" + DIR_DELIM + name + ".9.ogg");
 +      }
 +public:
 +      void fetchSounds(const std::string &name,
 +              std::set<std::string> &dst_paths,
 +              std::set<std::string> &dst_datas)
 +      {
 +              if (m_fetched.count(name))
 +                      return;
 +
 +              m_fetched.insert(name);
 +
 +              paths_insert(dst_paths, porting::path_share, name);
 +              paths_insert(dst_paths, porting::path_user,  name);
 +      }
 +};
 +
 +
 +typedef s32 SamplerLayer_t;
 +
 +
 +class GameGlobalShaderConstantSetter : public IShaderConstantSetter
 +{
 +      Sky *m_sky;
 +      bool *m_force_fog_off;
 +      f32 *m_fog_range;
 +      bool m_fog_enabled;
 +      CachedPixelShaderSetting<float, 4> m_sky_bg_color;
 +      CachedPixelShaderSetting<float> m_fog_distance;
 +      CachedVertexShaderSetting<float> m_animation_timer_vertex;
 +      CachedPixelShaderSetting<float> m_animation_timer_pixel;
 +      CachedPixelShaderSetting<float, 3> m_day_light;
 +      CachedPixelShaderSetting<float, 4> m_star_color;
 +      CachedPixelShaderSetting<float, 3> m_eye_position_pixel;
 +      CachedVertexShaderSetting<float, 3> m_eye_position_vertex;
 +      CachedPixelShaderSetting<float, 3> m_minimap_yaw;
 +      CachedPixelShaderSetting<float, 3> m_camera_offset_pixel;
 +      CachedPixelShaderSetting<float, 3> m_camera_offset_vertex;
 +      CachedPixelShaderSetting<SamplerLayer_t> m_base_texture;
 +      CachedPixelShaderSetting<SamplerLayer_t> m_normal_texture;
 +      Client *m_client;
 +
 +public:
 +      void onSettingsChange(const std::string &name)
 +      {
 +              if (name == "enable_fog")
 +                      m_fog_enabled = g_settings->getBool("enable_fog");
 +      }
 +
 +      static void settingsCallback(const std::string &name, void *userdata)
 +      {
 +              reinterpret_cast<GameGlobalShaderConstantSetter*>(userdata)->onSettingsChange(name);
 +      }
 +
 +      void setSky(Sky *sky) { m_sky = sky; }
 +
 +      GameGlobalShaderConstantSetter(Sky *sky, bool *force_fog_off,
 +                      f32 *fog_range, Client *client) :
 +              m_sky(sky),
 +              m_force_fog_off(force_fog_off),
 +              m_fog_range(fog_range),
 +              m_sky_bg_color("skyBgColor"),
 +              m_fog_distance("fogDistance"),
 +              m_animation_timer_vertex("animationTimer"),
 +              m_animation_timer_pixel("animationTimer"),
 +              m_day_light("dayLight"),
 +              m_star_color("starColor"),
 +              m_eye_position_pixel("eyePosition"),
 +              m_eye_position_vertex("eyePosition"),
 +              m_minimap_yaw("yawVec"),
 +              m_camera_offset_pixel("cameraOffset"),
 +              m_camera_offset_vertex("cameraOffset"),
 +              m_base_texture("baseTexture"),
 +              m_normal_texture("normalTexture"),
 +              m_client(client)
 +      {
 +              g_settings->registerChangedCallback("enable_fog", settingsCallback, this);
 +              m_fog_enabled = g_settings->getBool("enable_fog");
 +      }
 +
 +      ~GameGlobalShaderConstantSetter()
 +      {
 +              g_settings->deregisterChangedCallback("enable_fog", settingsCallback, this);
 +      }
 +
 +      void onSetConstants(video::IMaterialRendererServices *services) override
 +      {
 +              // Background color
 +              video::SColor bgcolor = m_sky->getBgColor();
 +              video::SColorf bgcolorf(bgcolor);
 +              float bgcolorfa[4] = {
 +                      bgcolorf.r,
 +                      bgcolorf.g,
 +                      bgcolorf.b,
 +                      bgcolorf.a,
 +              };
 +              m_sky_bg_color.set(bgcolorfa, services);
 +
 +              // Fog distance
 +              float fog_distance = 10000 * BS;
 +
 +              if (m_fog_enabled && !*m_force_fog_off)
 +                      fog_distance = *m_fog_range;
 +
 +              m_fog_distance.set(&fog_distance, services);
 +
 +              u32 daynight_ratio = (float)m_client->getEnv().getDayNightRatio();
 +              video::SColorf sunlight;
 +              get_sunlight_color(&sunlight, daynight_ratio);
 +              float dnc[3] = {
 +                      sunlight.r,
 +                      sunlight.g,
 +                      sunlight.b };
 +              m_day_light.set(dnc, services);
 +
 +              video::SColorf star_color = m_sky->getCurrentStarColor();
 +              float clr[4] = {star_color.r, star_color.g, star_color.b, star_color.a};
 +              m_star_color.set(clr, services);
 +
 +              u32 animation_timer = porting::getTimeMs() % 1000000;
 +              float animation_timer_f = (float)animation_timer / 100000.f;
 +              m_animation_timer_vertex.set(&animation_timer_f, services);
 +              m_animation_timer_pixel.set(&animation_timer_f, services);
 +
 +              float eye_position_array[3];
 +              v3f epos = m_client->getEnv().getLocalPlayer()->getEyePosition();
 +              epos.getAs3Values(eye_position_array);
 +              m_eye_position_pixel.set(eye_position_array, services);
 +              m_eye_position_vertex.set(eye_position_array, services);
 +
 +              if (m_client->getMinimap()) {
 +                      float minimap_yaw_array[3];
 +                      v3f minimap_yaw = m_client->getMinimap()->getYawVec();
 +                      minimap_yaw.getAs3Values(minimap_yaw_array);
 +                      m_minimap_yaw.set(minimap_yaw_array, services);
 +              }
 +
 +              float camera_offset_array[3];
 +              v3f offset = intToFloat(m_client->getCamera()->getOffset(), BS);
 +              offset.getAs3Values(camera_offset_array);
 +              m_camera_offset_pixel.set(camera_offset_array, services);
 +              m_camera_offset_vertex.set(camera_offset_array, services);
 +
 +              SamplerLayer_t base_tex = 0, normal_tex = 1;
 +              m_base_texture.set(&base_tex, services);
 +              m_normal_texture.set(&normal_tex, services);
 +      }
 +};
 +
 +
 +class GameGlobalShaderConstantSetterFactory : public IShaderConstantSetterFactory
 +{
 +      Sky *m_sky;
 +      bool *m_force_fog_off;
 +      f32 *m_fog_range;
 +      Client *m_client;
 +      std::vector<GameGlobalShaderConstantSetter *> created_nosky;
 +public:
 +      GameGlobalShaderConstantSetterFactory(bool *force_fog_off,
 +                      f32 *fog_range, Client *client) :
 +              m_sky(NULL),
 +              m_force_fog_off(force_fog_off),
 +              m_fog_range(fog_range),
 +              m_client(client)
 +      {}
 +
 +      void setSky(Sky *sky) {
 +              m_sky = sky;
 +              for (GameGlobalShaderConstantSetter *ggscs : created_nosky) {
 +                      ggscs->setSky(m_sky);
 +              }
 +              created_nosky.clear();
 +      }
 +
 +      virtual IShaderConstantSetter* create()
 +      {
 +              auto *scs = new GameGlobalShaderConstantSetter(
 +                              m_sky, m_force_fog_off, m_fog_range, m_client);
 +              if (!m_sky)
 +                      created_nosky.push_back(scs);
 +              return scs;
 +      }
 +};
 +
 +#ifdef __ANDROID__
 +#define SIZE_TAG "size[11,5.5]"
 +#else
 +#define SIZE_TAG "size[11,5.5,true]" // Fixed size on desktop
 +#endif
 +
 +/****************************************************************************
 + ****************************************************************************/
 +
 +const float object_hit_delay = 0.2;
 +
 +struct FpsControl {
 +      u32 last_time, busy_time, sleep_time;
 +};
 +
 +
 +/* The reason the following structs are not anonymous structs within the
 + * class is that they are not used by the majority of member functions and
 + * many functions that do require objects of thse types do not modify them
 + * (so they can be passed as a const qualified parameter)
 + */
 +
 +struct GameRunData {
 +      u16 dig_index;
 +      u16 new_playeritem;
 +      PointedThing pointed_old;
 +      bool digging;
 +      bool punching;
 +      bool btn_down_for_dig;
 +      bool dig_instantly;
 +      bool digging_blocked;
 +      bool reset_jump_timer;
 +      float nodig_delay_timer;
 +      float dig_time;
 +      float dig_time_complete;
 +      float repeat_place_timer;
 +      float object_hit_delay_timer;
 +      float time_from_last_punch;
 +      ClientActiveObject *selected_object;
 +
 +      float jump_timer;
 +      float damage_flash;
 +      float update_draw_list_timer;
 +
 +      f32 fog_range;
 +
 +      v3f update_draw_list_last_cam_dir;
 +
 +      float time_of_day_smooth;
 +};
 +
 +class Game;
 +
 +struct ClientEventHandler
 +{
 +      void (Game::*handler)(ClientEvent *, CameraOrientation *);
 +};
 +
 +using PausedNodesList = std::vector<std::pair<irr_ptr<scene::IAnimatedMeshSceneNode>, float>>;
 +
 +class Game {
 +public:
 +      Game();
 +      ~Game();
 +
 +      bool startup(bool *kill,
 +                      InputHandler *input,
 +                      RenderingEngine *rendering_engine,
 +                      const GameStartData &game_params,
 +                      std::string &error_message,
 +                      bool *reconnect,
 +                      ChatBackend *chat_backend);
 +
 +
 +      void run();
 +      void shutdown();
 +
 +      // Basic initialisation
 +      bool init(const std::string &map_dir, const std::string &address,
 +                      u16 port, const SubgameSpec &gamespec);
 +      bool initSound();
 +      bool createSingleplayerServer(const std::string &map_dir,
 +                      const SubgameSpec &gamespec, u16 port);
 +
 +      // Client creation
 +      bool createClient(const GameStartData &start_data);
 +      bool initGui();
 +
 +      // Client connection
 +      bool connectToServer(const GameStartData &start_data,
 +                      bool *connect_ok, bool *aborted);
 +      bool getServerContent(bool *aborted);
 +
 +      // Main loop
 +
 +      void updateInteractTimers(f32 dtime);
 +      bool checkConnection();
 +      bool handleCallbacks();
 +      void processQueues();
 +      void updateProfilers(const RunStats &stats, const FpsControl &draw_times, f32 dtime);
++      void updateDebugState();
 +      void updateStats(RunStats *stats, const FpsControl &draw_times, f32 dtime);
 +      void updateProfilerGraphs(ProfilerGraph *graph);
 +
 +      // Input related
 +      void processUserInput(f32 dtime);
 +      void processKeyInput();
 +      void processItemSelection(u16 *new_playeritem);
 +
 +      void dropSelectedItem(bool single_item = false);
 +      void openInventory();
 +      void openEnderchest();
 +      void openConsole(float scale, const wchar_t *line=NULL);
 +      void toggleFreeMove();
 +      void toggleFreeMoveAlt();
 +      void togglePitchMove();
 +      void toggleFast();
 +      void toggleNoClip();
 +      void toggleKillaura();
 +      void toggleFreecam();
 +      void toggleScaffold();
 +      void toggleNextItem();
 +      void toggleCinematic();
++      void toggleBlockBounds();
 +      void toggleAutoforward();
 +
 +      void toggleMinimap(bool shift_pressed);
 +      void toggleFog();
 +      void toggleDebug();
 +      void toggleUpdateCamera();
 +      void updatePlayerCAOVisibility();
 +
 +      void increaseViewRange();
 +      void decreaseViewRange();
 +      void toggleFullViewRange();
 +      void checkZoomEnabled();
 +
 +      void updateCameraDirection(CameraOrientation *cam, float dtime);
 +      void updateCameraOrientation(CameraOrientation *cam, float dtime);
 +      void updatePlayerControl(const CameraOrientation &cam);
 +      void step(f32 *dtime);
 +      void processClientEvents(CameraOrientation *cam);
 +      void updateCamera(u32 busy_time, f32 dtime);
 +      void updateSound(f32 dtime);
 +      void processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug);
 +      /*!
 +       * Returns the object or node the player is pointing at.
 +       * Also updates the selected thing in the Hud.
 +       *
 +       * @param[in]  shootline         the shootline, starting from
 +       * the camera position. This also gives the maximal distance
 +       * of the search.
 +       * @param[in]  liquids_pointable if false, liquids are ignored
 +       * @param[in]  look_for_object   if false, objects are ignored
 +       * @param[in]  camera_offset     offset of the camera
 +       * @param[out] selected_object   the selected object or
 +       * NULL if not found
 +       */
 +      PointedThing updatePointedThing(
 +                      const core::line3d<f32> &shootline, bool liquids_pointable,
 +                      bool look_for_object, const v3s16 &camera_offset);
 +      void handlePointingAtNothing(const ItemStack &playerItem);
 +      void handlePointingAtNode(const PointedThing &pointed,
 +                      const ItemStack &selected_item, const ItemStack &hand_item, f32 dtime);
 +      void handlePointingAtObject(const PointedThing &pointed, const ItemStack &playeritem,
 +                      const v3f &player_position, bool show_debug);
 +      void handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
 +                      const ItemStack &selected_item, const ItemStack &hand_item, f32 dtime);
 +      void updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
 +                      const CameraOrientation &cam);
++      void updateShadows();
 +
 +      // Misc
 +      void limitFps(FpsControl *fps_timings, f32 *dtime);
 +
 +      void showOverlayMessage(const char *msg, float dtime, int percent,
 +                      bool draw_clouds = true);
 +
 +      static void freecamChangedCallback(const std::string &setting_name, void *data);
 +      static void settingChangedCallback(const std::string &setting_name, void *data);
 +      static void updateAllMapBlocksCallback(const std::string &setting_name, void *data);
 +      void readSettings();
 +
 +      bool isKeyDown(GameKeyType k);
 +      bool wasKeyDown(GameKeyType k);
 +      bool wasKeyPressed(GameKeyType k);
 +      bool wasKeyReleased(GameKeyType k);
 +
 +#ifdef __ANDROID__
 +      void handleAndroidChatInput();
 +#endif
 +
 +      struct Flags {
 +              bool force_fog_off = false;
 +              bool disable_camera_update = false;
 +      };
 +
 +      void showDeathFormspec();
 +      void showPauseMenu();
 +
 +      void pauseAnimation();
 +      void resumeAnimation();
 +
 +      // ClientEvent handlers
 +      void handleClientEvent_None(ClientEvent *event, CameraOrientation *cam);
 +      void handleClientEvent_PlayerDamage(ClientEvent *event, CameraOrientation *cam);
 +      void handleClientEvent_PlayerForceMove(ClientEvent *event, CameraOrientation *cam);
 +      void handleClientEvent_Deathscreen(ClientEvent *event, CameraOrientation *cam);
 +      void handleClientEvent_ShowFormSpec(ClientEvent *event, CameraOrientation *cam);
 +      void handleClientEvent_ShowLocalFormSpec(ClientEvent *event, CameraOrientation *cam);
 +      void handleClientEvent_HandleParticleEvent(ClientEvent *event,
 +              CameraOrientation *cam);
 +      void handleClientEvent_HudAdd(ClientEvent *event, CameraOrientation *cam);
 +      void handleClientEvent_HudRemove(ClientEvent *event, CameraOrientation *cam);
 +      void handleClientEvent_HudChange(ClientEvent *event, CameraOrientation *cam);
 +      void handleClientEvent_SetSky(ClientEvent *event, CameraOrientation *cam);
 +      void handleClientEvent_SetSun(ClientEvent *event, CameraOrientation *cam);
 +      void handleClientEvent_SetMoon(ClientEvent *event, CameraOrientation *cam);
 +      void handleClientEvent_SetStars(ClientEvent *event, CameraOrientation *cam);
 +      void handleClientEvent_OverrideDayNigthRatio(ClientEvent *event,
 +              CameraOrientation *cam);
 +      void handleClientEvent_CloudParams(ClientEvent *event, CameraOrientation *cam);
 +
 +      void updateChat(f32 dtime, const v2u32 &screensize);
 +
 +      bool nodePlacement(const ItemDefinition &selected_def, const ItemStack &selected_item,
 +              const v3s16 &nodepos, const v3s16 &neighbourpos, const PointedThing &pointed,
 +              const NodeMetadata *meta, bool force = false);
 +      static const ClientEventHandler clientEventHandler[CLIENTEVENT_MAX];
 +
 +      f32 getSensitivityScaleFactor() const;
 +
 +      InputHandler *input = nullptr;
 +
 +      Client *client = nullptr;
 +      Server *server = nullptr;
 +
 +      IWritableTextureSource *texture_src = nullptr;
 +      IWritableShaderSource *shader_src = nullptr;
 +
 +      // When created, these will be filled with data received from the server
 +      IWritableItemDefManager *itemdef_manager = nullptr;
 +      NodeDefManager *nodedef_manager = nullptr;
 +
 +      GameOnDemandSoundFetcher soundfetcher; // useful when testing
 +      ISoundManager *sound = nullptr;
 +      bool sound_is_dummy = false;
 +      SoundMaker *soundmaker = nullptr;
 +
 +      ChatBackend *chat_backend = nullptr;
 +      LogOutputBuffer m_chat_log_buf;
 +
 +      EventManager *eventmgr = nullptr;
 +      QuicktuneShortcutter *quicktune = nullptr;
 +      bool registration_confirmation_shown = false;
 +
 +      std::unique_ptr<GameUI> m_game_ui;
 +      GUIChatConsole *gui_chat_console = nullptr; // Free using ->Drop()
 +      CheatMenu *m_cheat_menu = nullptr;
 +      MapDrawControl *draw_control = nullptr;
 +      Camera *camera = nullptr;
 +      Clouds *clouds = nullptr;                         // Free using ->Drop()
 +      Sky *sky = nullptr;                         // Free using ->Drop()
 +      Hud *hud = nullptr;
 +      Minimap *mapper = nullptr;
 +
 +      // Map server hud ids to client hud ids
 +      std::unordered_map<u32, u32> m_hud_server_to_client;
 +
 +      GameRunData runData;
 +      Flags m_flags;
 +
 +      /* 'cache'
 +         This class does take ownership/responsibily for cleaning up etc of any of
 +         these items (e.g. device)
 +      */
 +      IrrlichtDevice *device;
 +      RenderingEngine *m_rendering_engine;
 +      video::IVideoDriver *driver;
 +      scene::ISceneManager *smgr;
 +      bool *kill;
 +      std::string *error_message;
 +      bool *reconnect_requested;
 +      scene::ISceneNode *skybox;
 +      PausedNodesList paused_animated_nodes;
 +
 +      bool simple_singleplayer_mode;
 +      /* End 'cache' */
 +
 +      /* Pre-calculated values
 +       */
 +      int crack_animation_length;
 +
 +      IntervalLimiter profiler_interval;
 +
 +      /*
 +       * TODO: Local caching of settings is not optimal and should at some stage
 +       *       be updated to use a global settings object for getting thse values
 +       *       (as opposed to the this local caching). This can be addressed in
 +       *       a later release.
 +       */
 +      bool m_cache_doubletap_jump;
 +      bool m_cache_enable_clouds;
 +      bool m_cache_enable_joysticks;
 +      bool m_cache_enable_particles;
 +      bool m_cache_enable_fog;
 +      bool m_cache_enable_noclip;
 +      bool m_cache_enable_free_move;
 +      f32  m_cache_mouse_sensitivity;
 +      f32  m_cache_joystick_frustum_sensitivity;
 +      f32  m_repeat_place_time;
 +      f32  m_cache_cam_smoothing;
 +      f32  m_cache_fog_start;
 +
 +      bool m_invert_mouse = false;
 +      bool m_first_loop_after_window_activation = false;
 +      bool m_camera_offset_changed = false;
 +
 +      bool m_does_lost_focus_pause_game = false;
 +
 +      CameraOrientation cam_view_target  = { 0 };
 +      CameraOrientation cam_view  = { 0 };
 +
 +      int m_reset_HW_buffer_counter = 0;
 +#ifdef __ANDROID__
 +      bool m_cache_hold_aux1;
 +      bool m_android_chat_open;
 +#endif
 +};
 +extern Game *g_game;
  
  void the_game(bool *kill,
                InputHandler *input,
index c97ae93b80bf006aa2985db2ffc1281141327e23,9b77cf6ff148299243c2c94cbce66b92765edce9..66a006ea196cae71925725bb84105933e0897462
@@@ -100,26 -100,10 +103,27 @@@ void GameUI::update(const RunStats &sta
        const CameraOrientation &cam, const PointedThing &pointed_old,
        const GUIChatConsole *chat_console, float dtime)
  {
 +      LocalPlayer *player = client->getEnv().getLocalPlayer();
 +      v3f player_position = player->getPosition();
 +
        v2u32 screensize = RenderingEngine::getWindowSize();
  
-       if (m_flags.show_debug) {
 +      bool show_coords = g_settings->getBool("coords");
 +
 +      if (show_coords) {
 +              std::ostringstream os(std::ios_base::binary);
 +              os << std::setprecision(1) << std::fixed
 +                      << (player_position.X / BS)
 +                      << ", " << (player_position.Y / BS)
 +                      << ", " << (player_position.Z / BS);
 +              setStaticText(m_guitext_coords, utf8_to_wide(os.str()).c_str());
 +              m_guitext_coords->setRelativePosition(core::rect<s32>(5, screensize.Y - 5 - g_fontengine->getTextHeight(), screensize.X, screensize.Y));
 +      }
 +
 +      m_guitext_coords->setVisible(show_coords);
 +
+       // Minimal debug text must only contain info that can't give a gameplay advantage
+       if (m_flags.show_minimal_debug) {
                static float drawtime_avg = 0;
                drawtime_avg = drawtime_avg * 0.95 + stats.drawtime * 0.05;
                u16 fps = 1.0 / stats.dtime_jitter.avg;
@@@ -239,14 -229,15 +248,16 @@@ void GameUI::setChatText(const Enriched
  {
  
        // Update gui element size and position
 -      s32 chat_y = 5;
 +
 +      const v2u32 &window_size = RenderingEngine::getWindowSize();
 +
 +      s32 chat_y = window_size.Y - 150 - m_guitext_chat->getTextHeight();
  
-       if (m_flags.show_debug)
-               chat_y += 2 * g_fontengine->getLineHeight();
+       if (m_flags.show_minimal_debug)
+               chat_y += g_fontengine->getLineHeight();
+       if (m_flags.show_basic_debug)
+               chat_y += g_fontengine->getLineHeight();
  
 -      const v2u32 &window_size = RenderingEngine::getWindowSize();
 -
        core::rect<s32> chat_size(10, chat_y,
                window_size.X - 20, 0);
        chat_size.LowerRightCorner.Y = std::min((s32)window_size.Y,
index f04fd97b8d996accaf2cd6d6569a4a528d2d5645,cb460b1c38adc116dd800a3477a2841346b5ad14..5404643e2321e65a18f8152eaf87e83612d2491b
@@@ -58,9 -58,9 +58,10 @@@ public
                bool show_chat = true;
                bool show_hud = true;
                bool show_minimap = false;
-               bool show_debug = true;
+               bool show_minimal_debug = false;
+               bool show_basic_debug = false;
                bool show_profiler_graph = false;
 +              bool show_cheat_menu = true;
        };
  
        void init();
Simple merge
Simple merge
Simple merge
Simple merge
index 8877e054987da90fd831b04b084a6f892e0196f3,03522eca9326db57e6a91f5c3f512b3ec2a5eb6c..52729632a6c143f0ad93b14e99c6f21f434f8e26
@@@ -805,14 -780,11 +805,14 @@@ static void getTileInfo
        VoxelManipulator &vmanip = data->m_vmanip;
        const NodeDefManager *ndef = data->m_client->ndef();
        v3s16 blockpos_nodes = data->m_blockpos * MAP_BLOCKSIZE;
-       
        const MapNode &n0 = vmanip.getNodeRefUnsafe(blockpos_nodes + p);
  
 +      content_t c0 = n0.getContent();
 +      if (xray && xraySet.find(c0) != xraySet.end())
 +              c0 = CONTENT_AIR;
        // Don't even try to get n1 if n0 is already CONTENT_IGNORE
 -      if (n0.getContent() == CONTENT_IGNORE) {
 +      if (c0 == CONTENT_IGNORE) {
                makes_face = false;
                return;
        }
@@@ -930,11 -899,10 +933,12 @@@ static void updateFastFaceRow
                                        next_makes_face, next_p_corrected,
                                        next_face_dir_corrected, next_lights,
                                        waving,
 -                                      next_tile);
 +                                      next_tile,
 +                                      xray,
 +                                      xraySet);
-                       
-                       if (next_makes_face == makes_face
+                       if (!force_not_tiling
+                                       && next_makes_face == makes_face
                                        && next_p_corrected == p_corrected + translate_dir
                                        && next_face_dir_corrected == face_dir_corrected
                                        && memcmp(next_lights, lights, sizeof(lights)) == 0
@@@ -1070,16 -1032,7 +1074,16 @@@ MapBlockMesh::MapBlockMesh(MeshMakeDat
  
        std::vector<FastFace> fastfaces_new;
        fastfaces_new.reserve(512);
-       
 +      /*
 +              X-Ray
 +      */
 +      bool xray = g_settings->getBool("xray");
 +      std::set<content_t> xraySet, nodeESPSet;
 +      if (xray)
 +              xraySet = splitToContentT(g_settings->get("xray_nodes"), data->m_client->ndef());
-       
++
 +      nodeESPSet = splitToContentT(g_settings->get("node_esp_nodes"), data->m_client->ndef());
        /*
                We are including the faces of the trailing edges of the block.
                This means that when something changes, the caller must
index 99af085f96fdb30d6378a55dd40df5359d7176c9,f151832f34fa00d75e80abac43d89345c5ac9173..1028a96e140a5619b15cda7b0b41e7e03cc2d93d
@@@ -25,9 -24,7 +25,10 @@@ with this program; if not, write to th
  #include "client/clientmap.h"
  #include "client/hud.h"
  #include "client/minimap.h"
 +#include "client/content_cao.h"
 +#include "mapblock.h"
 +#include "mapsector.h"
+ #include "client/shadows/dynamicshadowsrender.h"
  
  RenderingCore::RenderingCore(IrrlichtDevice *_device, Client *_client, Hud *_hud)
        : device(_device), driver(device->getVideoDriver()), smgr(device->getSceneManager()),
@@@ -69,94 -75,14 +79,97 @@@ void RenderingCore::draw(video::SColor 
        show_minimap = _show_minimap;
        draw_wield_tool = _draw_wield_tool;
        draw_crosshair = _draw_crosshair;
-       v3f entity_color = g_settings->getV3F("entity_esp_color");      
 +      draw_entity_esp = g_settings->getBool("enable_entity_esp");
 +      draw_entity_tracers = g_settings->getBool("enable_entity_tracers");
 +      draw_player_esp = g_settings->getBool("enable_player_esp");
 +      draw_player_tracers = g_settings->getBool("enable_player_tracers");
 +      draw_node_esp = g_settings->getBool("enable_node_esp");
 +      draw_node_tracers = g_settings->getBool("enable_node_tracers");
-       
++      v3f entity_color = g_settings->getV3F("entity_esp_color");
 +      v3f player_color = g_settings->getV3F("player_esp_color");
 +      entity_esp_color = video::SColor(255, entity_color.X, entity_color.Y, entity_color.Z);
 +      player_esp_color = video::SColor(255, player_color.X, player_color.Y, player_color.Z);
+       if (shadow_renderer)
+               shadow_renderer->update();
        beforeDraw();
        drawAll();
  }
  
- {     
 +void RenderingCore::drawTracersAndESP()
-       
++{
 +      ClientEnvironment &env = client->getEnv();
 +      Camera *camera = client->getCamera();
-       
++
 +      v3f camera_offset = intToFloat(camera->getOffset(), BS);
-       
++
 +      v3f eye_pos = (camera->getPosition() + camera->getDirection() - camera_offset);
-       
++
 +      video::SMaterial material, oldmaterial;
 +      oldmaterial = driver->getMaterial2D();
 +      material.setFlag(video::EMF_LIGHTING, false);
 +      material.setFlag(video::EMF_BILINEAR_FILTER, false);
 +      material.setFlag(video::EMF_ZBUFFER, false);
 +      material.setFlag(video::EMF_ZWRITE_ENABLE, false);
 +      driver->setMaterial(material);
-       
++
 +      if (draw_entity_esp || draw_entity_tracers || draw_player_esp || draw_player_tracers) {
 +              auto allObjects = env.getAllActiveObjects();
 +              for (auto &it : allObjects) {
 +                      ClientActiveObject *cao = it.second;
 +                      if (cao->isLocalPlayer() || cao->getParent())
 +                              continue;
 +                      GenericCAO *obj = dynamic_cast<GenericCAO *>(cao);
 +                      if (! obj)
 +                              continue;
 +                      bool is_player = obj->isPlayer();
 +                      bool draw_esp = is_player ? draw_player_esp : draw_entity_esp;
 +                      bool draw_tracers = is_player ? draw_player_tracers : draw_entity_tracers;
 +                      video::SColor color = is_player ? player_esp_color : entity_esp_color;
 +                      if (! (draw_esp || draw_tracers))
 +                              continue;
 +                      aabb3f box;
 +                      if (! obj->getSelectionBox(&box))
 +                              continue;
 +                      v3f pos = obj->getPosition() - camera_offset;
 +                      box.MinEdge += pos;
 +                      box.MaxEdge += pos;
 +                      if (draw_esp)
 +                              driver->draw3DBox(box, color);
 +                      if (draw_tracers)
 +                              driver->draw3DLine(eye_pos, box.getCenter(), color);
 +              }
 +      }
 +      if (draw_node_esp || draw_node_tracers) {
 +              Map &map = env.getMap();
 +              std::vector<v3s16> positions;
 +              map.listAllLoadedBlocks(positions);
 +              for (v3s16 blockp : positions) {
 +                      MapBlock *block = map.getBlockNoCreate(blockp);
 +                      if (! block->mesh)
 +                              continue;
 +                      for (v3s16 p : block->mesh->esp_nodes) {
 +                              v3f pos = intToFloat(p, BS) - camera_offset;
 +                              MapNode node = map.getNode(p);
 +                              std::vector<aabb3f> boxes;
 +                              node.getSelectionBoxes(client->getNodeDefManager(), &boxes, node.getNeighbors(p, &map));
 +                              video::SColor color = client->getNodeDefManager()->get(node).minimap_color;
 +                              for (aabb3f box : boxes) {
 +                                      box.MinEdge += pos;
 +                                      box.MaxEdge += pos;
 +                                      if (draw_node_esp)
 +                                              driver->draw3DBox(box, color);
 +                                      if (draw_node_tracers)
 +                                              driver->draw3DLine(eye_pos, box.getCenter(), color);
 +                              }
 +                      }
 +              }
 +      }
++
 +      driver->setMaterial(oldmaterial);
 +}
 +
  void RenderingCore::draw3D()
  {
        smgr->drawAll();
@@@ -176,7 -103,7 +192,7 @@@ void RenderingCore::drawHUD(
        if (show_hud) {
                if (draw_crosshair)
                        hud->drawCrosshair();
--      
++
                hud->drawHotbar(client->getEnv().getLocalPlayer()->getWieldIndex());
                hud->drawLuaElements(camera->getOffset());
                camera->drawNametags();
Simple merge
Simple merge
index 3e784523df62f57332e17b4dcfe548202a5ad8bf,2cb345ba7814e7968fb58deb1ff3bf71f30ef4d9..64335afffecb7a951b4e55ceb109ea725bf67995
@@@ -65,66 -65,9 +65,68 @@@ void set_default_settings(
        settings->setDefault("max_out_chat_queue_size", "20");
        settings->setDefault("pause_on_lost_focus", "false");
        settings->setDefault("enable_register_confirmation", "true");
+       settings->setDefault("clickable_chat_weblinks", "false");
+       settings->setDefault("chat_weblink_color", "#8888FF");
  
 +      // Cheat Menu
 +      settings->setDefault("cheat_menu_font", "FM_Standard");
 +      settings->setDefault("cheat_menu_bg_color", "(45, 45, 68)");
 +      settings->setDefault("cheat_menu_bg_color_alpha", "173");
 +      settings->setDefault("cheat_menu_active_bg_color", "(0, 0, 0)");
 +      settings->setDefault("cheat_menu_active_bg_color_alpha", "210");
 +      settings->setDefault("cheat_menu_font_color", "(255, 255, 255)");
 +      settings->setDefault("cheat_menu_font_color_alpha", "195");
 +      settings->setDefault("cheat_menu_selected_font_color", "(255, 255, 255)");
 +      settings->setDefault("cheat_menu_selected_font_color_alpha", "235");
 +      settings->setDefault("cheat_menu_head_height", "50");
 +      settings->setDefault("cheat_menu_entry_height", "35");
 +      settings->setDefault("cheat_menu_entry_width", "200");
 +
 +      // Cheats
 +      settings->setDefault("xray", "false");
 +      settings->setDefault("xray_nodes", "default:stone,mcl_core:stone");
 +      settings->setDefault("fullbright", "false");
 +      settings->setDefault("priv_bypass", "true");
 +      settings->setDefault("freecam", "false");
 +      settings->setDefault("prevent_natural_damage", "true");
 +      settings->setDefault("freecam", "false");
 +      settings->setDefault("no_hurt_cam", "false");
 +      settings->setDefault("reach", "true");
 +      settings->setDefault("hud_flags_bypass", "true");
 +      settings->setDefault("antiknockback", "false");
 +      settings->setDefault("entity_speed", "false");
 +      settings->setDefault("autodig", "false");
 +      settings->setDefault("fastdig", "false");
 +      settings->setDefault("jesus", "false");
 +      settings->setDefault("fastplace", "false");
 +      settings->setDefault("autoplace", "false");
 +      settings->setDefault("instant_break", "false");
 +      settings->setDefault("no_night", "false");
 +      settings->setDefault("coords", "false");
 +      settings->setDefault("point_liquids", "false");
 +      settings->setDefault("spamclick", "false");
 +      settings->setDefault("no_force_rotate", "false");
 +      settings->setDefault("no_slow", "false");
 +      settings->setDefault("float_above_parent", "false");
 +      settings->setDefault("dont_point_nodes", "false");
 +      settings->setDefault("cheat_hud", "true");
 +      settings->setDefault("node_esp_nodes", "");
 +      settings->setDefault("jetpack", "false");
 +      settings->setDefault("autohit", "false");
 +      settings->setDefault("antislip", "false");
 +      settings->setDefault("enable_entity_esp", "false");
 +      settings->setDefault("enable_entity_tracers", "false");
 +      settings->setDefault("enable_player_esp", "false");
 +      settings->setDefault("enable_player_tracers", "false");
 +      settings->setDefault("enable_node_esp", "false");
 +      settings->setDefault("enable_node_tracers", "false");
 +      settings->setDefault("entity_esp_color", "(255, 255, 255)");
 +      settings->setDefault("player_esp_color", "(0, 255, 0)");
 +      settings->setDefault("tool_range", "2");
 +      settings->setDefault("scaffold", "false");
 +      settings->setDefault("killaura", "false");
 +      settings->setDefault("airjump", "false");
 +
        // Keymap
        settings->setDefault("remote_port", "30000");
        settings->setDefault("keymap_forward", "KEY_KEY_W");
diff --cc src/map.cpp
Simple merge
diff --cc src/map.h
Simple merge
Simple merge
diff --cc src/player.h
Simple merge
index 897ca28626abb640e5c5b39de9775c079c85bd22,5a095fd8f1fb57f0f1247f6e26bc3bec8ea770ff..8ca3a722fb505261977281155d5e661234ddd89d
@@@ -200,11 -197,9 +200,9 @@@ void read_object_properties(lua_State *
        if (getintfield(L, -1, "hp_max", hp_max)) {
                prop->hp_max = (u16)rangelim(hp_max, 0, U16_MAX);
  
 -              if (prop->hp_max < sao->getHP()) {
 +              if (sao && prop->hp_max < sao->getHP()) {
                        PlayerHPChangeReason reason(PlayerHPChangeReason::SET_HP);
                        sao->setHP(prop->hp_max, reason);
-                       if (sao->getType() == ACTIVEOBJECT_TYPE_PLAYER)
-                               sao->getEnv()->getGameDef()->SendPlayerHPOrDie((PlayerSAO *)sao, reason);
                }
        }
  
index dc8f19ef3fc19503e64cefc083b734a7936760e0,e762604a4e0131de61f51653648b6706d44dabf1..1aed7901e835c3db11afe04d29d397d8509d9289
@@@ -120,9 -119,6 +120,9 @@@ void               read_object_properti
  void               push_object_properties    (lua_State *L,
                                                ObjectProperties *prop);
  
-                                               
 +void               push_inventory              (lua_State *L,
 +                                              Inventory *inventory);
++
  void               push_inventory_list       (lua_State *L,
                                                Inventory *inv,
                                                const char *name);
@@@ -197,14 -193,12 +197,14 @@@ void               read_json_valu
  void push_pointed_thing(lua_State *L, const PointedThing &pointed, bool csm =
        false, bool hitpoint = false);
  
- void               push_objectRef            (lua_State *L, const u16 id);
+ void push_objectRef            (lua_State *L, const u16 id);
  
- void               read_hud_element          (lua_State *L, HudElement *elem);
+ void read_hud_element          (lua_State *L, HudElement *elem);
  
- void               push_hud_element          (lua_State *L, HudElement *elem);
+ void push_hud_element          (lua_State *L, HudElement *elem);
  
HudElementStat     read_hud_change           (lua_State *L, HudElement *elem, void **value);
bool read_hud_change           (lua_State *L, HudElementStat &stat, HudElement *elem, void **value);
  
- void               push_collision_move_result(lua_State *L, const collisionMoveResult &res);
+ void push_collision_move_result(lua_State *L, const collisionMoveResult &res);
 +
- void                     push_physics_override         (lua_State *L, float speed, float jump, float gravity, bool sneak, bool sneak_glitch, bool new_move);
++void push_physics_override       (lua_State *L, float speed, float jump, float gravity, bool sneak, bool sneak_glitch, bool new_move);
Simple merge
index a7a2c7203e890a439847a9ae46e3251fdff8d7f4,06df2abe3945860647ee5e62911930ef7755a377..e49745f4e8b6ce860cd0720d873dc375b1e81725
@@@ -108,10 -105,11 +107,12 @@@ public
        ScriptingType getType() { return m_type; }
  #ifndef SERVER
        Client* getClient();
 +      Game *getGame() { return m_game; }
  #endif
  
-       std::string getOrigin() { return m_last_run_mod; }
+       // IMPORTANT: these cannot be used for any security-related uses, they exist
+       // only to enrich error messages
+       const std::string &getOrigin() { return m_last_run_mod; }
        void setOriginDirect(const char *origin);
        void setOriginFromTableRaw(int index, const char *fxn);
  
index 1ed273a3018e21a01a68090ce63237a61b792a56,c889fffa085ffe4dd3aef70cc7a9f5b96b8020bb..5d20f547dad6a04ec5c7220795e5d32a071703d3
@@@ -346,9 -281,22 +399,14 @@@ bool ScriptApiClient::on_inventory_open
        lua_getglobal(L, "core");
        lua_getfield(L, -1, "registered_on_inventory_open");
  
 -      std::vector<const InventoryList*> lists = inventory->getLists();
 -      std::vector<const InventoryList*>::iterator iter = lists.begin();
 -      lua_createtable(L, 0, lists.size());
 -      for (; iter != lists.end(); iter++) {
 -              const char* name = (*iter)->getName().c_str();
 -              lua_pushstring(L, name);
 -              push_inventory_list(L, inventory, name);
 -              lua_rawset(L, -3);
 -      }
 +      push_inventory(L, inventory);
  
-       runCallbacks(1, RUN_CALLBACKS_MODE_OR);
+       try {
+               runCallbacks(1, RUN_CALLBACKS_MODE_OR);
+       } catch (LuaError &e) {
+               getClient()->setFatalError(e);
+               return true;
+       }
        return readParam<bool>(L, -1);
  }
  
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 026f5282c9008fee93b80489aa57be937a6deebc,473faaa14430d7ea2484e12c7253e3311001bbd8..b4672fe2a4a4b69a15429545767da77306a82d8a
@@@ -553,9 -536,7 +537,6 @@@ void ModApiServer::Initialize(lua_Stat
        API_FCT(get_ban_description);
        API_FCT(ban_player);
        API_FCT(kick_player);
 -      API_FCT(remove_player);
        API_FCT(unban_player_or_ip);
        API_FCT(notify_authentication_modified);
-       API_FCT(get_last_run_mod);
-       API_FCT(set_last_run_mod);
  }
index 624828956ca29a85addf414da952d448fdfd07fc,2405cd90dc365e0d052aff1c3d3a51e3c9ea0ada..d575eb6037017e7a6ea0d73501fc58d1fb548922
@@@ -559,9 -625,7 +627,10 @@@ void ModApiUtil::InitializeClient(lua_S
        API_FCT(get_version);
        API_FCT(sha1);
        API_FCT(colorspec_to_colorstring);
+       API_FCT(colorspec_to_bytes);
 +
 +      LuaSettings::create(L, g_settings, g_settings_path);
 +      lua_setfield(L, top, "settings");
  }
  
  void ModApiUtil::InitializeAsync(lua_State *L, int top)
Simple merge
Simple merge
Simple merge