]> git.lizzy.rs Git - dragonfireclient.git/commitdiff
Update to minetest 5.4.0-dev
authorElias Fleckenstein <eliasfleckenstein@web.de>
Sat, 18 Jul 2020 11:53:15 +0000 (13:53 +0200)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Sat, 18 Jul 2020 11:53:15 +0000 (13:53 +0200)
104 files changed:
1  2 
.gitignore
CMakeLists.txt
builtin/common/misc_helpers.lua
builtin/mainmenu/init.lua
builtin/mainmenu/tab_credits.lua
builtin/settingtypes.txt
games/devtest/mods/basetools/.sounds/default_grass_footstep.1.ogg
games/devtest/mods/basetools/sounds/default_break_glass.1.ogg
games/devtest/mods/basetools/sounds/default_break_glass.2.ogg
games/devtest/mods/basetools/sounds/default_break_glass.3.ogg
games/devtest/mods/basetools/sounds/default_chest_close.ogg
games/devtest/mods/basetools/sounds/default_chest_open.ogg
games/devtest/mods/basetools/sounds/default_cool_lava.1.ogg
games/devtest/mods/basetools/sounds/default_cool_lava.2.ogg
games/devtest/mods/basetools/sounds/default_cool_lava.3.ogg
games/devtest/mods/basetools/sounds/default_dig_choppy.ogg
games/devtest/mods/basetools/sounds/default_dig_cracky.ogg
games/devtest/mods/basetools/sounds/default_dig_crumbly.ogg
games/devtest/mods/basetools/sounds/default_dig_dig_immediate.ogg
games/devtest/mods/basetools/sounds/default_dig_metal.ogg
games/devtest/mods/basetools/sounds/default_dig_oddly_breakable_by_hand.ogg
games/devtest/mods/basetools/sounds/default_dig_snappy.ogg
games/devtest/mods/basetools/sounds/default_dirt_footstep.1.ogg
games/devtest/mods/basetools/sounds/default_dirt_footstep.2.ogg
games/devtest/mods/basetools/sounds/default_dug_metal.1.ogg
games/devtest/mods/basetools/sounds/default_dug_metal.2.ogg
games/devtest/mods/basetools/sounds/default_dug_node.1.ogg
games/devtest/mods/basetools/sounds/default_dug_node.2.ogg
games/devtest/mods/basetools/sounds/default_glass_footstep.ogg
games/devtest/mods/basetools/sounds/default_grass_footstep.2.ogg
games/devtest/mods/basetools/sounds/default_grass_footstep.3.ogg
games/devtest/mods/basetools/sounds/default_gravel_footstep.1.ogg
games/devtest/mods/basetools/sounds/default_gravel_footstep.2.ogg
games/devtest/mods/basetools/sounds/default_gravel_footstep.3.ogg
games/devtest/mods/basetools/sounds/default_gravel_footstep.4.ogg
games/devtest/mods/basetools/sounds/default_hard_footstep.1.ogg
games/devtest/mods/basetools/sounds/default_hard_footstep.2.ogg
games/devtest/mods/basetools/sounds/default_hard_footstep.3.ogg
games/devtest/mods/basetools/sounds/default_item_smoke.ogg
games/devtest/mods/basetools/sounds/default_metal_footstep.1.ogg
games/devtest/mods/basetools/sounds/default_metal_footstep.2.ogg
games/devtest/mods/basetools/sounds/default_metal_footstep.3.ogg
games/devtest/mods/basetools/sounds/default_place_node.1.ogg
games/devtest/mods/basetools/sounds/default_place_node.2.ogg
games/devtest/mods/basetools/sounds/default_place_node.3.ogg
games/devtest/mods/basetools/sounds/default_place_node_hard.1.ogg
games/devtest/mods/basetools/sounds/default_place_node_hard.2.ogg
games/devtest/mods/basetools/sounds/default_place_node_metal.1.ogg
games/devtest/mods/basetools/sounds/default_place_node_metal.2.ogg
games/devtest/mods/basetools/sounds/default_sand_footstep.1.ogg
games/devtest/mods/basetools/sounds/default_sand_footstep.2.ogg
games/devtest/mods/basetools/sounds/default_snow_footstep.1.ogg
games/devtest/mods/basetools/sounds/default_snow_footstep.2.ogg
games/devtest/mods/basetools/sounds/default_snow_footstep.3.ogg
games/devtest/mods/basetools/sounds/default_snow_footstep.4.ogg
games/devtest/mods/basetools/sounds/default_snow_footstep.5.ogg
games/devtest/mods/basetools/sounds/default_tool_breaks.1.ogg
games/devtest/mods/basetools/sounds/default_tool_breaks.2.ogg
games/devtest/mods/basetools/sounds/default_tool_breaks.3.ogg
games/devtest/mods/basetools/sounds/default_water_footstep.1.ogg
games/devtest/mods/basetools/sounds/default_water_footstep.2.ogg
games/devtest/mods/basetools/sounds/default_water_footstep.3.ogg
games/devtest/mods/basetools/sounds/default_water_footstep.4.ogg
games/devtest/mods/basetools/sounds/default_wood_footstep.1.ogg
games/devtest/mods/basetools/sounds/default_wood_footstep.2.ogg
games/devtest/mods/basetools/sounds/player_damage.ogg
games/devtest/mods/player_api/README.txt
games/devtest/mods/player_api/api.lua
games/devtest/mods/player_api/init.lua
games/devtest/mods/player_api/license.txt
games/devtest/mods/player_api/mod.conf
games/devtest/mods/player_api/models/character.b3d
games/devtest/mods/player_api/models/character.blend
games/devtest/mods/player_api/models/character.png
games/devtest/mods/player_api/textures/player.png
games/devtest/mods/player_api/textures/player_back.png
src/client/client.cpp
src/client/client.h
src/client/content_cao.cpp
src/client/game.cpp
src/client/game.h
src/client/mapblock_mesh.cpp
src/defaultsettings.cpp
src/network/clientpackethandler.cpp
src/network/networkprotocol.h
src/network/serveropcodes.cpp
src/nodedef.cpp
src/script/common/c_content.cpp
src/script/cpp_api/s_base.cpp
src/script/cpp_api/s_base.h
src/script/cpp_api/s_security.cpp
src/script/lua_api/l_base.cpp
src/script/lua_api/l_base.h
src/script/lua_api/l_client.cpp
src/script/lua_api/l_client.h
src/script/lua_api/l_item.cpp
src/script/lua_api/l_localplayer.cpp
src/script/lua_api/l_localplayer.h
src/script/lua_api/l_server.cpp
src/script/lua_api/l_server.h
src/script/lua_api/l_util.cpp
src/script/scripting_client.cpp
src/server.cpp
src/server.h

