mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-02 12:15:03 +00:00

using this shell script: find src -type f -print0 | xargs -0 sed -i "s|Copyright (C) \([[:digit:]]*\)\([ ]*\)-\([ ]*\)2015|Copyright (C) \1\2-\32016|g"
285 lines
7.5 KiB
C++
285 lines
7.5 KiB
C++
/*
|
|
Copyright (C) 2003 - 2016 by David White <dave@whitevine.net>
|
|
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY.
|
|
|
|
See the COPYING file for more details.
|
|
*/
|
|
|
|
#include "carryover.hpp"
|
|
|
|
#include "global.hpp"
|
|
|
|
#include "config.hpp"
|
|
#include "team.hpp"
|
|
#include "unit.hpp"
|
|
#include <boost/foreach.hpp>
|
|
#include <cassert>
|
|
|
|
carryover::carryover(const config& side)
|
|
: add_(!side["carryover_add"].empty() ? side["carryover_add"].to_bool() : side["add"].to_bool())
|
|
, current_player_(side["current_player"])
|
|
, gold_(!side["carryover_gold"].empty() ? side["carryover_gold"].to_int() : side["gold"].to_int())
|
|
// if we load it from a snapshot we need to read the recruits from "recruits" and not from "previous_recruits".
|
|
, previous_recruits_(side.has_attribute("recruit") ? utils::set_split(side["recruit"]) :utils::set_split(side["previous_recruits"]))
|
|
, recall_list_()
|
|
, save_id_(side["save_id"])
|
|
, variables_(side.child_or_empty("variables"))
|
|
{
|
|
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");
|
|
}
|
|
}
|
|
|
|
carryover::carryover(const team& t, const int gold, const bool add)
|
|
: add_ (add)
|
|
, current_player_(t.current_player())
|
|
, gold_(gold)
|
|
, previous_recruits_(t.recruits())
|
|
, recall_list_()
|
|
, save_id_(t.save_id())
|
|
, variables_(t.variables())
|
|
{
|
|
BOOST_FOREACH(const unit_const_ptr & u, t.recall_list()) {
|
|
recall_list_.push_back(config());
|
|
u->write(recall_list_.back());
|
|
}
|
|
}
|
|
|
|
static const int default_gold_qty = 100;
|
|
|
|
void carryover::transfer_all_gold_to(config& side_cfg){
|
|
|
|
int cfg_gold = side_cfg["gold"].to_int();
|
|
|
|
if(side_cfg["gold"].empty()) {
|
|
cfg_gold = default_gold_qty;
|
|
side_cfg["gold"] = cfg_gold;
|
|
}
|
|
|
|
if(add_ && gold_ > 0){
|
|
side_cfg["gold"] = cfg_gold + gold_;
|
|
}
|
|
else if(gold_ > cfg_gold){
|
|
side_cfg["gold"] = gold_;
|
|
}
|
|
side_cfg.child_or_add("variables").swap(variables_);
|
|
variables_.clear();
|
|
gold_ = 0;
|
|
}
|
|
|
|
void carryover::transfer_all_recruits_to(config& side_cfg){
|
|
std::string can_recruit_str = utils::join(previous_recruits_, ",");
|
|
previous_recruits_.clear();
|
|
side_cfg["previous_recruits"] = can_recruit_str;
|
|
}
|
|
|
|
void carryover::transfer_all_recalls_to(config& side_cfg){
|
|
BOOST_FOREACH(const config & u_cfg, recall_list_) {
|
|
side_cfg.add_child("unit", u_cfg);
|
|
}
|
|
recall_list_.clear();
|
|
}
|
|
|
|
std::string carryover::get_recruits(bool erase){
|
|
// Join the previous recruits into a string.
|
|
std::string can_recruit_str = utils::join(previous_recruits_);
|
|
if ( erase )
|
|
// Clear the previous recruits.
|
|
previous_recruits_.clear();
|
|
|
|
return can_recruit_str;
|
|
}
|
|
|
|
const std::string carryover::to_string(){
|
|
std::string side = "";
|
|
side.append("Side " + save_id_ + ": gold " + str_cast<int>(gold_) + " recruits " + get_recruits(false) + " units ");
|
|
BOOST_FOREACH(const config & u_cfg, recall_list_) {
|
|
side.append(u_cfg["name"].str() + ", ");
|
|
}
|
|
return side;
|
|
}
|
|
|
|
void carryover::to_config(config& cfg){
|
|
config& side = cfg.add_child("side");
|
|
side["save_id"] = save_id_;
|
|
side["gold"] = gold_;
|
|
side["add"] = add_;
|
|
side["current_player"] = current_player_;
|
|
side["previous_recruits"] = get_recruits(false);
|
|
BOOST_FOREACH(const config & u_cfg, recall_list_)
|
|
side.add_child("unit", u_cfg);
|
|
}
|
|
|
|
carryover_info::carryover_info(const config& cfg, bool from_snpashot)
|
|
: carryover_sides_()
|
|
, variables_(cfg.child_or_empty("variables"))
|
|
, rng_(cfg)
|
|
, wml_menu_items_()
|
|
, next_scenario_(cfg["next_scenario"])
|
|
, next_underlying_unit_id_(cfg["next_underlying_unit_id"].to_int(0))
|
|
{
|
|
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));
|
|
}
|
|
BOOST_FOREACH(const config& item, cfg.child_range("menu_item"))
|
|
{
|
|
wml_menu_items_.push_back(new config(item));
|
|
}
|
|
}
|
|
|
|
std::vector<carryover>& carryover_info::get_all_sides() {
|
|
return carryover_sides_;
|
|
}
|
|
|
|
void carryover_info::add_side(const config& cfg) {
|
|
carryover_sides_.push_back(carryover(cfg));
|
|
}
|
|
|
|
void carryover_info::remove_side(const std::string& id) {
|
|
for (std::vector<carryover>::iterator it = carryover_sides_.begin();
|
|
it != carryover_sides_.end(); ++it) {
|
|
|
|
if (it->get_save_id() == id) {
|
|
carryover_sides_.erase(it);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
struct save_id_equals
|
|
{
|
|
save_id_equals(std::string val) : value (val) {}
|
|
bool operator () (carryover& v2)
|
|
{
|
|
return value == v2.get_save_id();
|
|
}
|
|
|
|
std::string value;
|
|
};
|
|
|
|
void carryover_info::transfer_all_to(config& side_cfg){
|
|
if(side_cfg["save_id"].empty()){
|
|
side_cfg["save_id"] = side_cfg["id"];
|
|
}
|
|
std::vector<carryover>::iterator iside = std::find_if(
|
|
carryover_sides_.begin(),
|
|
carryover_sides_.end(),
|
|
save_id_equals(side_cfg["save_id"])
|
|
);
|
|
if(iside != carryover_sides_.end())
|
|
{
|
|
iside->transfer_all_gold_to(side_cfg);
|
|
iside->transfer_all_recalls_to(side_cfg);
|
|
iside->transfer_all_recruits_to(side_cfg);
|
|
carryover_sides_.erase(iside);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
//if no carryover was found for this side, check if starting gold is defined
|
|
if(!side_cfg.has_attribute("gold") || side_cfg["gold"].empty()){
|
|
side_cfg["gold"] = default_gold_qty;
|
|
}
|
|
}
|
|
}
|
|
|
|
void carryover_info::transfer_to(config& level)
|
|
{
|
|
if(!level.has_attribute("next_underlying_unit_id"))
|
|
{
|
|
level["next_underlying_unit_id"] = next_underlying_unit_id_;
|
|
}
|
|
|
|
//if the game has been loaded from a snapshot, the existing variables will be the current ones
|
|
if(!level.has_child("variables")) {
|
|
level.add_child("variables", variables_);
|
|
}
|
|
|
|
config::attribute_value & seed_value = level["random_seed"];
|
|
if ( seed_value.empty() ) {
|
|
seed_value = rng_.get_random_seed_str();
|
|
level["random_calls"] = rng_.get_random_calls();
|
|
}
|
|
|
|
if(!level.has_child("menu_item")){
|
|
BOOST_FOREACH(config& item , wml_menu_items_)
|
|
{
|
|
level.add_child("menu_item").swap(item);
|
|
}
|
|
}
|
|
|
|
next_scenario_ = "";
|
|
variables_ = config();
|
|
wml_menu_items_.clear();
|
|
|
|
}
|
|
|
|
const config carryover_info::to_config()
|
|
{
|
|
config cfg;
|
|
cfg["next_underlying_unit_id"] = next_underlying_unit_id_;
|
|
cfg["next_scenario"] = next_scenario_;
|
|
|
|
BOOST_FOREACH(carryover& c, carryover_sides_){
|
|
c.to_config(cfg);
|
|
}
|
|
|
|
cfg["random_seed"] = rng_.get_random_seed_str();
|
|
cfg["random_calls"] = rng_.get_random_calls();
|
|
|
|
cfg.add_child("variables", variables_);
|
|
BOOST_FOREACH(const config& item , wml_menu_items_)
|
|
{
|
|
cfg.add_child("menu_item", item);
|
|
}
|
|
return cfg;
|
|
}
|
|
|
|
carryover* carryover_info::get_side(std::string save_id){
|
|
BOOST_FOREACH(carryover& side, carryover_sides_){
|
|
if(side.get_save_id() == save_id){
|
|
return &side;
|
|
}
|
|
}
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|