Merge pull request #165 from gfgtdf/defeat_condition

replace fight_on_without_leader with defeat_condition
This commit is contained in:
gfgtdf 2014-05-19 19:58:55 +02:00
commit b258433650
6 changed files with 67 additions and 28 deletions

View File

@ -131,7 +131,7 @@ play_controller::play_controller(const config& level, game_state& state_of_game,
savenames_(), savenames_(),
wml_commands_(), wml_commands_(),
victory_when_enemies_defeated_(true), victory_when_enemies_defeated_(true),
remove_from_carryover_on_leaders_loss_(true), remove_from_carryover_on_defeat_(true),
end_level_data_(), end_level_data_(),
victory_music_(), victory_music_(),
defeat_music_(), defeat_music_(),
@ -1403,28 +1403,33 @@ void play_controller::check_victory()
for (unit_map::const_iterator i = units_.begin(), for (unit_map::const_iterator i = units_.begin(),
i_end = units_.end(); i != i_end; ++i) i_end = units_.end(); i != i_end; ++i)
{ {
if (i->can_recruit()) { const team& tm = teams_[i->side()-1];
if (i->can_recruit() && tm.defeat_condition() == team::NO_LEADER) {
//DBG_NG << "seen leader for side " << i->side() << "\n"; //DBG_NG << "seen leader for side " << i->side() << "\n";
not_defeated.insert(i->side()); not_defeated.insert(i->side());
} else if (teams_[i->side()-1].fight_on_without_leader()) { } else if (tm.defeat_condition() == team::NO_UNITS) {
//DBG_NG << "side doesn't require leader " << i->side() << "\n"; //DBG_NG << "side doesn't require leader " << i->side() << "\n";
not_defeated.insert(i->side()); not_defeated.insert(i->side());
} }
} }
BOOST_FOREACH(team& tm, this->teams_)
// Clear villages for teams that have no leader and
// mark side as lost if it should be removed from carryover.
for (std::vector<team>::iterator tm_beg = teams_.begin(), tm = tm_beg,
tm_end = teams_.end(); tm != tm_end; ++tm)
{ {
if (not_defeated.find(tm - tm_beg + 1) == not_defeated.end()) { if(tm.defeat_condition() == team::NEVER)
tm->clear_villages(); {
not_defeated.insert(tm.side());
}
// Clear villages for teams that have no leader and
// mark side as lost if it should be removed from carryover.
if (not_defeated.find(tm.side()) == not_defeated.end())
{
tm.clear_villages();
// invalidate_all() is overkill and expensive but this code is // invalidate_all() is overkill and expensive but this code is
// run rarely so do it the expensive way. // run rarely so do it the expensive way.
gui_->invalidate_all(); gui_->invalidate_all();
if (!tm->fight_on_without_leader() && remove_from_carryover_on_leaders_loss_) { if (remove_from_carryover_on_defeat_)
tm->set_lost(); {
tm.set_lost();
} }
} }
} }

View File

@ -127,8 +127,8 @@ public:
void set_victory_when_enemies_defeated(bool e) void set_victory_when_enemies_defeated(bool e)
{ victory_when_enemies_defeated_ = e; } { victory_when_enemies_defeated_ = e; }
void set_remove_from_carryover_on_leaders_loss(bool e) void set_remove_from_carryover_on_defeat(bool e)
{ remove_from_carryover_on_leaders_loss_ = e; } { remove_from_carryover_on_defeat_= e; }
end_level_data& get_end_level_data() { end_level_data& get_end_level_data() {
return end_level_data_; return end_level_data_;
} }
@ -282,7 +282,7 @@ private:
std::vector<const_item_ptr> wml_commands_; std::vector<const_item_ptr> wml_commands_;
bool victory_when_enemies_defeated_; bool victory_when_enemies_defeated_;
bool remove_from_carryover_on_leaders_loss_; bool remove_from_carryover_on_defeat_;
end_level_data end_level_data_; end_level_data end_level_data_;
std::vector<std::string> victory_music_; std::vector<std::string> victory_music_;
std::vector<std::string> defeat_music_; std::vector<std::string> defeat_music_;

View File

@ -370,7 +370,7 @@ LEVEL_RESULT playsingle_controller::play_scenario(
} }
set_victory_when_enemies_defeated(level_["victory_when_enemies_defeated"].to_bool(true)); set_victory_when_enemies_defeated(level_["victory_when_enemies_defeated"].to_bool(true));
set_remove_from_carryover_on_leaders_loss(level_["remove_from_carryover_on_leaders_loss"].to_bool(true)); set_remove_from_carryover_on_defeat(level_["remove_from_carryover_on_defeat"].to_bool(true));
end_level_data &end_level = get_end_level_data(); end_level_data &end_level = get_end_level_data();
end_level.carryover_percentage = level_["carryover_percentage"].to_int(game_config::gold_carryover_percentage); end_level.carryover_percentage = level_["carryover_percentage"].to_int(game_config::gold_carryover_percentage);
end_level.carryover_add = level_["carryover_add"].to_bool(); end_level.carryover_add = level_["carryover_add"].to_bool();

