Merge branch 'master' of git://github.com/wesnoth/wesnoth

This partially reverts mordante's change to drop abs
rather than correct the expected result of expression.

Conflicts:
	src/tests/test_config.cpp
This commit is contained in:
Chris Beck 2014-05-31 14:49:31 -04:00
commit 50ed2187e1
12 changed files with 131 additions and 101 deletions

View file

@ -434,7 +434,7 @@ tidiv<T, 8>::idiv(tfloat<T, 8>& lhs, tfloat<T, 8> rhs)
* value is also quite likely to happen, so the case is optimized.
*/
Uint32 lhs_value = abs(lhs.value_);
Uint32 lhs_value = std::abs(lhs.value_);
if(LIKELY(lhs_value <= 0x007FFFFFu)) {
FLOATING_POINT_EMULATION_TRACER_COUNT("lhs_value <= 0x007FFFFFu");
sal(lhs.value_, 8);
@ -508,7 +508,7 @@ tidiv<T, 8>::idiv(tfloat<T, 8>& lhs, tfloat<T, 8> rhs)
* number of positions.
*/
Uint32 rhs_value = abs(rhs.value_);
Uint32 rhs_value = std::abs(rhs.value_);
/*
* Will contain the offset from bit 0 of the LSB set. Since we're only

View file

@ -24,6 +24,7 @@ transient_end_level::transient_end_level()
, custom_endlevel_music()
, reveal_map(true)
, disabled(false)
, proceed_to_next_level(false)
{}
end_level_data::end_level_data()

View file

@ -91,6 +91,7 @@ struct transient_end_level{
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 > */
bool proceed_to_next_level; /**< whether to proceed to the next scenario, equals (res == VICTORY) in sp. > */
};
/**

View file

@ -325,6 +325,8 @@ void connect_engine::update_and_send_diff(bool update_time_of_day)
if (update_time_of_day) {
// Set random start ToD.
// This doesn't do anything since the "const" parameter is now really a const.
// We currently resolve the random tod on all clients seperately with the synced rng.
tod_manager tod_mng(level_);
}

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);
@ -1486,6 +1489,8 @@ void play_controller::check_victory()
}
DBG_NG << "throwing end level exception..." << std::endl;
//Also proceed to the next scenario when another player survived.
end_level_data_.transient.proceed_to_next_level = found_player || found_network_player;
throw end_level_exception(found_player ? VICTORY : DEFEAT);
}

View file

@ -97,10 +97,10 @@ static void clear_carryover_WML (game_state & gamestate) {
}
}
static void store_carryover(game_state& gamestate, playsingle_controller& playcontroller, display& disp, const end_level_data& end_level){
static void store_carryover(game_state& gamestate, playsingle_controller& playcontroller, display& disp, const end_level_data& end_level, const LEVEL_RESULT res){
bool has_next_scenario = !resources::gamedata->next_scenario().empty() &&
resources::gamedata->next_scenario() != "null";
//explain me: when could this be the case??
if(resources::teams->size() < 1){
gamestate.carryover_sides_start["next_scenario"] = resources::gamedata->next_scenario();
return;
@ -117,9 +117,12 @@ static void store_carryover(game_state& gamestate, playsingle_controller& playco
if (obs) {
title = _("Scenario Report");
} else {
} else if (res == VICTORY) {
title = _("Victory");
report << "<b>" << _("You have emerged victorious!") << "</b>\n\n";
} else {
title = _("Defeat");
report << _("You have been defeated!") << "\n";
}
std::vector<team> teams = playcontroller.get_teams_const();
@ -130,7 +133,7 @@ static void store_carryover(game_state& gamestate, playsingle_controller& playco
}
}
if (persistent_teams > 0 && (has_next_scenario ||
if (persistent_teams > 0 && ((has_next_scenario && end_level.transient.proceed_to_next_level)||
gamestate.classification().campaign_type == game_classification::TEST))
{
gamemap map = playcontroller.get_map_const();
@ -296,25 +299,17 @@ static LEVEL_RESULT playsingle_scenario(const config& game_config,
config& cfg_end_level = state_of_game.carryover_sides.child_or_add("end_level_data");
end_level.write(cfg_end_level);
if (res == DEFEAT) {
if (resources::persist != NULL)
resources::persist->end_transaction();
gui2::show_transient_message(disp.video(),
_("Defeat"),
_("You have been defeated!")
);
}
else if(res == VICTORY){
store_carryover(state_of_game, playcontroller, disp, end_level);
}
if (!disp.video().faked() && res != QUIT)
if (res != QUIT)
{
try {
playcontroller.maybe_linger();
} catch(end_level_exception& e) {
if (e.result == QUIT) {
return QUIT;
store_carryover(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;
}
}
}
}
@ -347,27 +342,26 @@ static LEVEL_RESULT playmp_scenario(const config& game_config,
if (io_type == IO_CLIENT && playcontroller.is_host())
io_type = IO_SERVER;
if (res == DEFEAT) {
if (resources::persist != NULL)
resources::persist->end_transaction();
gui2::show_transient_message(disp.video(),
_("Defeat"),
_("You have been defeated!")
);
}
else if(res == VICTORY){
store_carryover(state_of_game, playcontroller, disp, end_level);
}
else if(res == OBSERVER_END){
state_of_game.carryover_sides_start["next_scenario"] = resources::gamedata->next_scenario();
}
if (!disp.video().faked() && res != QUIT) {
try {
playcontroller.maybe_linger();
} catch(end_level_exception& e) {
if (e.result == QUIT) {
return QUIT;
if (res != QUIT)
{
if(res != OBSERVER_END)
{
//We need to call this before linger because it also prints the defeated/victory message.
//(we want to see that message before entering the linger mode)
store_carryover(state_of_game, playcontroller, disp, end_level, res);
}
else
{
state_of_game.carryover_sides_start["next_scenario"] = resources::gamedata->next_scenario();
}
if(!disp.video().faked())
{
try {
playcontroller.maybe_linger();
} catch(end_level_exception& e) {
if (e.result == QUIT) {
return QUIT;
}
}
}
}
@ -535,13 +529,16 @@ LEVEL_RESULT play_game(game_display& disp, game_state& gamestate,
gamestate.replay_start().clear();
// On DEFEAT, QUIT, or OBSERVER_END, we're done now
if (res != VICTORY)
//if(res == QUIT || ((res != VICTORY) && gamestate.carryover_sides_start["next_scenario"].empty()))
//If there is no next scenario we're done now.
if(res == QUIT || !end_level.transient.proceed_to_next_level || gamestate.carryover_sides_start["next_scenario"].empty())
{
gamestate.snapshot = config();
return res;
}
else if(res == OBSERVER_END)
{
if (res != OBSERVER_END || gamestate.carryover_sides_start["next_scenario"].empty()) {
gamestate.snapshot = config();
return res;
}
const int dlg_res = gui2::show_message(disp.video(), _("Game Over"),
_("This scenario has ended. Do you want to continue the campaign?"),
gui2::tmessage::yes_no_buttons);

View file

@ -164,6 +164,7 @@ void playsingle_controller::check_end_level()
}
return;
}
get_end_level_data().transient.proceed_to_next_level = (level_result_ == VICTORY);
throw end_level_exception(level_result_);
}
@ -522,6 +523,7 @@ LEVEL_RESULT playsingle_controller::play_scenario(
if(defeat_music.empty() != true)
sound::play_music_once(defeat_music);
persist_.end_transaction();
return DEFEAT;
} else {
return QUIT;
@ -989,6 +991,8 @@ void playsingle_controller::check_time_over(){
}
check_victory();
get_end_level_data().transient.proceed_to_next_level = false;
throw end_level_exception(DEFEAT);
}
}

View file

@ -1665,8 +1665,8 @@ surface rotate_any_surface(const surface& surf, float angle, int zoom, int offse
min_y = std::min(0.0F, std::min(point_1y, std::min(point_2y, point_3y)));
max_x = (angle > 90 && angle < 180) ? 0 : std::max(point_1x, std::max(point_2x, point_3x));
max_y = (angle > 180 && angle < 270) ? 0 : std::max(point_1y, std::max(point_2y, point_3y));
dst_w = static_cast<int>(ceil(abs(max_x) - min_x)) / zoom;
dst_h = static_cast<int>(ceil(abs(max_y) - min_y)) / zoom;
dst_w = static_cast<int>(ceil(std::abs(max_x) - min_x)) / zoom;
dst_h = static_cast<int>(ceil(std::abs(max_y) - min_y)) / zoom;
}
surface dst(create_neutral_surface(dst_w, dst_h));
{

View file

@ -133,7 +133,7 @@ BOOST_AUTO_TEST_CASE ( test_config_attribute_value )
x_int = c["x"].to_int();
BOOST_CHECK_EQUAL(x_int, 1);
x_dbl = c["x"].to_double();
BOOST_CHECK(abs(x_dbl - 1.499) < 1e-6);
BOOST_CHECK(std::abs(x_dbl - 1.499) < 1e-6);
c["x"] = 123456789123ll;

View file

@ -39,14 +39,14 @@ struct MLFixture
vb = map_location(10,8);
vc = map_location(0,9);
vz = map_location::ZERO();
vt1 = map_location(va.vector_negation());
vt2 = map_location(vb.vector_sum(vc));
vt3 = map_location(va.vector_sum(vc.vector_negation()));
vt1 = va.vector_negation();
vt2 = vb.vector_sum(vc);
vt3 = va.vector_sum(vc.vector_negation());
vs1 = map_location(vz.get_direction(nw));
vs2 = map_location(vz.get_direction(n).get_direction(ne));
vs3 = map_location(vz.get_direction(s).get_direction(se));
vs4 = map_location(vz.get_direction(sw).get_direction(se));
vs1 = vz.get_direction(nw);
vs2 = vz.get_direction(n).get_direction(ne);
vs3 = vz.get_direction(s).get_direction(se);
vs4 = vz.get_direction(sw).get_direction(se);
preset_locs.push_back(va);
preset_locs.push_back(vb);

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