move [unstore_unit] definition to lua
This also adds a 'color' parameter to wesnoth.float_label. It was already previously possible to set a labels color using pango markup, but to implement [unstore_unit] i need to support the color= syntax as given by [unstore_unit] This also adds a 'fire_event' parameter to wesnoth.put_unit to specify whether the 'unit_placed' event is fired, this is needed to implement fire_events=yes/no in [unstore_unit] but its also generally useful for the same reason why [unstore_unit] has this parameter.
This commit is contained in:
parent
e13cf1e591
commit
50a9a25ae7
3 changed files with 56 additions and 117 deletions
|
@ -1709,3 +1709,46 @@ wesnoth.wml_actions.random_placement = function(cfg)
|
|||
utils.end_var_scope(variable, variable_previous)
|
||||
|
||||
end
|
||||
|
||||
local function on_board(x, y)
|
||||
if type(x) ~= "number" or type(y) ~= "number" then
|
||||
return false
|
||||
end
|
||||
local w, h = wesnoth.get_map_size()
|
||||
return x >= 1 and y >= 1 and x <= w and y <= h
|
||||
end
|
||||
|
||||
wml_actions.unstore_unit = function(cfg)
|
||||
local variable = cfg.variable or helper.wml_error("[unstore_unit] missing required 'variable' attribute")
|
||||
local unit_cfg = wesnoth.get_variable(variable)
|
||||
local unit = wesnoth.create_unit(unit_cfg)
|
||||
local advance = cfg.advance ~= false
|
||||
local animate = cfg.animate ~= false
|
||||
local x = cfg.x or unit.x or -1
|
||||
local y = cfg.y or unit.y or -1
|
||||
wesnoth.add_known_unit(unit.type)
|
||||
if on_board(x, y) then
|
||||
if cfg.find_vacant then
|
||||
x,y = wesnoth.find_vacant_tile(x, y, cfg.check_passability ~= false and unit)
|
||||
end
|
||||
unit:to_map(x, y, cfg.fire_event)
|
||||
local text = nil
|
||||
if unit_cfg.gender == "female" then
|
||||
text = cfg.female_text or cfg.text
|
||||
else
|
||||
text = cfg.male_text or cfg.text
|
||||
end
|
||||
local color = cfg.color
|
||||
if color == nil and cfg.red and cfg.blue and cfg.green then
|
||||
color = cfg.red .. "," .. cfg.green .. "," .. cfg.blue
|
||||
end
|
||||
if text ~= nil and not wesnoth.is_skipping_messages() then
|
||||
wesnoth.float_label(x, y, text, color)
|
||||
end
|
||||
if advance then
|
||||
wesnoth.advance_unit(unit, animate, cfg.fire_event)
|
||||
end
|
||||
else
|
||||
unit:to_recall()
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1309,119 +1309,6 @@ WML_HANDLER_FUNCTION(unit, /*event_info*/, cfg)
|
|||
|
||||
}
|
||||
|
||||
/// Unit serialization from variables
|
||||
WML_HANDLER_FUNCTION(unstore_unit, /*event_info*/, cfg)
|
||||
{
|
||||
try {
|
||||
const config &var = resources::gamedata->get_variable_cfg(cfg["variable"]);
|
||||
|
||||
config tmp_cfg(var);
|
||||
const unit_ptr u = unit_ptr( new unit(tmp_cfg, false));
|
||||
|
||||
preferences::encountered_units().insert(u->type_id());
|
||||
map_location loc = cfg_to_loc(
|
||||
(cfg.has_attribute("x") && cfg.has_attribute("y")) ? cfg : vconfig(var));
|
||||
const bool advance = cfg["advance"].to_bool(true);
|
||||
if(resources::gameboard->map().on_board(loc)) {
|
||||
if (cfg["find_vacant"].to_bool()) {
|
||||
const unit* pass_check = NULL;
|
||||
if (cfg["check_passability"].to_bool(true)) pass_check = u.get();
|
||||
loc = pathfind::find_vacant_tile(
|
||||
loc,
|
||||
pathfind::VACANT_ANY,
|
||||
pass_check);
|
||||
}
|
||||
|
||||
resources::units->erase(loc);
|
||||
resources::units->add(loc, *u);
|
||||
|
||||
if (cfg["fire_event"].to_bool(false)) {
|
||||
resources::game_events->pump().fire("unit placed", loc);
|
||||
}
|
||||
|
||||
config::attribute_value text = var["gender"].str() == "female" ? cfg["female_text"] : cfg["male_text"];
|
||||
if(text.blank()) {
|
||||
text = cfg["text"];
|
||||
}
|
||||
play_controller *controller = resources::controller;
|
||||
if(!text.empty() && !controller->is_skipping_replay())
|
||||
{
|
||||
// Print floating label
|
||||
SDL_Color color = font::LABEL_COLOR;
|
||||
|
||||
if(!cfg["color"].empty()) {
|
||||
color = string_to_color(cfg["color"]);
|
||||
} else if(cfg.has_attribute("red") || cfg.has_attribute("green") || cfg.has_attribute("blue")) {
|
||||
color = create_color(cfg["red"], cfg["green"], cfg["blue"]);
|
||||
}
|
||||
|
||||
resources::screen->float_label(loc, text, color);
|
||||
}
|
||||
if(advance) {
|
||||
advance_unit_at(advance_unit_params(loc)
|
||||
.fire_events(cfg["fire_event"].to_bool(false))
|
||||
.animate(cfg["animate"].to_bool(true)));
|
||||
}
|
||||
} else {
|
||||
if(advance && u->advances()) {
|
||||
WRN_NG << "Cannot advance units when unstoring to the recall list." << std::endl;
|
||||
}
|
||||
|
||||
team& t = (*resources::teams)[u->side()-1];
|
||||
|
||||
// Test whether the recall list has duplicates if so warn.
|
||||
// This might be removed at some point but the uniqueness of
|
||||
// the description is needed to avoid the recall duplication
|
||||
// bugs. Duplicates here might cause the wrong unit being
|
||||
// replaced by the wrong unit.
|
||||
if(t.recall_list().size() > 1) {
|
||||
std::vector<size_t> desciptions;
|
||||
BOOST_FOREACH ( const unit_const_ptr & pt, t.recall_list() ) {
|
||||
|
||||
const size_t desciption =
|
||||
pt->underlying_id();
|
||||
if(std::find(desciptions.begin(), desciptions.end(),
|
||||
desciption) != desciptions.end()) {
|
||||
|
||||
lg::wml_error << "Recall list has duplicate unit "
|
||||
"underlying_ids '" << desciption
|
||||
<< "' unstore_unit may not work as expected.\n";
|
||||
} else {
|
||||
desciptions.push_back(desciption);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Avoid duplicates in the list.
|
||||
/**
|
||||
* @todo it would be better to change recall_list() from
|
||||
* a vector to a map and use the underlying_id as key.
|
||||
*/
|
||||
size_t old_size = t.recall_list().size();
|
||||
t.recall_list().erase_by_underlying_id(u->underlying_id());
|
||||
if (t.recall_list().size() != old_size) {
|
||||
LOG_NG << "Replaced unit '"
|
||||
<< u->underlying_id() << "' on the recall list\n";
|
||||
}
|
||||
t.recall_list().add(u);
|
||||
}
|
||||
|
||||
// If we unstore a leader make sure the team gets a leader if not the loading
|
||||
// in MP might abort since a side without a leader has a recall list.
|
||||
if(u->can_recruit()) {
|
||||
(*resources::teams)[u->side() - 1].have_leader();
|
||||
}
|
||||
|
||||
}
|
||||
catch (const invalid_variablename_exception&)
|
||||
{
|
||||
ERR_NG << "invlid variable name in unstore_unit" << std::endl;
|
||||
}
|
||||
catch (game::game_error &e) {
|
||||
ERR_NG << "could not de-serialize unit: '" << e.message << "'" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
WML_HANDLER_FUNCTION(volume, /*event_info*/, cfg)
|
||||
{
|
||||
|
||||
|
|
|
@ -2275,13 +2275,16 @@ int game_lua_kernel::intf_print(lua_State *L) {
|
|||
* Places a unit on the map.
|
||||
* - Args 1,2: (optional) location.
|
||||
* - Arg 3: Unit (WML table or proxy), or nothing/nil to delete.
|
||||
* - Args 4: (optional) boolean
|
||||
* OR
|
||||
* - Arg 1: Unit (WML table or proxy)
|
||||
* - Args 2,3: (optional) location
|
||||
* - Args 4: (optional) boolean
|
||||
*/
|
||||
int game_lua_kernel::intf_put_unit(lua_State *L)
|
||||
{
|
||||
int unit_arg = 1;
|
||||
int fire_event_arg = 4;
|
||||
|
||||
lua_unit *lu = NULL;
|
||||
unit_ptr u = unit_ptr();
|
||||
|
@ -2299,6 +2302,8 @@ int game_lua_kernel::intf_put_unit(lua_State *L)
|
|||
if (!map().on_board(loc)) {
|
||||
return luaL_argerror(L, 1, "invalid location");
|
||||
}
|
||||
} else {
|
||||
fire_event_arg = 2;
|
||||
}
|
||||
|
||||
if (luaW_hasmetatable(L, unit_arg, getunitKey))
|
||||
|
@ -2351,9 +2356,9 @@ int game_lua_kernel::intf_put_unit(lua_State *L)
|
|||
u->set_location(loc);
|
||||
units().insert(u);
|
||||
}
|
||||
|
||||
play_controller_.pump().fire("unit placed", loc);
|
||||
|
||||
if(luaW_toboolean(L, fire_event_arg)) {
|
||||
play_controller_.pump().fire("unit placed", loc);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2516,10 +2521,14 @@ int game_lua_kernel::intf_float_label(lua_State *L)
|
|||
map_location loc;
|
||||
loc.x = luaL_checkinteger(L, 1) - 1;
|
||||
loc.y = luaL_checkinteger(L, 2) - 1;
|
||||
SDL_Color color = font::LABEL_COLOR;
|
||||
|
||||
t_string text = luaW_checktstring(L, 3);
|
||||
if (!lua_isnoneornil(L, 4)) {
|
||||
color = string_to_color(luaW_checktstring(L, 4));
|
||||
}
|
||||
if (game_display_) {
|
||||
game_display_->float_label(loc, text, font::LABEL_COLOR);
|
||||
game_display_->float_label(loc, text, color);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue