Skip to content

Commit

Permalink
refactor end_level_data, end_level_exception and LEVEL_RESULT
Browse files Browse the repository at this point in the history
I removed the NONE value of LEVEL_RESULT because 'LEVEL_RESULT==NONE'
was basicly the same information as '!end_level_data.transient.disabled'

I removed end_level_data.transient.disabled and instead store the end
level_data as an optional<end_level_data> to remember whether we already
have an end_level_data

I removed the SKIP_TO_LINGER value of LEVEL_RESULT because it was not
possible that play_scenario returned SKIP_TO_LINGER (so i removed that
code in playcampaign.cpp that handled this case)

I replaced playsingle_controller::level_result_ and
end_level_exception/struct::result which both held more or less the same
data with end_level_data::is_vitory, in case of QUIT the
optional<end_level_data> is empty (none_t)

I also reordered the if cases in playsingle_controller::play_scenario to
simplify.
  • Loading branch information
gfgtdf committed Mar 1, 2015
1 parent 5ac4fba commit 30e670f
Show file tree
Hide file tree
Showing 16 changed files with 193 additions and 208 deletions.
1 change: 0 additions & 1 deletion src/game_end_exceptions.cpp
Expand Up @@ -23,7 +23,6 @@ transient_end_level::transient_end_level()
, linger_mode(true)
, custom_endlevel_music()
, reveal_map(true)
, disabled(false)
{}

end_level_data::end_level_data()
Expand Down
37 changes: 13 additions & 24 deletions src/game_end_exceptions.hpp
Expand Up @@ -33,12 +33,10 @@
#include <boost/variant/variant.hpp>

MAKE_ENUM(LEVEL_RESULT,
(NONE, "none")
(VICTORY, "victory")
(DEFEAT, "defeat")
(QUIT, "quit")
(OBSERVER_END, "observer_end")
(SKIP_TO_LINGER,"skip_to_linger")
)
MAKE_ENUM_STREAM_OPS1(LEVEL_RESULT)

Expand Down Expand Up @@ -96,7 +94,7 @@ class restart_turn_exception
* Struct used to transmit info caught from an end_turn_exception.
*/
struct end_level_struct {
LEVEL_RESULT result;
bool is_quit;
};

/**
Expand All @@ -108,17 +106,17 @@ class end_level_exception
{
public:

end_level_exception(LEVEL_RESULT res)
end_level_exception(bool isquit = false)
: tlua_jailbreak_exception()
, std::exception()
, result(res)
, is_quit(isquit)
{
}

LEVEL_RESULT result;
bool is_quit;

end_level_struct to_struct() {
end_level_struct els = {result};
end_level_struct els = {is_quit};
return els;
}

Expand Down Expand Up @@ -188,20 +186,6 @@ class get_signal_type : public boost::static_visitor<END_PLAY_SIGNAL_TYPE> {
}
};

class get_result : public boost::static_visitor<LEVEL_RESULT> {
public:
LEVEL_RESULT operator()(restart_turn_struct & ) const
{
return NONE;
}

LEVEL_RESULT operator()(end_level_struct & s) const
{
return s.result;
}
};


/**
* The non-persistent part of end_level_data
*/
Expand All @@ -213,7 +197,6 @@ struct transient_end_level{
bool linger_mode; /**< Should linger mode be invoked? */
std::string custom_endlevel_music; /**< Custom short music played at the end. */
bool reveal_map; /**< Should we reveal map when game is ended? (Multiplayer only) */
bool disabled; /**< Limits execution of tag [endlevel] to a single time > */
};

/**
Expand All @@ -228,7 +211,7 @@ struct end_level_data
bool replay_save; /**< Should a replay save be made? */
bool proceed_to_next_level; /**< whether to proceed to the next scenario, equals (res == VICTORY) in sp. We need to save this in saves during linger mode. > */
transient_end_level transient;

bool is_victory;
void write(config& cfg) const;

void read(const config& cfg);
Expand All @@ -240,5 +223,11 @@ struct end_level_data
return r;
}
};

