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)
168 gold = cfg[
"gold"].to_int();
169 income = cfg[
"income"].to_int();
173 faction = cfg[
"faction"].str();
175 save_id = cfg[
"save_id"].str();
179 flag = cfg[
"flag"].str();
181 id = cfg[
"id"].str();
182 scroll_to_leader = cfg[
"scroll_to_leader"].to_bool(
true);
185 disallow_observers = cfg[
"disallow_observers"].to_bool();
186 allow_player = cfg[
"allow_player"].to_bool(
true);
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);
220 if(!cfg[
"start_gold"].empty()) {
222 }
else if(!cfg[
"gold"].empty()) {
249 if(
controller == side_controller::type::none) {
250 disallow_observers = cfg[
"disallow_observers"].to_bool(
true);
271 if(cfg[
"share_view"].to_bool()) {
273 }
else if(cfg[
"share_maps"].to_bool(
true)) {
285 cfg[
"income"] = income;
300 cfg[
"village_gold"] = income_per_village;
301 cfg[
"village_support"] = support_per_village;
303 cfg[
"disallow_observers"] = disallow_observers;
304 cfg[
"allow_player"] = allow_player;
310 cfg[
"scroll_to_leader"] = scroll_to_leader;
315 cfg[
"color"] =
color;
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;
396 countdown_time_ = chrono::parse_duration<std::chrono::milliseconds>(cfg[
"countdown_time"]);
453 if(old_value.
blank()) {
454 gamedata->clear_variable(
"owner_side");
465 const std::set<map_location>::const_iterator vil =
villages_.find(loc);
498 if(ut->
cost() < min) {
531 LOG_NGE <<
"team " <<
info_.
side <<
" calculates if it has enemy in team " <<
index + 1 <<
"; our team_name ["
535 for(
const std::string&
t : our_teams) {
536 if(std::find(their_teams.begin(), their_teams.end(),
t) != their_teams.end()) {
554 : new_controller_(new_controller)
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;
593 WRN_NG <<
"ignored attempt to change the currently playing side's controller to 'null'";
599 WRN_NG <<
"Received an invalid controller string from the server" << choice[
"controller"];
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(
const team&
t : teams) {
682 if(!
is_enemy(
t.side()) && (&
t ==
this ||
t.share_view() ||
t.share_maps())) {
691 const std::vector<const shroud_map*>&
team::ally_fog(
const std::vector<team>& teams)
const
694 for(
const team&
t : teams) {
695 if(!
is_enemy(
t.side()) && (&
t ==
this ||
t.share_view())) {
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;
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;
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) {
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') {
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});
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 }});
1018 if(
c.blank() ||
c.empty()) {
1023 if(
unsigned side =
c.to_unsigned()) {
1038 LOG_NG <<
"Adding recruitable units:";
1043 LOG_NG <<
"Added all recruitable units";
1056 std::vector<int> res;
1058 if(!
t.is_enemy(this->side()) &&
t.is_human()) {
1059 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)
std::chrono::milliseconds countdown_time_
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_
std::chrono::milliseconds countdown_time() const
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].
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