Port [object] ActionWML tag from C++ to Lua
Lua API additions: - wesnoth.show_popup_dialog() - optional write_to_mods parameter to wesnoth.add_modification
This commit is contained in:
parent
d4835b0157
commit
376020097f
10 changed files with 119 additions and 118 deletions
|
@ -14,6 +14,7 @@ end
|
|||
wesnoth.require "lua/wml/objectives.lua"
|
||||
wesnoth.require "lua/wml/items.lua"
|
||||
wesnoth.require "lua/wml/message.lua"
|
||||
wesnoth.require "lua/wml/object.lua"
|
||||
|
||||
local helper = wesnoth.require "lua/helper.lua"
|
||||
local location_set = wesnoth.require "lua/location_set.lua"
|
||||
|
|
80
data/lua/wml/object.lua
Normal file
80
data/lua/wml/object.lua
Normal file
|
@ -0,0 +1,80 @@
|
|||
|
||||
local helper = wesnoth.require "lua/helper.lua"
|
||||
local utils = wesnoth.require "lua/wml-utils.lua"
|
||||
local T = helper.set_wml_tag_metatable {}
|
||||
local wml_actions = wesnoth.wml_actions
|
||||
|
||||
local used_items = {}
|
||||
|
||||
function wml_actions.object(cfg)
|
||||
local context = wesnoth.current.event_context
|
||||
|
||||
-- If this item has already been used
|
||||
if cfg.id and used_items[cfg.id] then return end
|
||||
|
||||
local unit
|
||||
local filter = helper.get_child(cfg, "filter")
|
||||
if filter then
|
||||
unit = wesnoth.get_units(filter)[1]
|
||||
end
|
||||
if not unit then
|
||||
unit = wesnoth.get_unit(contxt.x, context.y)
|
||||
end
|
||||
|
||||
local command_type, text
|
||||
if unit then
|
||||
text = tostring(cfg.description or "")
|
||||
command_type = "then"
|
||||
|
||||
local dvs = cfg.delayed_variable_substitution
|
||||
local add = cfg.no_write ~= true
|
||||
if dvs then
|
||||
wesnoth.add_modification(unit, "object", helper.literal(cfg), add)
|
||||
else
|
||||
wesnoth.add_modification(unit, "object", helper.parsed(cfg), add)
|
||||
end
|
||||
|
||||
wesnoth.select_hex(unit.x, unit.y)
|
||||
|
||||
-- Mark this item as used up
|
||||
if cfg.id then used_items[cfg.id] = true end
|
||||
else
|
||||
text = tostring(cfg.cannot_use_message or "")
|
||||
command_type = "else"
|
||||
end
|
||||
|
||||
-- Default to silent if object has no description
|
||||
local silent = cfg.silent
|
||||
if silent == nil then silent = (text:len() == 0) end
|
||||
|
||||
if not silent then
|
||||
wml_actions.redraw{}
|
||||
local name = tostring(cfg.name or "")
|
||||
wesnoth.show_popup_dialog(name, text, cfg.image)
|
||||
end
|
||||
|
||||
for cmd in helper.child_range(cfg, command_type) do
|
||||
utils.handle_event_commands(cmd)
|
||||
end
|
||||
end
|
||||
|
||||
local old_on_load = wesnoth.game_events.on_load
|
||||
function wesnoth.game_events.on_load(cfg)
|
||||
for i = 1,#cfg do
|
||||
if cfg[i][1] == "used_items" then
|
||||
-- Not quite sure if this will work
|
||||
-- Might need to loop through and copy each ID separately
|
||||
used_items = cfg[i][2]
|
||||
table.remove(cfg, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
old_on_load(cfg)
|
||||
end
|
||||
|
||||
local old_on_save = wesnoth.game_events.on_save
|
||||
function wesnoth.game_events.on_save()
|
||||
local cfg = old_on_save()
|
||||
table.insert(cfg, T.used_items(used_items) )
|
||||
return cfg
|
||||
end
|
|
@ -248,11 +248,6 @@ namespace { // Support functions
|
|||
resources::screen->recalculate_minimap();
|
||||
resources::screen->invalidate_all();
|
||||
}
|
||||
|
||||
void handle_event_commands(const queued_event& event_info, const vconfig &cfg) {
|
||||
assert(resources::lua_kernel);
|
||||
resources::lua_kernel->run_wml_action("command", cfg, event_info);
|
||||
}
|
||||
} // end anonymous namespace (support functions)
|
||||
|
||||
void handle_deprecated_message(const config& cfg)
|
||||
|
@ -492,81 +487,6 @@ WML_HANDLER_FUNCTION(move_units_fake, /*event_info*/, cfg)
|
|||
LOG_NG << "Units moved\n";
|
||||
}
|
||||
|
||||
WML_HANDLER_FUNCTION(object, event_info, cfg)
|
||||
{
|
||||
const vconfig & filter = cfg.child("filter");
|
||||
boost::optional<unit_filter> ufilt;
|
||||
if (!filter.null())
|
||||
ufilt = unit_filter(filter, resources::filter_con);
|
||||
|
||||
std::string id = cfg["id"];
|
||||
|
||||
// If this item has already been used
|
||||
assert(resources::game_events);
|
||||
if ( resources::game_events->item_used(id) )
|
||||
return;
|
||||
|
||||
std::string image = cfg["image"];
|
||||
std::string caption = cfg["name"];
|
||||
std::string text;
|
||||
|
||||
map_location loc;
|
||||
if(ufilt) {
|
||||
unit_const_ptr u_ptr = ufilt->first_match_on_map();
|
||||
if (u_ptr) {
|
||||
loc = u_ptr->get_location();
|
||||
}
|
||||
}
|
||||
|
||||
if(loc.valid() == false) {
|
||||
loc = event_info.loc1;
|
||||
}
|
||||
|
||||
const unit_map::iterator u = resources::units->find(loc);
|
||||
|
||||
std::string command_type = "then";
|
||||
|
||||
if ( u != resources::units->end() && (!ufilt || ufilt->matches(*u)) )
|
||||
{
|
||||
text = cfg["description"].str();
|
||||
|
||||
const bool no_add = cfg["no_write"].to_bool(false);
|
||||
|
||||
if(cfg["delayed_variable_substitution"].to_bool(false))
|
||||
u->add_modification("object", cfg.get_config(), no_add);
|
||||
else
|
||||
u->add_modification("object", cfg.get_parsed_config(), no_add);
|
||||
|
||||
resources::screen->select_hex(event_info.loc1);
|
||||
resources::screen->invalidate_unit();
|
||||
|
||||
// Mark this item as used up.
|
||||
resources::game_events->item_used(id, true);
|
||||
} else {
|
||||
text = cfg["cannot_use_message"].str();
|
||||
command_type = "else";
|
||||
}
|
||||
|
||||
// Default to silent if object has no description
|
||||
const bool silent = cfg.has_attribute("silent") ? cfg["silent"].to_bool() : !cfg.has_attribute("description");
|
||||
|
||||
if (!silent)
|
||||
{
|
||||
// Redraw the unit, with its new stats
|
||||
resources::screen->draw();
|
||||
|
||||
try {
|
||||
gui2::show_transient_message(resources::screen->video(), caption, text, image, true);
|
||||
} catch(utf8::invalid_utf8_exception&) {
|
||||
// we already had a warning so do nothing.
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const vconfig &cmd, cfg.get_children(command_type)) {
|
||||
handle_event_commands(event_info, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
/// If we should recall units that match a certain description.
|
||||
WML_HANDLER_FUNCTION(recall, /*event_info*/, cfg)
|
||||
{
|
||||
|
|
|
@ -64,28 +64,6 @@ void manager::add_event_handler(const config & handler, bool is_menu_item)
|
|||
event_handlers_->add_event_handler(handler, *this, is_menu_item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if an item has been used.
|
||||
* (An empty id will never be considered used.)
|
||||
*/
|
||||
bool manager::item_used(const std::string & id)
|
||||
{
|
||||
return !id.empty() && used_items_.count(id) > 0;
|
||||
}
|
||||
|
||||
/** Records if an item has been used. */
|
||||
void manager::item_used(const std::string & id, bool used)
|
||||
{
|
||||
// Empty IDs are not tracked.
|
||||
if ( id.empty() )
|
||||
return;
|
||||
|
||||
if ( used )
|
||||
used_items_.insert(id);
|
||||
else
|
||||
used_items_.erase(id);
|
||||
}
|
||||
|
||||
/** Removes an event handler. */
|
||||
void manager::remove_event_handler(const std::string & id)
|
||||
{
|
||||
|
@ -98,7 +76,6 @@ void manager::remove_event_handler(const std::string & id)
|
|||
manager::manager(const config& cfg, const boost::shared_ptr<t_context> & res)
|
||||
: event_handlers_(new t_event_handlers())
|
||||
, unit_wml_ids_()
|
||||
, used_items_()
|
||||
, pump_(new game_events::t_pump(*this, res))
|
||||
, resources_(res)
|
||||
, wml_menu_items_()
|
||||
|
@ -122,14 +99,6 @@ manager::manager(const config& cfg, const boost::shared_ptr<t_context> & res)
|
|||
resources_->lua_kernel->set_wml_action(action_cur->first, action_cur->second);
|
||||
}
|
||||
|
||||
const std::string used = cfg["used_items"];
|
||||
if(!used.empty()) {
|
||||
const std::vector<std::string>& v = utils::split(used);
|
||||
for(std::vector<std::string>::const_iterator i = v.begin(); i != v.end(); ++i) {
|
||||
item_used(*i, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Create the event handlers for menu items.
|
||||
wml_menu_items_.init_handlers(me_);
|
||||
}
|
||||
|
@ -238,7 +207,6 @@ void manager::write_events(config& cfg)
|
|||
cfg.add_child("event", eh->get_config());
|
||||
}
|
||||
|
||||
cfg["used_items"] = utils::join(used_items_);
|
||||
cfg["unit_wml_ids"] = utils::join(unit_wml_ids_);
|
||||
wml_menu_items_.to_config(cfg);
|
||||
}
|
||||
|
|
|
@ -112,7 +112,6 @@ namespace game_events {
|
|||
|
||||
boost::scoped_ptr<t_event_handlers> event_handlers_;
|
||||
std::set<std::string> unit_wml_ids_;
|
||||
std::set<std::string> used_items_;
|
||||
|
||||
boost::scoped_ptr<game_events::t_pump> pump_;
|
||||
boost::shared_ptr<t_context> resources_;
|
||||
|
@ -127,10 +126,6 @@ namespace game_events {
|
|||
|
||||
/// Create an event handler.
|
||||
void add_event_handler(const config & handler, bool is_menu_item=false);
|
||||
/// Checks if an item has been used.
|
||||
bool item_used(const std::string & id);
|
||||
/// Records if an item has been used.
|
||||
void item_used(const std::string & id, bool used);
|
||||
/// Removes an event handler.
|
||||
void remove_event_handler(const std::string & id);
|
||||
|
||||
|
|
|
@ -3307,6 +3307,7 @@ static int intf_get_traits(lua_State* L)
|
|||
* - Arg 1: unit.
|
||||
* - Arg 2: string.
|
||||
* - Arg 3: WML table.
|
||||
* - Arg 4: (optional) Whether to add to [modifications] - default true
|
||||
*/
|
||||
static int intf_add_modification(lua_State *L)
|
||||
{
|
||||
|
@ -3320,9 +3321,13 @@ static int intf_add_modification(lua_State *L)
|
|||
if (sm != "advancement" && sm != "object" && sm != "trait") {
|
||||
return luaL_argerror(L, 2, "unknown modification type");
|
||||
}
|
||||
bool write_to_mods = true;
|
||||
if (!lua_isnone(L, 4)) {
|
||||
write_to_mods = lua_toboolean(L, 4);
|
||||
}
|
||||
|
||||
config cfg = luaW_checkconfig(L, 3);
|
||||
u->add_modification(sm, cfg);
|
||||
u->add_modification(sm, cfg, !write_to_mods);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "gui/dialogs/gamestate_inspector.hpp"
|
||||
#include "gui/dialogs/lua_interpreter.hpp"
|
||||
#include "gui/dialogs/wml_message.hpp"
|
||||
#include "gui/dialogs/transient_message.hpp"
|
||||
#include "gui/widgets/clickable.hpp" // for tclickable_
|
||||
#include "gui/widgets/control.hpp" // for tcontrol
|
||||
#include "gui/widgets/multi_page.hpp" // for tmulti_page
|
||||
|
@ -294,6 +295,21 @@ int show_message_dialog(lua_State *L, CVideo & video)
|
|||
|
||||
return 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a popup message
|
||||
* - Arg 1: Title (allows Pango markup)
|
||||
* - Arg 2: Message (allows Pango markup)
|
||||
* - Arg 3: Image (optional)
|
||||
*/
|
||||
int show_popup_dialog(lua_State *L, CVideo & video) {
|
||||
std::string title = luaL_checkstring(L, 1);
|
||||
std::string msg = luaL_checkstring(L, 2);
|
||||
std::string image = lua_isnoneornil(L, 3) ? "" : luaL_checkstring(L, 3);
|
||||
|
||||
gui2::show_transient_message(video, title, msg, image, true, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a widget on the current dialog.
|
||||
|
|
|
@ -33,6 +33,7 @@ int intf_set_dialog_visible(lua_State *L);
|
|||
int intf_add_dialog_tree_node(lua_State *L);
|
||||
int show_dialog(lua_State *L, CVideo & video);
|
||||
int show_message_dialog(lua_State *L, CVideo & video);
|
||||
int show_popup_dialog(lua_State *L, CVideo & video);
|
||||
int show_lua_console(lua_State*L, CVideo & video, lua_kernel_base * lk);
|
||||
int show_gamestate_inspector(CVideo & video, const vconfig & cfg);
|
||||
int intf_remove_dialog_item(lua_State *L);
|
||||
|
|
|
@ -130,6 +130,17 @@ int lua_kernel_base::intf_show_message_dialog(lua_State *L)
|
|||
return lua_gui2::show_message_dialog(L, *video_);
|
||||
}
|
||||
|
||||
int lua_kernel_base::intf_show_popup_dialog(lua_State *L)
|
||||
{
|
||||
if (!video_) {
|
||||
ERR_LUA << "Cannot show dialog, no video object is available to this lua kernel.";
|
||||
lua_error(L);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return lua_gui2::show_popup_dialog(L, *video_);
|
||||
}
|
||||
|
||||
// The show lua console callback is similarly a method of lua kernel
|
||||
int lua_kernel_base::intf_show_lua_console(lua_State *L)
|
||||
{
|
||||
|
@ -269,6 +280,7 @@ lua_kernel_base::lua_kernel_base(CVideo * video)
|
|||
{ "require", &dispatch<&lua_kernel_base::intf_require> },
|
||||
{ "show_dialog", &dispatch<&lua_kernel_base::intf_show_dialog> },
|
||||
{ "show_message_dialog", &dispatch<&lua_kernel_base::intf_show_message_dialog> },
|
||||
{ "show_popup_dialog", &dispatch<&lua_kernel_base::intf_show_popup_dialog> },
|
||||
{ "show_lua_console", &dispatch<&lua_kernel_base::intf_show_lua_console> },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
|
|
@ -106,6 +106,9 @@ protected:
|
|||
|
||||
// Show a message dialog, possibly with options
|
||||
int intf_show_message_dialog(lua_State * L);
|
||||
|
||||
// Show a transient popup message
|
||||
int intf_show_popup_dialog(lua_State * L);
|
||||
|
||||
// Show the interactive lua console (for debugging purposes)
|
||||
int intf_show_lua_console(lua_State * L);
|
||||
|
|
Loading…
Add table
Reference in a new issue