mirror of
https://github.com/minetest/minetest.git
synced 2024-11-23 16:13:46 +01:00
[CSM] Add local formspecs. (#5094)
This commit is contained in:
parent
2c19d51409
commit
c42c53fccf
@ -6,8 +6,18 @@ local commonpath = scriptpath.."common"..DIR_DELIM
|
|||||||
dofile(clientpath .. "register.lua")
|
dofile(clientpath .. "register.lua")
|
||||||
dofile(commonpath .. "after.lua")
|
dofile(commonpath .. "after.lua")
|
||||||
dofile(commonpath .. "chatcommands.lua")
|
dofile(commonpath .. "chatcommands.lua")
|
||||||
|
dofile(clientpath .. "chatcommands.lua")
|
||||||
dofile(clientpath .. "preview.lua")
|
dofile(clientpath .. "preview.lua")
|
||||||
|
|
||||||
core.register_on_death(function()
|
core.register_on_death(function()
|
||||||
core.display_chat_message("You died.")
|
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)
|
end)
|
||||||
|
@ -32,7 +32,7 @@ end)
|
|||||||
|
|
||||||
-- This is an example function to ensure it's working properly, should be removed before merge
|
-- This is an example function to ensure it's working properly, should be removed before merge
|
||||||
core.register_chatcommand("dump", {
|
core.register_chatcommand("dump", {
|
||||||
func = function(name, param)
|
func = function(param)
|
||||||
return true, dump(_G)
|
return true, dump(_G)
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
@ -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_death, core.register_on_death = make_registration()
|
||||||
core.registered_on_hp_modification, core.register_on_hp_modification = 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_damage_taken, core.register_on_damage_taken = make_registration()
|
||||||
|
core.registered_on_formspec_input, core.register_on_formspec_input = make_registration()
|
||||||
|
|
||||||
|
|
||||||
|
@ -606,7 +606,9 @@ if INIT == "mainmenu" then
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if INIT == "client" or INIT == "mainmenu" then
|
||||||
function fgettext_ne(text, ...)
|
function fgettext_ne(text, ...)
|
||||||
text = core.gettext(text)
|
text = core.gettext(text)
|
||||||
local arg = {n=select('#', ...), ...}
|
local arg = {n=select('#', ...), ...}
|
||||||
@ -636,4 +638,3 @@ if INIT == "mainmenu" then
|
|||||||
return core.formspec_escape(fgettext_ne(text, ...))
|
return core.formspec_escape(fgettext_ne(text, ...))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -699,7 +699,10 @@ Call these functions only at load time!
|
|||||||
* Called when server modified player's HP
|
* Called when server modified player's HP
|
||||||
* `minetest.register_on_damage_taken(func(hp))`
|
* `minetest.register_on_damage_taken(func(hp))`
|
||||||
* Called when player take damages
|
* 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
|
### Sounds
|
||||||
* `minetest.sound_play(spec, parameters)`: returns a handle
|
* `minetest.sound_play(spec, parameters)`: returns a handle
|
||||||
* `spec` is a `SimpleSoundSpec`
|
* `spec` is a `SimpleSoundSpec`
|
||||||
@ -754,7 +757,15 @@ Call these functions only at load time!
|
|||||||
* Encodes a string in base64.
|
* Encodes a string in base64.
|
||||||
* `minetest.decode_base64(string)`: returns string
|
* `minetest.decode_base64(string)`: returns string
|
||||||
* Decodes a string encoded in base64.
|
* 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
|
Class reference
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
|
@ -142,6 +142,7 @@ enum ClientEventType
|
|||||||
CE_PLAYER_FORCE_MOVE,
|
CE_PLAYER_FORCE_MOVE,
|
||||||
CE_DEATHSCREEN,
|
CE_DEATHSCREEN,
|
||||||
CE_SHOW_FORMSPEC,
|
CE_SHOW_FORMSPEC,
|
||||||
|
CE_SHOW_LOCAL_FORMSPEC,
|
||||||
CE_SPAWN_PARTICLE,
|
CE_SPAWN_PARTICLE,
|
||||||
CE_ADD_PARTICLESPAWNER,
|
CE_ADD_PARTICLESPAWNER,
|
||||||
CE_DELETE_PARTICLESPAWNER,
|
CE_DELETE_PARTICLESPAWNER,
|
||||||
@ -570,6 +571,11 @@ public:
|
|||||||
|
|
||||||
ClientScripting *getScript() { return m_script; }
|
ClientScripting *getScript() { return m_script; }
|
||||||
|
|
||||||
|
inline void pushToEventQueue(const ClientEvent &event)
|
||||||
|
{
|
||||||
|
m_client_event_queue.push(event);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// Virtual methods from con::PeerHandler
|
// Virtual methods from con::PeerHandler
|
||||||
|
67
src/game.cpp
67
src/game.cpp
@ -125,6 +125,7 @@ struct TextDestPlayerInventory : public TextDest {
|
|||||||
|
|
||||||
struct LocalFormspecHandler : public TextDest {
|
struct LocalFormspecHandler : public TextDest {
|
||||||
LocalFormspecHandler();
|
LocalFormspecHandler();
|
||||||
|
|
||||||
LocalFormspecHandler(std::string formname) :
|
LocalFormspecHandler(std::string formname) :
|
||||||
m_client(0)
|
m_client(0)
|
||||||
{
|
{
|
||||||
@ -178,39 +179,7 @@ struct LocalFormspecHandler : public TextDest {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_client->getScript()->on_formspec_input(m_formname, fields);
|
||||||
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++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Client *m_client;
|
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
|
#define SIZE_TAG "size[11,5.5,true]" // Fixed size on desktop
|
||||||
#endif
|
#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,
|
static void show_pause_menu(GUIFormSpecMenu **cur_formspec,
|
||||||
Client *client,
|
Client *client,
|
||||||
@ -3255,9 +3202,6 @@ void Game::processClientEvents(CameraOrientation *cam, float *damage_flash)
|
|||||||
cam->camera_yaw = event.player_force_move.yaw;
|
cam->camera_yaw = event.player_force_move.yaw;
|
||||||
cam->camera_pitch = event.player_force_move.pitch;
|
cam->camera_pitch = event.player_force_move.pitch;
|
||||||
} else if (event.type == CE_DEATHSCREEN) {
|
} else if (event.type == CE_DEATHSCREEN) {
|
||||||
show_deathscreen(¤t_formspec, client, texture_src,
|
|
||||||
device, &input->joystick);
|
|
||||||
|
|
||||||
client->getScript()->on_death();
|
client->getScript()->on_death();
|
||||||
|
|
||||||
/* Handle visualization */
|
/* Handle visualization */
|
||||||
@ -3283,6 +3227,13 @@ void Game::processClientEvents(CameraOrientation *cam, float *damage_flash)
|
|||||||
|
|
||||||
delete(event.show_formspec.formspec);
|
delete(event.show_formspec.formspec);
|
||||||
delete(event.show_formspec.formname);
|
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(¤t_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) ||
|
} else if ((event.type == CE_SPAWN_PARTICLE) ||
|
||||||
(event.type == CE_ADD_PARTICLESPAWNER) ||
|
(event.type == CE_ADD_PARTICLESPAWNER) ||
|
||||||
(event.type == CE_DELETE_PARTICLESPAWNER)) {
|
(event.type == CE_DELETE_PARTICLESPAWNER)) {
|
||||||
|
@ -548,7 +548,7 @@ private:
|
|||||||
class FormspecFormSource: public IFormSource
|
class FormspecFormSource: public IFormSource
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FormspecFormSource(std::string formspec)
|
FormspecFormSource(const std::string &formspec)
|
||||||
{
|
{
|
||||||
m_formspec = formspec;
|
m_formspec = formspec;
|
||||||
}
|
}
|
||||||
@ -556,7 +556,7 @@ public:
|
|||||||
~FormspecFormSource()
|
~FormspecFormSource()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void setForm(std::string formspec) {
|
void setForm(const std::string &formspec) {
|
||||||
m_formspec = FORMSPEC_VERSION_STRING + formspec;
|
m_formspec = FORMSPEC_VERSION_STRING + formspec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,3 +112,27 @@ void ScriptApiClient::environment_step(float dtime)
|
|||||||
+ script_get_backtrace(L));
|
+ 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);
|
||||||
|
}
|
||||||
|
@ -22,6 +22,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#define S_CLIENT_H_
|
#define S_CLIENT_H_
|
||||||
|
|
||||||
#include "cpp_api/s_base.h"
|
#include "cpp_api/s_base.h"
|
||||||
|
#include "util/string.h"
|
||||||
|
|
||||||
|
#ifdef _CRT_MSVCP_CURRENT
|
||||||
|
#include <cstdint>
|
||||||
|
#endif
|
||||||
|
|
||||||
class ScriptApiClient: virtual public ScriptApiBase
|
class ScriptApiClient: virtual public ScriptApiBase
|
||||||
{
|
{
|
||||||
@ -36,7 +41,7 @@ public:
|
|||||||
void on_damage_taken(int32_t damage_amount);
|
void on_damage_taken(int32_t damage_amount);
|
||||||
void on_hp_modification(int32_t newhp);
|
void on_hp_modification(int32_t newhp);
|
||||||
void on_death();
|
void on_death();
|
||||||
|
|
||||||
void environment_step(float dtime);
|
void environment_step(float dtime);
|
||||||
|
void on_formspec_input(const std::string &formname, const StringMap &fields);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "l_internal.h"
|
#include "l_internal.h"
|
||||||
#include "util/string.h"
|
#include "util/string.h"
|
||||||
#include "cpp_api/s_base.h"
|
#include "cpp_api/s_base.h"
|
||||||
|
#include "gettext.h"
|
||||||
|
|
||||||
int ModApiClient::l_get_current_modname(lua_State *L)
|
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)
|
// set_last_run_mod(modname)
|
||||||
int ModApiClient::l_set_last_run_mod(lua_State *L)
|
int ModApiClient::l_set_last_run_mod(lua_State *L)
|
||||||
{
|
{
|
||||||
|
if (!lua_isstring(L, 1))
|
||||||
|
return 0;
|
||||||
|
|
||||||
const char *mod = lua_tostring(L, 1);
|
const char *mod = lua_tostring(L, 1);
|
||||||
getScriptApiBase(L)->setOriginDirect(mod);
|
getScriptApiBase(L)->setOriginDirect(mod);
|
||||||
return 0;
|
lua_pushboolean(L, true);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// display_chat_message(message)
|
// display_chat_message(message)
|
||||||
int ModApiClient::l_display_chat_message(lua_State *L)
|
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);
|
std::string message = luaL_checkstring(L, 1);
|
||||||
getClient(L)->pushToChatQueue(utf8_to_wide(message));
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,4 +103,7 @@ void ModApiClient::Initialize(lua_State *L, int top)
|
|||||||
API_FCT(display_chat_message);
|
API_FCT(display_chat_message);
|
||||||
API_FCT(set_last_run_mod);
|
API_FCT(set_last_run_mod);
|
||||||
API_FCT(get_last_run_mod);
|
API_FCT(get_last_run_mod);
|
||||||
|
API_FCT(show_formspec);
|
||||||
|
API_FCT(send_respawn);
|
||||||
|
API_FCT(gettext);
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,15 @@ private:
|
|||||||
// display_chat_message(message)
|
// display_chat_message(message)
|
||||||
static int l_display_chat_message(lua_State *L);
|
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)
|
// get_last_run_mod(n)
|
||||||
static int l_get_last_run_mod(lua_State *L);
|
static int l_get_last_run_mod(lua_State *L);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user