Skip to content

Commit

Permalink
move carryover handling out of playcampaign.cpp
Browse files Browse the repository at this point in the history
this also makes a small change in the savefile format: [endlevel] ->
[end_level_data] in snapshots.

we still have the "store_carryover" function in playcampaign.cpp which does the visual message.
Note that the real carryover happens after linger mode while that message happens before linger mode this simplifies linger mode saves.
  • Loading branch information
gfgtdf committed Jun 15, 2014
1 parent 3574c44 commit 5bfce15
Show file tree
Hide file tree
Showing 12 changed files with 110 additions and 28 deletions.
52 changes: 50 additions & 2 deletions src/carryover.cpp
Expand Up @@ -20,6 +20,7 @@
#include "team.hpp"
#include "gamestatus.hpp"
#include <boost/foreach.hpp>
#include <cassert>

carryover::carryover(const config& side)
: add_(side["add"].to_bool())
Expand All @@ -33,6 +34,12 @@ carryover::carryover(const config& side)
{
BOOST_FOREACH(const config& u, side.child_range("unit")){
recall_list_.push_back(u);
config& u_back = recall_list_.back();
u_back.remove_attribute("side");
u_back.remove_attribute("goto_x");
u_back.remove_attribute("goto_y");
u_back.remove_attribute("x");
u_back.remove_attribute("y");
}
}

Expand Down Expand Up @@ -122,6 +129,10 @@ const std::string carryover::to_string(){
return side;
}

void carryover::set_gold(int gold){
gold_ = gold;
}

