Port [message] ActionWML tag from C++ to Lua
Lua API additions: - wesnoth.skipping_replay() - wesnoth.deselect_hex() Note: vultraz and aetheryn deserve partial credit for the Lua implementation
This commit is contained in:
parent
6200f60c79
commit
d4835b0157
7 changed files with 258 additions and 334 deletions
|
@ -13,14 +13,13 @@ end
|
|||
|
||||
wesnoth.require "lua/wml/objectives.lua"
|
||||
wesnoth.require "lua/wml/items.lua"
|
||||
wesnoth.require "lua/wml/message.lua"
|
||||
|
||||
local helper = wesnoth.require "lua/helper.lua"
|
||||
local location_set = wesnoth.require "lua/location_set.lua"
|
||||
local utils = wesnoth.require "lua/wml-utils.lua"
|
||||
local wml_actions = wesnoth.wml_actions
|
||||
|
||||
local engine_message = wml_actions.message
|
||||
|
||||
function wml_actions.sync_variable(cfg)
|
||||
local names = cfg.name or helper.wml_error "[sync_variable] missing required name= attribute."
|
||||
local result = wesnoth.synchronize_choice(
|
||||
|
@ -59,13 +58,6 @@ function wml_actions.sync_variable(cfg)
|
|||
end
|
||||
end
|
||||
|
||||
function wml_actions.message(cfg)
|
||||
local show_if = helper.get_child(cfg, "show_if")
|
||||
if not show_if or wesnoth.eval_conditional(show_if) then
|
||||
engine_message(cfg)
|
||||
end
|
||||
end
|
||||
|
||||
function wml_actions.chat(cfg)
|
||||
local side_list = wesnoth.get_sides(cfg)
|
||||
local speaker = tostring(cfg.speaker or "WML")
|
||||
|
|
227
data/lua/wml/message.lua
Normal file
227
data/lua/wml/message.lua
Normal file
|
@ -0,0 +1,227 @@
|
|||
|
||||
local helper = wesnoth.require "lua/helper.lua"
|
||||
local utils = wesnoth.require "lua/wml-utils.lua"
|
||||
local location_set = wesnoth.require "lua/location_set.lua"
|
||||
local skip_messages = false
|
||||
|
||||
local function log(msg, level)
|
||||
wesnoth.wml_actions.wml_message({
|
||||
message = msg,
|
||||
logger = level,
|
||||
})
|
||||
end
|
||||
|
||||
local function get_image(cfg, speaker)
|
||||
local image = cfg.image
|
||||
|
||||
if speaker and image == nil then
|
||||
image = speaker.__cfg.profile
|
||||
end
|
||||
|
||||
if image == "none" or image == nil then
|
||||
return ""
|
||||
end
|
||||
|
||||
return image
|
||||
end
|
||||
|
||||
local function get_caption(cfg, speaker)
|
||||
local caption = cfg.caption
|
||||
|
||||
if not caption and speaker ~= nil then
|
||||
caption = speaker.name or speaker.type_name
|
||||
end
|
||||
|
||||
return caption
|
||||
end
|
||||
|
||||
local function get_speaker(cfg)
|
||||
local speaker
|
||||
local context = wesnoth.current.event_context
|
||||
|
||||
if cfg.speaker == "narrator" then
|
||||
speaker = "narrator"
|
||||
elseif cfg.speaker == "unit" then
|
||||
speaker = wesnoth.get_unit(context.x1, context.y1)
|
||||
elseif cfg.speaker == "second_unit" then
|
||||
speaker = wesnoth.get_unit(context.x2, context.y2)
|
||||
else
|
||||
speaker = wesnoth.get_units(cfg)[1]
|
||||
end
|
||||
|
||||
return speaker
|
||||
end
|
||||
|
||||
local function message_user_choice(cfg, speaker, options, text_input)
|
||||
local image = get_image(cfg, speaker)
|
||||
local caption = get_caption(cfg, speaker)
|
||||
|
||||
local left_side = true
|
||||
-- If this doesn't work, might need tostring()
|
||||
if image:find("~RIGHT()") then
|
||||
left_side = false
|
||||
-- The percent signs escape the parentheses for a literal match
|
||||
image = image:gsub("~RIGHT%(%)", "")
|
||||
end
|
||||
|
||||
local msg_cfg = {
|
||||
left_side = left_side,
|
||||
title = caption,
|
||||
message = cfg.message,
|
||||
portrait = image,
|
||||
}
|
||||
|
||||
-- Parse input text, if not available all fields are empty
|
||||
if text_input then
|
||||
local input_max_size = tonumber(text_input.max_length) or 256
|
||||
if input_max_size > 1024 or input_max_size < 1 then
|
||||
log("Invalid maximum size for input " .. input_max_size, "warning")
|
||||
input_max_size = 256
|
||||
end
|
||||
|
||||
-- This roundabout method is because text_input starts out
|
||||
-- as an immutable userdata value
|
||||
text_input = {
|
||||
label = text_input.label or "",
|
||||
text = text_input.text or "",
|
||||
max_length = input_max_size,
|
||||
}
|
||||
end
|
||||
|
||||
return function()
|
||||
local option_chosen, ti_content = wesnoth.show_message_dialog(msg_cfg, options, text_input)
|
||||
|
||||
if option_chosen == -2 then -- Pressed Escape (only if no input)
|
||||
skip_messages = true
|
||||
end
|
||||
|
||||
local result_cfg = {}
|
||||
|
||||
if #options > 0 then
|
||||
result_cfg.value = option_chosen
|
||||
end
|
||||
|
||||
if text_input ~= nil then
|
||||
result_cfg.text = ti_content
|
||||
end
|
||||
|
||||
return result_cfg
|
||||
end
|
||||
end
|
||||
|
||||
function wesnoth.wml_actions.message(cfg)
|
||||
local show_if = helper.get_child(cfg, "show_if") or {}
|
||||
if not wesnoth.eval_conditional(show_if) then
|
||||
log("[message] skipped because [show_if] did not pass", "debug")
|
||||
return
|
||||
end
|
||||
|
||||
-- Only the first text_input tag is considered
|
||||
local text_input
|
||||
for cfg in helper.child_range(cfg, "text_input") do
|
||||
if text_input ~= nil then
|
||||
log("Too many [text_input] tags, only one accepted", "warning")
|
||||
break
|
||||
end
|
||||
text_input = cfg
|
||||
end
|
||||
|
||||
local options, option_events = {}, {}
|
||||
for option in helper.child_range(cfg, "option") do
|
||||
local condition = helper.get_child(cfg, "show_if") or {}
|
||||
|
||||
if wesnoth.eval_conditional(condition) then
|
||||
table.insert(options, option.message)
|
||||
table.insert(option_events, {})
|
||||
|
||||
for cmd in helper.child_range(option, "command") do
|
||||
table.insert(option_events[#option_events], cmd)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Check if there is any input to be made, if not the message may be skipped
|
||||
local has_input = text_input ~= nil or #options > 0
|
||||
|
||||
if not has_input and (wesnoth.skipping_replay() or skip_messages) then
|
||||
-- No input to get and the user is not interested either
|
||||
log("Skipping [message] because user not interested", "debug")
|
||||
return
|
||||
end
|
||||
|
||||
local sides_for = cfg.side_for
|
||||
if sides_for and not has_input then
|
||||
local show_for_side = false
|
||||
|
||||
-- Sanity checks on side number and controller
|
||||
for side in utils.split(sides_for) do
|
||||
side = tonumber(side)
|
||||
if side > 0 and side < #wesnoth.sides and wesnoth.sides[side].controller == "human" then
|
||||
show_for_side = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not show_for_side then
|
||||
-- Player isn't controlling side which should see the message
|
||||
log("Player isn't controlling side that should see [message]", "debug")
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local speaker = get_speaker(cfg)
|
||||
if not speaker then
|
||||
-- No matching unit found, continue onto the next message
|
||||
log("No speaker found for [message]", "debug")
|
||||
return
|
||||
elseif speaker == "narrator" then
|
||||
-- Narrator, so deselect units
|
||||
wesnoth.deselect_hex()
|
||||
-- The speaker is expected to be either nil or a unit later
|
||||
speaker = nil
|
||||
else
|
||||
-- Check ~= false, because the default if omitted should be true
|
||||
if cfg.scroll ~= false then
|
||||
wesnoth.scroll_to_tile(speaker.x, speaker.y)
|
||||
end
|
||||
|
||||
wesnoth.select_hex(speaker.x, speaker.y, false)
|
||||
end
|
||||
|
||||
if cfg.sound then wesnoth.play_sound(cfg.sound) end
|
||||
|
||||
local msg_dlg = message_user_choice(cfg, speaker, options, text_input)
|
||||
|
||||
local option_chosen
|
||||
if not has_input then
|
||||
-- Always show the dialog if it has no input, whether we are replaying or not
|
||||
msg_dlg()
|
||||
else
|
||||
local choice = wesnoth.synchronize_choice(msg_dlg)
|
||||
|
||||
option_chosen = tonumber(choice.value)
|
||||
|
||||
if text_input ~= nil then
|
||||
-- Implement the consequences of the choice
|
||||
wesnoth.set_variable(text_input.variable or "input", choice.text)
|
||||
end
|
||||
end
|
||||
|
||||
if #options > 0 then
|
||||
if option_chosen > #options then
|
||||
log("invalid choice (" .. option_chosen .. ") was specified, choice 1 to " ..
|
||||
#options .. " was expected", "debug")
|
||||
return
|
||||
end
|
||||
|
||||
for i, cmd in ipairs(option_events[option_chosen]) do
|
||||
utils.handle_event_commands(cmd)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local on_event = wesnoth.game_events.on_event
|
||||
function wesnoth.game_events.on_event(...)
|
||||
if type(on_event) == "function" then on_event(...) end
|
||||
skip_messages = false
|
||||
end
|
|
@ -96,79 +96,6 @@ namespace game_events
|
|||
// (So keep it at the rop of this file?)
|
||||
wml_action::map wml_action::registry_;
|
||||
|
||||
|
||||
namespace { // advance declarations
|
||||
std::string get_caption(const vconfig& cfg, unit_map::iterator speaker);
|
||||
std::string get_image(const vconfig& cfg, unit_map::iterator speaker);
|
||||
}
|
||||
|
||||
namespace { // Types
|
||||
struct message_user_choice : mp_sync::user_choice
|
||||
{
|
||||
vconfig cfg;
|
||||
unit_map::iterator speaker;
|
||||
vconfig text_input_element;
|
||||
bool has_text_input;
|
||||
const std::vector<std::string> &options;
|
||||
|
||||
message_user_choice(const vconfig &c, const unit_map::iterator &s,
|
||||
const vconfig &t, bool ht, const std::vector<std::string> &o)
|
||||
: cfg(c), speaker(s), text_input_element(t)
|
||||
, has_text_input(ht), options(o)
|
||||
{}
|
||||
|
||||
virtual config query_user(int /*side*/) const
|
||||
{
|
||||
std::string image = get_image(cfg, speaker);
|
||||
std::string caption = get_caption(cfg, speaker);
|
||||
|
||||
size_t right_offset = image.find("~RIGHT()");
|
||||
bool left_side = right_offset == std::string::npos;
|
||||
if (!left_side) {
|
||||
image.erase(right_offset);
|
||||
}
|
||||
|
||||
// Parse input text, if not available all fields are empty
|
||||
std::string text_input_label = text_input_element["label"];
|
||||
std::string text_input_content = text_input_element["text"];
|
||||
unsigned input_max_size = text_input_element["max_length"].to_int(256);
|
||||
if (input_max_size > 1024 || input_max_size < 1) {
|
||||
lg::wml_error << "invalid maximum size for input "
|
||||
<< input_max_size << '\n';
|
||||
input_max_size = 256;
|
||||
}
|
||||
|
||||
int option_chosen = -1;
|
||||
int dlg_result = gui2::show_wml_message(left_side,
|
||||
resources::screen->video(), caption, cfg["message"],
|
||||
image, false, has_text_input, text_input_label,
|
||||
&text_input_content, input_max_size, options,
|
||||
&option_chosen);
|
||||
|
||||
/* Since gui2::show_wml_message needs to do undrawing the
|
||||
chatlines can get garbled and look dirty on screen. Force a
|
||||
redraw to fix it. */
|
||||
/** @todo This hack can be removed once gui2 is finished. */
|
||||
resources::screen->invalidate_all();
|
||||
resources::screen->draw(true,true);
|
||||
|
||||
if (dlg_result == gui2::twindow::CANCEL) {
|
||||
resources::game_events->pump().context_skip_messages(true);
|
||||
}
|
||||
|
||||
config cfg;
|
||||
if (!options.empty()) cfg["value"] = option_chosen;
|
||||
if (has_text_input) cfg["text"] = text_input_content;
|
||||
return cfg;
|
||||
}
|
||||
|
||||
virtual config random_choice(int /*side*/) const
|
||||
{
|
||||
return config();
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace (types)
|
||||
|
||||
namespace { // Support functions
|
||||
|
||||
/**
|
||||
|
@ -277,103 +204,6 @@ namespace { // Support functions
|
|||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to handle the caption part of [message].
|
||||
*
|
||||
* @param cfg cfg of message.
|
||||
* @param speaker The speaker of the message.
|
||||
*
|
||||
* @returns The caption to show.
|
||||
*/
|
||||
std::string get_caption(const vconfig& cfg, unit_map::iterator speaker)
|
||||
{
|
||||
std::string caption = cfg["caption"];
|
||||
if (caption.empty() && speaker != resources::units->end()) {
|
||||
caption = speaker->name();
|
||||
if(caption.empty()) {
|
||||
caption = speaker->type_name();
|
||||
}
|
||||
}
|
||||
return caption;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to handle the image part of [message].
|
||||
*
|
||||
* @param cfg cfg of message.
|
||||
* @param speaker The speaker of the message.
|
||||
*
|
||||
* @returns The image to show.
|
||||
*/
|
||||
std::string get_image(const vconfig& cfg, unit_map::iterator speaker)
|
||||
{
|
||||
std::string image = cfg["image"];
|
||||
|
||||
if (image == "none") {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (image.empty() && speaker != resources::units->end())
|
||||
{
|
||||
image = speaker->big_profile();
|
||||
#ifndef LOW_MEM
|
||||
if(image == speaker->absolute_image()) {
|
||||
image += speaker->image_mods();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to handle the speaker part of [message].
|
||||
*
|
||||
* @param event_info event_info of message.
|
||||
* @param cfg cfg of message.
|
||||
*
|
||||
* @returns The unit who's the speaker or units->end().
|
||||
*/
|
||||
unit_map::iterator handle_speaker(const queued_event& event_info,
|
||||
const vconfig& cfg, bool scroll)
|
||||
{
|
||||
unit_map *units = resources::units;
|
||||
game_display &screen = *resources::screen;
|
||||
|
||||
unit_map::iterator speaker = units->end();
|
||||
const std::string speaker_str = cfg["speaker"];
|
||||
|
||||
if(speaker_str == "unit") {
|
||||
speaker = units->find(event_info.loc1);
|
||||
} else if(speaker_str == "second_unit") {
|
||||
speaker = units->find(event_info.loc2);
|
||||
} else if(speaker_str != "narrator") {
|
||||
const unit_filter ufilt(cfg, resources::filter_con);
|
||||
for(speaker = units->begin(); speaker != units->end(); ++speaker){
|
||||
if ( ufilt(*speaker) )
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(speaker != units->end()) {
|
||||
LOG_NG << "set speaker to '" << speaker->name() << "'\n";
|
||||
const map_location &spl = speaker->get_location();
|
||||
screen.highlight_hex(spl);
|
||||
if(scroll) {
|
||||
LOG_DP << "scrolling to speaker..\n";
|
||||
screen.scroll_to_tile(spl);
|
||||
}
|
||||
screen.highlight_hex(spl);
|
||||
} else if(speaker_str == "narrator") {
|
||||
LOG_NG << "no speaker\n";
|
||||
screen.highlight_hex(map_location::null_location());
|
||||
} else {
|
||||
return speaker;
|
||||
}
|
||||
|
||||
screen.draw(false);
|
||||
LOG_DP << "done scrolling to speaker...\n";
|
||||
return speaker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements the lifting and resetting of fog via WML.
|
||||
* Keeping affect_normal_fog as false causes only the fog override to be affected.
|
||||
|
@ -562,141 +392,6 @@ WML_HANDLER_FUNCTION(lift_fog, /*event_info*/, cfg)
|
|||
toggle_fog(true, cfg, !cfg["multiturn"].to_bool(false));
|
||||
}
|
||||
|
||||
/// Display a message dialog
|
||||
WML_HANDLER_FUNCTION(message, event_info, cfg)
|
||||
{
|
||||
// Check if there is any input to be made, if not the message may be skipped
|
||||
const vconfig::child_list menu_items = cfg.get_children("option");
|
||||
|
||||
const vconfig::child_list text_input_elements = cfg.get_children("text_input");
|
||||
const bool has_text_input = (text_input_elements.size() == 1);
|
||||
|
||||
bool has_input= (has_text_input || !menu_items.empty() );
|
||||
|
||||
// skip messages during quick replay
|
||||
play_controller *controller = resources::controller;
|
||||
if(!has_input && (
|
||||
controller->is_skipping_replay() ||
|
||||
resources::game_events->pump().context_skip_messages()
|
||||
))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if this message is for this side
|
||||
// handeling of side_for for messages with input is done below in the get_user_choice call
|
||||
std::string side_for_raw = cfg["side_for"];
|
||||
if (!side_for_raw.empty() && !has_input)
|
||||
{
|
||||
bool side_for_show = false;
|
||||
|
||||
std::vector<std::string> side_for =
|
||||
utils::split(side_for_raw, ',', utils::STRIP_SPACES | utils::REMOVE_EMPTY);
|
||||
std::vector<std::string>::iterator itSide;
|
||||
size_t side;
|
||||
|
||||
// Check if any of side numbers are human controlled
|
||||
for (itSide = side_for.begin(); itSide != side_for.end(); ++itSide)
|
||||
{
|
||||
side = lexical_cast_default<size_t>(*itSide);
|
||||
// Make sanity check that side number is good
|
||||
// then check if this side is human controlled.
|
||||
if (side > 0 && side <= resources::teams->size() &&
|
||||
(*resources::teams)[side-1].is_local_human())
|
||||
{
|
||||
side_for_show = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!side_for_show)
|
||||
{
|
||||
DBG_NG << "player isn't controlling side which should get message\n";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
unit_map::iterator speaker = handle_speaker(event_info, cfg, cfg["scroll"].to_bool(true));
|
||||
if (speaker == resources::units->end() && cfg["speaker"] != "narrator") {
|
||||
// No matching unit found, so the dialog can't come up.
|
||||
// Continue onto the next message.
|
||||
WRN_NG << "cannot show message" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string> options;
|
||||
std::vector<vconfig::child_list> option_events;
|
||||
|
||||
for(vconfig::child_list::const_iterator mi = menu_items.begin();
|
||||
mi != menu_items.end(); ++mi) {
|
||||
std::string msg_str = (*mi)["message"];
|
||||
if (!mi->has_child("show_if")
|
||||
|| conditional_passed(mi->child("show_if")))
|
||||
{
|
||||
options.push_back(msg_str);
|
||||
option_events.push_back((*mi).get_children("command"));
|
||||
}
|
||||
}
|
||||
|
||||
has_input = !options.empty() || has_text_input;
|
||||
if (!has_input && resources::controller->is_skipping_replay()) {
|
||||
// No input to get and the user is not interested either.
|
||||
return;
|
||||
}
|
||||
|
||||
if (cfg.has_attribute("sound")) {
|
||||
sound::play_sound(cfg["sound"]);
|
||||
}
|
||||
|
||||
if(text_input_elements.size()>1) {
|
||||
lg::wml_error << "too many text_input tags, only one accepted\n";
|
||||
}
|
||||
|
||||
const vconfig text_input_element = has_text_input ?
|
||||
text_input_elements.front() : vconfig::empty_vconfig();
|
||||
|
||||
int option_chosen = 0;
|
||||
std::string text_input_result;
|
||||
|
||||
DBG_DP << "showing dialog...\n";
|
||||
|
||||
message_user_choice msg(cfg, speaker, text_input_element, has_text_input,
|
||||
options);
|
||||
if (!has_input)
|
||||
{
|
||||
/* Always show the dialog if it has no input, whether we are
|
||||
replaying or not. */
|
||||
msg.query_user(resources::controller->current_side());
|
||||
}
|
||||
else
|
||||
{
|
||||
config choice = mp_sync::get_user_choice("input", msg, cfg["side_for"].to_int(0));
|
||||
option_chosen = choice["value"];
|
||||
text_input_result = choice["text"].str();
|
||||
}
|
||||
|
||||
// Implement the consequences of the choice
|
||||
if(options.empty() == false) {
|
||||
if(size_t(option_chosen) >= menu_items.size()) {
|
||||
std::stringstream errbuf;
|
||||
errbuf << "invalid choice (" << option_chosen
|
||||
<< ") was specified, choice 0 to " << (menu_items.size() - 1)
|
||||
<< " was expected.\n";
|
||||
replay::process_error(errbuf.str());
|
||||
return;
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const vconfig &cmd, option_events[option_chosen]) {
|
||||
handle_event_commands(event_info, cmd);
|
||||
}
|
||||
}
|
||||
if(has_text_input) {
|
||||
std::string variable_name=text_input_element["variable"];
|
||||
if(variable_name.empty())
|
||||
variable_name="input";
|
||||
resources::gamedata->set_variable(variable_name, text_input_result);
|
||||
}
|
||||
}
|
||||
|
||||
WML_HANDLER_FUNCTION(modify_turns, /*event_info*/, cfg)
|
||||
{
|
||||
config::attribute_value value = cfg["value"];
|
||||
|
|
|
@ -75,9 +75,8 @@ namespace context {
|
|||
/// State when processing a particular flight of events or commands.
|
||||
struct state {
|
||||
bool mutated;
|
||||
bool skip_messages;
|
||||
|
||||
explicit state(bool s, bool m = true) : mutated(m), skip_messages(s) {}
|
||||
explicit state(bool m = true) : mutated(m) {}
|
||||
};
|
||||
|
||||
class scoped {
|
||||
|
@ -417,8 +416,7 @@ context::scoped::scoped(std::stack<context::state> & contexts, bool m)
|
|||
//The default context at least should always be on the stack
|
||||
assert(contexts_.size() > 0);
|
||||
|
||||
bool skip_messages = (contexts_.size() > 1) && contexts_.top().skip_messages;
|
||||
contexts_.push(context::state(skip_messages, m));
|
||||
contexts_.push(context::state(m));
|
||||
}
|
||||
|
||||
context::scoped::~scoped()
|
||||
|
@ -441,18 +439,6 @@ void t_pump::context_mutated(bool b)
|
|||
impl_->contexts_.top().mutated = b;
|
||||
}
|
||||
|
||||
bool t_pump::context_skip_messages()
|
||||
{
|
||||
assert(impl_->contexts_.size() > 0);
|
||||
return impl_->contexts_.top().skip_messages;
|
||||
}
|
||||
|
||||
void t_pump::context_skip_messages(bool b)
|
||||
{
|
||||
assert(impl_->contexts_.size() > 0);
|
||||
impl_->contexts_.top().skip_messages = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function which determines whether a wml_message text can
|
||||
* really be pushed into the wml_messages_stream, and does it.
|
||||
|
|
|
@ -71,10 +71,6 @@ namespace game_events
|
|||
bool context_mutated();
|
||||
/// Sets whether or not we believe WML might have changed something.
|
||||
void context_mutated(bool mutated);
|
||||
/// Returns whether or not we are skipping messages.
|
||||
bool context_skip_messages();
|
||||
/// Sets whether or not we are skipping messages.
|
||||
void context_skip_messages(bool skip);
|
||||
|
||||
/// Helper function which determines whether a wml_message text can
|
||||
/// really be pushed into the wml_messages_stream, and does it.
|
||||
|
|
|
@ -2850,6 +2850,30 @@ int game_lua_kernel::intf_select_hex(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deselects any highlighted hex on the map.
|
||||
* No arguments or return values
|
||||
*/
|
||||
int game_lua_kernel::intf_deselect_hex(lua_State*)
|
||||
{
|
||||
const map_location loc;
|
||||
play_controller_.get_mouse_handler_base().select_hex(
|
||||
loc, false, false, false);
|
||||
if (game_display_) {
|
||||
game_display_->highlight_hex(loc);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if a replay is in progress but the player has chosen to skip it
|
||||
*/
|
||||
int game_lua_kernel::intf_skipping_replay(lua_State *L)
|
||||
{
|
||||
lua_pushboolean(L, play_controller_.is_skipping_replay());
|
||||
return 1;
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct lua_synchronize : mp_sync::user_choice
|
||||
{
|
||||
|
@ -4154,6 +4178,8 @@ game_lua_kernel::game_lua_kernel(CVideo * video, game_state & gs, play_controlle
|
|||
{ "scroll", &dispatch<&game_lua_kernel::intf_scroll > },
|
||||
{ "scroll_to_tile", &dispatch<&game_lua_kernel::intf_scroll_to_tile > },
|
||||
{ "select_hex", &dispatch<&game_lua_kernel::intf_select_hex > },
|
||||
{ "deselect_hex", &dispatch<&game_lua_kernel::intf_deselect_hex > },
|
||||
{ "skipping_replay", &dispatch<&game_lua_kernel::intf_skipping_replay > },
|
||||
{ "set_end_campaign_credits", &dispatch<&game_lua_kernel::intf_set_end_campaign_credits > },
|
||||
{ "set_end_campaign_text", &dispatch<&game_lua_kernel::intf_set_end_campaign_text > },
|
||||
{ "set_menu_item", &dispatch<&game_lua_kernel::intf_set_menu_item > },
|
||||
|
|
|
@ -129,6 +129,8 @@ class game_lua_kernel : public lua_kernel_base
|
|||
int intf_simulate_combat(lua_State *L);
|
||||
int intf_scroll_to_tile(lua_State *L);
|
||||
int intf_select_hex(lua_State *L);
|
||||
int intf_deselect_hex(lua_State *L);
|
||||
int intf_skipping_replay(lua_State *L);
|
||||
int intf_synchronize_choice(lua_State *L);
|
||||
int intf_get_locations(lua_State *L);
|
||||
int intf_get_villages(lua_State *L);
|
||||
|
|
Loading…
Add table
Reference in a new issue