1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-07-02 16:38:41 +00:00

[CSM] Add local formspecs. (#5094)

This commit is contained in:
red-001 2017-01-24 16:26:15 +00:00 committed by Loïc Blot
parent 2c19d51409
commit c42c53fccf
12 changed files with 126 additions and 67 deletions

View file

@ -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

View file

@ -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)) {

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}

View file

@ -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);