void carryover::to_config(config& cfg){
config& side = cfg.add_child("side");
side["save_id"] = save_id_;
Expand All @@ -135,7 +146,7 @@ void carryover::to_config(config& cfg){
side.add_child("unit", u_cfg);
}

carryover_info::carryover_info(const config& cfg)
carryover_info::carryover_info(const config& cfg, bool from_snpashot)
: carryover_sides_()
, end_level_()
, variables_(cfg.child_or_empty("variables"))
Expand All @@ -144,9 +155,27 @@ carryover_info::carryover_info(const config& cfg)
, next_scenario_(cfg["next_scenario"])
, next_underlying_unit_id_(cfg["next_underlying_unit_id"].to_int(0))
{
int turns_left = cfg["turns"].to_int() - cfg["turn_at"].to_int();
end_level_.read(cfg.child_or_empty("end_level_data"));
BOOST_FOREACH(const config& side, cfg.child_range("side")){
BOOST_FOREACH(const config& side, cfg.child_range("side"))
{
if(side["lost"].to_bool(false) || !side["persistent"].to_bool(true))
{
//this shouldnt happen outside a snpshot.
assert(from_snpashot);
continue;
}
this->carryover_sides_.push_back(carryover(side));
if(from_snpashot)
{
//adjust gold
int finishing_bonus_per_turn = cfg["map_villages_num"] * side["village_gold"] + side["income"];
int finishing_bonus = std::max(0, finishing_bonus_per_turn * turns_left);
if(end_level_.gold_bonus)
{
carryover_sides_.back().set_gold(div100rounded((finishing_bonus + side["gold"]) * end_level_.carryover_percentage));
}
}
}

wml_menu_items_.set_menu_items(cfg);
Expand Down Expand Up @@ -296,3 +325,22 @@ carryover* carryover_info::get_side(std::string save_id){
}
return NULL;
}


void carryover_info::merge_old_carryover(const carryover_info& old_carryover)
{
BOOST_FOREACH(const carryover & old_side, old_carryover.carryover_sides_)
{
std::vector<carryover>::iterator iside = std::find_if(
carryover_sides_.begin(),
carryover_sides_.end(),
save_id_equals(old_side.get_save_id())
);
//add the side if don't already have it.
if(iside == carryover_sides_.end())
{
this->carryover_sides_.push_back(old_side);
}
}
}

8 changes: 6 additions & 2 deletions src/carryover.hpp
Expand Up @@ -38,6 +38,7 @@ class carryover{
void initialize_team(config& side_cfg);
const std::string to_string();
void to_config(config& cfg);
void set_gold(int gold);
private:
bool add_;
std::string color_;
Expand Down Expand Up @@ -65,8 +66,9 @@ class carryover_info{
, next_scenario_()
, next_underlying_unit_id_()
{}
// Turns config from a loaded savegame into carryover_info
explicit carryover_info(const config& cfg);
/// Turns config from a loaded savegame into carryover_info
/// @param from_snapshot true if cfg is a [snapshot], false if cfg is [carryover_sides(_start)]
explicit carryover_info(const config& cfg, bool from_snapshot = false);

carryover* get_side(std::string save_id);
std::vector<carryover>& get_all_sides();
Expand Down Expand Up @@ -94,6 +96,8 @@ class carryover_info{
const std::string& next_scenario() const { return next_scenario_; }

const config to_config();

void merge_old_carryover(const carryover_info& old_carryover);
private:
std::vector<carryover> carryover_sides_;
end_level_data end_level_;
Expand Down
5 changes: 5 additions & 0 deletions src/game_board.cpp
Expand Up @@ -78,7 +78,9 @@ void game_board::all_survivors_to_recall() {
if (teams_[un.side() - 1].persistent()) {
un.new_turn();
un.new_scenario();
#if 0
teams_[un.side() - 1].recall_list().push_back(un);
#endif
}
}
}
Expand Down Expand Up @@ -263,6 +265,9 @@ void game_board::write_config(config & cfg) const {

//write the map
cfg["map_data"] = map_->write();

//Used by the carryover calculations.
cfg["map_villages_num"] = map_->villages().size();
}

temporary_unit_placer::temporary_unit_placer(unit_map& m, const map_location& loc, unit& u)
Expand Down
7 changes: 7 additions & 0 deletions src/game_end_exceptions.hpp
Expand Up @@ -228,6 +228,13 @@ struct end_level_data
void write(config& cfg) const;

void read(const config& cfg);

config to_config() const
{
config r;
write(r);
return r;
}
};

#endif /* ! GAME_END_EXCEPTIONS_HPP_INCLUDED */
11 changes: 11 additions & 0 deletions src/gamestatus.cpp
Expand Up @@ -700,6 +700,17 @@ void convert_old_saves(config& cfg){
carryover_sides_start["next_underlying_unit_id"] = cfg["next_underlying_unit_id"];
}
}

if(config& snapshot = cfg.child("snapshot"))
{
//make [end_level] -> [end_level_data] since its alo called [end_level_data] in the carryover.
if(config& end_level = cfg.child("end_level") )
{
snapshot.add_child("end_level_data", end_level);
snapshot.remove_child("end_level",0);
}
}

//1.12-1.13 end
LOG_RG<<"cfg after conversion "<<cfg<<"\n";
}
2 changes: 1 addition & 1 deletion src/play_controller.cpp
Expand Up @@ -752,7 +752,7 @@ config play_controller::to_config() const
if(linger_) {
config endlevel;
end_level_data_.write(endlevel);
cfg.add_child("endlevel", endlevel);
cfg.add_child("end_level_data", endlevel);
}

// Write terrain_graphics data in snapshot, too
Expand Down
27 changes: 8 additions & 19 deletions src/playcampaign.cpp
Expand Up @@ -66,10 +66,6 @@ static void store_carryover(saved_game& gamestate, playsingle_controller& playco
return;
}

carryover_info sides(gamestate.carryover_sides);

sides.transfer_from(*resources::gamedata);

std::ostringstream report;
std::string title;

Expand Down Expand Up @@ -108,19 +104,12 @@ static void store_carryover(saved_game& gamestate, playsingle_controller& playco

BOOST_FOREACH(const team &t, teams)
{
if (!t.persistent()){
continue;
} else if (t.lost()) {
sides.remove_side(t.save_id());
if (!t.persistent() || t.lost() || !t.is_human())
{
continue;
}
int carryover_gold = div100rounded((t.gold() + finishing_bonus) * end_level.carryover_percentage);
sides.transfer_from(t, carryover_gold);

if (!t.is_human()){
continue;
}


if (persistent_teams > 1) {
report << "\n<b>" << t.current_player() << "</b>\n";
}
Expand All @@ -132,8 +121,6 @@ static void store_carryover(saved_game& gamestate, playsingle_controller& playco
if (end_level.transient.carryover_report) {
gui2::show_transient_message(disp.video(), title, report.str(), "", true);
}

gamestate.carryover_sides_start = sides.to_config();
}

static void generate_scenario(config const*& scenario)
Expand Down Expand Up @@ -266,6 +253,7 @@ static LEVEL_RESULT playsingle_scenario(const config& game_config,
}
}
}
state_of_game.set_snapshot(playcontroller.to_config());

return res;
}
Expand Down Expand Up @@ -314,8 +302,9 @@ static LEVEL_RESULT playmp_scenario(const config& game_config,
}
}
}
}

}
state_of_game.set_snapshot(playcontroller.to_config());
return res;
}

