1 ///////////////////////////////////////////////////////////////////////////////
2 //            Copyright (C) 2004-2010 by The Allacrost Project
3 //                         All Rights Reserved
4 //
5 // This code is licensed under the GNU GPL version 2. It is free software
6 // and you may modify it and/or redistribute it under the terms of this license.
7 // See http://www.gnu.org/copyleft/gpl.html for details.
8 ///////////////////////////////////////////////////////////////////////////////
9 
10 /** ****************************************************************************
11 *** \file    map_objects.h
12 *** \author  Tyler Olsen, roots@allacrost.org
13 *** \brief   Header file for map mode objects.
14 *** *****************************************************************************/
15 
16 #ifndef __MAP_OBJECTS_HEADER__
17 #define __MAP_OBJECTS_HEADER__
18 
19 // Allacrost utilities
20 #include "utils.h"
21 #include "defs.h"
22 
23 // Allacrost engines
24 #include "video.h"
25 
26 // Local map mode headers
27 #include "map_utils.h"
28 
29 namespace hoa_map {
30 
31 namespace private_map {
32 
33 /** ****************************************************************************
34 *** \brief Abstract class that represents objects on a map
35 ***
36 *** A map object can be anything from a sprite to a tree to a house. To state
37 *** it simply, a map object is a map image that is not tiled and need not be fixed
38 *** in place. Map objects are drawn in one of three layers: ground, pass, and sky
39 *** object layers.
40 
41 *** All map objects have both a collision rectangle and an image rectangle.
42 *** The collision rectangle indicates what parts of the object may not overlap
43 *** with other collision rectangles and unwalkable sections of the map. The image
44 *** rectangle determines the size of the object as it is visible on the screen.
45 *** The collision rectangle and image rectangles do not need to be the same size.
46 *** Typically the collision rectangle is smaller than the image rectangle. It is
47 *** also possible to disable both rectangles via special properties that can be
48 *** enabled in this class. This would prevent the object from being a factor in
49 *** collision detection and/or it would never be drawn to the screen.
50 ***
51 *** State information about map objects may need to be retained upon leaving a
52 *** map. For example, a treasure (which is a type of map object) needs to know
53 *** whether or not the player has retrieved its contents already so that they
54 *** can not be gained a second time. This data is stored in the saved game file
55 *** so that even when the player exits the game, the state information can be
56 *** retrieved when the application starts again later.
57 ***
58 *** \note It is advised not to attempt to make map objects with dynamic sizes (i.e.
59 *** the various image frames that compose the object should all be the same size).
60 *** In theory, dynamically sized objects are feasible to implement in maps, but
61 *** they are much easier to be subject to bugs and other issues.
62 *** ***************************************************************************/
63 class MapObject {
64 public:
65 	MapObject();
66 
~MapObject()67 	virtual ~MapObject()
68 		{}
69 
70 	/** \brief An identification number for the object as it is represented in the map file.
71 	*** Player sprites are assigned object IDs from 5000 and above. Technically this means that
72 	*** a map can have no more than 5000 objects that are not player sprites, but no map should
73 	*** need to contain that many objects in the first place. Objects with an ID less than zero
74 	*** are invalid.
75 	**/
76 	int16 object_id;
77 
78 	/** \brief The map context that the object currently resides in.
79 	*** Context helps to determine where an object "resides". For example, inside of a house or
80 	*** outside of a house. The context member determines if the object should be drawn or not,
81 	*** since objects are only drawn if they are in the same context as the map's camera.
82 	*** Objects can only interact with one another if they both reside in the same context.
83 	***
84 	*** \note The default value for this member is the base context (context 01).
85 	**/
86 	MAP_CONTEXT context;
87 
88 	/** \brief Coordinates for the object's origin/position.
89 	*** The origin of every map object is the bottom center point of the object. These
90 	*** origin coordinates are used to determine where the object is on the map as well
91 	*** as where the objects collision rectangle lies.
92 	***
93 	*** The position coordinates are described by an integer (position) and a float (offset).
94 	*** The position coordinates point to the map grid tile that the object currently occupies
95 	*** and may range from 0 to the number of columns or rows of grid tiles on the map. The
96 	*** offset member will always range from 0.0f and 1.0f to indicate the exact position of
97 	*** the object within that grid tile.
98 	**/
99 	//@{
100 	uint16 x_position, y_position;
101 	float x_offset, y_offset;
102 	//@}
103 
104 	/** \brief The half-width and height of the image, in map grid coordinates.
105 	*** The half_width member is indeed just that: half the width of the object's image. We keep
106 	*** the half width rather than the full width because the origin of the object is its bottom
107 	*** center, and it is more convenient to store only half the sprite's width.
108 	***
109 	*** \note These members assume that the object retains the same width and height regardless
110 	*** of the current animation frame or image being drawn. If the object's image changes size
111 	*** for any reason, the programmer must remember to change these values accordingly.
112 	**/
113 	float img_half_width, img_height;
114 
115 	/** \brief Determines the collision rectangle for the object.
116 	*** The collision area determines what portion of the map object may not be overlapped
117 	*** by other objects or unwalkable regions of the map. The x and y coordinates are
118 	*** relative to the origin, so an x value of 0.5f means that the collision rectangle
119 	*** extends the length of 1/2 of a grid element from the origin on both sides, and a y value
120 	*** of 1.0f means that the collision area exists from the origin to one grid element above.
121 	***
122 	*** \note These members should always be positive and non-zero. Setting these members to
123 	*** zero does <b>not</b> eliminate collision detection for the object.
124 	**/
125 	float coll_half_width, coll_height;
126 
127 	//! \name Object Properties
128 	//@{
129 	//! \brief When false, the Update() function will do nothing (default == true).
130 	bool updatable;
131 
132 	//! \brief When false, the Draw() function will do nothing (default == true).
133 	bool visible;
134 
135 	//! \brief When true, the object will not be examined for collision detection (default == false).
136 	bool no_collision;
137 
138 	/** \brief When true, indicates that the object exists on the sky object layer (default == false).
139 	*** This member is necessary for collision detection purposes. When a sprite needs to detect
140 	*** if it has encountered a collision, that collision must be examined with other objects on
141 	*** the appropriate layer (the ground/pass layers or the sky layer).
142 	**/
143 	bool sky_object;
144 
145 	/** \brief When true, objects in the ground object layer will be drawn after the pass objects
146 	*** This member is only checked for objects that exist in the ground layer. It has no meaning
147 	*** for objects in the pass or sky layers. Its purpose is so that objects (such as a bridge)
148 	*** in the pass layer can be both walked over and walked under by sprites in the ground layer.
149 	**/
150 	bool draw_on_second_pass;
151 	//@}
152 
153 	// ---------- Methods
154 
155 	/** \brief Updates the state of an object.
156 	*** Many map objects may not actually have a use for this function. For example, animated objects
157 	*** like a tree will automatically have their frames updated by the video engine in the draw
158 	*** function. So it is the case that the implementation of this function in derived classes may
159 	*** simply do nothing.
160 	**/
161 	virtual void Update() = 0;
162 
163 	/** \brief Draws the object to the frame buffer.
164 	*** Objects are drawn differently depending on what type of object they are and what their current
165 	*** state is. Note that calling this function does not guarantee that the object will be drawn.
166 	*** Many implementations of this function in the derived classes first call the ShouldDraw() method
167 	*** to determine if the object should be drawn at all.
168 	**/
169 	virtual void Draw() = 0;
170 
171 	/** \brief Determines if an object should be drawn to the screen.
172 	*** \return True if the object should be drawn.
173 	*** \note This function also moves the draw cursor to the proper position if the object should be drawn
174 	***
175 	*** This method performs the common drawing operations of identifying whether or not the object
176 	*** is visible on the screen and moving the drawing cursor to its location. The children classes
177 	*** of this class may choose to make use of it (or not).
178 	**/
179 	bool ShouldDraw();
180 
181 	//! \brief Rolls over the position coordinates if the offsets exceed below 0.0f or above 1.0f
182 	void CheckPositionOffsets();
183 
184 	/** \brief Computes the full floating-point location coordinates of the object
185 	*** \return The full x or y coordinate location of the object
186 	***
187 	*** Since an object's position is stored as an integer component and an offset component, this
188 	*** method simply returns a single floating point value representing the full x and y positions
189 	*** of the object in a single variable.
190 	**/
191 	//@{
ComputeXLocation()192 	float ComputeXLocation() const
193 		{ return (static_cast<float>(x_position) + x_offset); }
194 
ComputeYLocation()195 	float ComputeYLocation() const
196 		{ return (static_cast<float>(y_position) + y_offset); }
197 	//@}
198 
199 	//! \brief Retrieves the object type identifier
GetObjectType()200 	MAP_OBJECT_TYPE GetObjectType() const
201 		{ return _object_type; }
202 
203 	/** \brief Returns the collision rectangle for the current object
204 	*** \param rect A reference to the MapRectangle object to store the collision rectangle data
205 	**/
206 	void GetCollisionRectangle(MapRectangle& rect) const;
207 
208 	/** \brief Returns the image rectangle for the current object
209 	*** \param rect A reference to the MapRectangle object to store the image rectangle data
210 	**/
211 	void GetImageRectangle(MapRectangle& rect) const;
212 
213 	/** \brief Restores the saved state of the object
214 	*** This state data is retained in the saved game file. When any map object is created and added
215 	*** to the map, this function is called to load any stored state data that there may be. Notice
216 	*** that the default implementation of this function does nothing.
217 	**/
RestoreSaved()218 	virtual void RestoreSaved()
219 		{}
220 
221 	/** \name Lua Access Functions
222 	*** These functions are specifically written to enable Lua to access the members of this class.
223 	*** C++ code may also choose to use these functions, although all of the members here are public
224 	*** so it is not mandatory to do so.
225 	**/
226 	//@{
227 	void SetObjectID(int16 id = 0)
228 		{ object_id = id; }
229 
SetContext(MAP_CONTEXT ctxt)230 	void SetContext(MAP_CONTEXT ctxt)
231 		{ context = ctxt; }
232 
SetXPosition(uint16 x,float offset)233 	void SetXPosition(uint16 x, float offset)
234 		{ x_position = x; x_offset = offset; }
235 
SetYPosition(uint16 y,float offset)236 	void SetYPosition(uint16 y, float offset)
237 		{ y_position = y; y_offset = offset; }
238 
SetImgHalfWidth(float width)239 	void SetImgHalfWidth(float width)
240 		{ img_half_width = width; }
241 
SetImgHeight(float height)242 	void SetImgHeight(float height)
243 		{ img_height = height; }
244 
SetCollHalfWidth(float collision)245 	void SetCollHalfWidth(float collision)
246 		{ coll_half_width = collision; }
247 
SetCollHeight(float collision)248 	void SetCollHeight(float collision)
249 		{ coll_height = collision; }
250 
SetUpdatable(bool update)251 	void SetUpdatable(bool update)
252 		{ updatable = update; }
253 
SetVisible(bool vis)254 	void SetVisible(bool vis)
255 		{ visible = vis; }
256 
SetNoCollision(bool coll)257 	void SetNoCollision(bool coll)
258 		{ no_collision = coll; }
259 
SetDrawOnSecondPass(bool pass)260 	void SetDrawOnSecondPass(bool pass)
261 		{ draw_on_second_pass = pass; }
262 
GetObjectID()263 	int16 GetObjectID() const
264 		{ return object_id; }
265 
GetContext()266 	MAP_CONTEXT GetContext() const
267 		{ return context; }
268 
GetXPosition(uint16 & x,float & offset)269 	void GetXPosition(uint16 &x, float &offset) const
270 		{ x = x_position; offset = x_offset; }
271 
GetYPosition(uint16 & y,float & offset)272 	void GetYPosition(uint16 &y, float &offset) const
273 		{ y = y_position; offset = y_offset; }
274 
GetImgHalfWidth()275 	float GetImgHalfWidth() const
276 		{ return img_half_width; }
277 
GetImgHeight()278 	float GetImgHeight() const
279 		{ return img_height; }
280 
GetCollHalfWidth()281 	float GetCollHalfWidth() const
282 		{ return coll_half_width; }
283 
GetCollHeight()284 	float GetCollHeight() const
285 		{ return coll_height; }
286 
IsUpdatable()287 	bool IsUpdatable() const
288 		{ return updatable; }
289 
IsVisible()290 	bool IsVisible() const
291 		{ return visible; }
292 
IsNoCollision()293 	bool IsNoCollision() const
294 		{ return no_collision; }
295 
IsDrawOnSecondPass()296 	bool IsDrawOnSecondPass() const
297 		{ return draw_on_second_pass; }
298 
GetType()299 	MAP_OBJECT_TYPE GetType() const
300 		{ return _object_type; }
301 	//@}
302 
303 protected:
304 	//! \brief This is used to identify the type of map object for inheriting classes.
305 	MAP_OBJECT_TYPE _object_type;
306 }; // class MapObject
307 
308 
309 /** \brief This is a predicate used to sort MapObjects in correct draw order
310 *** \return True if the MapObject pointed by a should be drawn behind MapObject pointed by b
311 *** \note A simple '<' operator cannot be used with the sorting algorithm because it is sorting pointers.
312 **/
313 struct MapObject_Ptr_Less {
operatorMapObject_Ptr_Less314 	const bool operator()(const MapObject* a, const MapObject* b) {
315 		return (a->y_position + a->y_offset) < (b->y_position + b->y_offset);
316 	}
317 };
318 
319 
320 /** ****************************************************************************
321 *** \brief Represents visible objects on the map that have no motion.
322 ***
323 *** This class represents both still image and animated objects. These objects
324 *** are usually fixed in place and do not change their position. The object must
325 *** have at least one entry in its image vector, otherwise a segmentation fault
326 *** will occur if the Update or Draw functions are called.
327 ***
328 *** \note If the object does not have any animated images, set the 'updatable'
329 *** member of the base class to false. Forgetting to do this will do no harm, but
330 *** it will
331 *** ***************************************************************************/
332 class PhysicalObject : public MapObject {
333 public:
334 	PhysicalObject();
335 
336 	~PhysicalObject();
337 
338 	/** \brief The index to the animations vector that contains the current image to display
339 	*** When modifying this member, take care not to exceed the bounds of the animations vector
340 	**/
341 	uint8 current_animation;
342 
343 	/** \brief A vector containing all the object's animations.
344 	*** These need not be actual animations. If you just want a still image, add only a single
345 	*** frame to the animation. Usually only need a single still image or animation will be
346 	*** needed, but a vector is used here in case others are needed.
347 	**/
348 	std::vector<hoa_video::AnimatedImage> animations;
349 
350 	//! \brief Updates the object's current animation.
351 	virtual void Update();
352 
353 	//! \brief Draws the object to the screen, if it is visible.
354 	virtual void Draw();
355 
356 	/** \name Lua Access Functions
357 	*** These functions are specifically to enable Lua to access the members of this class.
358 	**/
359 	//@{
AddAnimation(hoa_video::AnimatedImage new_img)360 	void AddAnimation(hoa_video::AnimatedImage new_img)
361 		{ animations.push_back(new_img); }
362 
SetCurrentAnimation(uint8 current)363 	void SetCurrentAnimation(uint8 current)
364 		{ animations[current_animation].SetTimeProgress(0); current_animation = current; }
365 
SetAnimationProgress(uint32 progress)366 	void SetAnimationProgress(uint32 progress)
367 		{ animations[current_animation].SetTimeProgress(progress); }
368 
GetCurrentAnimation()369 	uint8 GetCurrentAnimation() const
370 		{ return current_animation; }
371 	//@}
372 }; // class PhysicalObject : public MapObject
373 
374 
375 /** ****************************************************************************
376 *** \brief A helper class to MapMode responsible for management of all object and sprite data
377 ***
378 *** This class is responsible for loading, updating, and drawing all map objects
379 *** and map sprites, in addition to maintaining the map's collision grid and map
380 *** zones. This class contains the implementation of the collision detection
381 *** and path finding algorithms.
382 ***
383 *** \todo Each map object is assigned an ID and certain values of IDs are reserved
384 *** for different types of map objects. We need to find out what these are and
385 *** maintain a list of those ranges here.
386 *** ***************************************************************************/
387 class ObjectSupervisor {
388 	friend class hoa_map::MapMode;
389 	// TEMP: for allowing context zones to access all objects
390 	friend class hoa_map::private_map::ContextZone;
391 
392 public:
393 	ObjectSupervisor();
394 
395 	~ObjectSupervisor();
396 
397 	//! \brief Returns a unique ID integer for an object to use
GenerateObjectID()398 	uint16 GenerateObjectID()
399 		{ return ++_last_id; }
400 
401 	/** \brief Retrieves a pointer to an object on this map
402 	*** \param object_id The id number of the object to retreive
403 	*** \return A pointer to the map object, or NULL if no object with that ID was found
404 	**/
405 	MapObject* GetObject(uint32 object_id);
406 
407 	//! \brief Sorts objects on all three layers according to their draw order
408 	void SortObjects();
409 
410 	/** \brief Loads the collision grid data and saved state of all map objects
411 	*** \param map_file A reference to the open map script file
412 	***
413 	*** The file must be open prior to making this call and additionally must
414 	*** be at the highest level scope (i.e., there are no actively open tables
415 	*** in the script descriptor object).
416 	**/
417 	void Load(hoa_script::ReadScriptDescriptor& map_file);
418 
419 	//! \brief Updates the state of all map zones and objects
420 	void Update();
421 
422 	/** \brief Draws the various object layers to the screen
423 	*** \param frame A pointer to the information required to draw this frame
424 	*** \note These functions do not reset the coordinate system and hence depend that the proper coordinate system
425 	*** is already set prior to these function calls (0.0f, SCREEN_COLS, SCREEN_ROWS, 0.0f). These functions do make
426 	*** modifications to the draw flags and the draw cursor position, which are not restored by the function
427 	*** upon its return. Take measures to retain this information before calling these functions if necessary.
428 	**/
429 	//@{
430 	void DrawGroundObjects(const MapFrame* const frame, const bool second_pass);
431 	void DrawPassObjects(const MapFrame* const frame);
432 	void DrawSkyObjects(const MapFrame* const frame);
433 	//@}
434 
435 	/** \brief Finds the nearest map object within a certain distance of a sprite
436 	*** \param sprite The sprite who is trying to find its nearest object
437 	*** \param search_distance The maximum distance to search for an object from the sprite (default == 3.0f)
438 	*** \return A pointer to the nearest map object, or NULL if no such object was found.
439 	***
440 	*** An interactable object must be in the same context as the function argument is. For an object
441 	*** to be valid, it's collision rectangle must be no greater than the search distance (in units of
442 	*** collision grid elements) from the sprite's "calling" axis. For example, if the search distance was 3.0f
443 	*** and the sprite was facing downwards, this function draws an imaginary rectangle below the sprite of height
444 	*** 3.0f and a length equal to the length of the sprite. Any objects that have their collision rectangles intersect
445 	*** with any portion of this search area are put on a list of valid objects, and once this list has been fully
446 	*** constructed the nearest of these objects will be returned.
447 	**/
448 	private_map::MapObject* FindNearestObject(const private_map::VirtualSprite* sprite, float search_distance = 3.0f);
449 
450 	/** \brief Determines if an object occupies an invalid position on the map
451 	*** \param obj A pointer to the map object whose position should be checked
452 	*** \return True if the object has collided with
453 	***
454 	*** The collision condition is true if the object's collision rectangle occupies any space
455 	*** outside of the map boundaries or if any of the collision grid tiles occupied by the
456 	*** collision rectangle are unwalkable in the object's current context.
457 	**/
458 	bool CheckMapCollision(const private_map::MapObject* const obj);
459 
460 	/** \brief Determines if a map object's collision rectangle intersects with a specified map area
461 	*** \param rect A reference to the rectangular section of the map to do collision detection with
462 	*** \param obj A pointer to a map object
463 	*** \return True if the objects collide with one another
464 	*** \note This test is "absolute", and does not factor in things such as map contexts or whether or
465 	*** not the no_collision property is enabled on the MapObject.
466 	**/
467 	bool CheckObjectCollision(const MapRectangle& rect, const private_map::MapObject* const obj);
468 
469 	/** \brief Determines if two map objects have overlapping collision rectangles
470 	*** \param obj1 A pointer to a map object
471 	*** \param obj2 A pointer to a different map object
472 	*** \return True if the objects collide
473 	**/
474 	bool DoObjectsCollide(const private_map::MapObject* const obj1, const private_map::MapObject* const obj2);
475 
476 	/** \brief Determines if a map object or sprite occupies a certain element of the collision grid
477 	*** \param col The collision grid column
478 	*** \param row The collision grid row
479 	*** \return A pointer to the object occupying the grid position or NULL if the position is unoccupied
480 	***
481 	*** \todo Take into account the object/sprite's collision property and also add a parameter for map context
482 	**/
483 	private_map::MapObject* IsPositionOccupied(int16 col, int16 row);
484 
485 	/** \brief Determines if a specific map object occupies a specific element of the collision grid
486 	*** \param col The collision grid column
487 	*** \param row The collision grid row
488 	*** \param object The object to check for occupation of the grid element
489 	*** \return True if the grid element is occupied by the object
490 	***
491 	*** \todo Take into account the object/sprite's collision property and also add a parameter for map context
492 	**/
493 	bool IsPositionOccupiedByObject(int16 col, int16 row, MapObject* object);
494 
495 	/** \brief Determines if a map sprite's position is invalid because of a collision
496 	*** \param sprite A pointer to the map sprite to check
497 	*** \param collision_object A pointer to a pointer to the object that collides with the sprite.
498 	*** This member may be set to NULL if this information is not required by the callee. Otherwise, the callee
499 	*** should declare a pointer member of type MapObject and pass the address of that pointer to this parameter.
500 	*** \return The type of collision detected, which may include NO_COLLISION if none was detected
501 	***
502 	*** This method is invoked by a map sprite who wishes to check for its own collision.
503 	*** The collision detection is performed against three types of obstacles:
504 	***
505 	*** -# Boundary conditions: where the sprite has walked off the edges of the map
506 	*** -# Grid collisions: where the sprite's collision rectangle overlaps with an unwalkable section of the map grid
507 	*** -# Object collision: where the sprite's collision rectangle overlaps that of another object's,
508 	***    where the object is in the same draw layer and context as the original sprite.
509 	**/
510 	COLLISION_TYPE DetectCollision(private_map::VirtualSprite* sprite, private_map::MapObject** collision_object);
511 
512 	/** \brief Attempts to modify a sprite's position in response to an obstruction that it has collided with
513 	*** \param coll_type The type of collision that has occurred
514 	*** \param coll_obj A pointer to the MapObject that the sprite has collided with, if any
515 	*** \return True if the sprite's position was successfully modified
516 	***
517 	*** This function enables sprites to "slide" or "roll" around targets that are in their way. For example,
518 	*** if a sprite moving west ran into a small tree, this function would examine the situation and if appropriate,
519 	*** it would move the sprite in the north or south directions to get around the tree. This allows for a more
520 	*** natural movement in the game and also enables sprites to better navigate through narrow passage ways. Put simply,
521 	*** this function allows sprites to automatically roll/slide around the corners of obstructions.
522 	***
523 	*** If the object that the sprite collided with is anothing moving sprite, then no attempt to modify the sprite's position
524 	*** is performed. This allows for two moving sprites that collided with one another to not come into a deadlock situation
525 	*** where they are both trying to move around the other since one sprite will stop its motion and the other will roll
526 	*** around until the two are free from colliding with one another.
527 	**/
528 	bool AdjustSpriteAroundCollision(VirtualSprite* sprite, COLLISION_TYPE coll_type, MapObject* coll_obj);
529 
530 	/** \brief Finds a path from a sprite's current position to a destination
531 	*** \param sprite A pointer of the sprite to find the path for
532 	*** \param path A reference to a vector of PathNode objects to store the path
533 	*** \param dest The destination coordinates
534 	*** \return True if a path to the destination was found successfully
535 	***
536 	*** This algorithm uses the A* algorithm to find a path from a source to a destination.
537 	*** This function ignores the position of all other objects and only concerns itself with
538 	*** which map grid elements are walkable.
539 	***
540 	*** \note If an error is detected or a path could not be found, the function will empty the path vector before returning
541 	**/
542 	bool FindPath(private_map::VirtualSprite* sprite, std::vector<private_map::PathNode>& path, const private_map::PathNode& dest);
543 
544 private:
545 	/** \brief The number of rows and columns in the collision gride
546 	*** The number of collision grid rows and columns is always equal to twice
547 	*** that of the number of rows and columns of tiles (stored in the TileManager).
548 	**/
549 	uint16 _num_grid_rows, _num_grid_cols;
550 
551 	//! \brief Holds the most recently generated object ID number
552 	uint16 _last_id;
553 
554 	/** \brief A "virtual sprite" that can serve as a focus point for the camera.
555 	*** This sprite is not visible to the player nor does it have any collision
556 	*** detection properties. Usually, the camera focuses on the player's sprite
557 	*** rather than this object, but it is useful for scripted sequences and other
558 	*** things.
559 	**/
560 	private_map::VirtualSprite *_virtual_focus;
561 
562 	/** \brief A 2D vector indicating which grid element on the map sprites may be occupied by objects.
563 	*** Each bit of each element in this grid corresponds to a context. So all together this entire grid
564 	*** stores the collision information for all 32 possible map contexts.
565 	**/
566 	std::vector<std::vector<uint32> > _collision_grid;
567 
568 	/** \brief A map containing pointers to all of the sprites on a map.
569 	*** This map does not include a pointer to the _virtual_focus object. The
570 	*** sprite's unique identifier integer is used as the map key.
571 	**/
572 	std::map<uint16, MapObject*> _all_objects;
573 
574 	/** \brief A container for all of the map objects located on the ground layer.
575 	*** The ground object layer is where most objects and sprites exist in a typical map.
576 	**/
577 	std::vector<MapObject*> _ground_objects;
578 
579 	/** \brief A container for all of the map objects located on the pass layer.
580 	*** The pass object layer is named so because objects on this layer can both be
581 	*** walked under or above by objects in the ground object layer. A good example
582 	*** of an object that would typically go on this layer would be a bridge. This
583 	*** layer usually has very few objects for the map.
584 	**/
585 	std::vector<MapObject*> _pass_objects;
586 
587 	/** \brief A container for all of the map objects located on the sky layer.
588 	*** The sky object layer contains the last series of elements that are drawn on
589 	*** a map. These objects exist high in the sky above all other tiles and objects.
590 	*** Translucent clouds can make good use of this object layer, for instance.
591 	**/
592 	std::vector<MapObject*> _sky_objects;
593 
594 	//! \brief Container for all zones used in this map
595 	std::vector<MapZone*> _zones;
596 
597 	// ---------- Methods
598 
599 	/** \brief Attempts to align a sprite's collision rectangle alongside whatever the sprite has collided against
600 	*** \param sprite The sprite to examine for positional alignment
601 	*** \param direction The direction in which the alignment should take place (only NORTH, SOUTH, EAST, and WEST are valid values)
602 	*** \param coll_type The type of collision that occurred
603 	*** \param sprite_coll_rect The collision rectangle of the sprite
604 	*** \param object_coll_rect The collision rectangle of the collided object (unused if coll_type is not equal to OBJECT_COLLISION)
605 	*** \return True if the sprite's position was modified
606 	**/
607 	bool _AlignSpriteWithCollision(VirtualSprite* sprite, uint16 direction, COLLISION_TYPE coll_type,
608 		const MapRectangle& sprite_coll_rect, const MapRectangle& object_coll_rect);
609 
610 	/** \brief A helper function to AdjustSpriteAroundCollision that moves a sprite around a corner
611 	*** \param sprite The sprite to examine for movement adjustments
612 	*** \param coll_type The type of collision that occurred (BOUNDARY_COLLISION is an invalid value for this function)
613 	*** \param sprite_coll_rect The collision rectangle of the sprite
614 	*** \param object_coll_rect The collision rectangle of the collided object (not valid if coll_type is not equal to OBJECT_COLLISION)
615 	*** \return True if the sprite's position was modified
616 	***
617 	*** This function is what allows a sprite to "roll" or "slide" around the corner of an obstruction when the sprite moves orthogonally.
618 	*** The algorithm works by examining the immediate area around the sprite in the direction where the collision
619 	*** occurred. It will examine a short line in the collision grid immediately next to the sprite in the collision
620 	*** direction. The length of this line will be three times the length/height of the sprite's collision grid (rounded up to
621 	*** whole integer values). For example, a sprite moving west with a collision rectangle size of 2 units wide by 3 units high will
622 	*** equate to a line of 9 collision grid units to examine. If this 9 unit line contains any walkable section
623 	*** that consists of 3 or more concurrent grid elements, the algorithm instructs the sprite to move in that direction.
624 	***
625 	*** If the collision type was an OBJECT_COLLISION, then in addition to the collision grid the algorithm will examine if there is
626 	*** a nearby corner of the object that was collided with. However, no other map objects will be considered in this case (because
627 	*** we wish to limit the computational complexity of this algorithm). If there is another object in the way, then the function will
628 	*** fail (return false) when it tries to modify the sprite's position around the corner.
629 	***
630 	*** \todo One possible downside to this algorithm is that it doesn't take into account other nearby objects that could be
631 	*** in the way. Theoretically if we had a line of sprites standing in an open plane and we tried to move one sprite through the middle
632 	*** of them, the sprite would continue to oscillate around this living wall thinking it has found a gap to get through when
633 	*** there is none. This is something to consider addressing in the future.
634 	**/
635 	bool _MoveSpriteAroundCollisionCorner(VirtualSprite* sprite, COLLISION_TYPE coll_type,
636 		const MapRectangle& sprite_coll_rect, const MapRectangle& object_coll_rect);
637 
638 	/** \brief A helper function to AdjustSpriteAroundCollision that handles diagonal adjustment to sprite movement
639 	*** \param sprite The sprite to examine for movement adjustments
640 	*** \param coll_type The type of collision that occurred
641 	*** \param sprite_coll_rect The collision rectangle of the sprite
642 	*** \param object_coll_rect The collision rectangle of the collided object (not valid if coll_type is not equal to OBJECT_COLLISION)
643 	*** \return True if the sprite's position was modified
644 	***
645 	*** This algorithm will first check for alignment of the sprite with its collision in either the horizontal or vertical directions
646 	*** (and in rare cases, both). If the sprite is not aligned with the collision, its position will be adjusted so that it is. If
647 	*** the sprite is already aligned, then the function will try moving the sprite in only the horizontal or vertical direction.
648 	*** The sprite will never be positioned to move backwards. That is, if the sprite is trying to move north east, this function may
649 	*** move the sprite north, east, or northeast, but it will never move it to the south or west.
650 	**/
651 	bool _MoveSpriteAroundCollisionDiagonal(VirtualSprite* sprite, COLLISION_TYPE coll_type,
652 		const MapRectangle& sprite_coll_rect, const MapRectangle& object_coll_rect);
653 
654 	/** \brief Modifies the position of a sprite and checks if the new position is valid
655 	*** \param sprite The sprite whose position should be modify
656 	*** \param direction The direction to modify the sprite's position in (NORTH, SOUTH, EAST, and WEST are the only valid values)
657 	*** \param distance The distance to move the sprite in the specified direction
658 	*** \return True if the sprite's position was successfully modified to a new valid location
659 	**/
660 	bool _ModifySpritePosition(VirtualSprite* sprite, uint16 direction, float distance);
661 }; // class ObjectSupervisor
662 
663 } // namespace private_map
664 
665 } // namespace hoa_map
666 
667 #endif // __MAP_OBJECTS_HEADER__
668