35 #define LOG_NG LOG_STREAM(info, log_engine)
42 , turn_(scenario_cfg[
"turn_at"].to_int(1))
43 , num_turns_(scenario_cfg[
"turns"].to_int(-1))
44 , has_turn_event_fired_(!scenario_cfg[
"it_is_a_new_turn"].to_bool(true))
45 , has_tod_bonus_changed_(false)
46 , has_cfg_liminal_bonus_(false)
49 if(scenario_cfg[
"current_time"].to_int(-17403) == -17403) {
75 std::transform(output_strings.begin(), output_strings.end(), std::back_inserter(
output),
76 [](
const std::string& str) { return std::stoi(str); });
77 }
catch(
const std::invalid_argument&) {
99 cfg[
"turn_at"] =
turn_;
116 if(tod.id !=
"nulltod") {
117 tod.write(cfg.
add_child(
"time"), textdomain);
125 if(a_tod.xsrc.empty() && a_tod.ysrc.empty()) {
128 area[
"x"] = a_tod.xsrc;
129 area[
"y"] = a_tod.ysrc;
134 if(tod.
id !=
"nulltod") {
139 area[
"current_time"] = a_tod.currentTime;
141 if(!a_tod.id.empty()) {
142 area[
"id"] = a_tod.id;
171 if(
i->hexes.find(
loc) !=
i->hexes.end()) {
172 return i->currentTime;
185 if(
i->hexes.find(
loc) !=
i->hexes.end() && !
i->times.empty())
202 if(
i->hexes.find(
loc) !=
i->hexes.end() && !
i->times.empty())
212 assert(area_i <
static_cast<int>(
areas_.size()));
229 std::vector<int> mod_list;
230 std::vector<int> max_list;
231 std::vector<int> min_list;
236 std::array<map_location, 7> locs;
240 for(std::size_t
i = 0;
i < locs.size(); ++
i) {
241 const auto itor = units.
find(locs[
i]);
242 if(itor != units.
end() && !itor->incapacitated()) {
249 mod_list.push_back(unit_mod);
250 max_list.push_back(illum.
highest(
"max_value").first);
251 min_list.push_back(illum.
lowest(
"min_value").first);
253 if(unit_mod > most_add) {
255 }
else if(unit_mod < most_sub) {
261 const bool net_darker = most_add < -most_sub;
264 int best_result = terrain_light;
265 const int base_light = terrain_light + (net_darker ? most_add : most_sub);
267 for(std::size_t
i = 0;
i != mod_list.size(); ++
i) {
268 int result =
bounded_add(base_light, mod_list[
i], max_list[
i], min_list[
i]);
270 if(net_darker && result < best_result) {
271 best_result = result;
272 }
else if(!net_darker && result > best_result) {
273 best_result = result;
292 std::vector<time_of_day> new_scedule;
309 assert(area_index <
static_cast<int>(
areas_.size()));
310 areas_[area_index].hexes = locs;
316 assert(area_index <
static_cast<int>(
areas_.size()));
319 if(area.
times.empty() || schedule.empty()) {
323 }
else if(area.
times[area.
currentTime].lawful_bonus != schedule.front().lawful_bonus) {
328 area.
times = schedule;
334 assert(area_index <
static_cast<int>(
areas_.size()));
340 assert(area_index <
static_cast<int>(
areas_.size()));
341 return areas_[area_index].id;
346 std::vector<std::string> areas;
348 areas.push_back(area.id);
362 static const std::set<map_location> res;
376 if(
i->hexes.find(
loc) !=
i->hexes.end() && !
i->times.empty())
377 return {std::distance(
areas_.rbegin(),
i),
i->id};
388 area.
id = cfg[
"id"].str();
389 area.
xsrc = cfg[
"x"].str();
390 area.
ysrc = cfg[
"y"].str();
393 area.
hexes.insert(locs.begin(), locs.end());
404 area.
currentTime = time_cfg[
"current_time"].to_int(0);
411 if(area_id.empty()) {
417 if((*i).id == area_id) {
430 assert(area_index <
static_cast<int>(
areas_.size()));
436 const std::vector<time_of_day>& times,
int nturn,
const int current_time)
const
464 "change_turns_wml",
config {
487 const int new_turn = std::max<int>(num, 1);
488 LOG_NG <<
"changing current turn number from " <<
turn_ <<
" to " << new_turn;
506 set_turn(num, vars, increase_limit_if_needed);
521 if(number_of_times == 0) {
525 return modulo(time, number_of_times);
530 if(number_of_times == 0) {
534 return modulo(current_time + for_turn_number -
turn_, number_of_times);
549 assert(area_index <
static_cast<int>(
areas_.size()));
556 if(area.id == area_id) {
586 int fearless_chaotic = 0;
587 int fearless_lawful = 0;
589 std::set<int> bonuses;
590 for(
const auto& tod : schedule) {
593 bonuses.insert(std::abs(tod.lawful_bonus));
596 int target = std::max(fearless_chaotic, fearless_lawful);
600 for(
int bonus : bonuses) {
601 int liminal_effect = 0;
602 for(
const auto& tod : schedule) {
606 if(std::abs(target - liminal_effect) < delta) {
608 delta = std::abs(target - liminal_effect);
int generic_combat_modifier(int lawful_bonus, unit_alignments::type alignment, bool is_fearless, int max_liminal_bonus)
Returns the amount that a unit's damage should be multiplied by due to a given lawful_bonus.
Various functions that implement attacks and attack calculations.
std::string str(const std::string &fallback="") const
bool to_bool(bool def=false) const
A config object defines a single node in a WML file, with access to child nodes.
bool has_attribute(config_key_type key) const
config & add_child(config_key_type key)
config::attribute_value & get_variable(const std::string &varname)
throws invalid_variablename_exception if varname is no valid variable name.
std::vector< map_location > parse_location_range(const std::string &xvals, const std::string &yvals, bool with_border=false) const
Parses ranges of locations into a vector of locations, using this map's dimensions as bounds.
bool on_board_with_border(const map_location &loc) const
Encapsulates the map of the game.
const terrain_type & get_terrain_info(const t_translation::terrain_code &terrain) const
virtual void send_to_wesnothd(const config &, const std::string &="unknown") const
this class does not give synced random results derived classes might do.
uint32_t next_random()
Provides the next random draw.
int light_bonus(int base) const
Returns the light (lawful) bonus for this terrain when the time of day gives a base bonus.
static bool is_start_ToD(const std::string &)
void update_server_information() const
void replace_schedule(const config &time_cfg)
Replace the time of day schedule.
const time_of_day & get_time_of_day_turn(const std::vector< time_of_day > ×, int nturn, const int current_time) const
Returns time of day object in the turn "nturn".
const time_of_day get_illuminated_time_of_day(const unit_map &units, const gamemap &map, const map_location &loc, int for_turn=0) const
Returns time of day object for the passed turn at a location.
const std::vector< time_of_day > & times(const map_location &loc=map_location::null_location()) const
const std::string & get_area_id(int area_index) const
std::vector< std::string > get_area_ids() const
void modify_turns_by_wml(const std::string &mod)
const std::set< map_location > & get_area_by_index(int index) const
void remove_time_area(const std::string &id)
Removes a time area from config, making it follow the scenario's normal time-of-day sequence.
void set_current_time(int time)
void set_area_id(int area_index, const std::string &id)
config to_config(const std::string &textdomain="") const
int get_current_time(const map_location &loc=map_location::null_location()) const
void set_turn_by_wml(const int num, game_data *vars=nullptr, const bool increase_limit_if_needed=true)
Dynamically change the current turn number.
void add_time_area(const gamemap &map, const config &cfg)
Adds a new local time area from config, making it follow its own time-of-day sequence.
int get_current_area_time(int index) const
bool has_tod_bonus_changed_
void replace_local_schedule(const std::vector< time_of_day > &schedule, int area_index, int initial_time=0)
void set_turn(const int num, game_data *vars=nullptr, const bool increase_limit_if_needed=true)
Dynamically change the current turn number.
bool has_turn_event_fired_
void set_number_of_turns(int num)
void set_number_of_turns_by_wml(int num)
const time_of_day & get_time_of_day(int for_turn=0) const
Returns global time of day for the passed turn.
static int fix_time_index(int number_of_times, int time)
Computes for the main time or a time area the index of its times where we're currently at.
bool next_turn(game_data *vars)
Function to move to the next turn.
std::vector< area_time_of_day > areas_
void replace_area_locations(int index, const std::set< map_location > &locs)
bool is_time_left() const
Function to check the end of turns.
const time_of_day & get_area_time_of_day(int area_i, int for_turn=0) const
Returns time of day for the passed turn in the specified tod area.
const std::set< map_location > & get_area_by_id(const std::string &id) const
bool has_cfg_liminal_bonus_
std::vector< time_of_day > times_
config::attribute_value random_tod_
int calculate_best_liminal_bonus(const std::vector< time_of_day > &schedule) const
Computes the maximum absolute value of lawful_bonus in the schedule.
tod_manager(const config &scenario_cfg=config())
std::pair< int, std::string > get_area_on_hex(const map_location &loc) const
const time_of_day & get_previous_time_of_day() const
void resolve_random(randomness::rng &r)
handles random_start_time, should be called before the game starts.
void modify_turns(const std::string &mod)
void set_new_current_times(const int new_current_turn_number)
For a change of the current turn number, sets the current times of the main time and all time areas.
int calculate_time_index_at_turn(int number_of_times, int for_turn_number, int current_time) const
Computes for the main time or a time area the index of its times where we're currently at.
int get_composite_value() const
std::pair< int, map_location > lowest(const std::string &key, int def=0) const
std::pair< int, map_location > highest(const std::string &key, int def=0) const
Container associating units to locations.
unit_iterator find(std::size_t id)
std::string id
Text to match against addon_info.tags()
void get_adjacent_tiles(const map_location &a, map_location *res)
Function which, given a location, will place all adjacent locations in res.
void write_location_range(const std::set< map_location > &locs, config &cfg)
Write a set of locations into a config using ranges, adding keys x=x1,..,xn and y=y1a-y1b,...
static std::ostream & output()
Standard logging facilities (interface).
constexpr int bounded_add(int base, int increment, int max_sum, int min_sum=0)
Returns base + increment, but will not increase base above max_sum, nor decrease it below min_sum.
constexpr T modulo(T num, int mod, T min=0)
play_controller * controller
@ EFFECT_WITHOUT_CLAMP_MIN_MAX
std::size_t index(std::string_view str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
bool string_bool(const std::string &str, bool def)
Convert no, false, off, 0, 0.0 to false, empty to def, and others to true.
void erase_if(Container &container, const Predicate &predicate)
Convenience wrapper for using std::remove_if on a container.
int apply_modifier(const int number, const std::string &amount, const int minimum)
std::vector< std::string > split(const config_attribute_value &val)
Encapsulates the map of the game.
static const map_location & null_location()
Object which defines a time of day with associated bonuses, image, sounds etc.
static void parse_times(const config &cfg, std::vector< time_of_day > &normal_times)
Parse config and add time of day entries into passed vector.
int lawful_bonus
The % bonus lawful units receive.
void write(config &cfg, const std::string &textdomain="") const
std::set< map_location > hexes
std::vector< time_of_day > times
static lg::log_domain log_engine("engine")
static const time_of_day & dummytime()