Expand Down Expand Up @@ -466,9 +455,9 @@ LEVEL_RESULT play_game(game_display& disp, saved_game& gamestate,
save.save_game_automatic(disp.video(), true);
}
}


gamestate.convert_to_start_save();
recorder.clear();
gamestate.remove_old_scenario();

// On DEFEAT, QUIT, or OBSERVER_END, we're done now

Expand Down
1 change: 1 addition & 0 deletions src/playmp_controller.cpp
Expand Up @@ -623,6 +623,7 @@ void playmp_controller::do_idle_notification()

void playmp_controller::maybe_linger()
{
linger_ = true;
if (!get_end_level_data_const().transient.linger_mode) {
if(!is_host()) {
// If we continue without lingering we need to
Expand Down
7 changes: 5 additions & 2 deletions src/playsingle_controller.cpp
Expand Up @@ -404,7 +404,7 @@ possible_end_play_signal playsingle_controller::play_scenario_main_loop(end_leve
// if we loaded a save file in linger mode, skip to it.
if (linger_) {
//determine the bonus gold handling for this scenario
end_level.read(level_.child_or_empty("endlevel"));
end_level.read(level_.child_or_empty("end_level_data"));
end_level.transient.carryover_report = false;
end_level.transient.disabled = true;
end_level_struct els = { SKIP_TO_LINGER };
Expand Down Expand Up @@ -566,10 +566,11 @@ LEVEL_RESULT playsingle_controller::play_scenario(
}

// Add all the units that survived the scenario.
// this function doesn't move unit to the recalllist anymore i just keep this name to prevent merging conflicts.
LOG_NG << "Add units that survived the scenario to the recall list.\n";
gameboard_.all_survivors_to_recall();

gamestate_.set_snapshot(config());
gamestate_.remove_snapshot();
if(!is_observer()) {
persist_.end_transaction();
}
Expand Down Expand Up @@ -1127,6 +1128,8 @@ bool playsingle_controller::is_host() const

void playsingle_controller::maybe_linger()
{
//Make sure [end_level_data] gets writen into the snapshot even when skipping linger mode.
linger_ = true;
if (get_end_level_data_const().transient.linger_mode) {
linger();
}
Expand Down
14 changes: 14 additions & 0 deletions src/saved_game.cpp
Expand Up @@ -45,6 +45,7 @@
#include "util.hpp"

#include <boost/foreach.hpp>
#include <cassert>

static lg::log_domain log_engine("engine");
#define ERR_NG LOG_STREAM(err, log_engine)
Expand Down Expand Up @@ -253,3 +254,16 @@ void saved_game::remove_old_scenario()
replay_data = config();
replay_start_ = config();
}

void saved_game::convert_to_start_save()
{
assert(starting_pos_type_ == STARTINGPOS_SNAPSHOT);
carryover_info sides(starting_pos_, true);
sides.merge_old_carryover(carryover_info(carryover_sides));

carryover_sides_start = sides.to_config();
replay_data = config();
replay_start_ = config();
carryover_sides = config();
remove_snapshot();
}
2 changes: 1 addition & 1 deletion src/saved_game.hpp
Expand Up @@ -50,7 +50,7 @@ class saved_game
{
return starting_pos_type_ == STARTINGPOS_SNAPSHOT;
}

void convert_to_start_save();

config& get_starting_pos();
config& replay_start() { return replay_start_; }
Expand Down
2 changes: 1 addition & 1 deletion src/scripting/lua.cpp
Expand Up @@ -4026,7 +4026,7 @@ void LuaKernel::initialize()
/// elsewhere (in the C++ code).
/// Any child tags not in this list will be passed to Lua's on_load event.
static char const *handled_file_tags[] = {
"color_palette", "color_range", "display", "endlevel", "era",
"color_palette", "color_range", "display", "end_level_data", "era",
"event", "generator", "label", "lua", "map", "menu_item",
"modification", "music", "options", "side", "sound_source",
"story", "terrain_graphics", "time", "time_area", "tunnel",
Expand Down

0 comments on commit 5bfce15

Please sign in to comment.