diff --cc .gitignore
Simple merge
diff --cc CMakeLists.txt
index 3f36037effafaab559bc9bd2477339c30572857f,fec9709d4b7b33e36c1325b2a0210f28e73f54cd..69424793f249f05bd62950daa412bd9d171cfd2e
@@@ -7,7 -7,7 +7,7 @@@ endif(
  
  # This can be read from ${PROJECT_NAME} after project() is called
  project(minetest)
--set(PROJECT_NAME_CAPITALIZED "Minetest")
++set(PROJECT_NAME_CAPITALIZED "Dragonfire")
  
  # Works only for cmake 3.1 and greater
  set(CMAKE_CXX_STANDARD 11)
Simple merge
Simple merge
Simple merge
Simple merge
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..ce625d92b7bb196dc2f7a3aa642b1c7b1fd96504
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b1ccc5fab1ceba59a7774aa6c88d067348a7f430
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b6cc9e85e2bd39521b4c04adda9d482d20fde87a
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..ae6a6bfc43d53d24668958b3bc52bc79e8fa7630
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..068d9002fb0db2e50ac3155f53fb3d610386c179
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..40b0b93416cbf8a724a255ba202bcbf4ec74f429
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..42506ddffa2cfa4d3177bf13ce1e49b6785ac4b8
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..2747ab81cb56b052ec6c1a9d5fc5bf5357a984ce
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8baeac32ed9941d91ca78903da3ac96cadbe34db
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e2ecd8416aa9d4a65ba144c64ac9f71828dd1340
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..da1167916197f789d30afba2616269d41f6633e9
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..a0b2a1f9f5426fdcb60e7a3142ccc52644666923
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e65d766ee43afeda581a667bb34ddd14d2e78965
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..0b585097a833720ae1a8bea3da50b66987cbed25
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..ef4d7b155c520618b5d19e8194c12dc9c7b68e30
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..3686fcddb5f3caf1ff812943126794cb1c33ceb5
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..201aa3b2daff77452b721edb2f7dfc796fd6cf5c
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..2667dbc210ae6cc70a4ca2da31eb8f471f43af9f
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..5d6cb5b1e715b5411f3c99e2524b9ab7b1f2eaeb
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..63567fc05ae56d13f5a2c6976f2cb1b140ad60ec
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c04975d42e120ace0eafdc94e824fa17492d4a73
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..9f209268ff377db99b55785e897b586742434f60
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..191287a330b5df91982dc109bb75f4fb2a5085f1
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d193068d21e54fa1c1f7761bfa32e2efaf8de749
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e1897ea383afb15f8435cac901e89d08161b66a5
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8d260ce01f4ce05786ce41c994c9db116b310ef2
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..2aba2c652513a7017a9183bf5aa4c67c9602d110
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..1bcd8a117c160a239793c3c8a9ec5c6d4efe65c5
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..696c9ffd2d4493661cab39edc4e60d5cc271a086
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..1748bc56a3a3a32235652cda3f5e31958d0b29e4
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..fe39fd784baef06f360e7d6d37c8ccf113574b70
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..5030e0607ad39446e20ca0792692b68478ef92cb
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..038a46e4f7ba09b151b9a45d9581564c8e836038
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..841286bdc30b7dc65dc2df8e386283df4dec2d35
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..aa61ed3386494085a1d81b587680a23cc888903e
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..4cc1ca47a3f388d6121254bd600205e62f1fff72
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..46b9756de3ecbd38d07d1c4dac5aa59ce23faa10
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d34c01a4329a28a8a4c54f54d004abbe688b8ffd
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..fc2936506476da38669cf8229411c364915027bf
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..9f97facad5abc48e4f2852b952fea91a8931cd32
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..1d3b3de2c78ba8d796f5178313ba273c26209943
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..5da085ea22be01f93c63acb6e74627b6b998c105
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..5ee67fcf605e3804a42579bc665873ee06343135
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..65b68c7e6e42d0ff3d9b13d89f852a942de4a12e
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..57f35f30a26cd2c3d1fcb5b5465b68deea88dcc2
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..97cc8252e99a8cf2a30a4e1602a04ab5b8d82d8c
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..97a6baa483caba104669dd4d6311cdb0fffa2ab5
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..bde1f21d49a618a6da63bafa6f04b94902021edb
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8ca6a590da2645c62a26c46b24515ab8b20baf47
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..220d60c9326c2a1025ddf0b0985bbded37cefd5f
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..2a571ae28d42304ec086ff85779220a8de7fb907
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..178935205d81de3a3b9053d212f2fd127b83cea7
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..a99c4b7e34ad54a62448577846e3b309b725c87f
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..63b9744ce5f53d8fb467245d06cd92680d7d44ea
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8d79c1f4b21f1b45fe9b70e370efe29d1927bd14
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f8891506d3ab866781155ac7abdc063dcb36e637
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..6f1eab8245fdc475451e6eb98186bd6db141fbfd
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..34f63a17c83df7f420835b445ea611386f6a9f08
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..124fc297c8917fd5bd8264947f536b9f74210624
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..788808710c1923c9ae797b7534b66a97dd18dd6d
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..0f6a0b8a50c0b8afb70ba2a07823e49ccf857cff
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,29 @@@
++Minetest Game mod: player_api
++=============================
++See license.txt for license information.
++
++Provides an API to allow multiple mods to set player models and textures.
++Also sets the default model, texture, and player flags.
++This mod is only for content related to the Player API and the player object.
++
++Authors of source code
++----------------------
++Originally by celeron55, Perttu Ahola <celeron55@gmail.com> (LGPLv2.1+)
++Various Minetest developers and contributors (LGPLv2.1+)
++
++Authors of media (textures, models and sounds)
++----------------------------------------------
++stujones11 (CC BY-SA 3.0):
++  character.b3d
++  character.blend -- Both derived from a model by MirceaKitsune (CC BY-SA 3.0)
++
++An0n3m0us (CC BY-SA 3.0):
++  character.b3d
++  character.blend -- Player animation improvement
++
++Jordach (CC BY-SA 3.0):
++  character.png
++
++celeron55, Perttu Ahola <celeron55@gmail.com> (CC BY-SA 3.0):
++  player.png
++  player_back.png
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..5803e954b33945acb256bc59113b3dcd3b2fa332
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,144 @@@
++-- Minetest 0.4 mod: player
++-- See README.txt for licensing and other information.
++
++player_api = {}
++
++-- Player animation blending
++-- Note: This is currently broken due to a bug in Irrlicht, leave at 0
++local animation_blend = 0
++
++player_api.registered_models = { }
++
++-- Local for speed.
++local models = player_api.registered_models
++
++function player_api.register_model(name, def)
++      models[name] = def
++end
++
++-- Player stats and animations
++local player_model = {}
++local player_textures = {}
++local player_anim = {}
++local player_sneak = {}
++player_api.player_attached = {}
++
++function player_api.get_animation(player)
++      local name = player:get_player_name()
++      return {
++              model = player_model[name],
++              textures = player_textures[name],
++              animation = player_anim[name],
++      }
++end
++
++-- Called when a player's appearance needs to be updated
++function player_api.set_model(player, model_name)
++      local name = player:get_player_name()
++      local model = models[model_name]
++      if model then
++              if player_model[name] == model_name then
++                      return
++              end
++              player:set_properties({
++                      mesh = model_name,
++                      textures = player_textures[name] or model.textures,
++                      visual = "mesh",
++                      visual_size = model.visual_size or {x = 1, y = 1},
++                      collisionbox = model.collisionbox or {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3},
++                      stepheight = model.stepheight or 0.6,
++                      eye_height = model.eye_height or 1.47,
++              })
++              player_api.set_animation(player, "stand")
++      else
++              player:set_properties({
++                      textures = {"player.png", "player_back.png"},
++                      visual = "upright_sprite",
++                      visual_size = {x = 1, y = 2},
++                      collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.75, 0.3},
++                      stepheight = 0.6,
++                      eye_height = 1.625,
++              })
++      end
++      player_model[name] = model_name
++end
++
++function player_api.set_textures(player, textures)
++      local name = player:get_player_name()
++      local model = models[player_model[name]]
++      local model_textures = model and model.textures or nil
++      player_textures[name] = textures or model_textures
++      player:set_properties({textures = textures or model_textures,})
++end
++
++function player_api.set_animation(player, anim_name, speed)
++      local name = player:get_player_name()
++      if player_anim[name] == anim_name then
++              return
++      end
++      local model = player_model[name] and models[player_model[name]]
++      if not (model and model.animations[anim_name]) then
++              return
++      end
++      local anim = model.animations[anim_name]
++      player_anim[name] = anim_name
++      player:set_animation(anim, speed or model.animation_speed, animation_blend)
++end
++
++minetest.register_on_leaveplayer(function(player)
++      local name = player:get_player_name()
++      player_model[name] = nil
++      player_anim[name] = nil
++      player_textures[name] = nil
++end)
++
++-- Localize for better performance.
++local player_set_animation = player_api.set_animation
++local player_attached = player_api.player_attached
++
++-- Prevent knockback for attached players
++local old_calculate_knockback = minetest.calculate_knockback
++function minetest.calculate_knockback(player, ...)
++      if player_attached[player:get_player_name()] then
++              return 0
++      end
++      return old_calculate_knockback(player, ...)
++end
++
++-- Check each player and apply animations
++minetest.register_globalstep(function()
++      for _, player in pairs(minetest.get_connected_players()) do
++              local name = player:get_player_name()
++              local model_name = player_model[name]
++              local model = model_name and models[model_name]
++              if model and not player_attached[name] then
++                      local controls = player:get_player_control()
++                      local animation_speed_mod = model.animation_speed or 30
++
++                      -- Determine if the player is sneaking, and reduce animation speed if so
++                      if controls.sneak then
++                              animation_speed_mod = animation_speed_mod / 2
++                      end
++
++                      -- Apply animations based on what the player is doing
++                      if player:get_hp() == 0 then
++                              player_set_animation(player, "lay")
++                      -- Determine if the player is walking
++                      elseif controls.up or controls.down or controls.left or controls.right then
++                              if player_sneak[name] ~= controls.sneak then
++                                      player_anim[name] = nil
++                                      player_sneak[name] = controls.sneak
++                              end
++                              if controls.LMB or controls.RMB then
++                                      player_set_animation(player, "walk_mine", animation_speed_mod)
++                              else
++                                      player_set_animation(player, "walk", animation_speed_mod)
++                              end
++                      elseif controls.LMB or controls.RMB then
++                              player_set_animation(player, "mine", animation_speed_mod)
++                      else
++                              player_set_animation(player, "stand", animation_speed_mod)
++                      end
++              end
++      end
++end)
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..19028de18ff6e0b6aecf21999cadb7c8f65e58b1
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,34 @@@
++-- player/init.lua
++
++dofile(minetest.get_modpath("player_api") .. "/api.lua")
++
++-- Default player appearance
++player_api.register_model("character.b3d", {
++      animation_speed = 30,
++      textures = {"character.png", },
++      animations = {
++              -- Standard animations.
++              stand     = {x = 0,   y = 79},
++              lay       = {x = 162, y = 166},
++              walk      = {x = 168, y = 187},
++              mine      = {x = 189, y = 198},
++              walk_mine = {x = 200, y = 219},
++              sit       = {x = 81,  y = 160},
++      },
++      collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3},
++      stepheight = 0.6,
++      eye_height = 1.47,
++})
++
++-- Update appearance when the player joins
++minetest.register_on_joinplayer(function(player)
++      player_api.player_attached[player:get_player_name()] = false
++      player_api.set_model(player, "character.b3d")
++      player:set_local_animation(
++              {x = 0,   y = 79},
++              {x = 168, y = 187},
++              {x = 189, y = 198},
++              {x = 200, y = 219},
++              30
++      )
++end)
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..dac0408a549bcc42b37ebb19aa85a4fdc2ef09b0
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,53 @@@
++License of source code
++----------------------
++
++GNU Lesser General Public License, version 2.1
++Copyright (C) 2011-2018 celeron55, Perttu Ahola <celeron55@gmail.com>
++Copyright (C) 2011-2018 Various Minetest developers and contributors
++
++This program is free software; you can redistribute it and/or modify it under the terms
++of the GNU Lesser General Public License as published by the Free Software Foundation;
++either version 2.1 of the License, or (at your option) any later version.
++
++This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
++without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
++See the GNU Lesser General Public License for more details:
++https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
++
++
++Licenses of media (textures, models and sounds)
++-----------------------------------------------
++
++Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
++Copyright (C) 2011-2018 celeron55, Perttu Ahola <celeron55@gmail.com>
++Copyright (C) 2012-2018 Jordach
++Copyright (C) 2018 stujones11
++Copyright (C) 2019 An0n3m0us
++
++You are free to:
++Share â€” copy and redistribute the material in any medium or format.
++Adapt â€” remix, transform, and build upon the material for any purpose, even commercially.
++The licensor cannot revoke these freedoms as long as you follow the license terms.
++
++Under the following terms:
++
++Attribution â€” You must give appropriate credit, provide a link to the license, and
++indicate if changes were made. You may do so in any reasonable manner, but not in any way
++that suggests the licensor endorses you or your use.
++
++ShareAlike â€” If you remix, transform, or build upon the material, you must distribute
++your contributions under the same license as the original.
++
++No additional restrictions â€” You may not apply legal terms or technological measures that
++legally restrict others from doing anything the license permits.
++
++Notices:
++
++You do not have to comply with the license for elements of the material in the public
++domain or where your use is permitted by an applicable exception or limitation.
++No warranties are given. The license may not give you all of the permissions necessary
++for your intended use. For example, other rights such as publicity, privacy, or moral
++rights may limit how you use the material.
++
++For more details:
++http://creativecommons.org/licenses/by-sa/3.0/
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..198b86dc1657685c57119c47289ec64d62fded5a
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,2 @@@
++name = player_api
++description = Minetest Game mod: player_api
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8edbaf6377891568c248cd73d2d691f97c775311
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f0ce4117f09231e5e527eab905f8051e226344a3
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..05021781e03fbb71cb309d5ac233c6c90f332fda
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..6d61c4342f39fd8da8330e97117c68a3709483fd
new file mode 100644 (file)
Binary files differ
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..5e9ef05420e51ddd7ad33c13a58e21b1bb86a60a
new file mode 100644 (file)
Binary files differ
Simple merge
Simple merge
index fa2ed43c9b0684b8459a1f03539dc42222d9a666,4f949f6b037f2cd56e3234556e4e2fe6eb7b5253..db78f7a65509edb744c6fd1fdd2f414c2dec52ed
@@@ -791,37 -802,32 +802,35 @@@ void GenericCAO::addToScene(ITextureSou
        setNodeLight(m_last_light);
  }
  
