38 #include <boost/dynamic_bitset.hpp> 41 #define DBG_NG LOG_STREAM(debug, log_engine) 42 #define LOG_NG LOG_STREAM(info, log_engine) 43 #define WRN_NG LOG_STREAM(warn, log_engine) 44 #define ERR_NG LOG_STREAM(err, log_engine) 47 #define DBG_NGE LOG_STREAM(debug, log_engine_enemies) 48 #define LOG_NGE LOG_STREAM(info, log_engine_enemies) 49 #define WRN_NGE LOG_STREAM(warn, log_engine_enemies) 59 "carryover_percentage",
87 "suppress_end_turn_confirmation",
102 "disallow_observers",
104 "faction_from_recruit",
125 , income_per_village(0)
126 , support_per_village(1)
127 , minimum_recruit_price(0)
138 , action_bonus_count(0)
142 , scroll_to_leader(true)
144 , objectives_changed(false)
147 , defeat_condition(
team::DEFEAT_CONDITION::NO_LEADER)
148 , proxy_controller(
team::PROXY_CONTROLLER::PROXY_HUMAN)
149 , share_vision(
team::SHARE_VISION::ALL)
150 , disallow_observers(false)
151 , allow_player(false)
152 , chose_random(false)
155 , no_turn_confirmation(false)
161 , carryover_add(false)
174 faction = cfg[
"faction"].str();
176 save_id = cfg[
"save_id"].str();
180 flag = cfg[
"flag"].str();
182 id = cfg[
"id"].str();
190 defeat_condition = cfg[
"defeat_condition"].to_enum<team::DEFEAT_CONDITION>(team::DEFEAT_CONDITION::NO_LEADER);
191 lost = cfg[
"lost"].to_bool(
false);
192 hidden = cfg[
"hidden"].to_bool();
194 side = cfg[
"side"].to_int(1);
200 is_local = cfg[
"is_local"].to_bool(
true);
217 can_recruit.insert(recruits.begin(), recruits.end());
221 if(!cfg[
"start_gold"].empty()) {
223 }
else if(!cfg[
"gold"].empty()) {
241 if(village_support.empty()) {
248 controller.parse(cfg[
"controller"].str());
251 if(controller == CONTROLLER::EMPTY) {
257 persistent = cfg[
"persistent"].to_bool(this->controller == CONTROLLER::HUMAN);
264 share_vision = cfg[
"share_vision"].to_enum<team::SHARE_VISION>(team::SHARE_VISION::ALL);
273 if(cfg[
"share_view"].to_bool()) {
275 }
else if(cfg[
"share_maps"].to_bool(
true)) {
317 cfg[
"color"] =
color;
367 <<
", fog: " <<
uses_fog() <<
".\n";
370 const config& fog_override = cfg.
child(
"fog_override");
372 const std::vector<map_location> fog_vector
374 fog_clearer_.insert(fog_vector.begin(), fog_vector.end());
394 WRN_NG <<
"[side] " <<
current_player() <<
" [village] points to a non-village location " << loc
456 if(old_value.
blank()) {
468 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()) {
537 LOG_NGE <<
"team " <<
info_.
side <<
" found same team name [" <<
t <<
"] in team " << index + 1
541 LOG_NGE <<
"team " <<
info_.
side <<
" not found same team name [" <<
t <<
"] in team " << index + 1
546 LOG_NGE <<
"team " <<
info_.
side <<
" has enemy in team " << index + 1 << std::endl;
555 controller_server_choice(team::CONTROLLER new_controller,
const team&
team)
556 : new_controller_(new_controller)
562 virtual config local_choice()
const 564 return config{
"controller", new_controller_,
"is_local",
true};
568 virtual config request()
const 571 "new_controller", new_controller_,
"old_controller", team_.controller(),
"side", team_.side(),
575 virtual const char*
name()
const 577 return "change_controller_wml";
581 team::CONTROLLER new_controller_;
588 CONTROLLER new_controller;
589 if(!new_controller.parse(new_controller_string)) {
590 WRN_NG <<
"ignored attempt to change controller to " << new_controller_string << std::endl;
595 WRN_NG <<
"ignored attempt to change the currently playing side's controller to 'null'" << std::endl;
600 if(!new_controller.parse(choice[
"controller"])) {
603 WRN_NG <<
"Received an invalid controller string from the server" << choice[
"controller"] << std::endl;
611 if(pc->current_side() ==
side() && new_controller !=
controller()) {
612 pc->set_player_type_changed();
623 if(!user_name.
empty()) {
638 t.ally_shroud_.clear();
680 const std::vector<const team::shroud_map*>&
team::ally_shroud(
const std::vector<team>& teams)
const 683 for(std::size_t
i = 0;
i < teams.size(); ++
i) {
693 const std::vector<const team::shroud_map*>&
team::ally_fog(
const std::vector<team>& teams)
const 696 for(std::size_t
i = 0;
i < teams.size(); ++
i) {
766 throw game::game_error(
"invalid side(" + std::to_string(side) +
") found in unit definition");
772 if(enabled_ ==
false || x < 0 || y < 0) {
776 if(x >= static_cast<int>(data_.size())) {
780 if(y >= static_cast<int>(data_[x].
size())) {
781 data_[x].resize(y + 1);
784 if(data_[x][y] ==
false) {
794 if(enabled_ ==
false || x < 0 || y < 0) {
798 if(x >= static_cast<int>(data_.size())) {
799 DBG_NG <<
"Couldn't place shroud on invalid x coordinate: (" << x <<
", " << y
800 <<
") - max x: " << data_.size() - 1 <<
"\n";
801 }
else if(y >= static_cast<int>(data_[x].
size())) {
802 DBG_NG <<
"Couldn't place shroud on invalid y coordinate: (" << x <<
", " << y
803 <<
") - max y: " << data_[x].size() - 1 <<
"\n";
811 if(enabled_ ==
false) {
815 for(
auto&
i : data_) {
816 std::fill(
i.begin(),
i.end(),
false);
827 if(x < 0 || x >= static_cast<int>(data_.size())) {
831 if(y < 0 || y >= static_cast<int>(data_[x].
size())) {
852 for(
const shroud_map*
const shared_map : maps) {
853 if(shared_map->enabled_ && !shared_map->value(x, y)) {
863 std::stringstream shroud_str;
864 for(
const auto& sh : data_) {
868 shroud_str << (
i ?
'1' :
'0');
874 return shroud_str.str();
881 for(
const char sh : str) {
883 data_.resize(data_.size() + 1);
886 if(data_.empty() ==
false) {
888 data_.back().push_back(
true);
889 }
else if(sh ==
'0') {
890 data_.back().push_back(
false);
899 for(std::size_t
i = 1;
i < str.length(); ++
i) {
903 }
else if(str[
i] ==
'1') {
906 }
else if(str[
i] ==
'0') {
914 if(enabled_ ==
false) {
918 bool cleared =
false;
920 if(m->enabled_ ==
false) {
924 const std::vector<std::vector<bool>>& v = m->data_;
925 for(std::size_t x = 0; x != v.size(); ++x) {
926 for(std::size_t y = 0; y != v[x].size(); ++y) {
928 cleared |=
clear(x, y);
946 return color_range({255, 0, 0}, {255, 255, 255}, {0, 0, 0}, {255, 0, 0});
964 const unsigned index = side - 1;
974 if(!side_color.empty()) {
982 }
catch(
const std::out_of_range&) {
995 return VGETTEXT(
"“$color_id”", {{
"color_id", color_id }});
1027 LOG_NG <<
"Adding recruitable units: \n";
1029 LOG_NG << recruit << std::endl;
1032 LOG_NG <<
"Added all recruitable units\n";
1045 std::vector<int> res;
1047 if(!
t.is_enemy(this->side()) &&
t.is_human()) {
1048 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
DEFEAT_CONDITION defeat_condition
std::map< std::string, color_range > team_rgb_range
Colors defined by WML [color_range] tags.
unsigned to_unsigned(unsigned def=0) const
SHARE_VISION share_vision
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()
bool copy_from(const std::vector< const shroud_map *> &maps)
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
bool value(int x, int y) const
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 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 write(config &cfg) const
void raise_recruit_list_changed()
Notifies all observers of 'ai_recruit_list_changed' 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...
This class stores all the data for a single 'side' (in game nomenclature).
std::string allied_human_teams() const
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
void read(const config &cfg)
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.
bool shared_value(const std::vector< const shroud_map *> &maps, int x, int y) const
Encapsulates the map of the game.
bool is_enemy(int n) const
Managing the AIs lifecycle - headers TODO: Refactor history handling and internal commands...
void merge(const std::string &shroud_data)
const std::vector< const shroud_map * > & ally_fog(const std::vector< team > &teams) const
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
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.
Default, unset return value.
void read(const std::string &shroud_data)
void set_enabled(bool enabled)
Game configuration data as global variables.
std::set< map_location > villages_
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)
std::set< map_location > fog_clearer_
Stores hexes that have been cleared of fog via WML.
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
void change_team(const std::string &name, const t_string &user_name)
std::set< std::string > can_recruit
std::string write() const
bool fogged(const map_location &loc) const
bool translatable() const
game_events::wml_event_pump & pump()
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.
const std::vector< const shroud_map * > & ally_shroud(const std::vector< team > &teams) const
std::vector< std::string > default_colors
std::tuple< bool, bool > pump_result_t
A config object defines a single node in a WML file, with access to child nodes.
std::map< std::string, t_string > team_rgb_name
This internal whiteboard class holds the planned action queues for a team, and offers many utility me...
std::string::const_iterator iterator
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
CONTROLLER controller() const