40 #define DBG_NG LOG_STREAM(debug, log_engine) 41 #define LOG_NG LOG_STREAM(info, log_engine) 42 #define WRN_NG LOG_STREAM(warn, log_engine) 43 #define ERR_NG LOG_STREAM(err, log_engine) 46 #define DBG_NGE LOG_STREAM(debug, log_engine_enemies) 47 #define LOG_NGE LOG_STREAM(info, log_engine_enemies) 48 #define WRN_NGE LOG_STREAM(warn, log_engine_enemies) 58 "carryover_percentage",
86 "suppress_end_turn_confirmation",
101 "disallow_observers",
103 "faction_from_recruit",
124 , income_per_village(0)
125 , support_per_village(1)
126 , minimum_recruit_price(0)
137 , action_bonus_count(0)
141 , scroll_to_leader(true)
143 , objectives_changed(false)
149 , disallow_observers(false)
150 , allow_player(false)
151 , chose_random(false)
154 , no_turn_confirmation(false)
160 , carryover_add(false)
173 faction = cfg[
"faction"].str();
175 save_id = cfg[
"save_id"].str();
179 flag = cfg[
"flag"].str();
181 id = cfg[
"id"].str();
190 lost = cfg[
"lost"].to_bool(
false);
191 hidden = cfg[
"hidden"].to_bool();
193 side = cfg[
"side"].to_int(1);
199 is_local = cfg[
"is_local"].to_bool(
true);
216 can_recruit.insert(recruits.begin(), recruits.end());
220 if(!cfg[
"start_gold"].empty()) {
222 }
else if(!cfg[
"gold"].empty()) {
240 if(village_support.empty()) {
249 if(controller == side_controller::type::none) {
255 persistent = cfg[
"persistent"].to_bool(this->controller == side_controller::type::human);
271 if(cfg[
"share_view"].to_bool()) {
273 }
else if(cfg[
"share_maps"].to_bool(
true)) {
315 cfg[
"color"] =
color;
365 <<
", fog: " <<
uses_fog() <<
".\n";
368 const config& fog_override = cfg.
child(
"fog_override");
370 const std::vector<map_location> fog_vector
372 fog_clearer_.insert(fog_vector.begin(), fog_vector.end());
392 WRN_NG <<
"[side] " <<
current_player() <<
" [village] points to a non-village location " << loc
454 if(old_value.
blank()) {
466 const std::set<map_location>::const_iterator vil =
villages_.find(loc);
496 if(ut->
cost() < min) {
529 LOG_NGE <<
"team " <<
info_.
side <<
" calculates if it has enemy in team " << index + 1 <<
"; our team_name [" 533 for(
const std::string&
t : our_teams) {
534 if(std::find(their_teams.begin(), their_teams.end(),
t) != their_teams.end()) {
535 LOG_NGE <<
"team " <<
info_.
side <<
" found same team name [" <<
t <<
"] in team " << index + 1
539 LOG_NGE <<
"team " <<
info_.
side <<
" not found same team name [" <<
t <<
"] in team " << index + 1
544 LOG_NGE <<
"team " <<
info_.
side <<
" has enemy in team " << index + 1 << std::endl;
554 : new_controller_(new_controller)
560 virtual config local_choice()
const 566 virtual config request()
const 573 virtual const char* name()
const 575 return "change_controller_wml";
587 if(!new_controller) {
588 WRN_NG <<
"ignored attempt to change controller to " << new_controller_string << std::endl;
593 WRN_NG <<
"ignored attempt to change the currently playing side's controller to 'null'" << std::endl;
599 WRN_NG <<
"Received an invalid controller string from the server" << choice[
"controller"] << std::endl;
609 if(pc->current_side() ==
side() && new_controller !=
controller()) {
610 pc->set_player_type_changed();
621 if(!user_name.
empty()) {
636 t.ally_shroud_.clear();
681 for(std::size_t
i = 0;
i < teams.size(); ++
i) {
691 const std::vector<const shroud_map*>&
team::ally_fog(
const std::vector<team>& teams)
const 694 for(std::size_t
i = 0;
i < teams.size(); ++
i) {
764 throw game::game_error(
"invalid side(" + std::to_string(side) +
") found in unit definition");
775 if(data_.size() == 0)
return 0;
776 return std::max_element(data_.begin(), data_.end(), [](
const auto&
a,
const auto&
b) {
777 return a.size() <
b.size();
783 if(enabled_ ==
false || x < 0 || y < 0) {
787 if(x >= static_cast<int>(data_.size())) {
791 if(y >= static_cast<int>(data_[x].
size())) {
792 data_[x].resize(y + 1);
795 if(data_[x][y] ==
false) {
805 if(enabled_ ==
false || x < 0 || y < 0) {
809 if(x >= static_cast<int>(data_.size())) {
810 DBG_NG <<
"Couldn't place shroud on invalid x coordinate: (" << x <<
", " << y
811 <<
") - max x: " << data_.size() - 1 <<
"\n";
812 }
else if(y >= static_cast<int>(data_[x].
size())) {
813 DBG_NG <<
"Couldn't place shroud on invalid y coordinate: (" << x <<
", " << y
814 <<
") - max y: " << data_[x].size() - 1 <<
"\n";
822 if(enabled_ ==
false) {
826 for(
auto&
i : data_) {
827 std::fill(
i.begin(),
i.end(),
false);
838 if(x < 0 || x >= static_cast<int>(data_.size())) {
842 if(y < 0 || y >= static_cast<int>(data_[x].
size())) {
863 for(
const shroud_map*
const shared_map : maps) {
864 if(shared_map->enabled_ && !shared_map->value(x, y)) {
874 std::stringstream shroud_str;
875 for(
const auto& sh : data_) {
879 shroud_str << (
i ?
'1' :
'0');
885 return shroud_str.str();
892 for(
const char sh : str) {
894 data_.resize(data_.size() + 1);
897 if(data_.empty() ==
false) {
899 data_.back().push_back(
true);
900 }
else if(sh ==
'0') {
901 data_.back().push_back(
false);
910 for(std::size_t
i = 1;
i < str.length(); ++
i) {
914 }
else if(str[
i] ==
'1') {
917 }
else if(str[
i] ==
'0') {
925 if(enabled_ ==
false) {
929 bool cleared =
false;
931 if(m->enabled_ ==
false) {
935 const std::vector<std::vector<bool>>& v = m->data_;
936 for(std::size_t x = 0; x != v.size(); ++x) {
937 for(std::size_t y = 0; y != v[x].size(); ++y) {
939 cleared |=
clear(x, y);
957 return color_range({255, 0, 0}, {255, 255, 255}, {0, 0, 0}, {255, 0, 0});
975 const unsigned index = side - 1;
985 if(!side_color.empty()) {
993 }
catch(
const std::out_of_range&) {
1003 if(rgb_name.empty())
1006 return VGETTEXT(
"“$color_id”", {{
"color_id", color_id }});
1038 LOG_NG <<
"Adding recruitable units: \n";
1040 LOG_NG << recruit << std::endl;
1043 LOG_NG <<
"Added all recruitable units\n";
1056 std::vector<int> res;
1058 if(!
t.is_enemy(this->side()) &&
t.is_human()) {
1059 res.push_back(
t.side());
play_controller * controller
bool empty() const
Tests for an attribute that either was never set or was set to "".
static const int default_team_gold_
config & child(config_key_type key, int n=0)
Returns the nth child with the given key, or a reference to an invalid config if there is none...
bool no_turn_confirmation
std::string last_recruit_
const unit_type * find(const std::string &key, unit_type::BUILD_STATUS status=unit_type::FULL) const
Finds a unit_type by its id() and makes sure it is built to the specified level.
virtual const std::vector< team > & teams() const override
bool copy_from(const std::vector< const shroud_map *> &maps)
std::map< std::string, color_range > team_rgb_range
Colors defined by WML [color_range] tags.
unsigned to_unsigned(unsigned def=0) const
void handle_legacy_share_vision(const config &cfg)
std::string join(const T &v, const std::string &s=",")
Generates a new string joining container items in a list.
void set_objectives(const t_string &new_objectives, bool silently=false)
static std::string get_side_color_id_from_config(const config &cfg)
static manager & get_singleton()
int minimum_recruit_price() const
void write(config &cfg) const
Variant for storing WML attributes.
New lexcical_cast header.
bool has_attribute(config_key_type key) const
static const color_range get_side_color_range(int side)
static bool has_manager()
void calculate_enemies(std::size_t index) const
void fix_villages(const gamemap &map)
static const std::set< std::string > attributes
Stores the attributes recognized by [side].
child_itors child_range(config_key_type key)
void clear(const std::string &key)
const std::string & gamedata
unit_type_data unit_types
void build(const config &cfg, const gamemap &map, int gold=default_team_gold_)
int minimum_recruit_price
std::shared_ptr< wb::side_actions > planned_actions_
Whiteboard planned actions for this team.
bool objectives_changed
< Team's objectives for the current level.
void add_recruit(const std::string &)
void change_controller(const std::string &new_controller)
int village_support() const
A single unit type that the player may recruit.
config::attribute_value & get_variable(const std::string &varname)
throws invalid_variablename_exception if varname is no valid variable name.
bool value(int x, int y) const
bool calculate_is_enemy(std::size_t index) const
static std::string get_side_highlight_pango(int side)
static const t_string get_side_color_name_for_UI(unsigned side)
static lg::log_domain log_engine_enemies("engine/enemies")
bool knows_about_team(std::size_t index) const
bool add_ai_for_side_from_file(side_number side, const std::string &file, bool replace=true)
Adds active AI for specified side from file.
void read(const std::string &shroud_data)
void write(config &cfg) const
void raise_recruit_list_changed()
Notifies all observers of 'ai_recruit_list_changed' event.
This class stores all the data for a single 'side' (in game nomenclature).
std::string allied_human_teams() const
void merge(const std::string &shroud_data)
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
team_shared_vision::type share_vision
void read(const config &cfg)
The base template for associating string values with enum values.
side_controller::type controller() const
const int gold_carryover_percentage
Default percentage gold carried over to the next scenario.
void set_local(bool local)
bool blank() const
Tests for an attribute that was never set.
Encapsulates the map of the game.
bool is_enemy(int n) const
Managing the AIs lifecycle - headers TODO: Refactor history handling and internal commands...
Error used for any general game error, e.g.
bool auto_shroud_updates_
void remove_fog_override(const std::set< map_location > &hexes)
Removes the record of hexes that were cleared of fog via WML.
std::vector< const shroud_map * > ally_fog_
game_events::manager * game_events
boost::dynamic_bitset enemies_
static std::string get_side_color_id(unsigned side)
Encapsulates the map of the game.
bool shrouded(const map_location &loc) const
std::string id
Text to match against addon_info.tags()
static void clear_caches()
clear the shroud, fog, and enemies cache for all teams
std::string current_player
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,..,yna-ynb.
Game configuration data as global variables.
std::set< map_location > villages_
static std::string get_string(typename T::type key)
Uses the int value of the provided enum to get the associated index of the values array in the implem...
void set_enabled(bool enabled)
std::string to_hex_string() const
Returns the stored color in rrggbb hex format.
Define the game's event mechanism.
A color range definition is made of four reference RGB colors, used for calculating conversions from ...
const std::string & current_player() const
static t_string from_serialized(const std::string &string)
void validate_side(int side)
std::size_t index(const std::string &str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
bool add_ai_for_side_from_config(side_number side, const config &cfg, bool replace=true)
Adds active AI for specified side from cfg.
std::vector< const shroud_map * > ally_shroud_
recall_list_manager recall_list_
void change_controller_by_wml(const std::string &new_controller)
static lg::log_domain log_engine("engine")
config & add_child(config_key_type key)
pump_result_t fire(const std::string &event, const entity_location &loc1=entity_location::null_entity, const entity_location &loc2=entity_location::null_entity, const config &data=config())
Function to fire an event.
bool is_village(const map_location &loc) const
game_events::pump_result_t get_village(const map_location &, const int owner_side, game_data *fire_event)
Acquires a village from owner_side.
static color_t get_minimap_color(int side)
const std::vector< const shroud_map * > & ally_fog(const std::vector< team > &teams) const
std::set< map_location > fog_clearer_
Stores hexes that have been cleared of fog via WML.
static std::optional< typename T::type > get_enum(const std::string value)
Convert a string into its enum equivalent.
color_t rep() const
High-contrast shade, intended for the minimap markers.
std::vector< std::string > split(const config_attribute_value &val)
void lose_village(const map_location &)
static color_t get_side_color(int side)
void log_recruitable() const
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...
void change_team(const std::string &name, const t_string &user_name)
std::set< std::string > can_recruit
bool fogged(const map_location &loc) const
bool translatable() const
game_events::wml_event_pump & pump()
defeat_condition::type defeat_cond
void clear_variable(const std::string &varname)
Clears attributes config children does nothing if varname is no valid variable name.
void set_recruits(const std::set< std::string > &recruits)
const config & child_or_empty(config_key_type key) const
Returns the first child with the given key, or an empty config if there is none.
std::vector< std::string > default_colors
std::tuple< bool, bool > pump_result_t
bool shared_value(const std::vector< const shroud_map *> &maps, int x, int y) const
A config object defines a single node in a WML file, with access to child nodes.
std::string write() const
std::map< std::string, t_string > team_rgb_name
side_controller::type controller
This internal whiteboard class holds the planned action queues for a team, and offers many utility me...
std::string::const_iterator iterator
const std::vector< const shroud_map * > & ally_shroud(const std::vector< team > &teams) const
std::string countdown_time
color_t mid() const
Average color shade.
const std::set< std::string > & recruits() const
static config ask_server_choice(const server_choice &)
If we are in a mp game, ask the server, otherwise generate the answer ourselves.
std::string str(const std::string &fallback="") const