1 #ifndef _BuildingType_h_ 2 #define _BuildingType_h_ 3 4 5 #include "CommonParams.h" 6 #include "../util/Export.h" 7 #include "../util/Pending.h" 8 9 10 namespace Effect { 11 class EffectsGroup; 12 } 13 namespace Condition { 14 struct Condition; 15 } 16 namespace ValueRef { 17 template <typename T> 18 struct ValueRef; 19 } 20 21 22 //! Class to specify a kind of building. 23 //! 24 //! Each building type must have a unique @a name string, by which it can be 25 //! looked up using GetBuildingType(...). 26 class FO_COMMON_API BuildingType { 27 public: 28 BuildingType(const std::string& name, 29 const std::string& description, 30 CommonParams& common_params, 31 CaptureResult capture_result, 32 const std::string& icon); 33 34 ~BuildingType(); 35 36 //! Returns the unique name for this type of building 37 auto Name() const -> const std::string& 38 { return m_name; } 39 40 //! Returns a text description of this type of building 41 auto Description() const -> const std::string& 42 { return m_description; } 43 44 //! Returns a data file format representation of this object 45 auto Dump(unsigned short ntabs = 0) const -> std::string; 46 47 //! Returns true if the production cost and time are invariant (does not 48 //! depend on) the location 49 auto ProductionCostTimeLocationInvariant() const -> bool; 50 51 //! Returns the number of production points required to build this building 52 //! at this location by this empire 53 auto ProductionCost(int empire_id, int location_id) const -> float; 54 55 //! Returns the maximum number of production points per turn that can be 56 //! spend on this building 57 auto PerTurnCost(int empire_id, int location_id) const -> float; 58 59 //! Returns the number of turns required to build this building at this 60 //! location by this empire 61 auto ProductionTime(int empire_id, int location_id) const -> int; 62 63 //! Returns the ValueRef that determines ProductionCost() 64 auto Cost() const -> const ValueRef::ValueRef<double>* 65 { return m_production_cost.get(); } 66 67 //! Returns the ValueRef that determines ProductionTime() 68 auto Time() const -> const ValueRef::ValueRef<int>* 69 { return m_production_time.get(); } 70 71 //! Returns whether this building type is producible by players and appears 72 //! on the production screen 73 auto Producible() const -> bool 74 { return m_producible; } 75 76 auto ProductionMeterConsumption() const -> const ConsumptionMap<MeterType>& 77 { return m_production_meter_consumption; } 78 79 auto ProductionSpecialConsumption() const -> const ConsumptionMap<std::string>& 80 { return m_production_special_consumption; } 81 82 auto Tags() const -> const std::set<std::string>& 83 { return m_tags; } 84 85 //! Returns the condition that determines the locations where this building 86 //! can be produced 87 auto Location() const -> const Condition::Condition* 88 { return m_location.get(); } 89 90 //! Returns a condition that can be used by the UI to further filter (beyond 91 //! the Location() requirement) where this building will be presented for 92 //! enqueuing onto the production queue, to avoid clutter in the 93 //! BuildDesignatorWnd. Example usage: Buildings that are already enqueued 94 //! at a production location are hidden so they don't appear in the list of 95 //! available items that can be enqueued/produced (again) at that location. 96 auto EnqueueLocation() const -> const Condition::Condition* 97 { return m_enqueue_location.get(); } 98 99 //! Returns the EffectsGroups that encapsulate the effects that buildings of 100 //! this type have when operational. 101 auto Effects() const -> const std::vector<std::shared_ptr<Effect::EffectsGroup>>& 102 { return m_effects; } 103 104 //! Returns the name of the grapic file for this building type 105 auto Icon() const -> const std::string& 106 { return m_icon; } 107 108 //! Returns true iff the empire with ID empire_id can produce this building 109 //! at the location with location_id 110 auto ProductionLocation(int empire_id, int location_id) const -> bool; 111 112 //! Returns true iff the empire with ID empire_id meets the requirements of 113 //! the EnqueueLocation() UI filter method for this building at the 114 //! location with location_id 115 auto EnqueueLocation(int empire_id, int location_id) const -> bool; 116 117 //! Returns CaptureResult for empire with ID @p to_empire_id capturing from 118 //! empire with IDs @p from_empire_id the planet (or other UniverseObject) 119 //! with id @p location_id on which this type of Building is located (if 120 //! @p as_production_item is false) or which is the location of a Production 121 //! Queue BuildItem for a building of this type (otherwise) 122 auto GetCaptureResult(int from_empire_id, int to_empire_id, int location_id, bool as_production_item) const -> CaptureResult 123 { return m_capture_result; } 124 125 //! Returns a number, calculated from the contained data, which should be 126 //! different for different contained data, and must be the same for 127 //! the same contained data, and must be the same on different platforms 128 //! and executions of the program and the function. Useful to verify that 129 //! the parsed content is consistent without sending it all between 130 //! clients and server. 131 auto GetCheckSum() const -> unsigned int; 132 133 private: 134 void Init(); 135 136 std::string m_name; 137 std::string m_description; 138 std::unique_ptr<ValueRef::ValueRef<double>> m_production_cost; 139 std::unique_ptr<ValueRef::ValueRef<int>> m_production_time; 140 bool m_producible = true; 141 CaptureResult m_capture_result; 142 std::set<std::string> m_tags; 143 ConsumptionMap<MeterType> m_production_meter_consumption; 144 ConsumptionMap<std::string> m_production_special_consumption; 145 std::unique_ptr<Condition::Condition> m_location; 146 std::unique_ptr<Condition::Condition> m_enqueue_location; 147 std::vector<std::shared_ptr<Effect::EffectsGroup>> m_effects; 148 std::string m_icon; 149 }; 150 151 //! Holds all FreeOrion BuildingType%s. Types may be looked up by name. 152 class BuildingTypeManager { 153 public: 154 using container_type = std::map<std::string, std::unique_ptr<BuildingType>>; 155 using iterator = container_type::const_iterator; 156 157 //! Returns the building type with the name @p name; you should use the 158 //! free function GetBuildingType(...) instead, mainly to save some typing. 159 auto GetBuildingType(const std::string& name) const -> const BuildingType*; 160 161 auto NumBuildingTypes() const -> std::size_t { return m_building_types.size(); } 162 163 //! iterator to the first building type 164 FO_COMMON_API auto begin() const -> iterator; 165 166 //! iterator to the last + 1th building type 167 FO_COMMON_API auto end() const -> iterator; 168 169 //! Returns the instance of this singleton class; you should use the free 170 //! function GetBuildingTypeManager() instead 171 static auto GetBuildingTypeManager() -> BuildingTypeManager&; 172 173 //! Returns a number, calculated from the contained data, which should be 174 //! different for different contained data, and must be the same for 175 //! the same contained data, and must be the same on different platforms 176 //! and executions of the program and the function. Useful to verify that 177 //! the parsed content is consistent without sending it all between 178 //! clients and server. 179 auto GetCheckSum() const -> unsigned int; 180 181 //! Sets building types to the future value of \p pending_building_types. 182 FO_COMMON_API void SetBuildingTypes(Pending::Pending<container_type>&& pending_building_types); 183 184 private: 185 BuildingTypeManager(); 186 187 //! Assigns any m_pending_building_types to m_bulding_types. 188 void CheckPendingBuildingTypes() const; 189 190 //! Future building type being parsed by parser. 191 //! Mutable so that it can be assigned to m_building_types when completed. 192 mutable boost::optional<Pending::Pending<container_type>> m_pending_building_types = boost::none; 193 194 //! Map of building types identified by the BuildingType::Name. 195 //! mutable so that when the parse complete it can be updated. 196 mutable container_type m_building_types; 197 198 static BuildingTypeManager* s_instance; 199 }; 200 201 //! Returns the singleton building type manager 202 FO_COMMON_API auto GetBuildingTypeManager() -> BuildingTypeManager&; 203 204 //! Returns the BuildingType specification object for a building of type 205 //! @p name. If no such BuildingType exists, nullptr is returned instead. 206 FO_COMMON_API auto GetBuildingType(const std::string& name) -> const BuildingType*; 207 208 209 #endif // _BuildingType_h_ 210