View File

@ -1182,9 +1182,9 @@ static int impl_side_get(lua_State *L)
return_string_attrib("name", t.name()); return_string_attrib("name", t.name());
return_string_attrib("color", t.color()); return_string_attrib("color", t.color());
return_cstring_attrib("controller", t.controller_string()); return_cstring_attrib("controller", t.controller_string());
return_bool_attrib("fight_on_without_leader", t.fight_on_without_leader()); return_string_attrib("defeat_condition", team::defeat_condition_to_string(t.defeat_condition()));
return_bool_attrib("lost", t.lost()); return_bool_attrib("lost", t.lost());
if (strcmp(m, "recruit") == 0) { if (strcmp(m, "recruit") == 0) {
std::set<std::string> const &recruits = t.recruits(); std::set<std::string> const &recruits = t.recruits();
lua_createtable(L, recruits.size(), 0); lua_createtable(L, recruits.size(), 0);
@ -1226,7 +1226,7 @@ static int impl_side_set(lua_State *L)
modify_string_attrib("team_name", t.change_team(value, t.user_team_name())); modify_string_attrib("team_name", t.change_team(value, t.user_team_name()));
modify_string_attrib("controller", t.change_controller(value)); modify_string_attrib("controller", t.change_controller(value));
modify_string_attrib("color", t.set_color(value)); modify_string_attrib("color", t.set_color(value));
modify_bool_attrib("fight_on_without_leader", t.set_fight_on_without_leader(value)); modify_string_attrib("defeat_condition", t.set_defeat_condition_string(value));
modify_bool_attrib("lost", t.set_lost(value)); modify_bool_attrib("lost", t.set_lost(value));
if (strcmp(m, "recruit") == 0) { if (strcmp(m, "recruit") == 0) {

View File

@ -49,7 +49,7 @@ const int team::default_team_gold_ = 100;
// Update this list of attributes if you change what is used to define a side // Update this list of attributes if you change what is used to define a side
// (excluding those attributes used to define the side's leader). // (excluding those attributes used to define the side's leader).
const std::set<std::string> team::attributes = boost::assign::list_of("ai_config") const std::set<std::string> team::attributes = boost::assign::list_of("ai_config")
("color")("controller")("current_player")("fight_on_without_leader")("flag") ("color")("controller")("current_player")("defeat_condition")("flag")
("flag_icon")("fog")("fog_data")("gold")("hidden")("income") ("flag_icon")("fog")("fog_data")("gold")("hidden")("income")
("no_leader")("objectives")("objectives_changed")("persistent")("lost") ("no_leader")("objectives")("objectives_changed")("persistent")("lost")
("recall_cost")("recruit")("save_id")("scroll_to_leader") ("recall_cost")("recruit")("save_id")("scroll_to_leader")
@ -70,6 +70,36 @@ const std::vector<team>& teams_manager::get_teams()
return *teams; return *teams;
} }
team::DEFEAT_CONDITION team::parse_defeat_condition(const std::string& cond, team::DEFEAT_CONDITION def)
{
if(cond == "no_leader")
return team::NO_LEADER;
else if (cond == "no_unit")
return team::NO_UNITS;
else if (cond == "never")
return team::NEVER;
else if (cond == "always")
return team::ALWAYS;
else
return def;
//throw game::game_error("Cannot parse string " + cond +" to a DEFEAT_CONDITION");
}
std::string team::defeat_condition_to_string(DEFEAT_CONDITION cond)
{
switch(cond)
{
case team::NO_LEADER:
return "no_leader";
case team::NO_UNITS:
return "no_unit";
case team::NEVER:
return "never";
case team::ALWAYS:
return "always";
default:
throw game::game_error("Found corrupted DEFEAT_CONDITION");
}
}
team::team_info::team_info() : team::team_info::team_info() :
name(), name(),
gold(0), gold(0),
@ -100,7 +130,7 @@ team::team_info::team_info() :
allow_player(false), allow_player(false),
chose_random(false), chose_random(false),
no_leader(true), no_leader(true),
fight_on_without_leader(false), defeat_condition(team::NO_LEADER),
hidden(true), hidden(true),
no_turn_confirmation(false), no_turn_confirmation(false),
color(), color(),
@ -131,7 +161,7 @@ void team::team_info::read(const config &cfg)
allow_player = cfg["allow_player"].to_bool(true); allow_player = cfg["allow_player"].to_bool(true);
chose_random = cfg["chose_random"].to_bool(false); chose_random = cfg["chose_random"].to_bool(false);
no_leader = cfg["no_leader"].to_bool(); no_leader = cfg["no_leader"].to_bool();
fight_on_without_leader = cfg["fight_on_without_leader"].to_bool(false); defeat_condition = team::parse_defeat_condition(cfg["defeat_condition"], team::NO_LEADER);
hidden = cfg["hidden"].to_bool(); hidden = cfg["hidden"].to_bool();
no_turn_confirmation = cfg["suppress_end_turn_confirmation"].to_bool(); no_turn_confirmation = cfg["suppress_end_turn_confirmation"].to_bool();
side = cfg["side"].to_int(1); side = cfg["side"].to_int(1);
@ -258,7 +288,7 @@ void team::team_info::write(config& cfg) const
cfg["allow_player"] = allow_player; cfg["allow_player"] = allow_player;
cfg["chose_random"] = chose_random; cfg["chose_random"] = chose_random;
cfg["no_leader"] = no_leader; cfg["no_leader"] = no_leader;
cfg["fight_on_without_leader"] = fight_on_without_leader; cfg["defeat_condition"] = team::defeat_condition_to_string(defeat_condition);
cfg["hidden"] = hidden; cfg["hidden"] = hidden;
cfg["suppress_end_turn_confirmation"] = no_turn_confirmation; cfg["suppress_end_turn_confirmation"] = no_turn_confirmation;
cfg["scroll_to_leader"] = scroll_to_leader; cfg["scroll_to_leader"] = scroll_to_leader;

View File

@ -33,7 +33,9 @@ class team : public savegame::savegame_config
{ {
public: public:
enum CONTROLLER { HUMAN, AI, NETWORK, NETWORK_AI, IDLE, EMPTY }; enum CONTROLLER { HUMAN, AI, NETWORK, NETWORK_AI, IDLE, EMPTY };
enum DEFEAT_CONDITION {NO_LEADER, NO_UNITS, NEVER, ALWAYS};
static DEFEAT_CONDITION parse_defeat_condition(const std::string& cond, team::DEFEAT_CONDITION def);
static std::string defeat_condition_to_string(DEFEAT_CONDITION cond);
private: private:
class shroud_map { class shroud_map {
public: public:
@ -104,7 +106,7 @@ private:
bool allow_player; bool allow_player;
bool chose_random; bool chose_random;
bool no_leader; bool no_leader;
bool fight_on_without_leader; DEFEAT_CONDITION defeat_condition;
bool hidden; bool hidden;
bool no_turn_confirmation; // Can suppress confirmations when ending a turn. bool no_turn_confirmation; // Can suppress confirmations when ending a turn.
@ -265,8 +267,10 @@ public:
void set_auto_shroud_updates(bool value) { auto_shroud_updates_ = value; } void set_auto_shroud_updates(bool value) { auto_shroud_updates_ = value; }
bool get_disallow_observers() const {return info_.disallow_observers; } bool get_disallow_observers() const {return info_.disallow_observers; }
bool no_leader() const { return info_.no_leader; } bool no_leader() const { return info_.no_leader; }
bool fight_on_without_leader() const { return info_.fight_on_without_leader; } DEFEAT_CONDITION defeat_condition() const { return info_.defeat_condition; }
void set_fight_on_without_leader(bool value) { info_.fight_on_without_leader = value; } void set_defeat_condition(DEFEAT_CONDITION value) { info_.defeat_condition = value; }
///sets the defeat condition if @param value is a valid defeat condition, otherwise nothing happes.
void set_defeat_condition_string(const std::string& value) { info_.defeat_condition = parse_defeat_condition(value, info_.defeat_condition); }
void have_leader(bool value=true) { info_.no_leader = !value; } void have_leader(bool value=true) { info_.no_leader = !value; }
bool hidden() const { return info_.hidden; } bool hidden() const { return info_.hidden; }
void set_hidden(bool value) { info_.hidden=value; } void set_hidden(bool value) { info_.hidden=value; }