summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorred-001 <red-001@outlook.ie>2017-01-24 16:26:15 +0000
committerLoïc Blot <nerzhul@users.noreply.github.com>2017-03-13 23:56:05 +0100
commitc42c53fccf87a3819ca78de52f8f20c47c4fbb9f (patch)
tree223bb0b18e989cfe7eb8f7d712bd606976be2c77
parent2c19d51409ca903021e0b508e5bc15299c4e51dc (diff)
downloadminetest-c42c53fccf87a3819ca78de52f8f20c47c4fbb9f.tar.gz
minetest-c42c53fccf87a3819ca78de52f8f20c47c4fbb9f.tar.bz2
minetest-c42c53fccf87a3819ca78de52f8f20c47c4fbb9f.zip
[CSM] Add local formspecs. (#5094)
-rw-r--r--builtin/client/init.lua10
-rw-r--r--builtin/client/preview.lua2
-rw-r--r--builtin/client/register.lua1
-rw-r--r--builtin/common/misc_helpers.lua3
-rw-r--r--doc/client_lua_api.txt15
-rw-r--r--src/client.h6
-rw-r--r--src/game.cpp67
-rw-r--r--src/guiFormSpecMenu.h4
-rw-r--r--src/script/cpp_api/s_client.cpp24
-rw-r--r--src/script/cpp_api/s_client.h7
-rw-r--r--src/script/lua_api/l_client.cpp45
-rw-r--r--src/script/lua_api/l_client.h9
12 files changed, 126 insertions, 67 deletions
diff --git a/builtin/client/init.lua b/builtin/client/init.lua
index dd218aab6..b204ee5e6 100644
--- a/builtin/client/init.lua
+++ b/builtin/client/init.lua
@@ -6,8 +6,18 @@ local commonpath = scriptpath.."common"..DIR_DELIM
dofile(clientpath .. "register.lua")
dofile(commonpath .. "after.lua")
dofile(commonpath .. "chatcommands.lua")
+dofile(clientpath .. "chatcommands.lua")
dofile(clientpath .. "preview.lua")
core.register_on_death(function()
core.display_chat_message("You died.")
+ local formspec = "size[11,5.5]bgcolor[#320000b4;true]" ..
+ "label[4.85,1.35;" .. fgettext("You died.") .. "]button_exit[4,3;3,0.5;btn_respawn;".. fgettext("Respawn") .."]"
+ core.show_formspec("bultin:death", formspec)
+end)
+
+core.register_on_formspec_input(function(formname, fields)
+ if formname == "bultin:death" then
+ core.send_respawn()
+ end
end)
diff --git a/builtin/client/preview.lua b/builtin/client/preview.lua
index 22e8bb97f..4c01d665f 100644
--- a/builtin/client/preview.lua
+++ b/builtin/client/preview.lua
@@ -32,7 +32,7 @@ end)
-- This is an example function to ensure it's working properly, should be removed before merge
core.register_chatcommand("dump", {
- func = function(name, param)
+ func = function(param)
return true, dump(_G)
end,
})
diff --git a/builtin/client/register.lua b/builtin/client/register.lua
index 8b60c1222..1e6ac4342 100644
--- a/builtin/client/register.lua
+++ b/builtin/client/register.lua
@@ -62,5 +62,6 @@ core.registered_on_sending_chat_messages, core.register_on_sending_chat_messages
core.registered_on_death, core.register_on_death = make_registration()
core.registered_on_hp_modification, core.register_on_hp_modification = make_registration()
core.registered_on_damage_taken, core.register_on_damage_taken = make_registration()
+core.registered_on_formspec_input, core.register_on_formspec_input = make_registration()
diff --git a/builtin/common/misc_helpers.lua b/builtin/common/misc_helpers.lua
index c2dc7514d..70b23600a 100644
--- a/builtin/common/misc_helpers.lua
+++ b/builtin/common/misc_helpers.lua
@@ -606,7 +606,9 @@ if INIT == "mainmenu" then
return nil
end
+end
+if INIT == "client" or INIT == "mainmenu" then
function fgettext_ne(text, ...)
text = core.gettext(text)
local arg = {n=select('#', ...), ...}
@@ -636,4 +638,3 @@ if INIT == "mainmenu" then
return core.formspec_escape(fgettext_ne(text, ...))
end
end
-
diff --git a/doc/client_lua_api.txt b/doc/client_lua_api.txt
index 8ce487bf8..3170f4c84 100644
--- a/doc/client_lua_api.txt
+++ b/doc/client_lua_api.txt
@@ -699,7 +699,10 @@ Call these functions only at load time!
* Called when server modified player's HP
* `minetest.register_on_damage_taken(func(hp))`
* Called when player take damages
-
+* `minetest.register_on_formspec_input(func(formname, fields))`
+ * Called when a button is pressed in player's inventory form
+ * Newest functions are called first
+ * If function returns `true`, remaining functions are not called
### Sounds
* `minetest.sound_play(spec, parameters)`: returns a handle
* `spec` is a `SimpleSoundSpec`
@@ -754,7 +757,15 @@ Call these functions only at load time!
* Encodes a string in base64.
* `minetest.decode_base64(string)`: returns string
* Decodes a string encoded in base64.
-
+* `core.gettext(string) : returns string
+ * look up the translation of a string in the gettext message catalog
+* `fgettext_ne(string, ...)`
+ * call core.gettext(string), replace "$1"..."$9" with the given
+ extra arguments and return the result
+* `fgettext(string, ...)` : returns string
+ * same as fgettext_ne(), but calls core.formspec_escape before returning result
+* `show_formspec(formname, formspec)` : returns true on success
+ * Shows a formspec to the player
Class reference
---------------
diff --git a/src/client.h b/src/client.h
index ff8aea591..d170f9a07 100644
--- a/src/client.h
+++ b/src/client.h
@@ -142,6 +142,7 @@ enum ClientEventType
CE_PLAYER_FORCE_MOVE,
CE_DEATHSCREEN,
CE_SHOW_FORMSPEC,
+ CE_SHOW_LOCAL_FORMSPEC,
CE_SPAWN_PARTICLE,
CE_ADD_PARTICLESPAWNER,
CE_DELETE_PARTICLESPAWNER,
@@ -570,6 +571,11 @@ public:
ClientScripting *getScript() { return m_script; }
+ inline void pushToEventQueue(const ClientEvent &event)
+ {
+ m_client_event_queue.push(event);
+ }
+
private:
// Virtual methods from con::PeerHandler
diff --git a/src/game.cpp b/src/game.cpp
index 2e2a8e0c1..c84e08b01 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -125,6 +125,7 @@ struct TextDestPlayerInventory : public TextDest {
struct LocalFormspecHandler : public TextDest {
LocalFormspecHandler();
+
LocalFormspecHandler(std::string formname) :
m_client(0)
{
@@ -178,39 +179,7 @@ struct LocalFormspecHandler : public TextDest {
return;
}
}
-
- if (m_formname == "MT_DEATH_SCREEN") {
- assert(m_client != 0);
-
- if ((fields.find("btn_respawn") != fields.end())) {
- m_client->sendRespawn();
- return;
- }
-
- if (fields.find("quit") != fields.end()) {
- m_client->sendRespawn();
- return;
- }
- }
-
- // don't show error message for unhandled cursor keys
- if ((fields.find("key_up") != fields.end()) ||
- (fields.find("key_down") != fields.end()) ||
- (fields.find("key_left") != fields.end()) ||
- (fields.find("key_right") != fields.end())) {
- return;
- }
-
- errorstream << "LocalFormspecHandler::gotText unhandled >"
- << m_formname << "< event" << std::endl;
-
- int i = 0;
- StringMap::const_iterator it;
- for (it = fields.begin(); it != fields.end(); ++it) {
- errorstream << "\t" << i << ": " << it->first
- << "=" << it->second << std::endl;
- i++;
- }
+ m_client->getScript()->on_formspec_input(m_formname, fields);
}
Client *m_client;
@@ -956,28 +925,6 @@ static inline void create_formspec_menu(GUIFormSpecMenu **cur_formspec,
#define SIZE_TAG "size[11,5.5,true]" // Fixed size on desktop
#endif
-static void show_deathscreen(GUIFormSpecMenu **cur_formspec,
- Client *client,
- IWritableTextureSource *tsrc, IrrlichtDevice *device,
- JoystickController *joystick)
-{
- std::string formspec =
- std::string(FORMSPEC_VERSION_STRING) +
- SIZE_TAG
- "bgcolor[#320000b4;true]"
- "label[4.85,1.35;" + gettext("You died.") + "]"
- "button_exit[4,3;3,0.5;btn_respawn;" + gettext("Respawn") + "]"
- ;
-
- /* Create menu */
- /* Note: FormspecFormSource and LocalFormspecHandler
- * are deleted by guiFormSpecMenu */
- FormspecFormSource *fs_src = new FormspecFormSource(formspec);
- LocalFormspecHandler *txt_dst = new LocalFormspecHandler("MT_DEATH_SCREEN", client);
-
- create_formspec_menu(cur_formspec, client, device, joystick, fs_src, txt_dst);
-}
-
/******************************************************************************/
static void show_pause_menu(GUIFormSpecMenu **cur_formspec,
Client *client,
@@ -3255,9 +3202,6 @@ void Game::processClientEvents(CameraOrientation *cam, float *damage_flash)
cam->camera_yaw = event.player_force_move.yaw;
cam->camera_pitch = event.player_force_move.pitch;
} else if (event.type == CE_DEATHSCREEN) {
- show_deathscreen(&current_formspec, client, texture_src,
- device, &input->joystick);
-
client->getScript()->on_death();
/* Handle visualization */
@@ -3283,6 +3227,13 @@ void Game::processClientEvents(CameraOrientation *cam, float *damage_flash)
delete(event.show_formspec.formspec);
delete(event.show_formspec.formname);
+ } else if (event.type == CE_SHOW_LOCAL_FORMSPEC) {
+ FormspecFormSource *fs_src = new FormspecFormSource(*event.show_formspec.formspec);
+ LocalFormspecHandler *txt_dst = new LocalFormspecHandler(*event.show_formspec.formname, client);
+ create_formspec_menu(&current_formspec, client, device, &input->joystick,
+ fs_src, txt_dst);
+ delete event.show_formspec.formspec;
+ delete event.show_formspec.formname;
} else if ((event.type == CE_SPAWN_PARTICLE) ||
(event.type == CE_ADD_PARTICLESPAWNER) ||
(event.type == CE_DELETE_PARTICLESPAWNER)) {
diff --git a/src/guiFormSpecMenu.h b/src/guiFormSpecMenu.h
index bbab9c164..35365a94b 100644
--- a/src/guiFormSpecMenu.h
+++ b/src/guiFormSpecMenu.h
@@ -548,7 +548,7 @@ private:
class FormspecFormSource: public IFormSource
{
public:
- FormspecFormSource(std::string formspec)
+ FormspecFormSource(const std::string &formspec)
{
m_formspec = formspec;
}
@@ -556,7 +556,7 @@ public:
~FormspecFormSource()
{}
- void setForm(std::string formspec) {
+ void setForm(const std::string &formspec) {
m_formspec = FORMSPEC_VERSION_STRING + formspec;
}
diff --git a/src/script/cpp_api/s_client.cpp b/src/script/cpp_api/s_client.cpp
index ce88d67e3..1827d483b 100644
--- a/src/script/cpp_api/s_client.cpp
+++ b/src/script/cpp_api/s_client.cpp
@@ -112,3 +112,27 @@ void ScriptApiClient::environment_step(float dtime)
+ script_get_backtrace(L));
}
}
+
+void ScriptApiClient::on_formspec_input(const std::string &formname,
+ const StringMap &fields)
+{
+ SCRIPTAPI_PRECHECKHEADER
+
+ // Get core.registered_on_chat_messages
+ lua_getglobal(L, "core");
+ lua_getfield(L, -1, "registered_on_formspec_input");
+ // Call callbacks
+ // param 1
+ lua_pushstring(L, formname.c_str());
+ // param 2
+ lua_newtable(L);
+ StringMap::const_iterator it;
+ for (it = fields.begin(); it != fields.end(); ++it) {
+ const std::string &name = it->first;
+ const std::string &value = it->second;
+ lua_pushstring(L, name.c_str());
+ lua_pushlstring(L, value.c_str(), value.size());
+ lua_settable(L, -3);
+ }
+ runCallbacks(2, RUN_CALLBACKS_MODE_OR_SC);
+}
diff --git a/src/script/cpp_api/s_client.h b/src/script/cpp_api/s_client.h
index 3d373f97c..42c41f8a4 100644
--- a/src/script/cpp_api/s_client.h
+++ b/src/script/cpp_api/s_client.h
@@ -22,6 +22,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define S_CLIENT_H_
#include "cpp_api/s_base.h"
+#include "util/string.h"
+
+#ifdef _CRT_MSVCP_CURRENT
+#include <cstdint>
+#endif
class ScriptApiClient: virtual public ScriptApiBase
{
@@ -36,7 +41,7 @@ public:
void on_damage_taken(int32_t damage_amount);
void on_hp_modification(int32_t newhp);
void on_death();
-
void environment_step(float dtime);
+ void on_formspec_input(const std::string &formname, const StringMap &fields);
};
#endif
diff --git a/src/script/lua_api/l_client.cpp b/src/script/lua_api/l_client.cpp
index 7eb340d78..9a04bd02f 100644
--- a/src/script/lua_api/l_client.cpp
+++ b/src/script/lua_api/l_client.cpp
@@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "l_internal.h"
#include "util/string.h"
#include "cpp_api/s_base.h"
+#include "gettext.h"
int ModApiClient::l_get_current_modname(lua_State *L)
{
@@ -44,18 +45,55 @@ int ModApiClient::l_get_last_run_mod(lua_State *L)
// set_last_run_mod(modname)
int ModApiClient::l_set_last_run_mod(lua_State *L)
{
+ if (!lua_isstring(L, 1))
+ return 0;
+
const char *mod = lua_tostring(L, 1);
getScriptApiBase(L)->setOriginDirect(mod);
- return 0;
+ lua_pushboolean(L, true);
+ return 1;
}
// display_chat_message(message)
int ModApiClient::l_display_chat_message(lua_State *L)
{
- NO_MAP_LOCK_REQUIRED;
+ if (!lua_isstring(L, 1))
+ return 0;
std::string message = luaL_checkstring(L, 1);
getClient(L)->pushToChatQueue(utf8_to_wide(message));
+ lua_pushboolean(L, true);
+ return 1;
+}
+
+// show_formspec(formspec)
+int ModApiClient::l_show_formspec(lua_State *L)
+{
+ if ( !lua_isstring(L, 1) || !lua_isstring(L, 2) )
+ return 0;
+
+ ClientEvent event;
+ event.type = CE_SHOW_LOCAL_FORMSPEC;
+ event.show_formspec.formname = new std::string(luaL_checkstring(L, 1));
+ event.show_formspec.formspec = new std::string(luaL_checkstring(L, 2));
+ getClient(L)->pushToEventQueue(event);
+ lua_pushboolean(L, true);
+ return 1;
+}
+
+// send_respawn()
+int ModApiClient::l_send_respawn(lua_State *L)
+{
+ getClient(L)->sendRespawn();
+ return 0;
+}
+
+// gettext(text)
+int ModApiClient::l_gettext(lua_State *L)
+{
+ std::string text = strgettext(std::string(luaL_checkstring(L, 1)));
+ lua_pushstring(L, text.c_str());
+
return 1;
}
@@ -65,4 +103,7 @@ void ModApiClient::Initialize(lua_State *L, int top)
API_FCT(display_chat_message);
API_FCT(set_last_run_mod);
API_FCT(get_last_run_mod);
+ API_FCT(show_formspec);
+ API_FCT(send_respawn);
+ API_FCT(gettext);
}
diff --git a/src/script/lua_api/l_client.h b/src/script/lua_api/l_client.h
index 150880e3c..14ef5aecc 100644
--- a/src/script/lua_api/l_client.h
+++ b/src/script/lua_api/l_client.h
@@ -33,6 +33,15 @@ private:
// display_chat_message(message)
static int l_display_chat_message(lua_State *L);
+ // show_formspec(name, fornspec)
+ static int l_show_formspec(lua_State *L);
+
+ // send_respawn()
+ static int l_send_respawn(lua_State *L);
+
+ // gettext(text)
+ static int l_gettext(lua_State *L);
+
// get_last_run_mod(n)
static int l_get_last_run_mod(lua_State *L);