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:
commit
50ed2187e1
12 changed files with 131 additions and 101 deletions
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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. > */
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -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_);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue