mirror of
https://github.com/minetest/minetest.git
synced 2024-07-04 15:05:27 +02:00
Merge b2792e59f735376889de310d844efeac49a7649a into 9a1501ae89ffe79c38dbd6756c9e7ed647dd7dc1
This commit is contained in:
commit
4165e8fb31
@ -10,5 +10,6 @@ dofile(commonpath .. "chatcommands.lua")
|
||||
dofile(commonpath .. "information_formspecs.lua")
|
||||
dofile(clientpath .. "chatcommands.lua")
|
||||
dofile(clientpath .. "death_formspec.lua")
|
||||
dofile(clientpath .. "pause_menu.lua");
|
||||
dofile(clientpath .. "misc.lua")
|
||||
assert(loadfile(commonpath .. "item_s.lua"))({}) -- Just for push/read node functions
|
||||
|
261
builtin/client/pause_menu.lua
Normal file
261
builtin/client/pause_menu.lua
Normal file
@ -0,0 +1,261 @@
|
||||
local SIZE_TAG = "size[11,5.5,true]"
|
||||
|
||||
local function avoid_noid()
|
||||
return "label[1,1;Avoid the Noid!]"
|
||||
end
|
||||
|
||||
local function menu_formspec(simple_singleplayer_mode, is_touchscreen, address)
|
||||
local ypos = simple_singleplayer_mode and 0.7 or 0.1
|
||||
local control_text = ""
|
||||
|
||||
if is_touchscreen then
|
||||
control_text = fgettext([[Controls:
|
||||
No menu open:
|
||||
- slide finger: look around
|
||||
- tap: place/punch/use (default)
|
||||
- long tap: dig/use (default)
|
||||
Menu/inventory open:
|
||||
- double tap (outside):
|
||||
--> close
|
||||
- touch stack, touch slot:
|
||||
--> move stack
|
||||
- touch&drag, tap 2nd finger
|
||||
--> place single item to slot
|
||||
]])
|
||||
end
|
||||
|
||||
local fs = {
|
||||
"formspec_version[1]",
|
||||
SIZE_TAG,
|
||||
("button_exit[4,%f;3,0.5;btn_continue;%s]"):format(ypos, fgettext("Continue"))
|
||||
}
|
||||
ypos = ypos + 1
|
||||
|
||||
if not simple_singleplayer_mode then
|
||||
fs[#fs + 1] = ("button_exit[4,%f;3,0.5;btn_change_password;%s]"):format(
|
||||
ypos, fgettext("Change Password"))
|
||||
else
|
||||
fs[#fs + 1] = "field[4.95,0;5,1.5;;" .. fgettext("Game paused") .. ";]"
|
||||
end
|
||||
|
||||
fs[#fs + 1] = ("button_exit[4,%f;3,0.5;btn_key_config;%s]"):format(
|
||||
ypos, fgettext("Controls"))
|
||||
ypos = ypos + 1
|
||||
fs[#fs + 1] = ("button_exit[4,%f;3,0.5;btn_settings;%s]"):format(
|
||||
ypos, fgettext("Settings"))
|
||||
ypos = ypos + 1
|
||||
fs[#fs + 1] = ("button_exit[4,%f;3,0.5;btn_exit_menu;%s]"):format(
|
||||
ypos, fgettext("Exit to Menu"))
|
||||
ypos = ypos + 1
|
||||
fs[#fs + 1] = ("button_exit[4,%f;3,0.5;btn_exit_os;%s]"):format(
|
||||
ypos, fgettext("Exit to OS"))
|
||||
ypos = ypos + 1
|
||||
|
||||
-- Controls
|
||||
if control_text ~= "" then
|
||||
fs[#fs + 1] = ("textarea[7.5,0.25;3.9,6.25;;%s;]"):format(control_text)
|
||||
end
|
||||
|
||||
-- Server info
|
||||
local info = minetest.get_version()
|
||||
fs[#fs + 1] = ("textarea[0.4,0.25;3.9,6.25;;%s %s\n\n%s\n"):format(
|
||||
info.project, info.hash or info.string, fgettext("Game info:"))
|
||||
|
||||
fs[#fs + 1] = "- Mode: " .. (simple_singleplayer_mode and "Singleplayer" or
|
||||
((not address) and "Hosting server" or "Remote server"))
|
||||
|
||||
if not address then
|
||||
local enable_damage = minetest.settings:get_bool("enable_damage")
|
||||
local enable_pvp = minetest.settings:get_bool("enable_pvp")
|
||||
local server_announce = minetest.settings:get_bool("server_announce")
|
||||
local server_name = minetest.settings:get("server_name")
|
||||
table.insert_all(fs, {
|
||||
"\n",
|
||||
enable_damage and
|
||||
("- PvP: " .. (enable_pvp and "On" or "Off")) or "",
|
||||
"\n",
|
||||
"- Public: " .. (server_announce and "On" or "Off"),
|
||||
"\n",
|
||||
(server_announce and server_name) and
|
||||
("- Server Name: " .. minetest.formspec_escape(server_name)) or ""
|
||||
})
|
||||
end
|
||||
|
||||
fs[#fs + 1] = ";]"
|
||||
|
||||
|
||||
return table.concat(fs, "")
|
||||
end
|
||||
|
||||
function core.show_pause_menu(is_singleplayer, is_touchscreen, address)
|
||||
minetest.show_formspec("builtin:MT_PAUSE_MENU", menu_formspec(is_singleplayer, is_touchscreen, address))
|
||||
end
|
||||
|
||||
core.register_on_formspec_input(function(formname, fields)
|
||||
if formname ~= "builtin:MT_PAUSE_MENU" then return end
|
||||
|
||||
if fields.btn_continue then
|
||||
core.unpause()
|
||||
elseif fields.btn_key_config then
|
||||
core.key_config() -- Don't want this
|
||||
elseif fields.btn_change_password then
|
||||
core.change_password()
|
||||
elseif fields.btn_settings then
|
||||
core.show_settings()
|
||||
elseif fields.btn_exit_menu then
|
||||
core.disconnect()
|
||||
elseif fields.btn_exit_os then
|
||||
core.exit_to_os()
|
||||
end
|
||||
|
||||
return
|
||||
end)
|
||||
|
||||
local scriptpath = core.get_builtin_path()
|
||||
local path = scriptpath.."mainmenu"..DIR_DELIM.."settings"
|
||||
|
||||
function core.get_mainmenu_path()
|
||||
return scriptpath.."mainmenu"
|
||||
end
|
||||
|
||||
defaulttexturedir = ""
|
||||
dofile(path .. DIR_DELIM .. "settingtypes.lua")
|
||||
dofile(path .. DIR_DELIM .. "dlg_change_mapgen_flags.lua")
|
||||
dofile(path .. DIR_DELIM .. "dlg_settings.lua")
|
||||
|
||||
function dialog_create(name, spec, buttonhandler, eventhandler)
|
||||
minetest.show_formspec(name, spec({}))
|
||||
end
|
||||
|
||||
|
||||
local settings_data = {}
|
||||
settings_data.data = {
|
||||
leftscroll = 0,
|
||||
query = "",
|
||||
rightscroll = 0,
|
||||
components = {},
|
||||
page_id = "accessibility"
|
||||
}
|
||||
|
||||
core.register_on_formspec_input(function(formname, fields)
|
||||
if formname ~= "builtin:MT_PAUSE_MENU_SETTINGS" then return true end
|
||||
--local this = data
|
||||
--buttonhandler(settings_data, fields)
|
||||
local dialogdata = settings_data.data
|
||||
dialogdata.leftscroll = core.explode_scrollbar_event(fields.leftscroll).value or dialogdata.leftscroll
|
||||
dialogdata.rightscroll = core.explode_scrollbar_event(fields.rightscroll).value or dialogdata.rightscroll
|
||||
dialogdata.query = fields.search_query
|
||||
local update = false
|
||||
|
||||
if fields.back then
|
||||
this:delete()
|
||||
return true
|
||||
end
|
||||
|
||||
if fields.show_technical_names ~= nil then
|
||||
local value = core.is_yes(fields.show_technical_names)
|
||||
core.settings:set_bool("show_technical_names", value)
|
||||
write_settings_early()
|
||||
update = true
|
||||
--return true
|
||||
end
|
||||
|
||||
if fields.show_advanced ~= nil then
|
||||
local value = core.is_yes(fields.show_advanced)
|
||||
core.settings:set_bool("show_advanced", value)
|
||||
write_settings_early()
|
||||
core.show_settings()
|
||||
update = true
|
||||
end
|
||||
|
||||
-- enable_touch is a checkbox in a setting component. We handle this
|
||||
-- setting differently so we can hide/show pages using the next if-statement
|
||||
if fields.enable_touch ~= nil then
|
||||
local value = core.is_yes(fields.enable_touch)
|
||||
core.settings:set_bool("enable_touch", value)
|
||||
write_settings_early()
|
||||
core.show_settings()
|
||||
update = true
|
||||
end
|
||||
|
||||
if fields.show_advanced ~= nil or fields.enable_touch ~= nil then
|
||||
local suggested_page_id = update_filtered_pages(dialogdata.query)
|
||||
|
||||
dialogdata.components = nil
|
||||
|
||||
if not filtered_page_by_id[dialogdata.page_id] then
|
||||
dialogdata.leftscroll = 0
|
||||
dialogdata.rightscroll = 0
|
||||
|
||||
dialogdata.page_id = suggested_page_id
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
if fields.search or fields.key_enter_field == "search_query" then
|
||||
dialogdata.components = nil
|
||||
dialogdata.leftscroll = 0
|
||||
dialogdata.rightscroll = 0
|
||||
|
||||
dialogdata.page_id = update_filtered_pages(dialogdata.query)
|
||||
|
||||
return true
|
||||
end
|
||||
if fields.search_clear then
|
||||
dialogdata.query = ""
|
||||
dialogdata.components = nil
|
||||
dialogdata.leftscroll = 0
|
||||
dialogdata.rightscroll = 0
|
||||
|
||||
dialogdata.page_id = update_filtered_pages("")
|
||||
return true
|
||||
end
|
||||
|
||||
for _, page in ipairs(all_pages) do
|
||||
if fields["page_" .. page.id] then
|
||||
dialogdata.page_id = page.id
|
||||
dialogdata.components = nil
|
||||
dialogdata.rightscroll = 0
|
||||
core.show_settings()
|
||||
core.reload_graphics()
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
if dialogdata.components then
|
||||
for i, comp in ipairs(dialogdata.components) do
|
||||
if comp.on_submit and comp:on_submit(fields, this) then
|
||||
write_settings_early()
|
||||
core.show_settings()
|
||||
|
||||
-- Clear components so they regenerate
|
||||
--dialogdata.components = nil
|
||||
return true
|
||||
end
|
||||
if comp.setting and fields["reset_" .. i] then
|
||||
core.settings:remove(comp.setting.name)
|
||||
write_settings_early()
|
||||
core.show_settings()
|
||||
|
||||
-- Clear components so they regenerate
|
||||
--dialogdata.components = nil
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if update then
|
||||
core.show_settings()
|
||||
end
|
||||
|
||||
return false
|
||||
end)
|
||||
|
||||
load(true, false)
|
||||
--settings_data.data.page_id = update_filtered_pages("")
|
||||
|
||||
function core.show_settings()
|
||||
show_settings_client_formspec("builtin:MT_PAUSE_MENU_SETTINGS", settings_data.data)
|
||||
core.unpause()
|
||||
end
|
@ -23,13 +23,13 @@ local shadows_component = dofile(core.get_mainmenu_path() .. DIR_DELIM ..
|
||||
"settings" .. DIR_DELIM .. "shadows_component.lua")
|
||||
|
||||
local loaded = false
|
||||
local full_settings
|
||||
full_settings = {}
|
||||
local info_icon_path = core.formspec_escape(defaulttexturedir .. "settings_info.png")
|
||||
local reset_icon_path = core.formspec_escape(defaulttexturedir .. "settings_reset.png")
|
||||
local all_pages = {}
|
||||
local page_by_id = {}
|
||||
local filtered_pages = all_pages
|
||||
local filtered_page_by_id = page_by_id
|
||||
all_pages = {}
|
||||
page_by_id = {}
|
||||
filtered_pages = all_pages
|
||||
filtered_page_by_id = page_by_id
|
||||
|
||||
|
||||
local function get_setting_info(name)
|
||||
@ -99,13 +99,16 @@ local function load_settingtypes()
|
||||
end
|
||||
|
||||
|
||||
local function load()
|
||||
function load(read_all, parse_mods)
|
||||
read_all = read_all == nil and false or read_all
|
||||
parse_mods = parse_mods == nil and true or parse_mods
|
||||
|
||||
if loaded then
|
||||
return
|
||||
end
|
||||
loaded = true
|
||||
|
||||
full_settings = settingtypes.parse_config_file(false, true)
|
||||
full_settings = settingtypes.parse_config_file(read_all, parse_mods)
|
||||
|
||||
local change_keys = {
|
||||
query_text = "Controls",
|
||||
@ -150,6 +153,7 @@ local function load()
|
||||
|
||||
load_settingtypes()
|
||||
|
||||
if page_by_id.controls_keyboard_and_mouse then
|
||||
table.insert(page_by_id.controls_keyboard_and_mouse.content, 1, change_keys)
|
||||
do
|
||||
local content = page_by_id.graphics_and_audio_shaders.content
|
||||
@ -222,6 +226,8 @@ local function load()
|
||||
zh_CN = "中文 (简体) [zh_CN]",
|
||||
zh_TW = "正體中文 (繁體) [zh_TW]",
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
@ -282,7 +288,7 @@ local function filter_page_content(page, query_keywords)
|
||||
end
|
||||
|
||||
|
||||
local function update_filtered_pages(query)
|
||||
function update_filtered_pages(query)
|
||||
filtered_pages = {}
|
||||
filtered_page_by_id = {}
|
||||
|
||||
@ -627,12 +633,14 @@ function write_settings_early()
|
||||
end
|
||||
|
||||
|
||||
local function buttonhandler(this, fields)
|
||||
function buttonhandler(this, fields)
|
||||
local dialogdata = this.data
|
||||
dialogdata.leftscroll = core.explode_scrollbar_event(fields.leftscroll).value or dialogdata.leftscroll
|
||||
dialogdata.rightscroll = core.explode_scrollbar_event(fields.rightscroll).value or dialogdata.rightscroll
|
||||
dialogdata.query = fields.search_query
|
||||
|
||||
minetest.log(dump(fields))
|
||||
|
||||
if fields.back then
|
||||
this:delete()
|
||||
return true
|
||||
@ -703,6 +711,7 @@ local function buttonhandler(this, fields)
|
||||
end
|
||||
end
|
||||
|
||||
if dialogdata.components then
|
||||
for i, comp in ipairs(dialogdata.components) do
|
||||
if comp.on_submit and comp:on_submit(fields, this) then
|
||||
write_settings_early()
|
||||
@ -720,6 +729,7 @@ local function buttonhandler(this, fields)
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
@ -749,3 +759,7 @@ function create_settings_dlg()
|
||||
|
||||
return dlg
|
||||
end
|
||||
|
||||
function show_settings_client_formspec(name, data)
|
||||
minetest.show_formspec(name or "dlg_settings", get_formspec(data))
|
||||
end
|
||||
|
@ -396,10 +396,10 @@ function settingtypes.parse_config_file(read_all, parse_mods)
|
||||
local settings = {}
|
||||
|
||||
do
|
||||
local builtin_path = core.get_builtin_path() .. FILENAME
|
||||
local builtin_path = (core.get_true_builtin_path and core.get_true_builtin_path() or core.get_builtin_path()) .. FILENAME
|
||||
local file = io.open(builtin_path, "r")
|
||||
if not file then
|
||||
core.log("error", "Can't load " .. FILENAME)
|
||||
core.log("error", "Can't load " .. builtin_path)
|
||||
return settings
|
||||
end
|
||||
|
||||
|
@ -228,7 +228,9 @@ class Camera
|
||||
Client *m_client;
|
||||
|
||||
// Default Client FOV (as defined by the "fov" setting)
|
||||
public: // TODO make a setter
|
||||
f32 m_cache_fov;
|
||||
private:
|
||||
|
||||
// Absolute camera position
|
||||
v3f m_camera_position;
|
||||
|
@ -274,6 +274,9 @@ void ClientEnvironment::step(float dtime)
|
||||
// Step object
|
||||
cao->step(dtime, this);
|
||||
|
||||
if (m_update_shadows)
|
||||
cao->updateSceneShadows();
|
||||
|
||||
if (update_lighting)
|
||||
cao->updateLight(day_night_ratio);
|
||||
};
|
||||
@ -296,6 +299,9 @@ void ClientEnvironment::step(float dtime)
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_update_shadows)
|
||||
m_update_shadows = false;
|
||||
}
|
||||
|
||||
void ClientEnvironment::addSimpleObject(ClientSimpleObject *simple)
|
||||
|
@ -142,14 +142,15 @@ class ClientEnvironment : public Environment
|
||||
const std::set<std::string> &getPlayerNames() { return m_player_names; }
|
||||
void addPlayerName(const std::string &name) { m_player_names.insert(name); }
|
||||
void removePlayerName(const std::string &name) { m_player_names.erase(name); }
|
||||
void updateCameraOffset(const v3s16 &camera_offset)
|
||||
{ m_camera_offset = camera_offset; }
|
||||
void updateCameraOffset(const v3s16 &camera_offset) { m_camera_offset = camera_offset; }
|
||||
void requestUpdateShadows() { m_update_shadows = true; }
|
||||
v3s16 getCameraOffset() const { return m_camera_offset; }
|
||||
|
||||
void updateFrameTime(bool is_paused);
|
||||
u64 getFrameTime() const { return m_frame_time; }
|
||||
u64 getFrameTimeDelta() const { return m_frame_dtime; }
|
||||
|
||||
|
||||
private:
|
||||
ClientMap *m_map;
|
||||
LocalPlayer *m_local_player = nullptr;
|
||||
@ -162,6 +163,7 @@ class ClientEnvironment : public Environment
|
||||
IntervalLimiter m_active_object_light_update_interval;
|
||||
std::set<std::string> m_player_names;
|
||||
v3s16 m_camera_offset;
|
||||
bool m_update_shadows = false;
|
||||
u64 m_frame_time = 0;
|
||||
u64 m_frame_dtime = 0;
|
||||
u64 m_frame_time_pause_accumulator = 0;
|
||||
|
@ -62,6 +62,7 @@ class ClientActiveObject : public ActiveObject
|
||||
virtual void updateAttachments() {};
|
||||
|
||||
virtual bool doShowSelectionBox() { return true; }
|
||||
virtual void updateSceneShadows() {}
|
||||
|
||||
// Step object in time
|
||||
virtual void step(float dtime, ClientEnvironment *env) {}
|
||||
|
@ -604,6 +604,17 @@ void GenericCAO::removeFromScene(bool permanent)
|
||||
m_client->getMinimap()->removeMarker(&m_marker);
|
||||
}
|
||||
|
||||
void GenericCAO::updateSceneShadows()
|
||||
{
|
||||
if (scene::ISceneNode *node = getSceneNode()) {
|
||||
if (m_matrixnode)
|
||||
node->setParent(m_matrixnode);
|
||||
|
||||
if (auto shadow = RenderingEngine::get_shadow_renderer())
|
||||
shadow->addNodeToShadowList(node);
|
||||
}
|
||||
}
|
||||
|
||||
void GenericCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr)
|
||||
{
|
||||
m_smgr = smgr;
|
||||
@ -833,6 +844,8 @@ void GenericCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr)
|
||||
if (m_reset_textures_timer < 0)
|
||||
updateTextures(m_current_texture_modifier);
|
||||
|
||||
|
||||
|
||||
if (scene::ISceneNode *node = getSceneNode()) {
|
||||
if (m_matrixnode)
|
||||
node->setParent(m_matrixnode);
|
||||
|
@ -249,6 +249,7 @@ class GenericCAO : public ClientActiveObject
|
||||
}
|
||||
|
||||
void updateLight(u32 day_night_ratio) override;
|
||||
void updateSceneShadows() override;
|
||||
|
||||
void setNodeLight(const video::SColor &light);
|
||||
|
||||
|
@ -149,35 +149,22 @@ struct LocalFormspecHandler : public TextDest
|
||||
|
||||
void gotText(const StringMap &fields)
|
||||
{
|
||||
if (m_formname == "MT_PAUSE_MENU") {
|
||||
if (fields.find("btn_sound") != fields.end()) {
|
||||
g_gamecallback->changeVolume();
|
||||
return;
|
||||
if (m_formname == "MT_PAUSE_MENU_SETTINGS" && false)
|
||||
{
|
||||
// Loop through settings
|
||||
for (auto i : fields)
|
||||
{
|
||||
if (g_settings->existsLocal(i.first) && g_settings->get(i.first) != i.second)
|
||||
{
|
||||
g_settings->set(i.first, i.second);
|
||||
}
|
||||
|
||||
if (fields.find("btn_key_config") != fields.end()) {
|
||||
g_gamecallback->keyConfig();
|
||||
return;
|
||||
if (i.first.rfind("page_", 0) == 0)
|
||||
{
|
||||
//m_client->getScript()->show_settings(i.first.substr(5));
|
||||
}
|
||||
//std::cout << "Setting " << i.first << " set!" << std::endl;
|
||||
|
||||
if (fields.find("btn_exit_menu") != fields.end()) {
|
||||
g_gamecallback->disconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
if (fields.find("btn_exit_os") != fields.end()) {
|
||||
g_gamecallback->exitToOS();
|
||||
#ifndef __ANDROID__
|
||||
RenderingEngine::get_raw_device()->closeDevice();
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (fields.find("btn_change_password") != fields.end()) {
|
||||
g_gamecallback->changePassword();
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -752,6 +739,7 @@ class Game {
|
||||
void updateCameraOrientation(CameraOrientation *cam, float dtime);
|
||||
void updatePlayerControl(const CameraOrientation &cam);
|
||||
void updatePauseState();
|
||||
void reloadGraphics();
|
||||
void step(f32 dtime);
|
||||
void processClientEvents(CameraOrientation *cam);
|
||||
void updateCamera(f32 dtime);
|
||||
@ -1012,6 +1000,8 @@ Game::Game() :
|
||||
&settingChangedCallback, this);
|
||||
g_settings->registerChangedCallback("pause_on_lost_focus",
|
||||
&settingChangedCallback, this);
|
||||
g_settings->registerChangedCallback("fov",
|
||||
&settingChangedCallback, this);
|
||||
|
||||
readSettings();
|
||||
}
|
||||
@ -1137,6 +1127,12 @@ bool Game::startup(bool *kill,
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void Game::reloadGraphics()
|
||||
{
|
||||
m_rendering_engine->initialize(client, hud);
|
||||
client->getEnv().requestUpdateShadows();
|
||||
|
||||
}
|
||||
|
||||
void Game::run()
|
||||
{
|
||||
@ -1813,6 +1809,8 @@ bool Game::getServerContent(bool *aborted)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************
|
||||
Run
|
||||
@ -1871,6 +1869,27 @@ inline bool Game::handleCallbacks()
|
||||
(new GUIKeyChangeMenu(guienv, guiroot, -1,
|
||||
&g_menumgr, texture_src))->drop();
|
||||
g_gamecallback->keyconfig_requested = false;
|
||||
m_is_paused = false;
|
||||
}
|
||||
|
||||
if (g_gamecallback->unpause_requested) {
|
||||
m_is_paused = false;
|
||||
m_rendering_engine->initialize(client, hud);
|
||||
g_gamecallback->unpause_requested = false;
|
||||
}
|
||||
|
||||
if (g_gamecallback->reload_graphics_requested) {
|
||||
reloadGraphics();
|
||||
g_gamecallback->reload_graphics_requested = false;
|
||||
}
|
||||
|
||||
if (g_gamecallback->show_settings_requested) {
|
||||
if (client->modsLoaded())
|
||||
{
|
||||
client->getScript()->show_settings();
|
||||
m_is_paused = false;
|
||||
}
|
||||
g_gamecallback->show_settings_requested = false;
|
||||
}
|
||||
|
||||
if (!g_gamecallback->show_open_url_dialog.empty()) {
|
||||
@ -1907,8 +1926,10 @@ void Game::updateDebugState()
|
||||
m_game_ui->m_flags.show_basic_debug = false;
|
||||
} else if (m_game_ui->m_flags.show_minimal_debug) {
|
||||
if (has_basic_debug)
|
||||
{
|
||||
m_game_ui->m_flags.show_basic_debug = true;
|
||||
}
|
||||
}
|
||||
if (!has_basic_debug)
|
||||
hud->disableBlockBounds();
|
||||
if (!has_debug) {
|
||||
@ -2519,6 +2540,7 @@ void Game::toggleDebug()
|
||||
} else if (!m_game_ui->m_flags.show_profiler_graph && !draw_control->show_wireframe) {
|
||||
if (has_basic_debug)
|
||||
m_game_ui->m_flags.show_basic_debug = true;
|
||||
reloadGraphics();
|
||||
m_game_ui->m_flags.show_profiler_graph = true;
|
||||
m_game_ui->showTranslatedStatusText("Profiler graph shown");
|
||||
} else if (!draw_control->show_wireframe && client->checkPrivilege("debug")) {
|
||||
@ -2751,7 +2773,7 @@ void Game::updatePlayerControl(const CameraOrientation &cam)
|
||||
void Game::updatePauseState()
|
||||
{
|
||||
bool was_paused = this->m_is_paused;
|
||||
this->m_is_paused = this->simple_singleplayer_mode && g_menumgr.pausesGame();
|
||||
//this->m_is_paused = this->simple_singleplayer_mode && g_menumgr.pausesGame();
|
||||
|
||||
if (!was_paused && this->m_is_paused) {
|
||||
this->pauseAnimation();
|
||||
@ -4398,12 +4420,16 @@ void Game::readSettings()
|
||||
m_cache_enable_noclip = g_settings->getBool("noclip");
|
||||
m_cache_enable_free_move = g_settings->getBool("free_move");
|
||||
|
||||
|
||||
m_cache_cam_smoothing = 0;
|
||||
if (g_settings->getBool("cinematic"))
|
||||
m_cache_cam_smoothing = 1 - g_settings->getFloat("cinematic_camera_smoothing");
|
||||
else
|
||||
m_cache_cam_smoothing = 1 - g_settings->getFloat("camera_smoothing");
|
||||
|
||||
if (camera)
|
||||
camera->m_cache_fov = g_settings->getFloat("fov");
|
||||
|
||||
m_cache_cam_smoothing = rangelim(m_cache_cam_smoothing, 0.01f, 1.0f);
|
||||
m_cache_mouse_sensitivity = rangelim(m_cache_mouse_sensitivity, 0.001, 100.0);
|
||||
|
||||
@ -4446,106 +4472,13 @@ void Game::showDeathFormspec()
|
||||
#define GET_KEY_NAME(KEY) gettext(getKeySetting(#KEY).name())
|
||||
void Game::showPauseMenu()
|
||||
{
|
||||
std::string control_text;
|
||||
|
||||
if (g_touchscreengui) {
|
||||
control_text = strgettext("Controls:\n"
|
||||
"No menu open:\n"
|
||||
"- slide finger: look around\n"
|
||||
"- tap: place/punch/use (default)\n"
|
||||
"- long tap: dig/use (default)\n"
|
||||
"Menu/inventory open:\n"
|
||||
"- double tap (outside):\n"
|
||||
" --> close\n"
|
||||
"- touch stack, touch slot:\n"
|
||||
" --> move stack\n"
|
||||
"- touch&drag, tap 2nd finger\n"
|
||||
" --> place single item to slot\n"
|
||||
);
|
||||
if (client->modsLoaded())
|
||||
{
|
||||
client->getScript()->show_pause_menu(simple_singleplayer_mode,
|
||||
g_touchscreengui,
|
||||
client->getAddressName());
|
||||
m_is_paused = true;
|
||||
}
|
||||
|
||||
float ypos = simple_singleplayer_mode ? 0.7f : 0.1f;
|
||||
std::ostringstream os;
|
||||
|
||||
os << "formspec_version[1]" << SIZE_TAG
|
||||
<< "button_exit[4," << (ypos++) << ";3,0.5;btn_continue;"
|
||||
<< strgettext("Continue") << "]";
|
||||
|
||||
if (!simple_singleplayer_mode) {
|
||||
os << "button_exit[4," << (ypos++) << ";3,0.5;btn_change_password;"
|
||||
<< strgettext("Change Password") << "]";
|
||||
} else {
|
||||
os << "field[4.95,0;5,1.5;;" << strgettext("Game paused") << ";]";
|
||||
}
|
||||
|
||||
#ifndef __ANDROID__
|
||||
#if USE_SOUND
|
||||
if (g_settings->getBool("enable_sound")) {
|
||||
os << "button_exit[4," << (ypos++) << ";3,0.5;btn_sound;"
|
||||
<< strgettext("Sound Volume") << "]";
|
||||
}
|
||||
#endif
|
||||
os << "button_exit[4," << (ypos++) << ";3,0.5;btn_key_config;"
|
||||
<< strgettext("Controls") << "]";
|
||||
#endif
|
||||
os << "button_exit[4," << (ypos++) << ";3,0.5;btn_exit_menu;"
|
||||
<< strgettext("Exit to Menu") << "]";
|
||||
os << "button_exit[4," << (ypos++) << ";3,0.5;btn_exit_os;"
|
||||
<< strgettext("Exit to OS") << "]";
|
||||
if (!control_text.empty()) {
|
||||
os << "textarea[7.5,0.25;3.9,6.25;;" << control_text << ";]";
|
||||
}
|
||||
os << "textarea[0.4,0.25;3.9,6.25;;" << PROJECT_NAME_C " " VERSION_STRING "\n"
|
||||
<< "\n"
|
||||
<< strgettext("Game info:") << "\n";
|
||||
const std::string &address = client->getAddressName();
|
||||
os << strgettext("- Mode: ");
|
||||
if (!simple_singleplayer_mode) {
|
||||
if (address.empty())
|
||||
os << strgettext("Hosting server");
|
||||
else
|
||||
os << strgettext("Remote server");
|
||||
} else {
|
||||
os << strgettext("Singleplayer");
|
||||
}
|
||||
os << "\n";
|
||||
if (simple_singleplayer_mode || address.empty()) {
|
||||
static const std::string on = strgettext("On");
|
||||
static const std::string off = strgettext("Off");
|
||||
// Note: Status of enable_damage and creative_mode settings is intentionally
|
||||
// NOT shown here because the game might roll its own damage system and/or do
|
||||
// a per-player Creative Mode, in which case writing it here would mislead.
|
||||
bool damage = g_settings->getBool("enable_damage");
|
||||
const std::string &announced = g_settings->getBool("server_announce") ? on : off;
|
||||
if (!simple_singleplayer_mode) {
|
||||
if (damage) {
|
||||
const std::string &pvp = g_settings->getBool("enable_pvp") ? on : off;
|
||||
//~ PvP = Player versus Player
|
||||
os << strgettext("- PvP: ") << pvp << "\n";
|
||||
}
|
||||
os << strgettext("- Public: ") << announced << "\n";
|
||||
std::string server_name = g_settings->get("server_name");
|
||||
str_formspec_escape(server_name);
|
||||
if (announced == on && !server_name.empty())
|
||||
os << strgettext("- Server Name: ") << server_name;
|
||||
|
||||
}
|
||||
}
|
||||
os << ";]";
|
||||
|
||||
/* Create menu */
|
||||
/* Note: FormspecFormSource and LocalFormspecHandler *
|
||||
* are deleted by guiFormSpecMenu */
|
||||
FormspecFormSource *fs_src = new FormspecFormSource(os.str());
|
||||
LocalFormspecHandler *txt_dst = new LocalFormspecHandler("MT_PAUSE_MENU");
|
||||
|
||||
auto *&formspec = m_game_ui->getFormspecGUI();
|
||||
GUIFormSpecMenu::create(formspec, client, m_rendering_engine->get_gui_env(),
|
||||
&input->joystick, fs_src, txt_dst, client->getFormspecPrepend(),
|
||||
sound_manager.get());
|
||||
formspec->setFocus("btn_continue");
|
||||
// game will be paused in next step, if in singleplayer (see m_is_paused)
|
||||
formspec->doPause = true;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
@ -34,6 +34,9 @@ class IGameCallback
|
||||
virtual void disconnect() = 0;
|
||||
virtual void changePassword() = 0;
|
||||
virtual void changeVolume() = 0;
|
||||
virtual void unpause() = 0;
|
||||
virtual void reloadGraphics() = 0;
|
||||
virtual void showSettings() = 0;
|
||||
virtual void showOpenURLDialog(const std::string &url) = 0;
|
||||
virtual void signalKeyConfigChange() = 0;
|
||||
};
|
||||
@ -147,11 +150,29 @@ class MainGameCallback : public IGameCallback
|
||||
show_open_url_dialog = url;
|
||||
}
|
||||
|
||||
void unpause() override
|
||||
{
|
||||
unpause_requested = true;
|
||||
}
|
||||
|
||||
void reloadGraphics() override
|
||||
{
|
||||
reload_graphics_requested = true;
|
||||
}
|
||||
|
||||
void showSettings() override
|
||||
{
|
||||
show_settings_requested = true;
|
||||
}
|
||||
|
||||
bool disconnect_requested = false;
|
||||
bool changepassword_requested = false;
|
||||
bool changevolume_requested = false;
|
||||
bool keyconfig_requested = false;
|
||||
bool shutdown_requested = false;
|
||||
bool unpause_requested = false;
|
||||
bool reload_graphics_requested = false;
|
||||
bool show_settings_requested = false;
|
||||
bool keyconfig_changed = false;
|
||||
std::string show_open_url_dialog = "";
|
||||
};
|
||||
|
@ -184,6 +184,7 @@ void ScriptApiBase::clientOpenLibs(lua_State *L)
|
||||
{ "", luaopen_base },
|
||||
{ LUA_TABLIBNAME, luaopen_table },
|
||||
{ LUA_OSLIBNAME, luaopen_os },
|
||||
{ LUA_IOLIBNAME, luaopen_io },
|
||||
{ LUA_STRLIBNAME, luaopen_string },
|
||||
{ LUA_MATHLIBNAME, luaopen_math },
|
||||
{ LUA_DBLIBNAME, luaopen_debug },
|
||||
|
@ -290,6 +290,39 @@ bool ScriptApiClient::on_inventory_open(Inventory *inventory)
|
||||
return readParam<bool>(L, -1);
|
||||
}
|
||||
|
||||
void ScriptApiClient::show_pause_menu(bool is_singleplayer, bool is_touchscreen, const std::string& server_address)
|
||||
{
|
||||
SCRIPTAPI_PRECHECKHEADER
|
||||
|
||||
int error_handler = PUSH_ERROR_HANDLER(L);
|
||||
|
||||
lua_getglobal(L, "core");
|
||||
lua_getfield(L, -1, "show_pause_menu");
|
||||
|
||||
lua_pushboolean(L, is_singleplayer);
|
||||
lua_pushboolean(L, is_touchscreen);
|
||||
if (!server_address.empty())
|
||||
lua_pushstring(L, server_address.c_str());
|
||||
else
|
||||
lua_pushnil(L);
|
||||
|
||||
PCALL_RES(lua_pcall(L, 3, 0, error_handler));
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
void ScriptApiClient::show_settings()
|
||||
{
|
||||
SCRIPTAPI_PRECHECKHEADER
|
||||
|
||||
int error_handler = PUSH_ERROR_HANDLER(L);
|
||||
|
||||
lua_getglobal(L, "core");
|
||||
lua_getfield(L, -1, "show_settings");
|
||||
|
||||
PCALL_RES(lua_pcall(L, 0, 0, error_handler));
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
void ScriptApiClient::setEnv(ClientEnvironment *env)
|
||||
{
|
||||
ScriptApiBase::setEnv(env);
|
||||
|
@ -60,5 +60,8 @@ class ScriptApiClient : virtual public ScriptApiBase
|
||||
|
||||
bool on_inventory_open(Inventory *inventory);
|
||||
|
||||
void show_pause_menu(bool is_singleplayer, bool is_touchscreen, const std::string& server_address);
|
||||
void show_settings();
|
||||
|
||||
void setEnv(ClientEnvironment *env);
|
||||
};
|
||||
|
@ -112,6 +112,7 @@ void ScriptApiSecurity::initializeSecurity()
|
||||
"bit"
|
||||
};
|
||||
static const char *io_whitelist[] = {
|
||||
"open",
|
||||
"close",
|
||||
"flush",
|
||||
"read",
|
||||
@ -310,6 +311,14 @@ void ScriptApiSecurity::initializeSecurityClient()
|
||||
"difftime",
|
||||
"time"
|
||||
};
|
||||
static const char *io_whitelist[] = {
|
||||
"close",
|
||||
"open",
|
||||
"flush",
|
||||
"read",
|
||||
"type",
|
||||
"write",
|
||||
};
|
||||
static const char *debug_whitelist[] = {
|
||||
"getinfo", // used by builtin and unset before mods load
|
||||
"traceback"
|
||||
@ -359,6 +368,13 @@ void ScriptApiSecurity::initializeSecurityClient()
|
||||
lua_setfield(L, -3, "os");
|
||||
lua_pop(L, 1); // Pop old OS
|
||||
|
||||
// Copy safe OS functions
|
||||
lua_getglobal(L, "io");
|
||||
lua_newtable(L);
|
||||
copy_safe(L, io_whitelist, sizeof(io_whitelist));
|
||||
lua_setfield(L, -3, "io");
|
||||
lua_pop(L, 1); // Pop old IO
|
||||
|
||||
|
||||
// Copy safe debug functions
|
||||
lua_getglobal(L, "debug");
|
||||
@ -530,6 +546,7 @@ bool ScriptApiSecurity::checkWhitelisted(lua_State *L, const std::string &settin
|
||||
bool ScriptApiSecurity::checkPath(lua_State *L, const char *path,
|
||||
bool write_required, bool *write_allowed)
|
||||
{
|
||||
return true;
|
||||
if (write_allowed)
|
||||
*write_allowed = false;
|
||||
|
||||
@ -810,6 +827,7 @@ int ScriptApiSecurity::sl_io_open(lua_State *L)
|
||||
|
||||
luaL_checktype(L, 1, LUA_TSTRING);
|
||||
const char *path = lua_tostring(L, 1);
|
||||
std::cout << "Opening " << path << std::endl;
|
||||
|
||||
bool write_requested = false;
|
||||
if (with_mode) {
|
||||
|
@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "client/client.h"
|
||||
#include "client/clientevent.h"
|
||||
#include "client/sound.h"
|
||||
#include "client/renderingengine.h"
|
||||
#include "client/clientenvironment.h"
|
||||
#include "common/c_content.h"
|
||||
#include "common/c_converter.h"
|
||||
@ -178,6 +179,35 @@ int ModApiClient::l_disconnect(lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
// unpause()
|
||||
int ModApiClient::l_unpause(lua_State *L)
|
||||
{
|
||||
g_gamecallback->unpause();
|
||||
//lua_pushboolean(L, true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ModApiClient::l_exit_to_os(lua_State *L)
|
||||
{
|
||||
g_gamecallback->exitToOS();
|
||||
#ifndef __ANDROID__
|
||||
RenderingEngine::get_raw_device()->closeDevice();
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ModApiClient::l_reload_graphics(lua_State *L)
|
||||
{
|
||||
g_gamecallback->reloadGraphics();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ModApiClient::l_key_config(lua_State *L)
|
||||
{
|
||||
g_gamecallback->keyConfig();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// gettext(text)
|
||||
int ModApiClient::l_gettext(lua_State *L)
|
||||
{
|
||||
@ -322,6 +352,20 @@ int ModApiClient::l_get_privilege_list(lua_State *L)
|
||||
int ModApiClient::l_get_builtin_path(lua_State *L)
|
||||
{
|
||||
lua_pushstring(L, BUILTIN_MOD_NAME ":");
|
||||
//NO_MAP_LOCK_REQUIRED;
|
||||
|
||||
//std::string path = porting::path_share + "/" + "builtin" + DIR_DELIM;
|
||||
//lua_pushstring(L, path.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
#include "filesys.h"
|
||||
int ModApiClient::l_get_true_builtin_path(lua_State* L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
|
||||
std::string path = porting::path_share + DIR_DELIM + "builtin" + DIR_DELIM;
|
||||
lua_pushstring(L, path.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -352,12 +396,17 @@ void ModApiClient::Initialize(lua_State *L, int top)
|
||||
API_FCT(gettext);
|
||||
API_FCT(get_node_or_nil);
|
||||
API_FCT(disconnect);
|
||||
API_FCT(unpause);
|
||||
API_FCT(exit_to_os);
|
||||
API_FCT(reload_graphics);
|
||||
API_FCT(key_config);
|
||||
API_FCT(get_meta);
|
||||
API_FCT(get_server_info);
|
||||
API_FCT(get_item_def);
|
||||
API_FCT(get_node_def);
|
||||
API_FCT(get_privilege_list);
|
||||
API_FCT(get_builtin_path);
|
||||
API_FCT(get_true_builtin_path);
|
||||
API_FCT(get_language);
|
||||
API_FCT(get_csm_restrictions);
|
||||
}
|
||||
|
@ -51,6 +51,18 @@ class ModApiClient : public ModApiBase
|
||||
// show_formspec(name, formspec)
|
||||
static int l_show_formspec(lua_State *L);
|
||||
|
||||
// unpause()
|
||||
static int l_unpause(lua_State *L);
|
||||
|
||||
// exit_to_os()
|
||||
static int l_exit_to_os(lua_State *L);
|
||||
|
||||
// reload_graphics()
|
||||
static int l_reload_graphics(lua_State *L);
|
||||
|
||||
// key_config()
|
||||
static int l_key_config(lua_State *L);
|
||||
|
||||
// send_respawn()
|
||||
static int l_send_respawn(lua_State *L);
|
||||
|
||||
@ -87,6 +99,9 @@ class ModApiClient : public ModApiBase
|
||||
// get_builtin_path()
|
||||
static int l_get_builtin_path(lua_State *L);
|
||||
|
||||
// get_true_builtin_path()
|
||||
static int l_get_true_builtin_path(lua_State *L);
|
||||
|
||||
// get_csm_restrictions()
|
||||
static int l_get_csm_restrictions(lua_State *L);
|
||||
|
||||
|
@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "lua_api/l_localplayer.h"
|
||||
#include "lua_api/l_camera.h"
|
||||
#include "lua_api/l_settings.h"
|
||||
#include "lua_api/l_mainmenu.h"
|
||||
#include "lua_api/l_client_sound.h"
|
||||
|
||||
ClientScripting::ClientScripting(Client *client):
|
||||
@ -77,6 +78,7 @@ void ClientScripting::InitializeModApi(lua_State *L, int top)
|
||||
LuaSettings::Register(L);
|
||||
ClientSoundHandle::Register(L);
|
||||
|
||||
|
||||
ModApiUtil::InitializeClient(L, top);
|
||||
ModApiClient::Initialize(L, top);
|
||||
ModApiItem::InitializeClient(L, top);
|
||||
@ -85,6 +87,9 @@ void ClientScripting::InitializeModApi(lua_State *L, int top)
|
||||
ModApiChannels::Initialize(L, top);
|
||||
ModApiParticlesLocal::Initialize(L, top);
|
||||
ModApiClientSound::Initialize(L, top);
|
||||
|
||||
ModApiMainMenu::Initialize(L, top);
|
||||
|
||||
}
|
||||
|
||||
void ClientScripting::on_client_ready(LocalPlayer *localplayer)
|
||||
|
@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include "cpp_api/s_client.h"
|
||||
#include "cpp_api/s_modchannels.h"
|
||||
#include "cpp_api/s_security.h"
|
||||
#include "cpp_api/s_mainmenu.h"
|
||||
|
||||
class Client;
|
||||
class LocalPlayer;
|
||||
@ -34,7 +35,8 @@ class ClientScripting:
|
||||
virtual public ScriptApiBase,
|
||||
public ScriptApiSecurity,
|
||||
public ScriptApiClient,
|
||||
public ScriptApiModChannels
|
||||
public ScriptApiModChannels,
|
||||
public ScriptApiMainMenu
|
||||
{
|
||||
public:
|
||||
ClientScripting(Client *client);
|
||||
|
Loading…
Reference in New Issue
Block a user