1 #ifndef _Universe_h_ 2 #define _Universe_h_ 3 4 5 #include "EnumsFwd.h" 6 #include "ObjectMap.h" 7 #include "UniverseObject.h" 8 #include "../util/Pending.h" 9 10 #include <boost/signals2/signal.hpp> 11 #include <boost/serialization/access.hpp> 12 #include <boost/thread/shared_mutex.hpp> 13 #include <boost/container/flat_map.hpp> 14 15 #include <list> 16 #include <map> 17 #include <memory> 18 #include <set> 19 #include <string> 20 #include <vector> 21 #include <unordered_map> 22 23 #include "../util/Export.h" 24 25 26 class Empire; 27 struct UniverseObjectVisitor; 28 class XMLElement; 29 class ShipDesign; 30 class System; 31 class Pathfinder; 32 class IDAllocator; 33 struct UnlockableItem; 34 class FleetPlan; 35 class MonsterFleetPlan; 36 37 38 namespace Condition { 39 struct Condition; 40 typedef std::vector<std::shared_ptr<const UniverseObject>> ObjectSet; 41 } 42 43 namespace Effect { 44 struct AccountingInfo; 45 struct TargetsAndCause; // struct TargetsAndCause { TargetSet target_set; EffectCause effect_cause; }; 46 struct SourcedEffectsGroup; // struct SourcedEffectsGroup { int source_object_id; const EffectsGroup* effects_group; }; 47 class EffectsGroup; 48 typedef std::vector<std::shared_ptr<UniverseObject>> TargetSet; 49 typedef std::unordered_map<int, boost::container::flat_map<MeterType, std::vector<AccountingInfo>>> AccountingMap; 50 typedef std::vector<std::pair<SourcedEffectsGroup, TargetsAndCause>> SourcesEffectsTargetsAndCausesVec; 51 } 52 53 namespace ValueRef { 54 template <typename T> 55 struct ValueRef; 56 } 57 58 #if defined(_MSC_VER) 59 # if (_MSC_VER == 1900) 60 namespace boost { 61 FO_COMMON_API const volatile Universe* get_pointer(const volatile Universe* p); 62 } 63 # endif 64 #endif 65 66 /** The Universe class contains the majority of FreeOrion gamestate: All the 67 * UniverseObjects in a game, and (of less importance) all ShipDesigns in a 68 * game. (Other gamestate is contained in the Empire class.) 69 * The Universe class also provides functions with which to access objects in 70 * it, information about the objects, and information about the objects' 71 * relationships to each other. As well, there are functions that generate 72 * and populate new Universe gamestates when new games are started. */ 73 class FO_COMMON_API Universe { 74 private: 75 typedef std::map<int, ObjectMap> EmpireObjectMap; ///< Known information each empire had about objects in the Universe; keyed by empire id 76 77 public: 78 typedef std::map<Visibility, int> VisibilityTurnMap; ///< Most recent turn number on which a something, such as a Universe object, was observed at various Visibility ratings or better 79 80 private: 81 typedef std::map<int, VisibilityTurnMap> ObjectVisibilityTurnMap; ///< Most recent turn number on which the objects were observed at various Visibility ratings; keyed by object id 82 typedef std::map<int, ObjectVisibilityTurnMap> EmpireObjectVisibilityTurnMap; ///< Each empire's most recent turns on which object information was known; keyed by empire id 83 84 typedef std::map<int, std::set<int>> ObjectKnowledgeMap; ///< IDs of Empires which know information about an object (or deleted object); keyed by object id 85 86 typedef const ValueRef::ValueRef<Visibility>* VisValRef; 87 typedef std::vector<std::pair<int, VisValRef>> SrcVisValRefVec; 88 typedef std::map<int, SrcVisValRefVec> ObjSrcVisValRefVecMap; 89 typedef std::map<int, ObjSrcVisValRefVecMap> EmpireObjectVisValueRefMap; 90 91 /** Discrepancy between meter's value at start of turn, and the value that 92 * this client calculate that the meter should have with the knowledge 93 * available -> the unknown factor affecting the meter. This is used 94 * when generating effect accounting, in the case where the expected 95 * and actual meter values don't match. */ 96 typedef std::unordered_map<int, boost::container::flat_map<MeterType, double>> DiscrepancyMap; 97 98 public: 99 typedef std::map<int, Visibility> ObjectVisibilityMap; ///< map from object id to Visibility level for a particular empire 100 typedef std::map<int, ObjectVisibilityMap> EmpireObjectVisibilityMap; ///< map from empire id to ObjectVisibilityMap for that empire 101 102 typedef std::map<int, std::set<std::string>> ObjectSpecialsMap; ///< map from object id to names of specials on an object 103 typedef std::map<int, ObjectSpecialsMap> EmpireObjectSpecialsMap; ///< map from empire id to ObjectSpecialsMap of known specials for objects for that empire 104 105 typedef std::map<int, ShipDesign*> ShipDesignMap; ///< ShipDesigns in universe; keyed by design id 106 typedef ShipDesignMap::const_iterator ship_design_iterator; ///< const iterator over ship designs created by players that are known by this client 107 108 /** \name Signal Types */ //@{ 109 /** emitted just before the UniverseObject is deleted */ 110 typedef boost::signals2::signal<void (std::shared_ptr<const UniverseObject>)> UniverseObjectDeleteSignalType; 111 //@} 112 113 /** \name Structors */ //@{ 114 Universe(); 115 virtual ~Universe(); 116 //@} 117 118 /** \name Accessors */ //@{ 119 /** Returns objects in this Universe. */ Objects()120 const ObjectMap& Objects() const { return m_objects; } Objects()121 ObjectMap& Objects() { return m_objects; } 122 123 /** Returns latest known state of objects for the Empire with 124 * id \a empire_id or the true / complete state of all objects in this 125 * Universe (the same as calling Objects()) if \a empire_id is 126 * ALL_EMPIRES*/ 127 const ObjectMap& EmpireKnownObjects(int empire_id = ALL_EMPIRES) const; 128 ObjectMap& EmpireKnownObjects(int empire_id = ALL_EMPIRES); 129 130 /** Returns IDs of objects that the Empire with id \a empire_id has vision 131 * of on the current turn, or objects that at least one empire has vision 132 * of on the current turn if \a empire_id = ALL_EMPIRES */ 133 std::set<int> EmpireVisibleObjectIDs(int empire_id = ALL_EMPIRES) const; 134 135 /** Returns IDs of objects that have been destroyed. */ 136 const std::set<int>& DestroyedObjectIds() const; 137 int HighestDestroyedObjectID() const; 138 139 /** Returns IDs of objects that the Empire with id \a empire_id knows have 140 * been destroyed. Each empire's latest known objects data contains the 141 * last known information about each object, whether it has been destroyed 142 * or not. If \a empire_id = ALL_EMPIRES an empty set of IDs is 143 * returned. */ 144 const std::set<int>& EmpireKnownDestroyedObjectIDs(int empire_id) const; 145 146 /** Returns IDs of objects that the Empire with id \a empire_id has stale 147 * knowledge of in its latest known objects. The latest known data about 148 * these objects suggests that they should be visible, but they are not. */ 149 const std::set<int>& EmpireStaleKnowledgeObjectIDs(int empire_id) const; 150 151 const ShipDesign* GetShipDesign(int ship_design_id) const; ///< returns the ship design with id \a ship_design id, or 0 if non exists 152 void RenameShipDesign(int design_id, const std::string& name = "", 153 const std::string& description = ""); beginShipDesigns()154 ship_design_iterator beginShipDesigns() const {return m_ship_designs.begin();} endShipDesigns()155 ship_design_iterator endShipDesigns() const {return m_ship_designs.end();} 156 157 const ShipDesign* GetGenericShipDesign(const std::string& name) const; 158 159 /** Returns IDs of ship designs that the Empire with id \a empire_id has 160 * seen during the game. If \a empire_id = ALL_EMPIRES an empty set of 161 * ids is returned */ 162 const std::set<int>& EmpireKnownShipDesignIDs(int empire_id) const; 163 164 /** Returns the Visibility level of empire with id \a empire_id of 165 * UniverseObject with id \a object_id as determined by calling 166 * UpdateEmpireObjectVisibilities. */ 167 Visibility GetObjectVisibilityByEmpire(int object_id, int empire_id) const; 168 169 /** Returns the map from Visibility level to turn number on which the empire 170 * with id \a empire_id last had the various Visibility levels of the 171 * UniverseObject with id \a object_id . The returned map may be empty or 172 * not have entries for all visibility levels, if the empire has not seen 173 * the object at that visibility level yet. */ 174 const VisibilityTurnMap& GetObjectVisibilityTurnMapByEmpire(int object_id, int empire_id) const; 175 176 /** Returns the set of specials attached to the object with id \a object_id 177 * that the empire with id \a empire_id can see this turn. */ 178 std::set<std::string> GetObjectVisibleSpecialsByEmpire(int object_id, int empire_id) const; 179 180 /** Return the Pathfinder */ GetPathfinder()181 std::shared_ptr<const Pathfinder> GetPathfinder() const {return m_pathfinder;} 182 183 /** Returns map, indexed by object id, to map, indexed by MeterType, 184 * to vector of EffectAccountInfo for the meter, in order effects 185 * were applied to the meter. */ GetEffectAccountingMap()186 const Effect::AccountingMap& GetEffectAccountingMap() const {return m_effect_accounting_map;} 187 188 const std::map<std::string, std::map<int, std::map<int, double>>>& GetStatRecords()189 GetStatRecords() const { return m_stat_records; } 190 191 mutable UniverseObjectDeleteSignalType UniverseObjectDeleteSignal; ///< the state changed signal object for this UniverseObject 192 //@} 193 194 /** \name Mutators */ //@{ 195 /** Inserts \a ship_design into the universe. Return true on success. The 196 ship design's id will be the newly assigned id. 197 \note Universe gains ownership of \a ship_design once inserted. */ 198 bool InsertShipDesign(ShipDesign* ship_design); 199 200 /** Inserts \a ship_design into the universe with given \a id; returns true 201 * on success, or false on failure. An empire id of none indicates that 202 * the server is allocating an id on behalf of itself. This can be removed 203 * when no longer supporting legacy id allocation in pending Orders. \note 204 * Universe gains ownership of \a ship_design once inserted. */ 205 bool InsertShipDesignID(ShipDesign* ship_design, boost::optional<int> empire_id, int id); 206 207 /** Reset object and ship design id allocation for a new game. */ 208 void ResetAllIDAllocation(const std::vector<int>& empire_ids = std::vector<int>()); 209 210 /** Clears main ObjectMap, empires' latest known objects map, and 211 * ShipDesign map. */ 212 void Clear(); 213 214 /** Resets meters */ 215 void ResetAllObjectMeters(bool target_max_unpaired = true, bool active = true); 216 217 /** Determines all effectsgroups' target sets, then resets meters and 218 * executes all effects on all objects. Then clamps meter values so 219 * target and max meters are within a reasonable range and any current 220 * meters with associated max meters are limited by their max. */ 221 void ApplyAllEffectsAndUpdateMeters(bool do_accounting = true); 222 223 /** Determines all effectsgroups' target sets, then resets meters and 224 * executes only SetMeter effects on all objects whose ids are listed in 225 * \a object_ids. Then clamps meter values so target and max meters are 226 * within a reasonable range and any current meters with associated max 227 * meters are limited by their max. */ 228 void ApplyMeterEffectsAndUpdateMeters(const std::vector<int>& object_ids, bool do_accounting = true); 229 230 /** Calls above ApplyMeterEffectsAndUpdateMeters() function on all objects.*/ 231 void ApplyMeterEffectsAndUpdateMeters(bool do_accounting = true); 232 233 /** Executes effects that modify objects' appearance in the human client. */ 234 void ApplyAppearanceEffects(const std::vector<int>& object_ids); 235 236 /** Executes effects that modify objects' apperance for all objects. */ 237 void ApplyAppearanceEffects(); 238 239 /** Executes effects that modify objects' apperance for all objects. */ 240 void ApplyGenerateSitRepEffects(); 241 242 /** For all objects and meters, determines discrepancies between actual meter 243 * maxes and what the known universe should produce, and and stores in 244 * m_effect_discrepancy_map. */ 245 void InitMeterEstimatesAndDiscrepancies(); 246 247 /** Based on (known subset of, if in a client) universe and any orders 248 * given so far this turn, updates estimated meter maxes for next turn 249 * for the objects with ids indicated in \a objects_vec. */ 250 void UpdateMeterEstimates(const std::vector<int>& objects_vec); 251 252 /** Updates indicated object's meters, and if applicable, the 253 * meters of objects contained within the indicated object. 254 * If \a object_id is INVALID_OBJECT_ID, then all 255 * objects' meters are updated. */ 256 void UpdateMeterEstimates(int object_id, bool update_contained_objects = false); 257 258 /** Updates all meters for all (known) objects */ 259 void UpdateMeterEstimates(); 260 void UpdateMeterEstimates(bool do_accounting); 261 262 /** Sets all objects' meters' initial values to their current values. */ 263 void BackPropagateObjectMeters(); 264 265 /** Determines which empires can see which objects at what visibility 266 * level, based on */ 267 void UpdateEmpireObjectVisibilities(); 268 269 /** Sets a special record of visibility that overrides the standard 270 * empire-object visibility after the latter is processed. */ 271 void SetEffectDerivedVisibility(int empire_id, int object_id, int source_id, 272 const ValueRef::ValueRef<Visibility>* vis); 273 274 /** Applies empire-object visibilities set by effects. */ 275 void ApplyEffectDerivedVisibilities(); 276 277 /** If an \p empire_id can't currently see \p object_id, then remove 278 * \p object_id' object from the object map and the set of known objects. */ 279 void ForgetKnownObject(int empire_id, int object_id); 280 281 /** Sets visibility for indicated \a empire_id of object with \a object_id 282 * a vis */ 283 void SetEmpireObjectVisibility(int empire_id, int object_id, Visibility vis); 284 285 /** Sets visibility for indicated \a empire_id for the indicated \a special */ 286 void SetEmpireSpecialVisibility(int empire_id, int object_id, 287 const std::string& special_name, bool visible = true); 288 289 /** Stores latest known information about each object for each empire and 290 * updates the record of the last turn on which each empire has visibility 291 * of object that can be seen on the current turn with the level of 292 * visibility that the empire has this turn. */ 293 void UpdateEmpireLatestKnownObjectsAndVisibilityTurns(); 294 295 /** Checks latest known information about each object for each empire and, 296 * in cases when the latest known state (stealth and location) suggests 297 * that the empire should be able to see the object, but the object can't 298 * be seen by the empire, updates the latest known state to note this. */ 299 void UpdateEmpireStaleObjectKnowledge(); 300 301 /** Fills pathfinding data structure and determines least jumps distances 302 * between systems for the empire with id \a for_empire_id or uses the 303 * main / true / visible objects if \a for_empire_id is ALL_EMPIRES*/ 304 void InitializeSystemGraph(int for_empire_id = ALL_EMPIRES); 305 306 /** Regenerates per-empire system view graphs by filtering the complete 307 * system graph based on empire visibility. Does not regenerate the base 308 * graph to account for actual system-starlane connectivity changes. */ 309 void UpdateEmpireVisibilityFilteredSystemGraphs(int for_empire_id = ALL_EMPIRES); 310 311 /** Adds the object ID \a object_id to the set of object ids for the empire 312 * with id \a empire_id that the empire knows have been destroyed. */ 313 void SetEmpireKnowledgeOfDestroyedObject(int object_id, int empire_id); 314 315 /** Adds the ship design ID \a ship_design_id to the set of ship design ids 316 * known by the empire with id \a empire_id */ 317 void SetEmpireKnowledgeOfShipDesign(int ship_design_id, int empire_id); 318 319 /** Record in statistics that \a object_id was destroyed by species/empire 320 * associated with \a source_object_id */ 321 void CountDestructionInStats(int object_id, int source_object_id); 322 323 /** Removes the object with ID number \a object_id from the universe's map 324 * of existing objects, and adds the object's id to the set of destroyed 325 * object ids. If \a update_destroyed_object_knowers is true, empires 326 * that currently have visibility of the object have its id added to 327 * their set of objects' ids that are known to have been destroyed. Older 328 * or limited versions of objects remain in empires latest known objects 329 * ObjectMap, regardless of whether the empire knows the object is 330 * destroyed. */ 331 void Destroy(int object_id, bool update_destroyed_object_knowers = true); 332 333 /** Destroys object with ID \a object_id, and destroys any associted 334 * objects, such as contained buildings of planets, contained anything of 335 * systems, or fleets if their last ship has id \a object_id and the fleet 336 * is thus empty. Returns the ids of all destroyed objects. */ 337 std::set<int> RecursiveDestroy(int object_id); 338 339 /** Used by the Destroy effect to mark an object for destruction later 340 * during turn processing. (objects can't be destroyed immediately as 341 * other effects might depend on their existence) */ 342 void EffectDestroy(int object_id, int source_object_id = INVALID_OBJECT_ID); 343 344 /** Permanently deletes object with ID number \a object_id. no 345 * information about this object is retained in the Universe. Can be 346 * performed on objects whether or not the have been destroyed. Returns 347 * true if such an object was found, false otherwise. */ 348 bool Delete(int object_id); 349 350 /** Permanently deletes the ship design with ID number \a design_id. No 351 * information about this design is retained in the Universe. */ 352 bool DeleteShipDesign(int design_id); 353 354 /** Sets whether to inhibit UniverseObjectSignals. Inhibits if \a inhibit 355 * is true, and (re)enables UniverseObjectSignals if \a inhibit is false. */ 356 void InhibitUniverseObjectSignals(bool inhibit = true); 357 358 void UpdateStatRecords(); 359 //@} 360 361 /** Returns true if UniverseOjbectSignals are inhibited, false otherwise. */ 362 const bool& UniverseObjectSignalsInhibited(); 363 364 /** HACK! This must be set to the encoding empire's id when serializing a 365 * Universe, so that only the relevant parts of the Universe are 366 * serialized. The use of this global variable is done just so I don't 367 * have to rewrite any custom boost::serialization classes that implement 368 * empire-dependent visibility. */ 369 int& EncodingEmpire(); 370 371 double UniverseWidth() const; SetUniverseWidth(double width)372 void SetUniverseWidth(double width) { m_universe_width = width; } AllObjectsVisible()373 bool AllObjectsVisible() const { return m_all_objects_visible; } 374 375 /** \name Generators */ //@{ 376 /** InsertNew constructs and inserts a UniverseObject into the object map with a new 377 id. It returns the new object. */ 378 template <typename T, typename... Args> InsertNew(Args &&...args)379 std::shared_ptr<T> InsertNew(Args&&... args) { 380 int id = GenerateObjectID(); 381 return InsertID<T>(id, std::forward<Args>(args)...); 382 } 383 384 /** InsertTemp constructs and inserts a temporary UniverseObject into the object map with a 385 temporary id. It returns the new object. */ 386 template <typename T, typename... Args> InsertTemp(Args &&...args)387 std::shared_ptr<T> InsertTemp(Args&&... args) { 388 auto id = TEMPORARY_OBJECT_ID; 389 return InsertID<T>(id, std::forward<Args>(args)...); 390 } 391 392 /** \p empire_id inserts object \p obj into the universe with the given \p id. 393 This is provided for use with Orders which are run once on the client 394 and receive a new id and then are run a second time on the server using 395 the id assigned on the client. */ 396 template <typename T, typename... Args> InsertByEmpireWithID(int empire_id,int id,Args &&...args)397 std::shared_ptr<T> InsertByEmpireWithID(int empire_id, int id, Args&&... args) { 398 if (!VerifyUnusedObjectID(empire_id, id)) 399 return nullptr; 400 401 return InsertID<T>(id, std::forward<Args>(args)...); 402 } 403 //@} 404 405 //! Set items unlocked before turn 1 from \p future. 406 void SetInitiallyUnlockedItems(Pending::Pending<std::vector<UnlockableItem>>&& future); 407 //! Items unlocked before turn 1. 408 const std::vector<UnlockableItem>& InitiallyUnlockedItems() const; 409 410 //! Set buildings unlocked before turn 1 from \p future. 411 void SetInitiallyUnlockedBuildings(Pending::Pending<std::vector<UnlockableItem>>&& future); 412 //! Buildings unlocked before turn 1. 413 const std::vector<UnlockableItem>& InitiallyUnlockedBuildings() const; 414 415 /** Set fleets unlocked before turn 1 from \p future.*/ 416 void SetInitiallyUnlockedFleetPlans(Pending::Pending<std::vector<std::unique_ptr<FleetPlan>>>&& future); 417 /** Fleets unlocked before turn 1.*/ 418 const std::vector<FleetPlan*> InitiallyUnlockedFleetPlans() const; 419 420 /** Set items unlocked before turn 1 from \p future..*/ 421 void SetMonsterFleetPlans(Pending::Pending<std::vector<std::unique_ptr<MonsterFleetPlan>>>&& future); 422 /** Items unlocked before turn 1.*/ 423 const std::vector<MonsterFleetPlan*> MonsterFleetPlans() const; 424 425 /** Set the empire stats from \p future. */ 426 using EmpireStatsMap = std::map<std::string, std::unique_ptr<ValueRef::ValueRef<double>>>; 427 void SetEmpireStats(Pending::Pending<EmpireStatsMap> future); 428 private: 429 const EmpireStatsMap& EmpireStats() const; 430 public: 431 /** ObfuscateIDGenerator applies randomization to the IDAllocator to prevent clients from 432 inferring too much information about other client's id generation activities. */ 433 void ObfuscateIDGenerator(); 434 435 private: 436 /* Pathfinder setup for the viewing empire 437 */ 438 std::shared_ptr<Pathfinder> m_pathfinder; 439 440 /** Generates an object ID for a future object. Usually used by the server 441 * to service new ID requests. */ 442 int GenerateObjectID(); 443 444 /** Generates design ID for a new (ship) design. Usually used by the 445 * server to service new ID requests. */ 446 int GenerateDesignID(); 447 448 /** Verify that an object ID \p id could be generated by \p empire_id. */ 449 bool VerifyUnusedObjectID(const int empire_id, const int id); 450 451 /** Inserts object \p obj into the universe with the given \p id. */ 452 template <typename T, typename... Args> InsertID(int id,Args &&...args)453 std::shared_ptr<T> InsertID(int id, Args&&... args) { 454 auto obj = std::make_shared<T>(std::forward<Args>(args)...); 455 auto uobj = std::dynamic_pointer_cast<UniverseObject>(obj); 456 if (!uobj) 457 return std::shared_ptr<T>(); 458 459 InsertIDCore(uobj, id); 460 return obj; 461 } 462 463 /** Inserts object \p obj into the universe with the given \p id. */ 464 void InsertIDCore(std::shared_ptr<UniverseObject> obj, int id); 465 466 /** Clears \a source_effects_targets_causes, and then populates with all 467 * EffectsGroups and their targets in the known universe. */ 468 void GetEffectsAndTargets(std::map<int, Effect::SourcesEffectsTargetsAndCausesVec>& source_effects_targets_causes, 469 bool only_meter_effects = false) const; 470 471 /** Removes entries in \a source_effects_targets_causes about effects groups acting 472 * on objects in \a target_objects, and then repopulates for EffectsGroups 473 * that act on at least one of the objects in \a target_objects. If 474 * \a target_objects is empty then default target candidates will be used. */ 475 void GetEffectsAndTargets(std::map<int, Effect::SourcesEffectsTargetsAndCausesVec>& source_effects_targets_causes, 476 const std::vector<int>& target_objects, 477 bool only_meter_effects = false) const; 478 479 void ResetObjectMeters(const std::vector<std::shared_ptr<UniverseObject>>& objects, 480 bool target_max_unpaired = true, bool active = true); 481 482 /** Executes all effects. For use on server when processing turns. 483 * If \a only_meter_effects is true, then only SetMeter effects are 484 * executed. This is useful on server or clients to update meter 485 * values after the rest of effects (including non-meter effects) have 486 * been executed. */ 487 void ExecuteEffects(std::map<int, Effect::SourcesEffectsTargetsAndCausesVec>& source_effects_targets_causes, 488 bool update_effect_accounting, 489 bool only_meter_effects = false, 490 bool only_appearance_effects = false, 491 bool include_empire_meter_effects = false, 492 bool only_generate_sitrep_effects = false); 493 494 /** Does actual updating of meter estimates after the public function have 495 * processed objects_vec or whatever they were passed and cleared the 496 * relevant effect accounting for those objects and meters. If an empty 497 * vector is passed, it will instead update all existing objects. */ 498 void UpdateMeterEstimatesImpl(const std::vector<int>& objects_vec, bool do_accounting); 499 500 ObjectMap m_objects; ///< map from object id to UniverseObjects in the universe. for the server: all of them, up to date and true information about object is stored; for clients, only limited information based on what the client knows about is sent. 501 EmpireObjectMap m_empire_latest_known_objects; ///< map from empire id to (map from object id to latest known information about each object by that empire) 502 503 std::set<int> m_destroyed_object_ids; ///< all ids of objects that have been destroyed (on server) or that a player knows were destroyed (on clients) 504 505 EmpireObjectVisibilityMap m_empire_object_visibility; ///< map from empire id to (map from object id to visibility of that object for that empire) 506 EmpireObjectVisibilityTurnMap m_empire_object_visibility_turns; ///< map from empire id to (map from object id to (map from Visibility rating to turn number on which the empire last saw the object at the indicated Visibility rating or higher) 507 508 EmpireObjectVisValueRefMap m_effect_specified_empire_object_visibilities; 509 510 EmpireObjectSpecialsMap m_empire_object_visible_specials; ///< map from empire id to (map from object id to (set of names of specials that empire can see are on that object) ) 511 512 ObjectKnowledgeMap m_empire_known_destroyed_object_ids;///< map from empire id to (set of object ids that the empire knows have been destroyed) 513 ObjectKnowledgeMap m_empire_stale_knowledge_object_ids;///< map from empire id to (set of object ids that the empire has previously observed but has subsequently been unable to detect at its last known location despite expecting to be able to detect it based on stealth of the object and having detectors in range) 514 515 ShipDesignMap m_ship_designs; ///< ship designs in the universe 516 std::map<int, std::set<int>> m_empire_known_ship_design_ids; ///< ship designs known to each empire 517 518 Effect::AccountingMap m_effect_accounting_map; ///< map from target object id, to map from target meter, to orderered list of structs with details of an effect and what it does to the meter 519 520 /// map from target object id, to map from target meter, to discrepancy 521 /// between meter's actual initial value, and the initial value that this 522 /// meter should have as far as the client can tell: the unknown factor 523 /// affecting the meter. 524 DiscrepancyMap m_effect_discrepancy_map; 525 526 std::map<int, std::set<int>> m_marked_destroyed; ///< used while applying effects to cache objects that have been destroyed. this allows to-be-destroyed objects to remain undestroyed until all effects have been processed, which ensures that to-be-destroyed objects still exist when other effects need to access them as a source object. key is destroyed object, and value set are the ids of objects that caused the destruction (may be multiples destroying a single target on a given turn) 527 528 double m_universe_width; 529 bool m_inhibit_universe_object_signals; 530 int m_encoding_empire; ///< used during serialization to globally set what empire knowledge to use 531 bool m_all_objects_visible; ///< flag set to skip visibility tests and make everything visible to all players 532 533 std::map<std::string, std::map<int, std::map<int, double>>> 534 m_stat_records; ///< storage for statistics calculated for empires. Indexed by stat name (string), contains a map indexed by empire id, contains a map from turn number (int) to stat value (double). 535 536 //! @name Parsed items 537 //! Various unlocked items are kept as a Pending::Pending while being parsed and 538 //! then transfered. They are mutable to allow processing in const accessors. 539 //! @{ 540 mutable boost::optional<Pending::Pending<std::vector<UnlockableItem>>> m_pending_items = boost::none; 541 mutable boost::optional<Pending::Pending<std::vector<UnlockableItem>>> m_pending_buildings = boost::none; 542 mutable boost::optional<Pending::Pending<std::vector<std::unique_ptr<FleetPlan>>>> m_pending_fleet_plans = boost::none; 543 mutable boost::optional<Pending::Pending<std::vector<std::unique_ptr<MonsterFleetPlan>>>> m_pending_monster_fleet_plans = boost::none; 544 mutable boost::optional<Pending::Pending<EmpireStatsMap>> m_pending_empire_stats = boost::none; 545 546 mutable std::vector<UnlockableItem> m_unlocked_items; 547 mutable std::vector<UnlockableItem> m_unlocked_buildings; 548 mutable std::vector<std::unique_ptr<FleetPlan>> m_unlocked_fleet_plans; 549 mutable std::vector<std::unique_ptr<MonsterFleetPlan>> m_monster_fleet_plans; 550 mutable EmpireStatsMap m_empire_stats; 551 //! @} 552 553 /** Fills \a designs_to_serialize with ShipDesigns known to the empire with 554 * the ID \a encoding empire. If encoding_empire is ALL_EMPIRES, then all 555 * designs are included. */ 556 void GetShipDesignsToSerialize(ShipDesignMap& designs_to_serialize, int encoding_empire) const; 557 558 /** Fills \a objects with copies of UniverseObjects that should be sent 559 * to the empire with id \a encoding_empires */ 560 void GetObjectsToSerialize(ObjectMap& objects, int encoding_empire) const; 561 562 /** Fills \a destroyed_object_ids with ids of objects known to be destroyed 563 * by the empire with ID \a encoding empire. If encoding_empire is 564 * ALL_EMPIRES, then all destroyed objects are included. */ 565 void GetDestroyedObjectsToSerialize(std::set<int>& destroyed_object_ids, int encoding_empire) const; 566 567 /** Fills \a empire_latest_known_objects map with the latest known data 568 * about UniverseObjects for the empire with id \a encoding_empire. If 569 * the encoding empire is ALL_EMPIRES then all stored empire object 570 * knowledge is included. */ 571 void GetEmpireKnownObjectsToSerialize(EmpireObjectMap& empire_latest_known_objects, int encoding_empire) const; 572 573 /***/ 574 void GetEmpireObjectVisibilityMap(EmpireObjectVisibilityMap& empire_object_visibility, int encoding_empire) const; 575 576 /***/ 577 void GetEmpireObjectVisibilityTurnMap(EmpireObjectVisibilityTurnMap& empire_object_visibility_turns, int encoding_empire) const; 578 579 /***/ 580 //void GetEffectSpecifiedVisibilities(EmpireObjectVisibilityMap& effect_specified_empire_object_visibilities, int encoding_empire) const; 581 582 /***/ 583 void GetEmpireKnownDestroyedObjects(ObjectKnowledgeMap& empire_known_destroyed_object_ids, int encoding_empire) const; 584 585 /***/ 586 void GetEmpireStaleKnowledgeObjects(ObjectKnowledgeMap& empire_stale_knowledge_object_ids, int encoding_empire) const; 587 588 /** Manages allocating and verifying new object ids.*/ 589 std::unique_ptr<IDAllocator> const m_object_id_allocator; 590 591 /** Manages allocating and verifying new ship design ids.*/ 592 std::unique_ptr<IDAllocator> const m_design_id_allocator; 593 594 friend class boost::serialization::access; 595 template <typename Archive> 596 void serialize(Archive& ar, const unsigned int version); 597 }; 598 599 600 /** Compute a checksum for each of the universe's content managers. Each value will be of the form 601 ("BuildingManager", <checksum>) */ 602 FO_COMMON_API std::map<std::string, unsigned int> CheckSumContent(); 603 604 #endif // _Universe_h_ 605