39 #define DBG_NG LOG_STREAM(debug, log_engine)
40 #define LOG_NG LOG_STREAM(info, log_engine)
41 #define WRN_NG LOG_STREAM(warn, log_engine)
42 #define ERR_NG LOG_STREAM(err, log_engine)
45 #define DBG_NGE LOG_STREAM(debug, log_engine_enemies)
46 #define LOG_NGE LOG_STREAM(info, log_engine_enemies)
47 #define WRN_NGE LOG_STREAM(warn, log_engine_enemies)
57 "carryover_percentage",
85 "suppress_end_turn_confirmation",
100 "disallow_observers",
102 "faction_from_recruit",
123 , income_per_village(0)
124 , support_per_village(1)
125 , minimum_recruit_price(0)
136 , action_bonus_count(0)
140 , scroll_to_leader(true)
142 , objectives_changed(false)
148 , disallow_observers(false)
149 , allow_player(false)
150 , chose_random(false)
153 , no_turn_confirmation(false)
159 , carryover_add(false)
168 income = cfg[
"income"];
172 faction = cfg[
"faction"].str();
174 save_id = cfg[
"save_id"].str();
178 flag = cfg[
"flag"].str();
180 id = cfg[
"id"].str();
181 scroll_to_leader = cfg[
"scroll_to_leader"].to_bool(
true);
184 disallow_observers = cfg[
"disallow_observers"].to_bool();
185 allow_player = cfg[
"allow_player"].to_bool(
true);
189 lost = cfg[
"lost"].to_bool(
false);
190 hidden = cfg[
"hidden"].to_bool();
192 side = cfg[
"side"].to_int(1);
198 is_local = cfg[
"is_local"].to_bool(
true);
219 if(!cfg[
"start_gold"].empty()) {
221 }
else if(!cfg[
"gold"].empty()) {
248 if(
controller == side_controller::type::none) {
249 disallow_observers = cfg[
"disallow_observers"].to_bool(
true);
270 if(cfg[
"share_view"].to_bool()) {
272 }
else if(cfg[
"share_maps"].to_bool(
true)) {
284 cfg[
"income"] = income;
299 cfg[
"village_gold"] = income_per_village;
300 cfg[
"village_support"] = support_per_village;
302 cfg[
"disallow_observers"] = disallow_observers;
303 cfg[
"allow_player"] = allow_player;
309 cfg[
"scroll_to_leader"] = scroll_to_leader;
314 cfg[
"color"] =
color;
369 const std::vector<map_location> fog_vector
371 fog_clearer_.insert(fog_vector.begin(), fog_vector.end());
391 WRN_NG <<
"[side] " <<
current_player() <<
" [village] points to a non-village location " << loc;
452 if(old_value.
blank()) {
453 gamedata->clear_variable(
"owner_side");
464 const std::set<map_location>::const_iterator vil =
villages_.find(loc);
497 if(ut->
cost() < min) {
530 LOG_NGE <<
"team " <<
info_.
side <<
" calculates if it has enemy in team " <<
index + 1 <<
"; our team_name ["
534 for(
const std::string&
t : our_teams) {
535 if(std::find(their_teams.begin(), their_teams.end(),
t) != their_teams.end()) {
553 : new_controller_(new_controller)
572 virtual const char*
name()
const
574 return "change_controller_wml";
586 if(!new_controller) {
587 WRN_NG <<
"ignored attempt to change controller to " << new_controller_string;
592 WRN_NG <<
"ignored attempt to change the currently playing side's controller to 'null'";
598 WRN_NG <<
"Received an invalid controller string from the server" << choice[
"controller"];
608 if(pc->current_side() ==
side() && new_controller !=
controller()) {
609 pc->set_player_type_changed();
620 if(!user_name.
empty()) {
635 t.ally_shroud_.clear();
680 for(
const team&
t : teams) {
681 if(!
is_enemy(
t.side()) && (&
t ==
this ||
t.share_view() ||
t.share_maps())) {
690 const std::vector<const shroud_map*>&
team::ally_fog(
const std::vector<team>& teams)
const
693 for(
const team&
t : teams) {
694 if(!
is_enemy(
t.side()) && (&
t ==
this ||
t.share_view())) {
763 throw game::game_error(
"invalid side(" + std::to_string(side) +
") found in unit definition");
774 if(
data_.size() == 0)
return 0;
775 return std::max_element(
data_.begin(),
data_.end(), [](
const auto& a,
const auto&
b) {
776 return a.size() < b.size();
782 if(
enabled_ ==
false || x < 0 || y < 0) {
786 if(x >=
static_cast<int>(
data_.size())) {
790 if(y >=
static_cast<int>(
data_[x].
size())) {
791 data_[x].resize(y + 1);
794 if(
data_[x][y] ==
false) {
804 if(
enabled_ ==
false || x < 0 || y < 0) {
808 if(x >=
static_cast<int>(
data_.size())) {
809 DBG_NG <<
"Couldn't place shroud on invalid x coordinate: (" << x <<
", " << y
810 <<
") - max x: " <<
data_.size() - 1;
811 }
else if(y >=
static_cast<int>(
data_[x].
size())) {
812 DBG_NG <<
"Couldn't place shroud on invalid y coordinate: (" << x <<
", " << y
813 <<
") - max y: " <<
data_[x].size() - 1;
837 if(x < 0 || x >=
static_cast<int>(
data_.size())) {
841 if(y < 0 || y >=
static_cast<int>(
data_[x].
size())) {
862 for(
const shroud_map*
const shared_map : maps) {
863 if(shared_map->enabled_ && !shared_map->value(x, y)) {
873 std::stringstream shroud_str;
874 for(
const auto& sh :
data_) {
878 shroud_str << (
i ?
'1' :
'0');
884 return shroud_str.str();
891 for(
const char sh : str) {
896 if(
data_.empty() ==
false) {
898 data_.back().push_back(
true);
899 }
else if(sh ==
'0') {
900 data_.back().push_back(
false);
909 for(std::size_t
i = 1;
i < str.length(); ++
i) {
913 }
else if(str[
i] ==
'1') {
916 }
else if(str[
i] ==
'0') {
928 bool cleared =
false;
930 if(m->enabled_ ==
false) {
934 const std::vector<std::vector<bool>>& v = m->data_;
935 for(std::size_t x = 0; x != v.size(); ++x) {
936 for(std::size_t y = 0; y != v[x].size(); ++y) {
938 cleared |=
clear(x, y);
956 return color_range({255, 0, 0}, {255, 255, 255}, {0, 0, 0}, {255, 0, 0});
984 if(!side_color.empty()) {
992 }
catch(
const std::out_of_range&) {
1002 if(rgb_name.empty())
1005 return VGETTEXT(
"“$color_id”", {{
"color_id", color_id }});
1017 if(
c.blank() ||
c.empty()) {
1022 if(
unsigned side =
c.to_unsigned()) {
1037 LOG_NG <<
"Adding recruitable units:";
1042 LOG_NG <<
"Added all recruitable units";
1055 std::vector<int> res;
1057 if(!
t.is_enemy(this->side()) &&
t.is_human()) {
1058 res.push_back(
t.side());
Managing the AIs lifecycle - headers TODO: Refactor history handling and internal commands.
bool add_ai_for_side_from_config(side_number side, const config &cfg, bool replace=true)
Adds active AI for specified side from cfg.
static manager & get_singleton()
static bool has_manager()
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 raise_recruit_list_changed()
Notifies all observers of 'ai_recruit_list_changed' event.
A color range definition is made of four reference RGB colors, used for calculating conversions from ...
color_t rep() const
High-contrast shade, intended for the minimap markers.
color_t mid() const
Average color shade.
Variant for storing WML attributes.
bool blank() const
Tests for an attribute that was never set.
A config object defines a single node in a WML file, with access to child nodes.
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.
bool has_attribute(config_key_type key) const
child_itors child_range(config_key_type key)
optional_config_impl< config > optional_child(config_key_type key, int n=0)
Equivalent to mandatory_child, but returns an empty optional if the nth child was not found.
config & add_child(config_key_type key)
virtual const std::vector< team > & teams() const override
game_events::wml_event_pump & pump()
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.
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.
Encapsulates the map of the game.
bool is_village(const map_location &loc) const
bool copy_from(const std::vector< const shroud_map * > &maps)
void read(const std::string &shroud_data)
void set_enabled(bool enabled)
std::vector< std::vector< bool > > data_
bool shared_value(const std::vector< const shroud_map * > &maps, int x, int y) const
void merge(const std::string &shroud_data)
bool value(int x, int y) const
std::string write() const
virtual config request() const =0
The request which is sent to the mp server.
virtual const char * name() const =0
virtual config local_choice() const =0
We are in a game with no mp server and need to do this choice locally.
static config ask_server_choice(const server_choice &)
If we are in a mp game, ask the server, otherwise generate the answer ourselves.
static t_string from_serialized(const std::string &string)
bool translatable() const
This class stores all the data for a single 'side' (in game nomenclature).
static std::string get_side_highlight_pango(int side)
int carryover_gold() const
const std::string & color() const
static color_t get_minimap_color(int side)
bool no_turn_confirmation() const
void fix_villages(const gamemap &map)
const std::string & side_name() const
recall_list_manager recall_list_
game_events::pump_result_t get_village(const map_location &, const int owner_side, game_data *fire_event)
Acquires a village from owner_side.
const std::string & faction() const
int village_support() const
std::vector< const shroud_map * > ally_shroud_
static const color_range get_side_color_range(int side)
void set_local(bool local)
const std::string & current_player() const
void set_recruits(const std::set< std::string > &recruits)
const std::string & team_name() const
bool objectives_changed() const
static std::string get_side_color_id_from_config(const config &cfg)
bool is_enemy(int n) const
team_shared_vision::type share_vision() const
int action_bonus_count() const
bool calculate_is_enemy(std::size_t index) const
bool knows_about_team(std::size_t index) const
const t_string & objectives() const
void change_team(const std::string &name, const t_string &user_name)
static const t_string get_side_color_name_for_UI(unsigned side)
const t_string & faction_name() const
defeat_condition::type defeat_cond() const
void set_objectives(const t_string &new_objectives, bool silently=false)
bool carryover_add() const
void handle_legacy_share_vision(const config &cfg)
int carryover_percentage() const
void write(config &cfg) const
static std::string get_side_color_id(unsigned side)
std::vector< const shroud_map * > ally_fog_
void build(const config &cfg, const gamemap &map, int gold=default_team_gold_)
const std::string & save_id() const
static const int default_team_gold_
void calculate_enemies(std::size_t index) const
void add_recruit(const std::string &)
side_controller::type controller() const
int minimum_recruit_price() const
double carryover_bonus() const
void change_controller(const std::string &new_controller)
static void clear_caches()
clear the shroud, fog, and enemies cache for all teams
bool auto_shroud_updates_
std::set< map_location > fog_clearer_
Stores hexes that have been cleared of fog via WML.
std::string allied_human_teams() const
bool shrouded(const map_location &loc) const
std::set< map_location > villages_
const std::string & flag_icon() const
const std::vector< const shroud_map * > & ally_fog(const std::vector< team > &teams) const
static color_t get_side_color(int side)
static const std::set< std::string > attributes
Stores the attributes recognized by [side].
int countdown_time() const
const std::string & flag() const
std::string last_recruit_
std::shared_ptr< wb::side_actions > planned_actions_
Whiteboard planned actions for this team.
const std::set< std::string > & recruits() const
const t_string & user_team_name() const
void lose_village(const map_location &)
boost::dynamic_bitset enemies_
void remove_fog_override(const std::set< map_location > &hexes)
Removes the record of hexes that were cleared of fog via WML.
bool fogged(const map_location &loc) const
void change_controller_by_wml(const std::string &new_controller)
bool chose_random() const
void log_recruitable() const
const std::vector< const shroud_map * > & ally_shroud(const std::vector< team > &teams) const
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.
A single unit type that the player may recruit.
This internal whiteboard class holds the planned action queues for a team, and offers many utility me...
std::string id
Text to match against addon_info.tags()
New lexcical_cast header.
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,...
void fill(const SDL_Rect &rect, uint8_t r, uint8_t g, uint8_t b, uint8_t a)
Fill an area with the given colour.
Game configuration data as global variables.
std::map< std::string, color_range, std::less<> > team_rgb_range
Colors defined by WML [color_range] tags.
std::map< std::string, t_string, std::less<> > team_rgb_name
const int gold_carryover_percentage
Default percentage gold carried over to the next scenario.
std::vector< std::string > default_colors
std::tuple< bool, bool > pump_result_t
game_events::manager * game_events
play_controller * controller
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.
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
std::string join(const T &v, const std::string &s=",")
Generates a new string joining container items in a list.
std::vector< std::string > split(const config_attribute_value &val)
std::string::const_iterator iterator
Define the game's event mechanism.
The basic class for representing 8-bit RGB or RGBA colour values.
std::string to_hex_string() const
Returns the stored color in rrggbb hex format.
Error used for any general game error, e.g.
Encapsulates the map of the game.
The base template for associating string values with enum values.
static std::string get_string(enum_type key)
Converts a enum to its string equivalent.
static constexpr utils::optional< enum_type > get_enum(const std::string_view value)
Converts a string into its enum equivalent.
void read(const config &cfg)
int minimum_recruit_price
void handle_legacy_share_vision(const config &cfg)
void write(config &cfg) const
std::set< std::string > can_recruit
bool objectives_changed
< Team's objectives for the current level.
static lg::log_domain log_engine("engine")
static lg::log_domain log_engine_enemies("engine/enemies")
void validate_side(int side)
const std::string & gamedata
unit_type_data unit_types