move most of [endlevel] implementation to lua
as a side effect we get read/write fields side.carryover_bonus/carryover_add/carryover_percentage in lua sides.
This commit is contained in:
parent
554547beac
commit
91943451c7
3 changed files with 70 additions and 119 deletions
|
@ -146,7 +146,7 @@ function wml_actions.allow_recruit(cfg)
|
|||
wesnoth.add_known_unit(type)
|
||||
end
|
||||
team.recruit = v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function wml_actions.allow_extra_recruit(cfg)
|
||||
|
@ -1443,6 +1443,7 @@ function wml_actions.end_turn(cfg)
|
|||
end
|
||||
|
||||
function wml_actions.endlevel(cfg)
|
||||
local parsed = helper.parsed(cfg)
|
||||
if wesnoth.check_end_level_disabled() then
|
||||
wesnoth.message("Repeated [endlevel] execution, ignoring")
|
||||
return
|
||||
|
@ -1463,8 +1464,66 @@ function wml_actions.endlevel(cfg)
|
|||
if end_credits ~= nil then
|
||||
wesnoth.set_end_campaign_credits(end_credits)
|
||||
end
|
||||
|
||||
local side_results = {}
|
||||
for result in helper.child_range(parsed, "result") do
|
||||
local side = result.side or helper.wml_error("[result] in [endlevel] missing required side= key")
|
||||
side_results[side] = result
|
||||
end
|
||||
local there_is_a_human_victory = false
|
||||
local there_is_a_human_defeat = false
|
||||
local there_is_a_local_human_victory = false
|
||||
local there_is_a_local_human_defeat = false
|
||||
|
||||
wesnoth.end_level(cfg)
|
||||
for k,v in ipairs(wesnoth.sides) do
|
||||
local side_result = side_results[v.side] or {}
|
||||
local victory_or_defeat = side_result.result or cfg.result or "victory"
|
||||
local victory = victory_or_defeat == "victory"
|
||||
if victory_or_defeat ~= "victory" and victory_or_defeat ~= "defeat" then
|
||||
return helper.wml_error("invalid result= key in [endlevel] '" .. victory_or_defeat .."'")
|
||||
end
|
||||
if v.controller == "human" or v.controller == "network" then
|
||||
if victory then
|
||||
there_is_a_human_victory = true
|
||||
else
|
||||
there_is_a_human_defeat = true
|
||||
end
|
||||
end
|
||||
if v.controller == "human" then
|
||||
if victory then
|
||||
there_is_a_local_human_victory = true
|
||||
else
|
||||
there_is_a_local_human_defeat = true
|
||||
end
|
||||
end
|
||||
if side_result.bonus ~= nil then
|
||||
v.carryover_bonus = side_result.bonus
|
||||
elseif cfg.bonus ~= nil then
|
||||
v.carryover_bonus = cfg.bonus
|
||||
end
|
||||
if side_result.carryover_add ~= nil then
|
||||
v.carryover_add = side_result.carryover_add
|
||||
elseif cfg.carryover_add ~= nil then
|
||||
v.carryover_add = cfg.carryover_add
|
||||
end
|
||||
if side_result.carryover_percentage ~= nil then
|
||||
v.carryover_percentage = side_result.carryover_percentage
|
||||
elseif cfg.carryover_percentage ~= nil then
|
||||
v.carryover_percentage = cfg.carryover_percentage
|
||||
end
|
||||
end
|
||||
local proceed_to_next_level = there_is_a_human_victory or (not there_is_a_human_defeat and cfg.result ~= "defeat")
|
||||
local victory = there_is_a_local_human_victory or (not there_is_a_local_human_defeat and proceed_to_next_level)
|
||||
wesnoth.end_level {
|
||||
music = cfg.music,
|
||||
carryover_report = cfg.carryover_report,
|
||||
save = cfg.save,
|
||||
replay_save = cfg.replay_save,
|
||||
linger_mode = cfg.linger_mode,
|
||||
reveal_map = cfg.reveal_map,
|
||||
proceed_to_next_level = proceed_to_next_level,
|
||||
result = victory and "victory" or "defeat",
|
||||
}
|
||||
end
|
||||
|
||||
function wml_actions.event(cfg)
|
||||
|
|
|
@ -1684,28 +1684,7 @@ int game_lua_kernel::intf_clear_messages(lua_State*)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
namespace {
|
||||
struct optional_int_visitor : public boost::static_visitor<boost::optional<int> >
|
||||
{
|
||||
template <typename T> result_type operator()(T const &) const
|
||||
{ return result_type(); }
|
||||
result_type operator()(int i) const
|
||||
{ return i; }
|
||||
result_type operator()(unsigned long long u) const
|
||||
{ return static_cast<int>(u); }
|
||||
};
|
||||
|
||||
struct optional_bool_visitor : public boost::static_visitor<boost::optional<bool> >
|
||||
{
|
||||
template <typename T> result_type operator()(T const &) const
|
||||
{ return result_type(); }
|
||||
//Cannot use bool, the case above would catch the yes_no and true_false values.
|
||||
result_type operator()(const config::attribute_value::yes_no & b) const
|
||||
{ return static_cast<bool>(b); }
|
||||
result_type operator()(const config::attribute_value::true_false & b) const
|
||||
{ return static_cast<bool>(b); }
|
||||
};
|
||||
}
|
||||
int game_lua_kernel::intf_end_level(lua_State *L)
|
||||
{
|
||||
vconfig cfg(luaW_checkvconfig(L, 1));
|
||||
|
@ -1715,108 +1694,15 @@ int game_lua_kernel::intf_end_level(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
end_level_data data;
|
||||
|
||||
// TODO: is this still needed?
|
||||
// Remove 0-hp units from the unit map to avoid the following problem:
|
||||
// In case a die event triggers an endlevel the dead unit is still as a
|
||||
// 'ghost' in linger mode. After save loading in linger mode the unit
|
||||
// is fully visible again.
|
||||
unit_map & um = units();
|
||||
unit_map::iterator u = um.begin();
|
||||
while (u) {
|
||||
if (u->hitpoints() <= 0) {
|
||||
um.erase(u++);
|
||||
} else {
|
||||
++u;
|
||||
}
|
||||
}
|
||||
|
||||
typedef boost::tuple<bool/*is_victory*/, boost::optional<bool>/*bonus*/, boost::optional<int>/*percentage*/, boost::optional<bool>/*add*/ > t_side_result;
|
||||
const t_side_result default_result = t_side_result(
|
||||
cfg["result"] != "defeat",
|
||||
cfg["bonus"].to_bool(true),
|
||||
cfg["carryover_percentage"].apply_visitor(optional_int_visitor()),
|
||||
cfg["carryover_add"].apply_visitor(optional_bool_visitor())
|
||||
);
|
||||
std::vector<t_side_result> side_results = std::vector<t_side_result>(board().teams().size(), default_result);
|
||||
BOOST_FOREACH(const vconfig& side_result, cfg.get_children("result")) {
|
||||
size_t side = side_result["side"].to_int();
|
||||
if(side >= side_results.size()) {
|
||||
return luaL_error(L, "invalid side index %d in [result] in wesnoth.end_level", side);
|
||||
}
|
||||
|
||||
std::string result = side_result["result"];
|
||||
VALIDATE_WITH_DEV_MESSAGE(
|
||||
result.empty() || result == "victory" || result == "defeat"
|
||||
, _("Invalid value in the result key for [end_level]")
|
||||
, "result = '" + result + "'.");
|
||||
|
||||
if(result != "") {
|
||||
side_results[side].get<0>() = result != "defeat";
|
||||
}
|
||||
if(boost::optional<bool> bonus = side_result["bonus"].apply_visitor(optional_bool_visitor())){
|
||||
side_results[side].get<1>() = bonus;
|
||||
}
|
||||
if(boost::optional<int> percentage = side_result["carryover_percentage"].apply_visitor(optional_int_visitor())){
|
||||
side_results[side].get<2>() = percentage;
|
||||
}
|
||||
if(boost::optional<bool> add = side_result["carryover_add"].apply_visitor(optional_bool_visitor())){
|
||||
side_results[side].get<3>() = add;
|
||||
}
|
||||
}
|
||||
//Find out whether it is victory or defeat:
|
||||
// If there is a local human side then we have a victory iff one of those sides has a victory
|
||||
// If there is no local human side but a remote human side then we have a victory iff one of those sides has a victory
|
||||
// else we use the default_result from ouside [result].
|
||||
bool any_human_victory = false;
|
||||
bool local_human_victory = false;
|
||||
bool there_is_a_remote_human = false;
|
||||
bool there_is_a_local_human = false;
|
||||
for(int i = 0; i < static_cast<int>(side_results.size()); ++i) {
|
||||
team& t = teams()[i];
|
||||
const t_side_result result = side_results[i];
|
||||
|
||||
if(t.is_local_human()) {
|
||||
there_is_a_local_human = true;
|
||||
if(result.get<0>()) {
|
||||
local_human_victory = true;
|
||||
any_human_victory = true;
|
||||
}
|
||||
}
|
||||
if(t.is_network_human()) {
|
||||
there_is_a_remote_human = true;
|
||||
if(result.get<0>()) {
|
||||
any_human_victory = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(boost::optional<bool> bonus = result.get<1>()){
|
||||
t.set_carryover_bonus(bonus.get());
|
||||
}
|
||||
if(boost::optional<int> percentage = result.get<2>()){
|
||||
t.set_carryover_percentage(percentage.get());
|
||||
}
|
||||
if(boost::optional<bool> add = result.get<3>()){
|
||||
t.set_carryover_add(add.get());
|
||||
}
|
||||
}
|
||||
if(!there_is_a_remote_human && !there_is_a_local_human) {
|
||||
any_human_victory = default_result.get<0>();
|
||||
}
|
||||
if(!there_is_a_local_human) {
|
||||
local_human_victory = any_human_victory;
|
||||
}
|
||||
data.proceed_to_next_level = any_human_victory;
|
||||
|
||||
|
||||
data.proceed_to_next_level = cfg["proceed_to_next_level"].to_bool(true);
|
||||
data.transient.custom_endlevel_music = cfg["music"].str();
|
||||
data.transient.carryover_report = cfg["carryover_report"].to_bool(true);
|
||||
data.prescenario_save = cfg["save"].to_bool(true);
|
||||
data.replay_save = cfg["replay_save"].to_bool(true);
|
||||
data.transient.linger_mode = cfg["linger_mode"].to_bool(true)
|
||||
&& !teams().empty();
|
||||
data.transient.linger_mode = cfg["linger_mode"].to_bool(true) && !teams().empty();
|
||||
data.transient.reveal_map = cfg["reveal_map"].to_bool(true);
|
||||
data.is_victory = local_human_victory;
|
||||
data.is_victory = cfg["result"] == "victory";
|
||||
play_controller_.set_end_level_data(data);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -74,6 +74,9 @@ static int impl_side_get(lua_State *L)
|
|||
return_cstring_attrib("controller", t.controller().to_string().c_str());
|
||||
return_string_attrib("defeat_condition", t.defeat_condition().to_string());
|
||||
return_string_attrib("share_vision", t.share_vision().to_string());
|
||||
return_bool_attrib("carryover_bonus", t.carryover_bonus());
|
||||
return_int_attrib("carryover_percentage", t.carryover_percentage());
|
||||
return_bool_attrib("carryover_add", t.carryover_add());
|
||||
return_bool_attrib("lost", t.lost());
|
||||
|
||||
if (strcmp(m, "recruit") == 0) {
|
||||
|
@ -118,6 +121,9 @@ static int impl_side_set(lua_State *L)
|
|||
modify_string_attrib("controller", t.change_controller_by_wml(value));
|
||||
modify_string_attrib("color", t.set_color(value));
|
||||
modify_string_attrib("defeat_condition", t.set_defeat_condition_string(value));
|
||||
modify_bool_attrib("carryover_bonus", t.set_carryover_bonus(value));
|
||||
modify_int_attrib("carryover_percentage", t.set_carryover_percentage(value));
|
||||
modify_bool_attrib("carryover_add", t.set_carryover_add(value));
|
||||
modify_bool_attrib("lost", t.set_lost(value));
|
||||
|
||||
if (strcmp(m, "recruit") == 0) {
|
||||
|
|
Loading…
Add table
Reference in a new issue