1 /* 2 * Copyright (C) 2002-2020 by the Widelands Development Team 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 2 7 * of the License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 * 18 */ 19 20 #ifndef WL_LOGIC_PLAYER_H 21 #define WL_LOGIC_PLAYER_H 22 23 #include <memory> 24 25 #include "base/macros.h" 26 #include "economy/economy.h" 27 #include "graphic/color.h" 28 #include "logic/editor_game_base.h" 29 #include "logic/map_objects/tribes/building.h" 30 #include "logic/map_objects/tribes/constructionsite.h" 31 #include "logic/map_objects/tribes/tribe_descr.h" 32 #include "logic/map_objects/tribes/warehouse.h" 33 #include "logic/mapregion.h" 34 #include "logic/message_queue.h" 35 #include "logic/see_unsee_node.h" 36 #include "logic/widelands.h" 37 #include "sound/constants.h" 38 39 class Node; 40 namespace Widelands { 41 42 struct Path; 43 struct PlayerImmovable; 44 class TrainingSite; 45 struct Road; 46 struct Waterway; 47 48 /** 49 * Manage in-game aspects of players, such as tribe, team, fog-of-war, statistics, 50 * messages (notification when a resource has been found etc.) and so on. 51 * 52 * Also provides functions for directly building player immovables; however, 53 * from the UI and AI codes, those should only ever be issued indirectly via 54 * \ref GameController and friends, so that replays and network games function 55 * properly. 56 */ 57 class Player { 58 public: 59 struct BuildingStats { 60 bool is_constructionsite; 61 Coords pos; 62 }; 63 using BuildingStatsVector = std::vector<BuildingStats>; 64 using PlayerBuildingStats = std::vector<BuildingStatsVector>; 65 66 friend class EditorGameBase; 67 friend struct GamePlayerInfoPacket; 68 friend struct GamePlayerEconomiesPacket; 69 friend struct GamePlayerAiPersistentPacket; 70 friend class MapBuildingdataPacket; 71 friend class MapPlayersViewPacket; 72 friend class MapExplorationPacket; 73 74 Player(EditorGameBase&, 75 PlayerNumber, 76 uint8_t initialization_index, 77 const TribeDescr& tribe, 78 const std::string& name); 79 ~Player(); 80 81 void allocate_map(); 82 messages()83 const MessageQueue& messages() const { 84 return messages_; 85 } get_messages()86 MessageQueue* get_messages() { 87 return &messages_; 88 } 89 90 /// Adds the message to the queue. 91 MessageId add_message(Game&, std::unique_ptr<Message> message, bool popup = false); 92 93 /// Like add_message, but if there has been a message from the same sender 94 /// in the last timeout milliseconds in a radius r around the coordinates 95 /// of m, the message deallocated instead. 96 MessageId add_message_with_timeout(Game&, 97 std::unique_ptr<Message> message, 98 uint32_t timeout, 99 uint32_t radius); 100 101 /// Indicates that the object linked to the message has been removed 102 /// from the game. This implementation deletes the message. 103 void message_object_removed(MessageId mid) const; 104 set_message_status(const MessageId & id,Message::Status const status)105 void set_message_status(const MessageId& id, Message::Status const status) { 106 get_messages()->set_message_status(id, status); 107 } 108 109 const std::set<Serial>& ships() const; 110 void add_ship(Serial ship); 111 void remove_ship(Serial ship); 112 egbase()113 const EditorGameBase& egbase() const { 114 return egbase_; 115 } egbase()116 EditorGameBase& egbase() { 117 return egbase_; 118 } player_number()119 PlayerNumber player_number() const { 120 return player_number_; 121 } team_number()122 TeamNumber team_number() const { 123 return team_number_; 124 } get_playercolor()125 const RGBColor& get_playercolor() const { 126 return kPlayerColors[player_number_ - 1]; 127 } tribe()128 const TribeDescr& tribe() const { 129 return tribe_; 130 } 131 get_name()132 const std::string& get_name() const { 133 return name_; 134 } set_name(const std::string & name)135 void set_name(const std::string& name) { 136 name_ = name; 137 } 138 void set_team_number(TeamNumber team); 139 140 void create_default_infrastructure(); 141 142 NodeCaps get_buildcaps(const FCoords&) const; 143 144 bool is_hostile(const Player&) const; 145 146 /** 147 * Returns whether the player lost the last warehouse. 148 */ 149 bool is_defeated() const; 150 151 // For cheating set_see_all(bool const t)152 void set_see_all(bool const t) { 153 see_all_ = t; 154 } see_all()155 bool see_all() const { 156 return see_all_; 157 } 158 159 /// Data that are used and managed by AI. They are here to have it saved as a part of player's 160 /// data 161 struct AiPersistentState { 162 // TODO(tiborb): this should be replaced by command line switch 163 static constexpr size_t kMagicNumbersSize = 200; 164 static constexpr size_t kNeuronPoolSize = 80; 165 static constexpr size_t kFNeuronPoolSize = 60; 166 167 // Seafaring constants for controlling expeditions 168 static constexpr uint32_t kColonyScanStartArea = 35; 169 static constexpr uint32_t kColonyScanMinArea = 12; 170 static constexpr uint32_t kNoExpedition = 0; 171 AiPersistentStateAiPersistentState172 AiPersistentState() 173 : initialized(false), 174 colony_scan_area(0), 175 trees_around_cutters(0), 176 expedition_start_time(0), 177 ships_utilization(0), 178 no_more_expeditions(false), 179 last_attacked_player(0), 180 least_military_score(0), 181 target_military_score(0), 182 ai_productionsites_ratio(0), 183 ai_personality_mil_upper_limit(0), 184 magic_numbers(kMagicNumbersSize, 0), 185 neuron_weights(kNeuronPoolSize, 0), 186 neuron_functs(kNeuronPoolSize, 0), 187 f_neurons(kFNeuronPoolSize, 0) { 188 } 189 190 void initialize(); 191 192 // Was initialized 193 bool initialized; 194 uint32_t colony_scan_area; 195 uint32_t trees_around_cutters; 196 uint32_t expedition_start_time; 197 int16_t 198 ships_utilization; // 0-10000 to avoid floats, used for decision for building new ships 199 bool no_more_expeditions; 200 int16_t last_attacked_player; 201 int32_t least_military_score; 202 int32_t target_military_score; 203 uint32_t ai_productionsites_ratio; 204 int32_t ai_personality_mil_upper_limit; 205 std::vector<int16_t> magic_numbers; 206 std::vector<int8_t> neuron_weights; 207 std::vector<int8_t> neuron_functs; 208 std::vector<uint32_t> f_neurons; 209 std::unordered_map<Widelands::DescriptionIndex, uint32_t> remaining_basic_buildings; 210 } ai_data; 211 get_mutable_ai_persistent_state()212 AiPersistentState* get_mutable_ai_persistent_state() { 213 return &ai_data; 214 } 215 216 /// Per-player field information. 217 struct Field { FieldField218 Field() 219 : military_influence(0), 220 vision(0), 221 r_e(RoadSegment::kNone), 222 r_se(RoadSegment::kNone), 223 r_sw(RoadSegment::kNone), 224 owner(0), 225 time_node_last_unseen(0), 226 map_object_descr(nullptr), 227 border(0), 228 border_r(0), 229 border_br(0), 230 border_bl(0) { 231 // Must be initialized because the rendering code is accessing it 232 // even for triangles that the player does not see (it is the 233 // darkening that actually hides the ground from the user). 234 terrains.d = terrains.r = 0; 235 236 time_triangle_last_surveyed[0] = never(); 237 time_triangle_last_surveyed[1] = never(); 238 } 239 240 /// Military influence is exerted by buildings with the help of soldiers. 241 /// When the first soldier enters a building, it starts to exert military 242 /// influence on the nodes within its conquer radius. When a building 243 /// starts to exert military influence, it adds influence values to the 244 /// nodes. When the last soldier leaves the building, it stops to exert 245 /// military influence. Then the same values are subtracted from the 246 /// nodes. Adding and subtracting military influence values affects land 247 /// ownership according to certain rules. 248 /// 249 /// This is not saved/loaded. It is recalculated during the loading 250 /// process by adding influence values to the nodes surrounding a 251 /// building when the first soldier located in it is loaded. 252 MilitaryInfluence military_influence; 253 254 /// Indicates whether the player is currently seeing this node or has 255 /// has ever seen it. 256 /// 257 /// The value is 258 /// 0 if the player has never seen the node 259 /// 1 if the player does not currently see the node, but has seen it 260 /// previously 261 /// 1+n if the player currently sees the node, where n is the number of 262 /// objects that can see the node. 263 /// 264 /// Note a fundamental difference between seeing a node, and having 265 /// knownledge about resources. A node is considered continuously seen by 266 /// a player as long as it is within vision range of any person of that 267 /// player. If something on the node changes, the game engine will inform 268 /// that player about it. But resource knowledge is not continuous. It is 269 /// instant (given at the time when the geological survey completes) and 270 /// immediately starts aging. Mining implies geological surveying, so a 271 /// player will be informed about resource changes that he causes himself 272 /// by mining. 273 /// 274 /// Buildings do not see on their own. Only people can see. But as soon 275 /// as a person enters a building, the person stops seeing. If it is the 276 /// only person in the building, the building itself starts to see (some 277 /// buildings, such as fortresses usually see much further than persons 278 /// standing on the ground). As soon as a person leaves a building, the 279 /// person begins to see on its own. If the building becomes empty of 280 /// people, it stops seeing. 281 /// 282 /// Only the Boolean representation of this value (whether the node has 283 /// ever been seen) is saved/loaded. The complete value is then obtained 284 /// by the calls to see_node or see_area peformed by all the building and 285 /// worker objects that can see the node. 286 /// 287 /// \note Never change this variable directly. Instead, use the functions 288 /// \ref see_node and \ref unsee_node or, more conveniently, 289 /// \ref see_area and \ref unsee_area . 290 Vision vision; 291 292 // Below follows information about the field, as far as this player 293 // knows. 294 295 /** 296 * The terrain types of the 2 triangles, as far as this player knows. 297 * Each value is only valid when one of the corner nodes of the triangle 298 * has been seen. 299 */ 300 Widelands::Field::Terrains terrains; 301 302 /** 303 * The road types of the 3 edges, as far as this player knows. 304 * Each value is only valid when this player has seen this node 305 * or the node to the the edge leads up to. 306 */ 307 RoadSegment r_e; 308 RoadSegment r_se; 309 RoadSegment r_sw; 310 311 /** 312 * The owner of this node, as far as this player knows. 313 * Only valid when this player has seen this node. 314 */ 315 PlayerNumber owner; 316 317 /** 318 * The amount of resource at each of the triangles, as far as this player 319 * knows. 320 * The d component is only valid when time_last_surveyed[0] != Never(). 321 * The r component is only valid when time_last_surveyed[1] != Never(). 322 */ 323 // TODO(unknown): Check this on access, at least in debug builds 324 Widelands::Field::ResourceAmounts resource_amounts; 325 326 /// Whether there is a road between this node and the node to the 327 /// east, as far as this player knows. 328 /// Only valid when this player has seen this node or the node to the 329 /// east. road_eField330 RoadSegment road_e() const { 331 return r_e; 332 } 333 334 /// Whether there is a road between this node and the node to the 335 /// southeast, as far as this player knows. 336 /// Only valid when this player has seen this node or the node to the 337 /// southeast. road_seField338 RoadSegment road_se() const { 339 return r_se; 340 } 341 342 /// Whether there is a road between this node and the node to the 343 /// southwest, as far as this player knows. 344 /// Only valid when this player has seen this node or the node to the 345 /// southwest. road_swField346 RoadSegment road_sw() const { 347 return r_sw; 348 } 349 350 /** 351 * The last time when this player surveyed the respective triangle 352 * geologically. Indexed by TCoords::TriangleIndex. A geologic survey is a 353 * thorough investigation. Therefore it is considered impossible to have 354 * knowledge about the resources of a triangle without having knowledge 355 * about each of the surrounding nodes: 356 * 357 * geologic information about a triangle => 358 * each neighbouring node has been seen 359 * 360 * and the contrapositive: 361 * 362 * some neighbouring node has never been seen => 363 * no geologic information about the triangle 364 * 365 * Is EditorGameBase::Never() when never surveyed. 366 */ 367 Time time_triangle_last_surveyed[2]; 368 369 /** 370 * The last time when this player saw this node. 371 * Only valid when \ref vision is 1, i.e. the player has previously seen 372 * this node but can't see it right now. 373 * 374 * This value is only for the node. 375 * 376 * The corresponding value for a triangle between the nodes A, B and C is 377 * max 378 * (time_node_last_unseen for A, 379 * time_node_last_unseen for B, 380 * time_node_last_unseen for C) 381 * and is only valid if all of {A, B, C} are currently not seen 382 * (i.e. \ref vision <= 1) 383 * and at least one of them has been seen at least once 384 * (i.e. \ref vision == 1). 385 * 386 * The corresponding value for an edge between the nodes A and B is 387 * max(time_node_last_unseen for A, time_node_last_unseen for B) 388 * and is only valid if all of {A, B} are currently not seen and at 389 * least one of them has been seen at least once. 390 * 391 */ 392 Time time_node_last_unseen; 393 394 /** 395 * The type of immovable on this node, as far as this player knows. 396 * Only valid when the player has seen this node (or maybe a nearby node 397 * if the immovable is big?). (Roads are not stored here.) 398 */ 399 const MapObjectDescr* map_object_descr; 400 401 /// Information for constructionsite's animation. 402 /// only valid, if there is a constructionsite on this node 403 ConstructionsiteInformation constructionsite; 404 405 /// Save whether the player saw a border the last time (s)he saw the node. 406 bool border; 407 bool border_r; 408 bool border_br; 409 bool border_bl; 410 411 // Summary of intended layout (not yet fully implemented) 412 // 413 // 32bit arch 64bit arch 414 // ============ ============ 415 // Identifier offset size offset size 416 // ======================= ====== ==== ====== ==== 417 // military_influence 0x000 0x10 0x000 0x10 418 // vision 0x010 0x10 0x010 0x10 419 // terrains 0x020 0x08 0x020 0x08 420 // roads 0x028 0x06 0x028 0x06 421 // owner_d 0x02e 0x05 0x02e 0x05 422 // owner_r 0x033 0x05 0x033 0x05 423 // resource_amounts 0x038 0x08 0x038 0x08 424 // time_triangle_last_surveyed[0] 0x040 0x20 0x040 0x20 425 // time_triangle_last_surveyed[1] 0x060 0x20 0x060 0x20 426 // time_node_last_unseen 0x080 0x20 0x080 0x20 427 // map_object_descr 0x0a0 0x20 0x0a0 0x40 428 // ConstructionsiteInformation 429 // border 430 // border_r 431 // border_br 432 // border_bl 433 // <end> 0x100 0x160 434 435 private: 436 DISALLOW_COPY_AND_ASSIGN(Field); 437 }; 438 fields()439 const Field* fields() const { 440 return fields_.get(); 441 } 442 443 // See area vision(MapIndex const i)444 Vision vision(MapIndex const i) const { 445 // Node visible if > 1 446 return (see_all_ ? 2 : 0) + fields_[i].vision; 447 } 448 449 /** 450 * Update this player's information about this node and the surrounding 451 * triangles and edges. 452 */ 453 Vision see_node(const Map&, const FCoords&, const Time, const bool forward = false); 454 455 /// Decrement this player's vision for a node. 456 457 Vision 458 unsee_node(MapIndex, Time, SeeUnseeNode mode = SeeUnseeNode::kUnsee, bool forward = false); 459 460 /// Call see_node for each node in the area. see_area(const Area<FCoords> & area)461 void see_area(const Area<FCoords>& area) { 462 const Time gametime = egbase().get_gametime(); 463 const Map& map = egbase().map(); 464 MapRegion<Area<FCoords>> mr(map, area); 465 do { 466 see_node(map, mr.location(), gametime); 467 } while (mr.advance(map)); 468 } 469 470 /// Decrement this player's vision for each node in an area. unsee_area(const Area<FCoords> & area)471 void unsee_area(const Area<FCoords>& area) { 472 const Time gametime = egbase().get_gametime(); 473 const Map& map = egbase().map(); 474 const Widelands::Field& first_map_field = map[0]; 475 MapRegion<Area<FCoords>> mr(map, area); 476 do 477 unsee_node(mr.location().field - &first_map_field, gametime); 478 while (mr.advance(map)); 479 } 480 481 /// Explicitly hide or reveal the field at 'c'. The modes are as follows: 482 /// - kUnsee: Decrement the field's vision 483 /// - kUnexplore: Set the field's vision to 0 484 /// - kReveal: If the field was hidden previously, restore the vision to the value it had 485 /// at the time of hiding. Otherwise, increment the vision. 486 void hide_or_reveal_field(const uint32_t gametime, const Coords& c, SeeUnseeNode mode); 487 military_influence(MapIndex const i)488 MilitaryInfluence military_influence(MapIndex const i) const { 489 return fields_[i].military_influence; 490 } 491 military_influence(MapIndex const i)492 MilitaryInfluence& military_influence(MapIndex const i) { 493 return fields_[i].military_influence; 494 } 495 is_worker_type_allowed(const DescriptionIndex & i)496 bool is_worker_type_allowed(const DescriptionIndex& i) const { 497 return allowed_worker_types_.at(i); 498 } 499 void allow_worker_type(DescriptionIndex, bool allow); 500 501 // Allowed buildings is_building_type_allowed(const DescriptionIndex & i)502 bool is_building_type_allowed(const DescriptionIndex& i) const { 503 return allowed_building_types_[i]; 504 } 505 void allow_building_type(DescriptionIndex, bool allow); 506 507 // Player commands 508 // Only to be called indirectly via CmdQueue 509 Flag& force_flag(const FCoords&); /// Do what it takes to create the flag. 510 Flag* build_flag(const Coords&); /// Build a flag if it is allowed. 511 Road& force_road(const Path&); 512 Road* build_road(const Path&); /// Build a road if it is allowed. 513 Waterway& force_waterway(const Path&); 514 Waterway* build_waterway(const Path&); /// Build a waterway if it is allowed. 515 Building& force_building(Coords, const FormerBuildings&); 516 Building& force_csite(Coords, DescriptionIndex, const FormerBuildings& = FormerBuildings()); 517 Building* build(Coords, DescriptionIndex, bool, FormerBuildings&); 518 void bulldoze(PlayerImmovable&, bool recurse = false); 519 void flagaction(Flag&); 520 void start_stop_building(PlayerImmovable&); 521 void military_site_set_soldier_preference(PlayerImmovable&, 522 SoldierPreference soldier_preference); 523 void start_or_cancel_expedition(Warehouse&); 524 void enhance_building(Building*, DescriptionIndex index_of_new_building, bool keep_wares); 525 void dismantle_building(Building*, bool keep_wares); 526 527 Economy* create_economy(WareWorker); 528 Economy* create_economy(Serial serial, WareWorker); // For saveloading only 529 void remove_economy(Serial serial); 530 const std::map<Serial, std::unique_ptr<Economy>>& economies() const; 531 Economy* get_economy(Widelands::Serial serial) const; 532 bool has_economy(Widelands::Serial serial) const; 533 534 uint32_t get_current_produced_statistics(uint8_t); 535 536 // Military stuff 537 void drop_soldier(PlayerImmovable&, Soldier&); 538 void change_training_options(TrainingSite&, TrainingAttribute attr, int32_t val); 539 540 uint32_t find_attack_soldiers(Flag&, 541 std::vector<Soldier*>* soldiers = nullptr, 542 uint32_t max = std::numeric_limits<uint32_t>::max()); 543 void enemyflagaction(Flag&, PlayerNumber attacker, const std::vector<Widelands::Soldier*>&); 544 casualties()545 uint32_t casualties() const { 546 return casualties_; 547 } kills()548 uint32_t kills() const { 549 return kills_; 550 } msites_lost()551 uint32_t msites_lost() const { 552 return msites_lost_; 553 } msites_defeated()554 uint32_t msites_defeated() const { 555 return msites_defeated_; 556 } civil_blds_lost()557 uint32_t civil_blds_lost() const { 558 return civil_blds_lost_; 559 } civil_blds_defeated()560 uint32_t civil_blds_defeated() const { 561 return civil_blds_defeated_; 562 } count_casualty()563 void count_casualty() { 564 ++casualties_; 565 } count_kill()566 void count_kill() { 567 ++kills_; 568 } count_msite_lost()569 void count_msite_lost() { 570 ++msites_lost_; 571 } count_msite_defeated()572 void count_msite_defeated() { 573 ++msites_defeated_; 574 } count_civil_bld_lost()575 void count_civil_bld_lost() { 576 ++civil_blds_lost_; 577 } count_civil_bld_defeated()578 void count_civil_bld_defeated() { 579 ++civil_blds_defeated_; 580 } 581 582 // Statistics 583 const BuildingStatsVector& get_building_statistics(const DescriptionIndex& i) const; 584 585 std::vector<uint32_t> const* get_ware_production_statistics(DescriptionIndex const) const; 586 587 std::vector<uint32_t> const* get_ware_consumption_statistics(DescriptionIndex const) const; 588 589 std::vector<uint32_t> const* get_ware_stock_statistics(DescriptionIndex const) const; 590 591 void 592 read_statistics(FileRead&, uint16_t packet_version, const TribesLegacyLookupTable& lookup_table); 593 void write_statistics(FileWrite&) const; 594 void read_remaining_shipnames(FileRead&); 595 void write_remaining_shipnames(FileWrite&) const; 596 void sample_statistics(); 597 void ware_produced(DescriptionIndex); 598 599 void ware_consumed(DescriptionIndex, uint8_t); 600 void next_ware_production_period(); 601 602 void set_ai(const std::string&); 603 const std::string& get_ai() const; 604 605 // used in shared kingdom mode add_further_starting_position(uint8_t plr,uint8_t init)606 void add_further_starting_position(uint8_t plr, uint8_t init) { 607 further_shared_in_player_.push_back(plr); 608 further_initializations_.push_back(init); 609 } 610 611 void set_attack_forbidden(PlayerNumber who, bool forbid); 612 bool is_attack_forbidden(PlayerNumber who) const; 613 614 const std::string pick_shipname(); 615 616 private: 617 BuildingStatsVector* get_mutable_building_statistics(const DescriptionIndex& i); 618 void update_building_statistics(Building&, NoteImmovable::Ownership ownership); 619 void update_team_players(); 620 void play_message_sound(const Message* message); 621 void enhance_or_dismantle(Building*, DescriptionIndex index_of_new_building, bool keep_wares); 622 623 // Called when a node becomes seen or has changed. Discovers the node and 624 // those of the 6 surrounding edges/triangles that are not seen from another 625 // node. 626 void rediscover_node(const Map&, const FCoords&); 627 628 std::unique_ptr<Notifications::Subscriber<NoteImmovable>> immovable_subscriber_; 629 std::unique_ptr<Notifications::Subscriber<NoteFieldTerrainChanged>> 630 field_terrain_changed_subscriber_; 631 632 MessageQueue messages_; 633 634 EditorGameBase& egbase_; 635 uint8_t initialization_index_; 636 std::vector<uint8_t> further_initializations_; // used in shared kingdom mode 637 std::vector<uint8_t> further_shared_in_player_; // '' '' '' '' '' 638 TeamNumber team_number_; 639 std::vector<Player*> team_player_; 640 bool team_player_uptodate_; 641 bool see_all_; 642 const PlayerNumber player_number_; 643 const TribeDescr& tribe_; // buildings, wares, workers, sciences 644 uint32_t casualties_, kills_; 645 uint32_t msites_lost_, msites_defeated_; 646 uint32_t civil_blds_lost_, civil_blds_defeated_; 647 std::unordered_set<std::string> remaining_shipnames_; 648 // If we run out of ship names, we'll want to continue with unique numbers 649 uint32_t ship_name_counter_; 650 651 std::unique_ptr<Field[]> fields_; 652 std::vector<bool> allowed_worker_types_; 653 std::vector<bool> allowed_building_types_; 654 std::map<Serial, std::unique_ptr<Economy>> economies_; 655 std::set<Serial> ships_; 656 std::string name_; // Player name 657 std::string ai_; /**< Name of preferred AI implementation */ 658 659 // Fields that were explicitly hidden, with their vision at the time of hiding 660 std::map<MapIndex, Widelands::Vision> hidden_fields_; 661 662 /** 663 * Wares produced (by ware id) since the last call to @ref sample_statistics 664 */ 665 std::vector<uint32_t> current_produced_statistics_; 666 667 /** 668 * Wares consumed (by ware id) since the last call to @ref sample_statistics 669 */ 670 std::vector<uint32_t> current_consumed_statistics_; 671 672 /** 673 * Statistics of wares produced over the life of the game, indexed as 674 * ware_productions_[ware id][time index] 675 */ 676 std::vector<std::vector<uint32_t>> ware_productions_; 677 678 /** 679 * Statistics of wares consumed over the life of the game, indexed as 680 * ware_consumptions_[ware_id][time_index] 681 */ 682 std::vector<std::vector<uint32_t>> ware_consumptions_; 683 684 /** 685 * Statistics of wares stored inside of warehouses over the 686 * life of the game, indexed as 687 * ware_stocks_[ware_id][time_index] 688 */ 689 std::vector<std::vector<uint32_t>> ware_stocks_; 690 691 std::set<PlayerNumber> forbid_attack_; 692 693 PlayerBuildingStats building_stats_; 694 695 FxId message_fx_; 696 FxId attack_fx_; 697 FxId occupied_fx_; 698 699 DISALLOW_COPY_AND_ASSIGN(Player); 700 }; 701 702 void find_former_buildings(const Tribes& tribes, 703 const DescriptionIndex bi, 704 FormerBuildings* former_buildings); 705 } // namespace Widelands 706 707 #endif // end of include guard: WL_LOGIC_PLAYER_H 708