- void GenericCAO::updateLight(u8 light_at_pos)
- {
-       if (g_settings->getBool("fullbright"))
-               light_at_pos = 255;
-               
-       // Don't update light of attached one
-       if (getParent() != NULL) {
+ void GenericCAO::updateLight(u32 day_night_ratio)
 -{
++{             
+       if (m_glow < 0)
                return;
-       }
  
-       updateLightNoCheck(light_at_pos);
+       u8 light_at_pos = 0;
+       bool pos_ok = false;
  
-       // Update light of all children
-       for (u16 i : m_attachment_child_ids) {
-               ClientActiveObject *obj = m_env->getActiveObject(i);
-               if (obj) {
-                       obj->updateLightNoCheck(light_at_pos);
++      if (g_settings->getBool("fullbright"))
++              light_at_pos = 255;
++              
+       v3s16 pos[3];
+       u16 npos = getLightPosition(pos);
+       for (u16 i = 0; i < npos; i++) {
+               bool this_ok;
+               MapNode n = m_env->getMap().getNode(pos[i], &this_ok);
+               if (this_ok) {
+                       u8 this_light = n.getLightBlend(day_night_ratio, m_client->ndef());
+                       light_at_pos = MYMAX(light_at_pos, this_light);
+                       pos_ok = true;
                }
        }
- }
+       if (!pos_ok)
+               light_at_pos = blend_light(day_night_ratio, LIGHT_SUN, 0);
  
- void GenericCAO::updateLightNoCheck(u8 light_at_pos)
- {
-       if (m_glow < 0)
-               return;
-       u8 li = decode_light(light_at_pos + m_glow);
-       if (li != m_last_light) {
-               m_last_light = li;
-               setNodeLight(li);
+       u8 light = decode_light(light_at_pos + m_glow);
+       if (light != m_last_light) {
+               m_last_light = light;
+               setNodeLight(light);
        }
  }
  
index adb8709949f982fad6482a88aef9f5ecebe21d52,42d60b21cdd0712583712edfc028f2efd9eb66bd..6db20d39b4ca9e17516022e8c26540b739e5f59c
@@@ -75,8 -77,847 +77,9 @@@ with this program; if not, write to th
  #else
        #include "client/sound.h"
  #endif
 -/*
 -      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;
 -                      }
 -
 -                      if (fields.find("quit") != fields.end()) {
 -                              return;
 -                      }
 -
 -                      if (fields.find("btn_continue") != fields.end()) {
 -                              return;
 -                      }
 -              }
 -
 -              if (m_formname == "MT_DEATH_SCREEN") {
 -                      assert(m_client != 0);
 -                      m_client->sendRespawn();
 -                      return;
 -              }
 -
 -              if (m_client && 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);
 -      }
 -};
 -
 -
 -// before 1.8 there isn't a "integer interface", only float
 -#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
 -typedef f32 SamplerLayer_t;
 -#else
 -typedef s32 SamplerLayer_t;
 -#endif
 -
 -
 -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, 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;
 -      CachedPixelShaderSetting<SamplerLayer_t> m_texture_flags;
 -      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_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_texture_flags("textureFlags"),
 -              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);
 -      }
 -
 -      virtual void onSetConstants(video::IMaterialRendererServices *services,
 -                      bool is_highlevel)
 -      {
 -              if (!is_highlevel)
 -                      return;
 -
 -              // 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);
 -
 -              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();
 -#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
 -              eye_position_array[0] = epos.X;
 -              eye_position_array[1] = epos.Y;
 -              eye_position_array[2] = epos.Z;
 -#else
 -              epos.getAs3Values(eye_position_array);
 -#endif
 -              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();
 -#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
 -                      minimap_yaw_array[0] = minimap_yaw.X;
 -                      minimap_yaw_array[1] = minimap_yaw.Y;
 -                      minimap_yaw_array[2] = minimap_yaw.Z;
 -#else
 -                      minimap_yaw.getAs3Values(minimap_yaw_array);
 -#endif
 -                      m_minimap_yaw.set(minimap_yaw_array, services);
 -              }
 -
 -              float camera_offset_array[3];
 -              v3f offset = intToFloat(m_client->getCamera()->getOffset(), BS);
 -#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
 -              camera_offset_array[0] = offset.X;
 -              camera_offset_array[1] = offset.Y;
 -              camera_offset_array[2] = offset.Z;
 -#else
 -              offset.getAs3Values(camera_offset_array);
 -#endif
 -              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,
 -                              flags_tex = 2;
 -              m_base_texture.set(&base_tex, services);
 -              m_normal_texture.set(&normal_tex, services);
 -              m_texture_flags.set(&flags_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()
 -      {
 -              GameGlobalShaderConstantSetter *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 ldown_for_dig;
 -      bool dig_instantly;
 -      bool digging_blocked;
 -      bool left_punch;
 -      bool reset_jump_timer;
 -      float nodig_delay_timer;
 -      float dig_time;
 -      float dig_time_complete;
 -      float repeat_rightclick_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 *);
 -};
 -
 -/****************************************************************************
 - THE GAME
 - ****************************************************************************/
 -
 -/* This is not intended to be a public class. If a public class becomes
 - * desirable then it may be better to create another 'wrapper' class that
 - * hides most of the stuff in this class (nothing in this class is required
 - * by any other file) but exposes the public methods/data only.
 - */
 -class Game {
 -public:
 -      Game();
 -      ~Game();
 -
 -      bool startup(bool *kill,
 -                      InputHandler *input,
 -                      const GameStartData &game_params,
 -                      std::string &error_message,
 -                      bool *reconnect,
 -                      ChatBackend *chat_backend);
 -
 -      void run();
 -      void shutdown();
 -
 -protected:
 -
 -      void extendedResourceCleanup();
 -
 -      // 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 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 openConsole(float scale, const wchar_t *line=NULL);
 -      void toggleFreeMove();
 -      void toggleFreeMoveAlt();
 -      void togglePitchMove();
 -      void toggleFast();
 -      void toggleNoClip();
 -      void toggleCinematic();
 -      void toggleAutoforward();
 -
 -      void toggleMinimap(bool shift_pressed);
 -      void toggleFog();
 -      void toggleDebug();
 -      void toggleUpdateCamera();
 -
 -      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);
 -
 -      // Misc
 -      void limitFps(FpsControl *fps_timings, f32 *dtime);
 -
 -      void showOverlayMessage(const char *msg, float dtime, int percent,
 -                      bool draw_clouds = true);
 -
 -      static void settingChangedCallback(const std::string &setting_name, void *data);
 -      void readSettings();
 -
 -      inline bool isKeyDown(GameKeyType k)
 -      {
 -              return input->isKeyDown(k);
 -      }
 -      inline bool wasKeyDown(GameKeyType k)
 -      {
 -              return input->wasKeyDown(k);
 -      }
 -
 -#ifdef __ANDROID__
 -      void handleAndroidChatInput();
 -#endif
 -
 -private:
 -      struct Flags {
 -              bool force_fog_off = false;
 -              bool disable_camera_update = false;
 -      };
 -
 -      void showDeathFormspec();
 -      void showPauseMenu();
 -
 -      // 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);
 -      static const ClientEventHandler clientEventHandler[CLIENTEVENT_MAX];
 -
 -      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()
 -      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;
 -
 -      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;
 -      video::IVideoDriver *driver;
 -      scene::ISceneManager *smgr;
 -      bool *kill;
 -      std::string *error_message;
 -      bool *reconnect_requested;
 -      scene::ISceneNode *skybox;
 -
 -      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_right_click_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;
 -
 -#ifdef __ANDROID__
 -      bool m_cache_hold_aux1;
 -      bool m_android_chat_open;
 -#endif
 -};
  
  Game::Game() :
+       m_chat_log_buf(g_logger),
        m_game_ui(new GameUI())
  {
        g_settings->registerChangedCallback("doubletap_jump",
@@@ -1069,35 -1911,47 +1073,53 @@@ void Game::processKeyInput(
                toggleFast();
        } else if (wasKeyDown(KeyType::NOCLIP)) {
                toggleNoClip();
 +      } else if (wasKeyDown(KeyType::XRAY)) {
 +              toggleXray();
 +      } else if (wasKeyDown(KeyType::FULLBRIGHT)) {
 +              toggleFullbright();
 +      } else if (wasKeyDown(KeyType::KILLAURA)) {
 +              toggleKillaura();
+ #if USE_SOUND
        } else if (wasKeyDown(KeyType::MUTE)) {
-               bool new_mute_sound = !g_settings->getBool("mute_sound");
-               g_settings->setBool("mute_sound", new_mute_sound);
-               if (new_mute_sound)
-                       m_game_ui->showTranslatedStatusText("Sound muted");
-               else
-                       m_game_ui->showTranslatedStatusText("Sound unmuted");
+               if (g_settings->getBool("enable_sound")) {
+                       bool new_mute_sound = !g_settings->getBool("mute_sound");
+                       g_settings->setBool("mute_sound", new_mute_sound);
+                       if (new_mute_sound)
+                               m_game_ui->showTranslatedStatusText("Sound muted");
+                       else
+                               m_game_ui->showTranslatedStatusText("Sound unmuted");
+               } else {
+                       m_game_ui->showTranslatedStatusText("Sound system is disabled");
+               }
        } else if (wasKeyDown(KeyType::INC_VOLUME)) {
-               float new_volume = rangelim(g_settings->getFloat("sound_volume") + 0.1f, 0.0f, 1.0f);
-               wchar_t buf[100];
-               g_settings->setFloat("sound_volume", new_volume);
-               const wchar_t *str = wgettext("Volume changed to %d%%");
-               swprintf(buf, sizeof(buf) / sizeof(wchar_t), str, myround(new_volume * 100));
-               delete[] str;
-               m_game_ui->showStatusText(buf);
+               if (g_settings->getBool("enable_sound")) {
+                       float new_volume = rangelim(g_settings->getFloat("sound_volume") + 0.1f, 0.0f, 1.0f);
+                       wchar_t buf[100];
+                       g_settings->setFloat("sound_volume", new_volume);
+                       const wchar_t *str = wgettext("Volume changed to %d%%");
+                       swprintf(buf, sizeof(buf) / sizeof(wchar_t), str, myround(new_volume * 100));
+                       delete[] str;
+                       m_game_ui->showStatusText(buf);
+               } else {
+                       m_game_ui->showTranslatedStatusText("Sound system is disabled");
+               }
        } else if (wasKeyDown(KeyType::DEC_VOLUME)) {
-               float new_volume = rangelim(g_settings->getFloat("sound_volume") - 0.1f, 0.0f, 1.0f);
-               wchar_t buf[100];
-               g_settings->setFloat("sound_volume", new_volume);
-               const wchar_t *str = wgettext("Volume changed to %d%%");
-               swprintf(buf, sizeof(buf) / sizeof(wchar_t), str, myround(new_volume * 100));
-               delete[] str;
-               m_game_ui->showStatusText(buf);
+               if (g_settings->getBool("enable_sound")) {
+                       float new_volume = rangelim(g_settings->getFloat("sound_volume") - 0.1f, 0.0f, 1.0f);
+                       wchar_t buf[100];
+                       g_settings->setFloat("sound_volume", new_volume);
+                       const wchar_t *str = wgettext("Volume changed to %d%%");
+                       swprintf(buf, sizeof(buf) / sizeof(wchar_t), str, myround(new_volume * 100));
+                       delete[] str;
+                       m_game_ui->showStatusText(buf);
+               } else {
+                       m_game_ui->showTranslatedStatusText("Sound system is disabled");
+               }
+ #else
+       } else if (wasKeyDown(KeyType::MUTE) || wasKeyDown(KeyType::INC_VOLUME)
+                       || wasKeyDown(KeyType::DEC_VOLUME)) {
+               m_game_ui->showTranslatedStatusText("Sound system is not supported on this build");
+ #endif
        } else if (wasKeyDown(KeyType::CINEMATIC)) {
                toggleCinematic();
        } else if (wasKeyDown(KeyType::SCREENSHOT)) {
@@@ -2362,29 -3175,9 +2384,29 @@@ PointedThing Game::updatePointedThing
        ClientMap &map = env.getClientMap();
        const NodeDefManager *nodedef = map.getNodeDefManager();
  
 +      if (g_settings->getBool("killaura")) {
 +              std::vector<DistanceSortedActiveObject> allObjects;
 +              env.getActiveObjects(shootline.start, shootline.getLength() + 10.0f, allObjects);
 +              const v3f line_vector = shootline.getVector();
 +              for (const auto &allObject : allObjects) {
 +                      ClientActiveObject *obj = allObject.obj;
 +                      s16 id = obj->getId();
 +                      v3f pos = obj->getPosition();
 +                      v3f intersection;
 +                      v3s16 normal;
 +                      aabb3f selection_box;
 +                      if (! obj->getSelectionBox(&selection_box))
 +                              continue;
 +                      aabb3f offsetted_box(selection_box.MinEdge + pos, selection_box.MaxEdge + pos);
 +                      boxLineCollision(offsetted_box, shootline.start, line_vector, &intersection, &normal);
 +                      PointedThing pointed(id, intersection, normal, (intersection - shootline.start).getLengthSQ());
 +                      client->interact(INTERACT_START_DIGGING, pointed);
 +                      break;
 +              }
 +      }
 +      
        runData.selected_object = NULL;
-       
+       hud->pointing_at_object = false;
 -
        RaycastState s(shootline, look_for_object, liquids_pointable);
        PointedThing result;
        env.continueRaycast(&s, &result);
@@@ -3451,26 -4245,14 +3479,18 @@@ void Game::showPauseMenu(
   ****************************************************************************/
  /****************************************************************************/
  
 +Game *g_game;
 +
  void the_game(bool *kill,
-               bool random_input,
                InputHandler *input,
-               const std::string &map_dir,
-               const std::string &playername,
-               const std::string &password,
-               const std::string &address,         // If empty local server is created
-               u16 port,
+               const GameStartData &start_data,
                std::string &error_message,
                ChatBackend &chat_backend,
-               bool *reconnect_requested,
-               const SubgameSpec &gamespec,        // Used for local game
-               bool simple_singleplayer_mode)
+               bool *reconnect_requested) // Used for local game
  {
        Game game;
 +      
 +      g_game = &game;
  
        /* Make a copy of the server address because if a local singleplayer server
         * is created then this is updated and we don't want to change the value
index 43b3660577e97c288022b015565be0ba038f3b51,d041532717640a8c1f4109377ca5ee0f297b9d82..cba52e6b43395937eef158c84327796649de02a8
@@@ -92,842 -42,10 +93,844 @@@ struct CameraOrientation 
        f32 camera_pitch;  // "up/down"
  };
  
- void the_game(bool *kill,
-               bool random_input,
-               InputHandler *input,
-               const std::string &map_dir,
-               const std::string &playername,
-               const std::string &password,
-               const std::string &address, // If "", local server is used
-               u16 port,
-               std::string &error_message,
-               ChatBackend &chat_backend,
-               bool *reconnect_requested,
-               const SubgameSpec &gamespec, // Used for local game
-               bool simple_singleplayer_mode);
++/*
++      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;
 +                      }
 +
 +                      if (fields.find("quit") != fields.end()) {
 +                              return;
 +                      }
 +
 +                      if (fields.find("btn_continue") != fields.end()) {
 +                              return;
 +                      }
 +              }
 +
 +              if (m_formname == "MT_DEATH_SCREEN") {
 +                      assert(m_client != 0);
 +                      m_client->sendRespawn();
 +                      return;
 +              }
 +
 +              if (m_client && 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)
++              m_player_step_timer(0),
++              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;
++              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);
 +      }
 +};
 +
 +
 +// before 1.8 there isn't a "integer interface", only float
 +#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
 +typedef f32 SamplerLayer_t;
 +#else
 +typedef s32 SamplerLayer_t;
 +#endif
 +
 +
 +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, 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;
 +      CachedPixelShaderSetting<SamplerLayer_t> m_texture_flags;
 +      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_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_texture_flags("textureFlags"),
 +              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);
 +      }
 +
 +      virtual void onSetConstants(video::IMaterialRendererServices *services,
 +                      bool is_highlevel)
 +      {
 +              if (!is_highlevel)
 +                      return;
 +
 +              // 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);
 +
 +              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();
 +#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
 +              eye_position_array[0] = epos.X;
 +              eye_position_array[1] = epos.Y;
 +              eye_position_array[2] = epos.Z;
 +#else
 +              epos.getAs3Values(eye_position_array);
 +#endif
 +              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();
 +#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
 +                      minimap_yaw_array[0] = minimap_yaw.X;
 +                      minimap_yaw_array[1] = minimap_yaw.Y;
 +                      minimap_yaw_array[2] = minimap_yaw.Z;
 +#else
 +                      minimap_yaw.getAs3Values(minimap_yaw_array);
 +#endif
 +                      m_minimap_yaw.set(minimap_yaw_array, services);
 +              }
 +
 +              float camera_offset_array[3];
 +              v3f offset = intToFloat(m_client->getCamera()->getOffset(), BS);
 +#if (IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8)
 +              camera_offset_array[0] = offset.X;
 +              camera_offset_array[1] = offset.Y;
 +              camera_offset_array[2] = offset.Z;
 +#else
 +              offset.getAs3Values(camera_offset_array);
 +#endif
 +              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,
 +                              flags_tex = 2;
 +              m_base_texture.set(&base_tex, services);
 +              m_normal_texture.set(&normal_tex, services);
 +              m_texture_flags.set(&flags_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()
 +      {
 +              GameGlobalShaderConstantSetter *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 ldown_for_dig;
 +      bool dig_instantly;
 +      bool digging_blocked;
 +      bool left_punch;
 +      bool reset_jump_timer;
 +      float nodig_delay_timer;
 +      float dig_time;
 +      float dig_time_complete;
 +      float repeat_rightclick_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 *);
 +};
 +
 +class Game {
 +public:
 +      Game();
 +      ~Game();
 +
 +      bool startup(bool *kill,
-                       bool random_input,
 +                      InputHandler *input,
-                       const std::string &map_dir,
-                       const std::string &playername,
-                       const std::string &password,
-                       // If address is "", local server is used and address is updated
-                       std::string *address,
-                       u16 port,
++                      const GameStartData &game_params,
 +                      std::string &error_message,
 +                      bool *reconnect,
-                       ChatBackend *chat_backend,
-                       const SubgameSpec &gamespec,    // Used for local game
-                       bool simple_singleplayer_mode);
++                      ChatBackend *chat_backend);
++
 +
 +      void run();
 +      void shutdown();
 +
 +      void extendedResourceCleanup();
 +
 +      // Basic initialisation
 +      bool init(const std::string &map_dir, std::string *address,
 +                      u16 port,
 +                      const SubgameSpec &gamespec);
 +      bool initSound();
 +      bool createSingleplayerServer(const std::string &map_dir,
 +                      const SubgameSpec &gamespec, u16 port, std::string *address);
 +
 +      // Client creation
 +      bool createClient(const std::string &playername,
 +                      const std::string &password, std::string *address, u16 port);
 +      bool initGui();
 +
 +      // Client connection
 +      bool connectToServer(const std::string &playername,
 +                      const std::string &password, std::string *address, u16 port,
 +                      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 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 openConsole(float scale, const wchar_t *line=NULL);
 +      void toggleFreeMove();
 +      void toggleFreeMoveAlt();
 +      void togglePitchMove();
 +      void toggleFast();
 +      void toggleNoClip();
 +      void toggleXray();
 +      void toggleFullbright();
 +      void toggleKillaura();
 +      void toggleCinematic();
 +      void toggleAutoforward();
 +
 +      void toggleMinimap(bool shift_pressed);
 +      void toggleFog();
 +      void toggleDebug();
 +      void toggleUpdateCamera();
 +
 +      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);
 +
 +      // Misc
 +      void limitFps(FpsControl *fps_timings, f32 *dtime);
 +
 +      void showOverlayMessage(const char *msg, float dtime, int percent,
 +                      bool draw_clouds = true);
 +
 +      static void settingChangedCallback(const std::string &setting_name, void *data);
 +      void readSettings();
 +
 +      inline bool isKeyDown(GameKeyType k)
 +      {
 +              return input->isKeyDown(k);
 +      }
 +      inline bool wasKeyDown(GameKeyType k)
 +      {
 +              return input->wasKeyDown(k);
 +      }
 +
 +#ifdef __ANDROID__
 +      void handleAndroidChatInput();
 +#endif
 +
 +      struct Flags {
 +              bool force_fog_off = false;
 +              bool disable_camera_update = false;
 +      };
 +
 +      void showDeathFormspec();
 +      void showPauseMenu();
 +
 +      // 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);
 +      static const ClientEventHandler clientEventHandler[CLIENTEVENT_MAX];
 +
 +      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;
 +
 +      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()
 +      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;
 +
 +      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;
 +      video::IVideoDriver *driver;
 +      scene::ISceneManager *smgr;
 +      bool *kill;
 +      std::string *error_message;
 +      bool *reconnect_requested;
 +      scene::ISceneNode *skybox;
 +
 +      bool random_input;
 +      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_right_click_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;
 +
 +#ifdef __ANDROID__
 +      bool m_cache_hold_aux1;
 +      bool m_android_chat_open;
 +#endif
 +};
 +extern Game *g_game;
+ void the_game(bool *kill,
+               InputHandler *input,
+               const GameStartData &start_data,
+               std::string &error_message,
+               ChatBackend &chat_backend,
+               bool *reconnect_requested);
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc src/nodedef.cpp
Simple merge
Simple merge
Simple merge
index c45bc2c610a1d565afaf827164010386b402e35e,86f7f7bac9fdf1c0b198bc0b29897d55eaf7b161..e2ef1f8749524a4ec542a5c7bb6e6c2cbdc0a356
@@@ -162,8 -159,9 +164,10 @@@ private
        lua_State      *m_luastack = nullptr;
  
        IGameDef       *m_gamedef = nullptr;
 +      Game       *m_game = nullptr;
        Environment    *m_environment = nullptr;
+ #ifndef SERVER
        GUIEngine      *m_guiengine = nullptr;
+ #endif
        ScriptingType  m_type;
  };
Simple merge
Simple merge
index 6a875300481488fd889059564461c02e0998b963,65fce848134e46858a972b565ff49bc7743fd2e1..0cbee7756987c337ba3df7043e97bcef5c9e018a
@@@ -32,7 -32,7 +32,8 @@@ extern "C" 
  
  #ifndef SERVER
  class Client;
 +class Game;
+ class GUIEngine;
  #endif
  
  class ScriptApiBase;
@@@ -45,14 -45,16 +46,16 @@@ class ModApiBase : protected LuaHelper 
  public:
        static ScriptApiBase*   getScriptApiBase(lua_State *L);
        static Server*          getServer(lua_State *L);
+       static ServerInventoryManager *getServerInventoryMgr(lua_State *L);
        #ifndef SERVER
        static Client*          getClient(lua_State *L);
 +      static Game*            getGame(lua_State *L);
+       static GUIEngine*       getGuiEngine(lua_State *L);
        #endif // !SERVER
  
        static IGameDef*        getGameDef(lua_State *L);
 -
        static Environment*     getEnv(lua_State *L);
-       static GUIEngine*       getGuiEngine(lua_State *L);
        // When we are not loading the mod, this function returns "."
        static std::string      getCurrentModPath(lua_State *L);
  
Simple merge
Simple merge
index 99b20b015c394c5b063ad9d80de17a2e5b474221,d67cab76f101bb3d57a4ba40beda11864b1ead28..7e024c899924daaa0ff8c1a70ad3028dadf2ea65
@@@ -24,15 -24,10 +24,16 @@@ with this program; if not, write to th
  #include "common/c_content.h"
  #include "itemdef.h"
  #include "nodedef.h"
 +#include "content_sao.h"
+ #include "server.h"
  #include "inventory.h"
  #include "log.h"
 -
 +#include "script/cpp_api/s_base.h"
 +#ifndef SERVER
 +#include "client/client.h"
 +#include "client/renderingengine.h"
 +#include "client/shader.h"
 +#endif
  
  // garbage collector
  int LuaItemStack::gc_object(lua_State *L)
index 2a87a3b05bbaec91d09c254ee30e36335955484b,851ede53570dda8e68dde7559872017e8b3083b3..bde120c1dab646a6e2de4ef91fbd429347dbe43a
@@@ -23,7 -24,7 +24,8 @@@ with this program; if not, write to th
  #include "client/localplayer.h"
  #include "hud.h"
  #include "common/c_content.h"
 +#include "client/client.h"
+ #include "client/content_cao.h"
  
  LuaLocalPlayer::LuaLocalPlayer(LocalPlayer *m) : m_localplayer(m)
  {
@@@ -218,16 -255,7 +256,18 @@@ int LuaLocalPlayer::l_get_pos(lua_Stat
        return 1;
  }
  
++// set_pos(self, pos)
 +int LuaLocalPlayer::l_set_pos(lua_State *L)
 +{
 +      LocalPlayer *player = getobject(L, 1);
 +      
 +      v3f pos = checkFloatPos(L, 2);
 +      player->setPosition(pos);
 +      getClient(L)->sendPlayerPos();
 +      return 0;
 +}
 +
+ // get_movement_acceleration(self)
  int LuaLocalPlayer::l_get_movement_acceleration(lua_State *L)
  {
        LocalPlayer *player = getobject(L, 1);
@@@ -431,10 -470,10 +482,11 @@@ const luaL_Reg LuaLocalPlayer::methods[
                luamethod(LuaLocalPlayer, get_last_velocity),
                luamethod(LuaLocalPlayer, get_last_look_horizontal),
                luamethod(LuaLocalPlayer, get_last_look_vertical),
-               luamethod(LuaLocalPlayer, get_key_pressed),
+               //
+               luamethod(LuaLocalPlayer, get_control),
                luamethod(LuaLocalPlayer, get_breath),
                luamethod(LuaLocalPlayer, get_pos),
 +              luamethod(LuaLocalPlayer, set_pos),
                luamethod(LuaLocalPlayer, get_movement_acceleration),
                luamethod(LuaLocalPlayer, get_movement_speed),
                luamethod(LuaLocalPlayer, get_movement),
index 13d45a7cb9183c6a58387486e46e6054f983ca4b,4413f2bdb8facb02f861996c6cb8037888905e76..2c9881d58ca6ba2c448e080aa041710ad3c5494f
@@@ -54,19 -63,28 +63,29 @@@ private
        static int l_get_last_velocity(lua_State *L);
        static int l_get_last_look_vertical(lua_State *L);
        static int l_get_last_look_horizontal(lua_State *L);
-       static int l_get_key_pressed(lua_State *L);
  
+       // get_control(self)
+       static int l_get_control(lua_State *L);
+       // get_breath(self)
        static int l_get_breath(lua_State *L);
  
+       // get_pos(self)
        static int l_get_pos(lua_State *L);
 +      static int l_set_pos(lua_State *L);
  
+       // get_movement_acceleration(self)
        static int l_get_movement_acceleration(lua_State *L);
  
+       // get_movement_speed(self)
        static int l_get_movement_speed(lua_State *L);
  
+       // get_movement(self)
        static int l_get_movement(lua_State *L);
  
+       // get_armor_groups(self)
+       static int l_get_armor_groups(lua_State *L);
        // hud_add(self, id, form)
        static int l_hud_add(lua_State *L);
  
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc src/server.cpp
Simple merge
diff --cc src/server.h
Simple merge