1 // Copyright 2014-2017 the openage authors. See copying.md for legal info. 2 3 #pragma once 4 5 #include <memory> 6 #include <unordered_map> 7 #include <vector> 8 9 #include "../coord/tile.h" 10 #include "../handlers.h" 11 #include "../util/timing.h" 12 13 14 namespace openage { 15 16 class Command; 17 class Player; 18 class Terrain; 19 class TerrainObject; 20 class Unit; 21 class UnitContainer; 22 class UnitType; 23 24 25 /** 26 * Type used to identify each single unit in the game. 27 */ 28 using id_t = unsigned long int; 29 30 31 /** 32 * immutable reference data 33 */ 34 struct reference_data { 35 reference_data(const UnitContainer *c, id_t id, Unit *); 36 37 const UnitContainer *const container; 38 const id_t unit_id; 39 Unit *const unit_ptr; 40 }; 41 42 /** 43 * Reference to a single unit, which may have been removed 44 * from the game, check is_valid() before calling get() 45 */ 46 class UnitReference { 47 public: 48 49 /** 50 * create an invalid reference 51 */ 52 UnitReference(); 53 54 /** 55 * create referece by unit id 56 */ 57 UnitReference(const UnitContainer *c, id_t id, Unit *); 58 59 bool is_valid() const; 60 Unit *get() const; 61 62 private: 63 64 /** 65 * The default copy constructor and assignment 66 * will just copy the shared pointer 67 */ 68 std::shared_ptr<reference_data> data; 69 }; 70 71 /** 72 * the list of units that are currently in use 73 * will also give a view of the current game state for networking in later milestones 74 */ 75 class UnitContainer { 76 public: 77 UnitContainer(); 78 ~UnitContainer(); 79 80 void reset(); 81 82 /** 83 * sets terrain to initialise units on 84 */ 85 void set_terrain(std::shared_ptr<Terrain> &t); 86 87 /** 88 * returns the terrain which units are placed on 89 */ 90 std::shared_ptr<Terrain> get_terrain() const; 91 92 /** 93 * checks the id is valid 94 */ 95 bool valid_id(id_t id) const; 96 97 /** 98 * returns a reference to a unit 99 */ 100 UnitReference get_unit(id_t id); 101 102 /** 103 * creates a new unit without initialising 104 */ 105 UnitReference new_unit(); 106 107 /** 108 * adds a new unit to the container and initialises using a unit type 109 */ 110 UnitReference new_unit(UnitType &type, Player &owner, coord::phys3 position); 111 112 /** 113 * adds a new unit to the container and initialises using a unit type 114 * places outside an existing object using the player of that object 115 */ 116 UnitReference new_unit(UnitType &type, Player &owner, TerrainObject *other); 117 118 /** 119 * give a command to a unit -- unit creation and deletion should be done as commands 120 */ 121 bool dispatch_command(id_t to_id, const Command &cmd); 122 123 /** 124 * update dispatched by the game engine on each physics tick. 125 * this will update all game objects. 126 */ 127 bool update_all(time_nsec_t lastframe_duration); 128 129 /** 130 * gets a list of all units in the container 131 */ 132 std::vector<openage::Unit *> all_units(); 133 134 private: 135 id_t next_new_id; 136 137 /** 138 * mapping unit ids to unit objects 139 */ 140 std::unordered_map<id_t, std::unique_ptr<Unit>> live_units; 141 142 /** 143 * Terrain for initialising new units 144 */ 145 std::weak_ptr<Terrain> terrain; 146 }; 147 148 } // namespace openage 149