1 // Copyright 2015-2018 the openage authors. See copying.md for legal info. 2 3 #pragma once 4 5 #include <functional> 6 #include <string> 7 8 namespace openage { 9 10 class ResourceBundle; 11 12 /** 13 * A resource 14 */ 15 class Resource { 16 public: 17 18 Resource(); 19 20 virtual int id() const = 0; 21 22 virtual std::string name() const = 0; 23 24 // TODO add images and icons 25 26 }; 27 28 class ResourceProducer : public Resource { 29 public: 30 ResourceProducer(int id,std::string name)31 ResourceProducer(int id, std::string name) 32 : 33 _id{id}, 34 _name{name} { } 35 id()36 int id() const override { return _id; } 37 name()38 std::string name() const override { return _name; } 39 40 private: 41 42 int _id; 43 std::string _name; 44 }; 45 46 /** 47 * All the resources. 48 * 49 * The the ids of the resources must be inside [0, count). 50 * 51 * The static variables wood, food, gold, stone are the ids of the representing resource. 52 * Any extension of Resources must use this ids as they are an engine dependency (at the moment). 53 */ 54 class Resources { 55 public: 56 57 Resources(); 58 59 virtual unsigned int get_count() const = 0; 60 61 virtual const Resource& get_resource(int id) const = 0; 62 63 ResourceBundle create_bundle() const; 64 65 // TODO remove when the engine is fully decupled from the data 66 static const int wood = 0; 67 static const int food = 1; 68 static const int gold = 2; 69 static const int stone = 3; 70 71 }; 72 73 class ClassicResources : public Resources { 74 public: 75 ClassicResources()76 ClassicResources() 77 : 78 resources{{Resources::wood, "wood"}, 79 {Resources::food, "food"}, 80 {Resources::gold, "gold"}, 81 {Resources::stone, "stone"}} { 82 } 83 get_count()84 unsigned int get_count() const override { return 4; } 85 get_resource(int id)86 const Resource& get_resource(int id) const override { return this->resources[id]; }; 87 88 private: 89 90 const ResourceProducer resources[4]; 91 }; 92 93 // TODO remove, here for backwards compatibility 94 enum class game_resource : int { 95 wood = 0, 96 food = 1, 97 gold = 2, 98 stone = 3, 99 RESOURCE_TYPE_COUNT = 4 100 }; 101 102 103 /** 104 * A set of amounts of game resources. 105 * 106 * Can be also used to store other information about the resources. 107 * 108 * TODO change amounts from doubles to integers 109 */ 110 class ResourceBundle { 111 public: 112 113 // TODO remove, here for backwards compatibility 114 ResourceBundle(); 115 116 ResourceBundle(const Resources& resources); 117 118 virtual ~ResourceBundle(); 119 120 ResourceBundle(const ResourceBundle& other); 121 122 ResourceBundle clone() const; 123 124 bool operator> (const ResourceBundle& other) const; 125 bool operator>= (const ResourceBundle& other) const; 126 127 ResourceBundle& operator+= (const ResourceBundle& other); 128 ResourceBundle& operator-= (const ResourceBundle& other); 129 130 ResourceBundle& operator*= (const double a); 131 132 /** 133 * Round each value to the nearest integer. 134 * Returns itself. 135 */ 136 ResourceBundle& round(); 137 138 bool has(const ResourceBundle& amount) const; 139 140 bool has(const ResourceBundle& amount1, const ResourceBundle& amount2) const; 141 142 /** 143 * If amount can't be deducted return false, else deduct the given amount 144 * and return true. 145 */ 146 bool deduct(const ResourceBundle& amount); 147 148 void set(const ResourceBundle& amount); 149 150 void set_all(const double amount); 151 152 void limit(const ResourceBundle& limits); 153 154 double& operator[] (const game_resource res) { return value[static_cast<int>(res)]; } 155 double& operator[] (const int id) { return value[id]; } 156 157 // Getters 158 get(const game_resource res)159 double get(const game_resource res) const { return value[static_cast<int>(res)]; } get(const int id)160 double get(const int id) const { return value[id]; } 161 162 /** 163 * Returns the sum of all the resources. 164 */ 165 double sum() const; 166 167 /** 168 * The number of resources 169 */ get_count()170 int get_count() const { return count; }; 171 172 private: 173 174 ResourceBundle(const int count); 175 176 void expand(const ResourceBundle& other); 177 178 void expand(const int count); 179 180 /** 181 * The number of resources 182 */ 183 int count; 184 185 double *value; 186 187 int min_count(const ResourceBundle& other); 188 189 }; 190 191 } // namespace openage 192 193 namespace std { 194 195 std::string to_string(const openage::game_resource &res); 196 197 /** 198 * hasher for game resource 199 */ 200 template<> struct hash<openage::game_resource> { 201 typedef underlying_type<openage::game_resource>::type underlying_type; 202 203 size_t operator()(const openage::game_resource &arg) const { 204 hash<underlying_type> hasher; 205 return hasher(static_cast<underlying_type>(arg)); 206 } 207 }; 208 209 } // namespace std 210