inline void throw_quit_game_exception()
{
// Distinguish 'Quit' from 'Regular' end_level_exceptions to solve the following problem:
// If a player quits the game during an event after an [endlevel] occurs, the game won't
// Quit but continue with the [endlevel] instead.
throw end_level_exception(true);
}
#endif /* ! GAME_END_EXCEPTIONS_HPP_INCLUDED */
33 changes: 14 additions & 19 deletions src/game_initialization/playcampaign.cpp
Expand Up @@ -171,7 +171,8 @@ LEVEL_RESULT play_replay(display& disp, saved_game& gamestate, const config& gam
e.show(disp);
}
}
return NONE;
//TODO: when can this happen?
return VICTORY;
}

static LEVEL_RESULT playsingle_scenario(const config& game_config,
Expand All @@ -188,25 +189,20 @@ static LEVEL_RESULT playsingle_scenario(const config& game_config,

LEVEL_RESULT res = playcontroller.play_scenario(story, skip_replay);

end_level = playcontroller.get_end_level_data_const();

if (res == QUIT)
{
return QUIT;
}
//if we are loading from linger mode then we already did this.
if(res != SKIP_TO_LINGER)
{
show_carryover_message(state_of_game, playcontroller, disp, end_level, res);
}

end_level = playcontroller.get_end_level_data_const();

show_carryover_message(state_of_game, playcontroller, disp, end_level, res);
if(!disp.video().faked())
{
try {
playcontroller.maybe_linger();
} catch(end_level_exception& e) {
if (e.result == QUIT) {
return QUIT;
}
} catch(end_level_exception&) {
return QUIT;
}
}
state_of_game.set_snapshot(playcontroller.to_config());
Expand All @@ -226,8 +222,6 @@ static LEVEL_RESULT playmp_scenario(const config& game_config,
game_config, tdata, disp.video(), skip_replay, blindfold_replay, io_type == IO_SERVER);
LEVEL_RESULT res = playcontroller.play_scenario(story, skip_replay);

end_level = playcontroller.get_end_level_data_const();

//Check if the player started as mp client and changed to host
if (io_type == IO_CLIENT && playcontroller.is_host())
io_type = IO_SERVER;
Expand All @@ -236,7 +230,10 @@ static LEVEL_RESULT playmp_scenario(const config& game_config,
{
return QUIT;
}
if(res != OBSERVER_END && res != SKIP_TO_LINGER)

end_level = playcontroller.get_end_level_data_const();

if(res != OBSERVER_END)
{
//We need to call this before linger because it prints the defeated/victory message.
//(we want to see that message before entering the linger mode)
Expand All @@ -246,10 +243,8 @@ static LEVEL_RESULT playmp_scenario(const config& game_config,
{
try {
playcontroller.maybe_linger();
} catch(end_level_exception& e) {
if (e.result == QUIT) {
return QUIT;
}
} catch(end_level_exception&) {
return QUIT;
}
}
playcontroller.update_savegame_snapshot();
Expand Down
6 changes: 2 additions & 4 deletions src/game_launcher.cpp
Expand Up @@ -593,7 +593,7 @@ int game_launcher::unit_test()

try {
LEVEL_RESULT res = play_game(disp(),state_,game_config_manager::get()->game_config(), game_config_manager::get()->terrain_types(), IO_SERVER, false, false, false, true);
if (!(res == VICTORY || res == NONE) || lg::broke_strict()) {
if (!(res == VICTORY) || lg::broke_strict()) {
return 1;
}
} catch (game::load_game_exception &) {
Expand Down Expand Up @@ -629,12 +629,10 @@ int game_launcher::unit_test()
try {
//LEVEL_RESULT res = play_game(disp(), state_, game_config_manager::get()->game_config(), IO_SERVER, false,false,false,true);
LEVEL_RESULT res = ::play_replay(disp(), state_, game_config_manager::get()->game_config(), game_config_manager::get()->terrain_types(), true);
if (!(res == VICTORY || res == NONE)) {
if (!(res == VICTORY)) {
std::cerr << "Observed failure on replay" << std::endl;
return 4;
}
/*::play_replay(disp(),state_,game_config_manager::get()->game_config(),
video_);*/
clear_loaded_game();
} catch (game::load_game_exception &) {
std::cerr << "Load_game_exception encountered during play_replay!" << std::endl;
Expand Down
4 changes: 2 additions & 2 deletions src/hotkey/command_executor.cpp
Expand Up @@ -522,7 +522,7 @@ void key_event(display& disp, const SDL_KeyboardEvent& event, command_executor*
const int res = gui2::show_message(disp.video(), _("Quit"),
_("Do you really want to quit?"), gui2::tmessage::yes_no_buttons);
if(res != gui2::twindow::CANCEL) {
throw end_level_exception(QUIT);
throw_quit_game_exception();
} else {
return;
}
Expand Down Expand Up @@ -693,7 +693,7 @@ void execute_command(display& disp, const hotkey_command& command, command_execu
const int res = gui2::show_message(disp.video(), _("Quit"),
_("Do you really want to quit?"), gui2::tmessage::yes_no_buttons);
if (res != gui2::twindow::CANCEL) {
throw end_level_exception(QUIT);
throw_quit_game_exception();
}
}
break;
Expand Down
14 changes: 9 additions & 5 deletions src/menu_events.cpp
Expand Up @@ -2950,7 +2950,7 @@ void console_handler::do_save_quit() {
do_quit();
}
void console_handler::do_quit() {
throw end_level_exception(QUIT);
throw_quit_game_exception();
}
void console_handler::do_ignore_replay_errors() {
game_config::ignore_replay_errors = (get_data() != "off") ? true : false;
Expand All @@ -2963,12 +2963,14 @@ void console_handler::do_next_level()
{
if (!get_data().empty())
menu_handler_.gamedata().set_next_scenario(get_data());
end_level_data &e = menu_handler_.pc_.get_end_level_data();
end_level_data e;
e.transient.carryover_report = false;
e.prescenario_save = true;
e.transient.linger_mode = false;
e.proceed_to_next_level = true;
throw end_level_exception(VICTORY);
e.is_victory = true;
menu_handler_.pc_.set_end_level_data(e);
throw end_level_exception();
}

void console_handler::do_choose_level() {
Expand Down Expand Up @@ -3011,12 +3013,14 @@ void console_handler::do_choose_level() {

if (size_t(choice) < options.size()) {
menu_handler_.gamedata().set_next_scenario(options[choice]);
end_level_data &e = menu_handler_.pc_.get_end_level_data();
end_level_data e;
e.transient.carryover_report = false;
e.prescenario_save = true;
e.transient.linger_mode = false;
e.proceed_to_next_level = true;
throw end_level_exception(VICTORY);
e.is_victory = true;
menu_handler_.pc_.set_end_level_data(e);
throw end_level_exception();
}
}

Expand Down
27 changes: 17 additions & 10 deletions src/play_controller.cpp
Expand Up @@ -163,6 +163,14 @@ play_controller::play_controller(const config& level, saved_game& state_of_game,
resources::mp_settings = &saved_game_.mp_settings();

persist_.start_transaction();

if(const config& endlevel_cfg = level.child("end_level_data")) {
end_level_data el_data;
el_data.read(endlevel_cfg);
el_data.transient.carryover_report = false;
set_end_level_data(el_data);
}

n_unit::id_manager::instance().set_save_id(level_["next_underlying_unit_id"]);

// Setup victory and defeat music
Expand All @@ -185,7 +193,7 @@ play_controller::~play_controller()
hotkey::delete_all_wml_hotkeys();
clear_resources();
}

struct throw_end_level { void operator()(const config&) { throw_quit_game_exception(); } };
void play_controller::init(CVideo& video){
util::scoped_resource<loadscreen::global_loadscreen_manager*, util::delete_item> scoped_loadscreen_manager;
loadscreen::global_loadscreen_manager* loadscreen_manager = loadscreen::global_loadscreen_manager::get();
Expand All @@ -205,9 +213,6 @@ void play_controller::init(CVideo& video){
whiteboard_manager_.reset(new wb::manager());
resources::whiteboard = whiteboard_manager_;

// mouse_handler expects at least one team for linger mode to work.
if (gamestate_.board_.teams().empty()) end_level_data_.transient.linger_mode = false;

LOG_NG << "loading units..." << (SDL_GetTicks() - ticks_) << std::endl;
loadscreen::start_stage("load units");
preferences::encounter_all_content(gamestate_.board_);
Expand Down Expand Up @@ -267,7 +272,7 @@ void play_controller::init(CVideo& video){
plugins_context_.reset(new plugins_context("Game"));
plugins_context_->set_callback("save_game", boost::bind(&play_controller::save_game_auto, this, boost::bind(get_str, _1, "filename" )), true);
plugins_context_->set_callback("save_replay", boost::bind(&play_controller::save_replay_auto, this, boost::bind(get_str, _1, "filename" )), true);
plugins_context_->set_callback("quit", boost::bind(&play_controller::force_end_level, this, QUIT), false);
plugins_context_->set_callback("quit", throw_end_level(), false);
}

void play_controller::init_managers(){
Expand Down Expand Up @@ -452,8 +457,8 @@ config play_controller::to_config() const

gamestate_.write(cfg);

if(linger_) {
end_level_data_.write(cfg.add_child("end_level_data"));
if(end_level_data_.get_ptr() != NULL) {
end_level_data_->write(cfg.add_child("end_level_data"));
}

// Write terrain_graphics data in snapshot, too
Expand Down Expand Up @@ -821,7 +826,6 @@ const std::string& play_controller::select_defeat_music() const
return defeat_music_[rand() % defeat_music_.size()];
}


void play_controller::set_victory_music_list(const std::string& list)
{
victory_music_ = utils::split(list);
Expand Down Expand Up @@ -885,8 +889,11 @@ void play_controller::check_victory()

DBG_EE << "throwing end level exception..." << std::endl;
//Also proceed to the next scenario when another player survived.
end_level_data_.proceed_to_next_level = found_player || found_network_player;
throw end_level_exception(found_player ? VICTORY : DEFEAT);
end_level_data el_data;
el_data.proceed_to_next_level = found_player || found_network_player;
el_data.is_victory = found_player;
set_end_level_data(el_data);
throw end_level_exception();
}

void play_controller::process_oos(const std::string& msg) const
Expand Down
18 changes: 12 additions & 6 deletions src/play_controller.hpp
Expand Up @@ -111,7 +111,6 @@ class play_controller : public controller_base, public events::observer, public
void init_side_end();

virtual void force_end_turn() = 0;
virtual void force_end_level(LEVEL_RESULT res) = 0;
virtual void check_end_level() = 0;

virtual void on_not_observer() = 0;
Expand All @@ -125,11 +124,18 @@ class play_controller : public controller_base, public events::observer, public
{ victory_when_enemies_defeated_ = e; }
void set_remove_from_carryover_on_defeat(bool e)
{ remove_from_carryover_on_defeat_= e; }
end_level_data& get_end_level_data() {
return end_level_data_;

void set_end_level_data(const end_level_data& data) {
end_level_data_ = data;
}
void reset_end_level_data() {
end_level_data_ = boost::none_t();
}
bool is_regular_game_end() const {
return end_level_data_.get_ptr() != NULL;
}
const end_level_data& get_end_level_data_const() const {
return end_level_data_;
return *end_level_data_;
}
const std::vector<team>& get_teams_const() const {
return gamestate_.board_.teams_;
Expand Down Expand Up @@ -279,7 +285,6 @@ class play_controller : public controller_base, public events::observer, public

const std::string& select_victory_music() const;
const std::string& select_defeat_music() const;

void set_victory_music_list(const std::string& list);
void set_defeat_music_list(const std::string& list);

Expand All @@ -294,7 +299,8 @@ class play_controller : public controller_base, public events::observer, public

bool victory_when_enemies_defeated_;
bool remove_from_carryover_on_defeat_;
end_level_data end_level_data_;
typedef boost::optional<end_level_data> t_possible_end_level_data;
t_possible_end_level_data end_level_data_;
std::vector<std::string> victory_music_;
std::vector<std::string> defeat_music_;

Expand Down

0 comments on commit 30e670f

Please sign in to comment.