Merge pull request #172 from gfgtdf/random_tod

sync random_start time the normal way
This commit is contained in:
gfgtdf 2014-05-31 18:44:00 +02:00
commit dd8ac6754a
3 changed files with 63 additions and 40 deletions

View file

@ -229,8 +229,11 @@ void play_controller::init(CVideo& video){
team_builders.push_back(tb_ptr);
}
{
//sync traits of start units
//sync traits of start units and the random start time.
random_new::set_random_determinstic deterministic(gamedata_.rng());
tod_manager_.resolve_random(*random_new::generator);
BOOST_FOREACH(team_builder_ptr tb_ptr, team_builders)
{
gamedata_.build_team_stage_two(tb_ptr);

View file

@ -20,11 +20,17 @@
#include "log.hpp"
#include "map.hpp"
#include "play_controller.hpp"
#include "random_new.hpp"
#include "resources.hpp"
#include "unit.hpp"
#include "unit_abilities.hpp"
#include <boost/foreach.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/bind.hpp>
static lg::log_domain log_engine("engine");
#define LOG_NG LOG_STREAM(info, log_engine)
@ -37,15 +43,15 @@ tod_manager::tod_manager(const config& scenario_cfg):
turn_(scenario_cfg["turn_at"].to_int(1)),
num_turns_(scenario_cfg["turns"].to_int(-1))
{
// ? : operator doesn't work in this case.
if (scenario_cfg["current_time"].to_int(-17403) == -17403)
random_tod_ = scenario_cfg["random_start_time"];
else
random_tod_ = false;
currentTime_ = calculate_current_time(times_.size(), turn_, scenario_cfg["current_time"].to_int(0), true);
time_of_day::parse_times(scenario_cfg,times_);
currentTime_ = get_start_ToD(scenario_cfg);
//TODO:
//Very bad, since we're pretending to not modify the cfg. Needed to transfer the result
//to the network clients in a mp game, otherwise we have OOS.
config& non_const_config = const_cast<config&>(scenario_cfg);
non_const_config["current_time"] = currentTime_;
}
tod_manager& tod_manager::operator=(const tod_manager& manager)
@ -64,12 +70,47 @@ tod_manager& tod_manager::operator=(const tod_manager& manager)
return *this;
}
template <typename T>
struct greater
{
greater(T val) : value (val) {}
bool operator () (T v2)
{
return value < v2;
}
T value;
};
void tod_manager::resolve_random(random_new::rng& r)
{
//process the random_start_time string, which can be boolean yes/no true/false or a
//comma-separated string of integers >= 1 referring to the times_ array indices
std::vector<int> output;
boost::copy( utils::split(random_tod_.str())
| boost::adaptors::transformed(boost::bind(lexical_cast_default<int, std::string>, _1 , 0))
| boost::adaptors::filtered(greater<int>(0))
, std::back_inserter(output) );
if(!output.empty())
{
int chosen = output[r.next_random() % output.size()];
currentTime_ = calculate_current_time(times_.size(), turn_, chosen, true);
r.next_random();
}
else if (random_tod_.to_bool(false))
{
currentTime_ = calculate_current_time(times_.size(), turn_, r.next_random(), true);
}
random_tod_ = false;
}
config tod_manager::to_config() const
{
config cfg;
cfg["turn_at"] = turn_;
cfg["turns"] = num_turns_;
cfg["current_time"] = currentTime_;
cfg["random_start_time"] = random_tod_;
std::vector<time_of_day>::const_iterator t;
for(t = times_.begin(); t != times_.end(); ++t) {
@ -323,36 +364,6 @@ void tod_manager::remove_time_area(int area_index)
areas_.erase(areas_.begin() + area_index);
}
int tod_manager::get_start_ToD(const config &level) const
{
const config::attribute_value& current_time = level["current_time"];
if (!current_time.blank())
{
return calculate_current_time(times_.size(), turn_, current_time.to_int(0), true);
}
const int default_result = calculate_current_time(times_.size(), turn_, currentTime_);
const config::attribute_value& cfg_random_start_time = level["random_start_time"];
if(!cfg_random_start_time.blank()) {
const std::string& random_start_time = cfg_random_start_time.str();
//TODO:
//Here there is danger of OOS (bug #15948)
//But this randomization is needed on the other hand to make the "random start time" option
//in the mp game selection screen work.
//process the random_start_time string, which can be boolean yes/no true/false or a
//comma-separated string of integers >= 1 referring to the times_ array indices
const std::vector<std::string>& random_start_time_strings = utils::split(random_start_time);
const int random_index = calculate_current_time(random_start_time_strings.size(), turn_, rand(), true);
const int given_current_time = lexical_cast_default<int, std::string>(random_start_time_strings[random_index], 0) - 1;
if(given_current_time >= 0) return calculate_current_time(times_.size(), turn_, given_current_time, true);
if(cfg_random_start_time.to_bool(false)) return calculate_current_time(times_.size(), turn_, rand(), true);
}
return default_result;
}
const time_of_day& tod_manager::get_time_of_day_turn(const std::vector<time_of_day>& times, int nturn, const int current_time) const
{
const int time = calculate_current_time(times.size(), nturn, current_time);

View file

@ -23,6 +23,11 @@ class game_state;
class gamemap;
class unit_map;
namespace random_new
{
class rng;
}
//time of day and turn functionality
class tod_manager : public savegame::savegame_config
{
@ -32,7 +37,10 @@ class tod_manager : public savegame::savegame_config
tod_manager& operator=(const tod_manager& manager);
config to_config() const;
/**
handles random_start_time, should be called before the game starts.
*/
void resolve_random(random_new::rng& r);
int get_current_time(const map_location& loc = map_location::null_location()) const;
void set_current_time(int time) { currentTime_ = time; }
@ -165,7 +173,6 @@ class tod_manager : public savegame::savegame_config
*/
bool is_time_left();
private:
int get_start_ToD(const config& level) const;
/**
* Returns time of day object in the turn "nturn".
@ -219,5 +226,7 @@ class tod_manager : public savegame::savegame_config
int turn_;
//turn limit
int num_turns_;
//
config::attribute_value random_tod_;
};
#endif