1 /////////////////////////////////////////////////////////////////////////////// 2 // Copyright (C) 2004-2011 by The Allacrost Project 3 // Copyright (C) 2012-2017 by Bertram (Valyria Tear) 4 // All Rights Reserved 5 // 6 // This code is licensed under the GNU GPL version 2. It is free software 7 // and you may modify it and/or redistribute it under the terms of this license. 8 // See https://www.gnu.org/copyleft/gpl.html for details. 9 /////////////////////////////////////////////////////////////////////////////// 10 11 #ifndef __MAP_OBJECT_SUPERVISOR_HEADER__ 12 #define __MAP_OBJECT_SUPERVISOR_HEADER__ 13 14 #include "modes/map/map_objects/map_object.h" 15 16 #include "script/script_read.h" 17 18 namespace vt_map 19 { 20 21 namespace private_map 22 { 23 24 class Halo; 25 class SavePoint; 26 class EscapePoint; 27 class SoundObject; 28 class Light; 29 30 /** **************************************************************************** 31 *** \brief A helper class to MapMode responsible for management of all object and sprite data 32 *** 33 *** This class is responsible for loading, updating, and drawing all map objects 34 *** and map sprites, in addition to maintaining the map's collision grid and map 35 *** zones. This class contains the implementation of the collision detection 36 *** and path finding algorithms. 37 *** 38 *** \todo Each map object is assigned an ID and certain values of IDs are reserved 39 *** for different types of map objects. We need to find out what these are and 40 *** maintain a list of those ranges here. 41 *** ***************************************************************************/ 42 class ObjectSupervisor 43 { 44 friend class vt_map::MapMode; 45 //friend void vt_defs::BindModeCode(); 46 47 public: 48 ObjectSupervisor(); 49 50 ~ObjectSupervisor(); 51 52 //! \brief Returns a unique ID integer for an object to use 53 //! Every object Id must be > 0 since 0 is reserved for speakerless dialogues. GenerateObjectID()54 uint16_t GenerateObjectID() { 55 return ++_last_id; 56 } 57 58 //! \brief Returns the number of objects stored by the supervisor, regardless of what layer they exist on GetNumberObjects()59 uint32_t GetNumberObjects() const { 60 return _all_objects.size(); 61 } 62 63 /** \brief Retrieves a pointer to an object on this map 64 *** \param object_id The id number of the object to retrieve 65 *** \return A pointer to the map object, or nullptr if no object with that ID was found 66 **/ 67 MapObject* GetObject(uint32_t object_id); 68 69 /** \brief Retrieves a pointer to a sprite on this map 70 *** \param object_id The id number of the sprite to retrieve 71 *** \return A pointer to the sprite object, or nullptr if the object was not found or was not a sprite type 72 **/ 73 VirtualSprite* GetSprite(uint32_t object_id); 74 75 //! \brief Wrapper to add an object in the all objects vector. 76 //! This should only be called by the MapObject constructor. 77 void RegisterObject(MapObject* object); 78 79 //! \brief Delete an object from memory. 80 void DeleteObject(MapObject* object); 81 82 //! \brief Add sound objects (Done within the sound object constructor) 83 void AddAmbientSound(SoundObject* object); 84 85 //! \brief Add a light object, often created through scripting. 86 //! Called by the Light object constructor 87 void AddLight(Light* light); 88 89 //! \brief Add a halo object, often created through scripting. 90 //! Called by the Halo object constructor 91 void AddHalo(Halo* halo); 92 93 //! \brief Add a save point. 94 //! Called by the SavePoint object constructor 95 void AddSavePoint(SavePoint* save_point); 96 97 //! \brief Add a escape point. 98 //! Called by the EscapePoint object constructor 99 void AddEscapePoint(EscapePoint* escape_point); 100 101 //! \brief Adds a new zone. 102 // Called by the Mazone constructor. 103 void AddZone(MapZone* zone); 104 105 //! \brief Sorts objects on all three layers according to their draw order 106 void SortObjects(); 107 108 /** \brief Loads the collision grid data and saved state of all map objects 109 *** \param map_file A reference to the open map script file 110 *** \return Whether the collision data loading was successful. 111 *** 112 *** The file must be open prior to making this call and additionally must 113 *** be at the highest level scope (i.e., there are no actively open tables 114 *** in the script descriptor object). 115 **/ 116 bool Load(vt_script::ReadScriptDescriptor &map_file); 117 118 //! \brief Updates the state of all map zones and objects 119 void Update(); 120 121 /** \brief Draws the various object layers to the screen 122 *** \param frame A pointer to the information required to draw this frame 123 *** \note These functions do not reset the coordinate system and hence depend that the proper coordinate system 124 *** is already set prior to these function calls (0.0f, SCREEN_COLS, SCREEN_ROWS, 0.0f). These functions do make 125 *** modifications to the draw flags and the draw cursor position, which are not restored by the function 126 *** upon its return. Take measures to retain this information before calling these functions if necessary. 127 **/ 128 //@{ 129 void DrawMapPoints(); 130 void DrawFlatGroundObjects(); 131 void DrawGroundObjects(const bool second_pass); 132 void DrawPassObjects(); 133 void DrawSkyObjects(); 134 void DrawLights(); 135 void DrawInteractionIcons(); 136 //@} 137 138 /** \brief Finds the nearest interactable map object within a certain distance of a sprite 139 *** \param sprite The sprite who is trying to find its nearest object 140 *** \param search_distance The maximum distance to search for an object from the sprite (default == 3.0f) 141 *** \return A pointer to the nearest map object, or nullptr if no such object was found. 142 *** 143 *** An interactable object must be in the same context as the function argument is. For an object 144 *** to be valid, it's collision rectangle must be no greater than the search distance (in units of 145 *** collision grid elements) from the sprite's "calling" axis. For example, if the search distance was 3.0f 146 *** and the sprite was facing downwards, this function draws an imaginary rectangle below the sprite of height 147 *** 3.0f and a length equal to the length of the sprite. Any objects that have their collision rectangles intersect 148 *** with any portion of this search area are put on a list of valid objects, and once this list has been fully 149 *** constructed the nearest of these objects will be returned. 150 **/ 151 private_map::MapObject* FindNearestInteractionObject(const private_map::VirtualSprite* sprite, 152 float search_distance = 3.0f); 153 154 /** \brief Determines if a map object's collision rectangle intersects with a specified map area 155 *** \param rect A reference to the rectangular section of the map to do collision detection with 156 *** \param obj A pointer to a map object 157 *** \return True if the objects collide with one another 158 *** \note This test is "absolute", and does not factor in things such as map contexts or whether or 159 *** not the no_collision property is enabled on the MapObject. 160 **/ 161 bool CheckObjectCollision(const vt_common::Rectangle2D& rect, 162 const private_map::MapObject *const obj); 163 164 /** \brief Determines if a specific map object occupies a specific element of the collision grid 165 *** \param x The x axis position 166 *** \param y The y axis position 167 *** \param object The object to check for occupation of the grid element 168 *** \return True if the grid element is occupied by the object 169 *** 170 *** \todo Take into account the object/sprite's collision property and also add a parameter for map context 171 **/ 172 bool IsPositionOccupiedByObject(float x, float y, MapObject *object); 173 174 /** \brief Tells the collision type corresponding to an object type. 175 *** \param obj A pointer to the map object to check 176 *** \return The corresponding type of collision detected. 177 **/ 178 COLLISION_TYPE GetCollisionFromObjectType(MapObject *obj) const; 179 180 /** \brief Tells the collision type of a sprite when it is at the given position 181 *** \param object A pointer to the map object to check 182 *** \param x The collision point on the x axis 183 *** \param y The collision point on the y axis 184 *** \param coll_obj A pointer to the MapObject that the sprite has collided with, if any 185 *** \return The type of collision detected, which may include NO_COLLISION 186 *** if none was detected 187 *** 188 *** This method is invoked by a map sprite who wishes to check for its own collision. 189 *** \See COLLISION_TYPE for more information. 190 **/ 191 COLLISION_TYPE DetectCollision(MapObject* object, float x, float y, 192 MapObject **collision_object_ptr = nullptr); 193 194 /** \brief Finds a path from a sprite's current position to a destination 195 *** \param sprite A pointer of the sprite to find the path for 196 *** \param dest The destination coordinates 197 *** \param path A vector of PathNode objects storing the path 198 *** \param max_cost Tells how far a path node can be computed agains the starting path node. 199 *** This is used to avoid heavy computations. 200 *** If this param is equal to 0, there is no limitation. 201 *** 202 *** This algorithm uses the A* algorithm to find a path from a source to a destination. 203 *** This function ignores the position of all other objects and only concerns itself with 204 *** which map grid elements are walkable. 205 *** 206 *** \note If an error is detected or a path could not be found, the function will empty the path vector before returning 207 **/ 208 Path FindPath(private_map::VirtualSprite *sprite, 209 const vt_common::Position2D& destination, 210 uint32_t max_cost = 0); 211 212 /** \brief Tells the object supervisor that the given sprite pointer 213 *** is the party member object. 214 *** This later permits to refresh the sprite shown based on the battle 215 *** formation front party member. 216 **/ SetPartyMemberVisibleSprite(private_map::MapSprite * sprite)217 void SetPartyMemberVisibleSprite(private_map::MapSprite *sprite) { 218 _visible_party_member = sprite; 219 } 220 221 /** Updates the party member sprite based on the first active party member 222 *** given by the global Manager. 223 **/ 224 void ReloadVisiblePartyMember(); 225 226 /** \brief Changes the state of every registered enemy sprite to 'dead' 227 *** Typically used just before a battle begins so that when the player returns to the map, they 228 *** are not swarmed by nearby enemies and quickly forced into another battle. This applies to enemies 229 *** on all object layers and in any context. Exercise caution when invoking this method. 230 **/ 231 void SetAllEnemyStatesToDead(); 232 233 //! \brief Tells whether the collision coords are valid. 234 bool IsWithinMapBounds(float x, float y) const; 235 236 //! \brief Tells whether the sprite has got valid collision coordinates. 237 bool IsWithinMapBounds(VirtualSprite *sprite) const; 238 239 //! \brief Draw the collision rectangles. Used for debugging purpose. 240 void DrawCollisionArea(const MapFrame *frame); 241 242 //! \brief some retrieval functions. These are all const to indicate that 243 //! external callers cannot modify the contents of the map_object; 244 245 //! \brief get the number of rows and columns in the collision grid GetGridAxis(uint32_t & x,uint32_t & y)246 void GetGridAxis(uint32_t &x, uint32_t &y) const { 247 x = _num_grid_x_axis; 248 y = _num_grid_y_axis; 249 } 250 251 //! \brief checks to see if the location is a wall for the party or not. The naming is to indicate 252 //! that we only check for non-moving objects. IE, characters / NPCs / enemies are not checked 253 //! note that treasure boxes, save spots, etc are also skipped 254 //! \param x x location on collision grid 255 //! \param y y location on collision grid 256 //! \return whether the location would be a "wall" for the party or not 257 bool IsStaticCollision(float x, float y); 258 259 //! \brief checks if the location on the grid has a simple map collision. This is different from 260 //! IsStaticCollision, in that it DOES NOT check static objects, but only the collision value for the map IsMapCollision(uint32_t x,uint32_t y)261 bool IsMapCollision(uint32_t x, uint32_t y) 262 { return (_collision_grid[y][x] > 0); } 263 264 //! \brief returns a const reference to the ground objects in GetGroundObjects()265 const std::vector<MapObject *>& GetGroundObjects() const 266 { return _ground_objects; } 267 268 //! \brief Stops sounds objects such as ambient sounds. 269 //! Used when starting a battle for instance. 270 void StopSoundObjects(); 271 272 //! \brief Restarts sounds objects that were previously stopped. 273 //! Used when leaving a battle for instance. 274 void RestartSoundObjects(); 275 276 private: 277 //! \brief Returns the nearest map point. Used by FindNearestObject. 278 private_map::MapObject* _FindNearestMapPoint(const VirtualSprite* sprite); 279 280 //! \brief Updates save points animation and active state. 281 void _UpdateMapPoints(); 282 283 //! \brief Updates the ambient sounds volume according to the camera distance. 284 void _UpdateAmbientSounds(); 285 286 //! \brief Debug: Draws the map zones in orange 287 void _DrawMapZones(); 288 289 //! \brief Returns the MapObject vector corresponding to the draw layer. 290 std::vector<MapObject*>& _GetObjectsFromDrawLayer(MapObjectDrawLayer layer); 291 292 /** \brief The number of rows and columns in the collision grid 293 *** The number of collision grid rows and columns is always equal to twice 294 *** that of the number of rows and columns of tiles (stored in the TileManager). 295 **/ 296 uint16_t _num_grid_x_axis, _num_grid_y_axis; 297 298 //! \brief Holds the most recently generated object ID number 299 uint16_t _last_id; 300 301 /** \brief The party member object is used to keep in memory the active member 302 *** seen on map. This is later useful in "dungeon" maps for instance, where 303 *** the party member in front of the battle formation is the one shown on map. 304 *** Do not create or delete it in the code, this is just a reference. 305 **/ 306 private_map::MapSprite* _visible_party_member; 307 308 /** \brief A 2D vector indicating which grid element on the map sprites may be occupied by objects. 309 *** Each bit of each element in this grid corresponds to a context. So all together this entire grid 310 *** stores the collision information for all 32 possible map contexts. 311 *** \Note A position in this member is stored like this: 312 *** _collision_grid[y][x] 313 **/ 314 std::vector<std::vector<uint32_t> > _collision_grid; 315 316 /** \brief A map containing pointers to all of the sprites on a map. 317 *** This map does not include a pointer to the _virtual_focus object. The 318 *** sprite's unique identifier integer is used as the vector key. 319 *** MapObjects should only be deleted here. 320 **/ 321 std::vector<MapObject *> _all_objects; 322 323 /** \brief A container for all of the map objects located on the ground layer, and being flat. 324 *** See this layer as a pre ground object layer 325 **/ 326 std::vector<MapObject *> _flat_ground_objects; 327 328 /** \brief A container for all of the map objects located on the ground layer. 329 *** The ground object layer is where most objects and sprites exist in a typical map. 330 **/ 331 std::vector<MapObject *> _ground_objects; 332 333 /** \brief A container for all of the map objects located on the pass layer. 334 *** The pass object layer is named so because objects on this layer can both be 335 *** walked under or above by objects in the ground object layer. A good example 336 *** of an object that would typically go on this layer would be a bridge. This 337 *** layer usually has very few objects for the map. 338 **/ 339 std::vector<MapObject *> _pass_objects; 340 341 /** \brief A container for all of the map objects located on the sky layer. 342 *** The sky object layer contains the last series of elements that are drawn on 343 *** a map. These objects exist high in the sky above all other tiles and objects. 344 *** Translucent clouds can make good use of this object layer, for instance. 345 **/ 346 std::vector<MapObject *> _sky_objects; 347 348 //! \brief A container for all of the save points, quite similar as the ground objects container. 349 std::vector<SavePoint *> _save_points; 350 351 //! \brief A container for all of the escape points, quite similar as the ground objects container. 352 std::vector<EscapePoint *> _escape_points; 353 354 //! \brief Ambient sound objects, that plays a sound with a volume according 355 //! to the distance with the camera. 356 std::vector<SoundObject *> _sound_objects; 357 358 //! \brief Vector used to know at what exact volume a sound should be played 359 //! when there are several instances of the same sound in a MapMode. 360 //! They are also used when restarting the MapMode. 361 std::vector<SoundObject*> _sound_object_highest_volumes; 362 363 //! \brief Containers for all of the map source of light, quite similar as the ground objects container. 364 std::vector<Halo *> _halos; 365 std::vector<Light *> _lights; 366 367 //! \brief Container for all zones used in this map 368 std::vector<MapZone *> _zones; 369 }; // class ObjectSupervisor 370 371 } // namespace private_map 372 373 } // namespace vt_map 374 375 #endif // __MAP_OBJECT_SUPERVISOR_HEADER__ 376