///////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2004-2007 by The Allacrost Project
// All Rights Reserved
//
// This code is licensed under the GNU GPL version 2. It is free software
// and you may modify it and/or redistribute it under the terms of this license.
// See http://www.gnu.org/copyleft/gpl.html for details.
///////////////////////////////////////////////////////////////////////////////
/** ****************************************************************************
*** \file map.h
*** \author Tyler Olsen, roots@allacrost.org
*** \brief Header file for map mode interface.
***
*** This code handles the game event processing and frame drawing when the user
*** is in map mode (when the user is exploring town or dungeon maps). This
*** includes handling of tile images, sprites, and events that occur on the map.
***
*** Each individual map is represented by it's own object
*** of the MapMode class. At this time, the intention is to keep the three most
*** recently accessed maps in memory so there is no loading time when the player
*** backtraces his or her steps. When a new map is loaded and there are already
*** three
*** ***************************************************************************/
#ifndef __MAP_HEADER__
#define __MAP_HEADER__
#include "defs.h"
#include "utils.h"
#include "mode_manager.h"
#include "script.h"
#include "video.h"
#include "gui.h"
//! All calls to map mode are wrapped in this namespace.
namespace hoa_map {
//! Determines whether the code in the hoa_map namespace should print debug statements or not.
extern bool MAP_DEBUG;
//! An internal namespace to be used only within the map code. Don't use this namespace anywhere else!
namespace private_map {
// ************************ MAP CONSTANTS ****************************
/** \name Screen Coordiante System Constants
*** \brief The number of rows and columns of map grid elements that compose the screen.
*** These are not the number of tiles that compose the screen. The number of tile
*** rows and columns that compose a screen are exactly one half of these numbers.
**/
//@{
const float SCREEN_COLS = 64.0f;
const float SCREEN_ROWS = 48.0f;
const float HALF_SCREEN_COLS = 32.0f;
const float HALF_SCREEN_ROWS = 24.0f;
const uint16 TILE_COLS = 32;
const uint16 TILE_ROWS = 24;
const uint16 HALF_TILE_COLS = 16;
const uint16 HALF_TILE_ROWS = 12;
//@}
//! \brief The number of tiles that are found in a tileset image (512x512 pixel image containing 32x32 pixel tiles)
const uint32 TILES_PER_TILESET = 256;
/** \name Map State Constants
*** \brief Constants used for describing the current state of operation during map mode.
*** These constants are largely used to determine what
**/
//@{
//! \brief The standard state of the map, where the player is free to roam.
const uint8 EXPLORE = 0x01;
//! \brief When a dialogue is in process, the map is in this state.
const uint8 DIALOGUE = 0x02;
//! \brief When the map is in this state, the player can not control the action.
const uint8 OBSERVATION = 0x04;
//@}
/** \name Map Context Constants
*** \brief Constants used to represent all 32 possible map contexts
**/
enum MAP_CONTEXT {
MAP_CONTEXT_01 = 0x00000001,
MAP_CONTEXT_02 = 0x00000002,
MAP_CONTEXT_03 = 0x00000004,
MAP_CONTEXT_04 = 0x00000008,
MAP_CONTEXT_05 = 0x00000010,
MAP_CONTEXT_06 = 0x00000020,
MAP_CONTEXT_07 = 0x00000040,
MAP_CONTEXT_08 = 0x00000080,
MAP_CONTEXT_09 = 0x00000100,
MAP_CONTEXT_10 = 0x00000200,
MAP_CONTEXT_11 = 0x00000400,
MAP_CONTEXT_12 = 0x00000800,
MAP_CONTEXT_13 = 0x00001000,
MAP_CONTEXT_14 = 0x00002000,
MAP_CONTEXT_15 = 0x00004000,
MAP_CONTEXT_16 = 0x00008000,
MAP_CONTEXT_17 = 0x00010000,
MAP_CONTEXT_18 = 0x00020000,
MAP_CONTEXT_19 = 0x00040000,
MAP_CONTEXT_20 = 0x00080000,
MAP_CONTEXT_21 = 0x00100000,
MAP_CONTEXT_22 = 0x00200000,
MAP_CONTEXT_23 = 0x00400000,
MAP_CONTEXT_24 = 0x00800000,
MAP_CONTEXT_25 = 0x01000000,
MAP_CONTEXT_26 = 0x02000000,
MAP_CONTEXT_27 = 0x04000000,
MAP_CONTEXT_28 = 0x08000000,
MAP_CONTEXT_29 = 0x10000000,
MAP_CONTEXT_30 = 0x20000000,
MAP_CONTEXT_31 = 0x40000000,
MAP_CONTEXT_32 = 0x80000000
};
/** ****************************************************************************
*** \brief Retains information about how the next map frame should be drawn.
***
*** This class is used by the MapMode class to determine how the next map frame
*** should be drawn. This includes which tiles will be visible and the offset
*** coordinates for the screen. Map objects also use this information to determine
*** where (and if) they should be drawn.
***
*** \note The MapMode class keeps an active object of this class with the latest
*** information about the map. It should be the only instance of this class that is
*** needed.
*** ***************************************************************************/
class MapFrame {
public:
//! \brief The column and row indeces of the starting tile to draw (the top-left tile).
int16 starting_col, starting_row;
//! \brief The number of columns and rows of tiles to draw on the screen.
uint8 num_draw_cols, num_draw_rows;
//! \brief The x and y position screen coordinates to start drawing tiles from.
float tile_x_start, tile_y_start;
/** \brief The position coordinates of the screen edges.
*** These members are in terms of the map grid 16x16 pixel coordinates that map objects use.
*** The presense of these coordinates make it easier for map objects to figure out whether or
*** not they should be drawn on the screen. Note that these are not used as drawing
*** cursor positions, but rather are map grid coordinates indicating where the screen edges lie.
**/
float left_edge, right_edge, top_edge, bottom_edge;
}; // class MapFrame
/** ****************************************************************************
*** \brief A container class for node information in pathfinding.
***
*** This class is used in the MapMode#_FindPath function to find an optimal
*** path from a given source to a destination.
*** *****************************************************************************/
class PathNode {
public:
/** \brief The coordinates for this node
*** These coordinates correspond to the MapMode#_walkable 2D vector, where
*** each element is a 16x16 pixel space on the map.
**/
//@{
int16 row, col;
//@}
//! \name Path Scoring Members
//@{
//! \brief The total score for this node (f = g + h).
int16 f_score;
//! \brief The score for this node relative to the source.
int16 g_score;
//! \brief The Manhattan distance from this node to the destination.
int16 h_score;
//@}
//PathNode *parent;
int16 parent_row, parent_col;
PathNode() :
row(-1), col(-1), f_score(0), g_score(0), h_score(0), parent_row( 0 ), parent_col( 0 ) {}
PathNode(int16 r, int16 c) :
row(r), col(c), f_score(0), g_score(0), h_score(0), parent_row( 0 ), parent_col( 0 ) {}
//! \brief Overloaded comparison operator checks that tile.row and tile.col are equal
bool operator==(const PathNode& that) const
{ return ((this->row == that.row) && (this->col == that.col)); }
//! \brief Overloaded comparison operator checks that tile.row or tile.col are not equal
bool operator!=(const PathNode& that) const
{ return ((this->row != that.row) || (this->col != that.col)); }
//! \brief Overloaded comparison operator only used for path finding. It compares the two f_scores.
bool operator<(const PathNode& that) const
{ return this->f_score > that.f_score; }
}; // class PathNode
} // namespace private_map
/** ****************************************************************************
*** \brief Represents a single tile on the map.
***
*** The images that a tile uses are not stored within this class. They are
*** stored in the MapMode#_tile_images vector, and this class contains three
*** indices to images in that vector. This class also does not contain any
*** information about walkability. That information is kept in a seperate vector
*** in the MapMode class.
***
*** \note The reason that tiles do not contain walkability information is that
*** each tile is 32x32 pixels, but walkability is defined on a 16x16 granularity,
*** meaning that there are four "walkable" sections to each tile. Code such as
*** pathfinding is more simple if all walkability information is kept in a seperate
*** container.
***
*** \note The coordinate system in MapMode is in terms of tiles. Specifically,
*** the screen is defined to be 32 tile columns wide and 24 tile rows high. Using
*** 32x32 tile images, this corresponds to a screen resolution of 1024x768, which
*** is the default screen resolution of Allacrost. The origin [0.0f, 0.0f] is the
*** top-left corner of the screen and the bottom-right corner coordinates are
*** [32.0f, 24.0f]. Both map tiles and map objects in Allacrost are drawn on the
*** screen using the bottom middle of the image as its reference point.
*** ***************************************************************************/
class MapTile {
public:
/** \name Tile Layer Indeces
*** \brief Indeces to MapMode#_tile_images, mapping to the three tile layers.
*** \note A value less than zero means that no image is registered to that tile layer.
**/
//@{
int16 lower_layer, middle_layer, upper_layer;
//@}
MapTile()
{ lower_layer = -1; middle_layer = -1; upper_layer = -1; }
MapTile(int16 lower, int16 middle, int16 upper)
{ lower_layer = lower; middle_layer = middle; upper_layer = upper; }
}; // class MapTile
/** ****************************************************************************
*** \brief Handles the game execution while the player is exploring maps.
***
*** This class contains all of the structures that together compose each map, as
*** well as some other information. The methods provided by this class are those
*** methods that are either commonly used, or require high performance. Each map
*** has a Lua script file in which the map data is permanently retained and
*** various script subroutines exist that modify the map's behavior. Keep in mind
*** that this class alone does not represent all of the data nor all of the code
*** that is used in a particular map, as the map's Lua file may retain some of
*** this information to itself.
***
*** Maps are composed by a series of tiles and objects. Tiles are 32x32 pixel
*** squares that are adjacent to one another on a map, and together make up the
*** map's background environment. Objects are variable sized entities that are
*** usually living, animated creatures (sprites), but may be something static
*** such as a large tree. Tiles and objects are drawn in multiple interwieving
*** layers to emulate a 3D environment for the game.
***
*** \note Although the drawing coordinates are in terms of 32x32 tiles, the rest
*** of the map follows a 16x16 grid for collision detection, pathfinding, etc.
*** Because the positions of map objects are defined in terms of this 16x16 grid,
*** that means that when drawing the images, the position must be converted to
*** the 32x32 grid.
*** ***************************************************************************/
class MapMode : public hoa_mode_manager::GameMode {
friend class private_map::MapFrame;
friend class private_map::MapObject;
friend class private_map::PhysicalObject;
friend class private_map::MapTreasure;
friend class private_map::VirtualSprite;
friend class private_map::MapSprite;
friend class private_map::EnemySprite;
friend class private_map::DialogueManager;
friend class private_map::TreasureMenu;
friend class private_map::MapDialogue;
friend class private_map::SpriteAction;
friend class private_map::ActionPathMove;
friend class private_map::EnemyZone;
friend void hoa_defs::BindEngineToLua();
public:
MapMode(std::string filename);
~MapMode();
//! \brief Resets appropriate class members. Called whenever the MapMode object is made the active game mode.
void Reset();
//! \brief Updates the game and calls various sub-update functions depending on the state of map mode.
void Update();
//! \brief Handles the drawing of everything on the map and makes sub-draw function calls as appropriate.
void Draw();
private:
/** \brief A reference to the current instance of MapMode
*** This is used for callbacks from Lua, as well as for map objects to be able to refer to the
*** map that they exist in.
**/
static MapMode *_current_map;
/** \brief A reference to the instance of MapMode which most recently had its constructor called
*** This is not the same as _current_map, and this pointer should only be used in conjunction with
*** loading code. The pointer is only updated when the MapMode constructor is called.
**/
static MapMode *_loading_map;
//! \brief Indicates if dialogue icons should be drawn or not.
static bool _show_dialogue_icons;
/** \brief A timer used for when the player first enters the map
*** This timer is set to 7000 ms (7 seconds) and is used to display the map's location graphic
*** and name at the top center of the screen. The graphic and text are faded in for the first
*** two seconds, drawn opaquely for the next three seconds, and faded out in the final two seconds.
**/
hoa_system::SystemTimer _intro_timer;
//! \brief The name of the script file that contains the map.
std::string _map_filename;
//! \brief The name of the map, as it will be read by the player in the game.
hoa_utils::ustring _map_name;
//! \brief A pointer to the object containing all of the event information for the map
hoa_global::GlobalEventGroup* _map_event_group;
//! \brief Holds an image that represents an outline of the location, used primarily in MenuMode
hoa_video::StillImage _location_graphic;
//! \brief Indicates the current state that the map is in, such as when a dialogue is taking place.
uint8 _map_state;
//! \brief The time elapsed since the last Update() call to MapMode.
uint32 _time_elapsed;
/** \brief The number of tile rows in the map.
*** This number must be greater than or equal to 24 for the map to be valid.
**/
uint16 _num_tile_rows;
/** \brief The number of tile rows in the map.
*** This number must be greater than or equal to 32 for the map to be valid.
**/
uint16 _num_tile_cols;
/** \brief The number of elements in the map grid
*** The number of map grid rows and columns is always equal to twice that of the number of
*** tile rows and tile columns.
**/
uint16 _num_grid_rows, _num_grid_cols;
//! \brief Holds the most recently generated object ID number
uint16 _lastID;
//! \brief While true, all user input commands to map mode are ignored
bool _ignore_input;
//! \brief If true, the player's stamina will not drain as they run
bool _run_forever;
//! \brief While true, the player is not allowed to run at all.
bool _run_disabled;
/** \brief The amount of stamina
*** This value ranges from 0 (empty) to 10000 (full). Stamina takes 10 seconds to completely fill from
*** the empty state and 5 seconds to empty from the full state.
**/
uint32 _run_stamina;
//! \brief Retains information needed to correctly draw the next map frame.
private_map::MapFrame _draw_info;
/** \brief The interface to the file which contains all the map's stored data and subroutines.
*** This class generally performs a large amount of communication with this script continuously.
*** The script remains open for as long as the MapMode object exists.
**/
hoa_script::ReadScriptDescriptor _map_script;
/** \brief A script function which assists with the MapMode#Update method
*** This function implements any custom update code that the specific map needs to be performed.
*** The most common operation that this script function performs is to check for trigger conditions
*** that cause map events to occur
**/
ScriptObject _update_function;
/** \brief Script function which assists with the MapMode#Draw method
*** This function allows for drawing of custom map visuals. Usually this includes lighting or
*** other visual effects for the map environment.
**/
ScriptObject _draw_function;
//! \brief A 2D vector that contains all of the map's tile objects.
std::vector > _tile_grid;
/** \brief A 2D vector indicating which spots on the map sprites may walk on.
*** This vector is kept seperate from the vector of tiles because each tile
*** has 4 walkable uint32 bitflags associated with it. Note that sprite objects may
*** come in various sizes, so not all sprites may fit through a narrow
*** passage way.
**/
std::vector > _map_grid;
/** \brief A map containing pointers to all of the sprites on a map.
*** This map does not include a pointer to the MapMode#_camera nor MapMode#_virtual_focus
*** sprites. The map key is used as the sprite's unique identifier for the map. Keys
*** 1000 and above are reserved for map sprites that correspond to the character's party.
**/
std::map _all_objects;
/** \brief A container for all of the map objects located on the ground layer.
*** The ground object layer is where most objects and sprites exist in Allacrost.
**/
std::vector _ground_objects;
/** \brief A container for all of the map objects located on the pass layer.
*** The pass object layer is named so because objects on this layer can both be
*** walked under or above by objects in the ground object layer. A good example
*** of an object that would typically go on this layer would be a bridge. This
*** layer usually has very few objects for the map. Also, objects on this layer
*** are unaffected by the maps context. In other words, these objects are always
*** drawn on the screen, regardless of the current context that the player is in.
**/
std::vector _pass_objects;
/** \brief A container for all of the map objects located on the sky layer.
*** The sky object layer contains the last series of elements that are drawn on
*** a map. These objects exist high in the sky above all other tiles and objects.
*** Translucent clouds can make good use of this object layer, for instance.
**/
std::vector _sky_objects;
/** \brief A pointer to the map sprite that the map camera will focus on.
*** \note Note that this member is a pointer to a map sprite, not a map object.
*** However, this does not mean that the camera is not able to focus on non-sprite
*** map objects. The MapMode#_virtual_focus member can be used to emulate that
*** focus.
**/
private_map::VirtualSprite* _camera;
/** \brief A "virtual sprite" that can serve as a focus point for the camera.
*** This sprite is not visible to the player nor does it have any collision
*** detection properties. Usually, the camera focuses on the player's sprite
*** rather than this object, but it is useful for scripted sequences and other
*** things.
**/
private_map::VirtualSprite *_virtual_focus;
//! \brief Contains the images for all map tiles, both still and animate.
std::vector _tile_images;
/** \brief Contains all of the animated tile images used on the map.
*** The purpose of this vector is to easily update all tile animations without stepping through the
*** _tile_images vector, which contains both still and animated images.
***
*** \note The elements in this vector point to the same AnimatedImages that are pointed to by _tile_images. Therefore,
*** this vector should not have delete invoked on its elements, since delete is already invoked on _tile_images.
**/
std::vector _animated_tile_images;
//! \brief Icon which appears over NPCs who have unread dialogue
hoa_video::AnimatedImage _new_dialogue_icon;
//! \brief Image which underlays the stamina bar for "running"
hoa_video::StillImage _stamina_bar_background;
//! \brief Image which overlays the stamina bar to show that the player has unlimited running
hoa_video::StillImage _stamina_bar_infinite_overlay;
//! \brief The music that the map will need to make use of.
std::vector _music;
//! \brief The sounds that the map needs available to it.
std::vector _sounds;
//! \brief This keeps a pointer to the active dialogue.
private_map::DialogueManager* _dialogue_manager;
//! \brief Class member object which processes all information related to treasure discovery
private_map::TreasureMenu* _treasure_menu;
//! \brief Container for map zones, used for various purposes such as spawning of enemies
std::vector _zones;
//! \brief store the namespace of the current map
std::string _map_namespace;
// -------------------- Battle Data Retained by the Map
/** \brief A container for the various foes which may appear on this map.
*** These enemies are kept at their initial stats. They are passed to battle mode, where a copy of
*** each enemy is made and initialized there.
**/
std::vector _enemies;
//! \brief Loads all map data as specified in the Lua file that defines the map.
void _Load();
//! \brief A helper function to MapMode::_Load, handles all operations on loading tilesets and tile images
void _LoadTiles();
// -------------------- Update Methods
//! \brief Handles user input when the map is in the explore state.
void _HandleInputExplore();
//! \brief Handles user input when the map is in the dialogue state.
void _HandleInputDialogue();
/** \brief Finds the nearest interactable object within a certain distance.
*** \param *sprite The sprite who is trying to find its nearest object.
*** \return A pointer to the nearest interactable map object, or NULL if no such object was found.
***
*** An interactable object must be in the same context as the function argument is. For an object
*** to be valid, it's collision rectangle must be no greater than 3 grid elements from the sprite's
*** "calling" axis, and th
***
**/
private_map::MapObject* _FindNearestObject(const private_map::VirtualSprite* sprite);
/** \brief Determines if a map sprite's position is invalid because of a collision
*** \param sprite A pointer to the map sprite to check
*** \return True if a collision was detected, false if one was not
***
*** This method is invoked by the map sprite who wishes to check for its own collision. The
*** collision detection is performed agains three types of obstacles:
***
*** -# Boundary conditions: where the sprite has walked off the map
*** -# Tile collisions: where the sprite's collision rectangle overlaps with an unwalkable map grid tile.
*** -# Object collision: where the sprite's collision rectangle overlaps that of another object's,
*** where the object is in the same draw layer and context as the original sprite.
***
*** \note This function does not check if the MapSprite argument has its no_collision member
*** set to false, but it does check that of the other MapObjects.
**/
bool _DetectCollision(private_map::VirtualSprite* sprite);
/** \brief Finds a path from a sprite's current position to a destination
*** \param sprite A pointer of the sprite to find the path for
*** \param path A reference to a vector of PathNode objects to store the path
*** \param dest The destination coordinates
***
*** This algorithm uses the A* algorithm to find a path from a source to a destination.
*** This function ignores the position of all other objects and only concerns itself with
*** which map grid elements are walkable.
***
*** \note If an error is detected, the function will return an empty path argument.
**/
void _FindPath(const private_map::VirtualSprite* sprite, std::vector& path, const private_map::PathNode& dest);
// -------------------- Draw Methods
//! \brief Calculates information about how to draw the next map frame.
void _CalculateDrawInfo();
//! \brief Draws all visible map tiles and sprites to the screen
void _DrawMapLayers();
//! \brief Draws all GUI visuals, such as dialogue icons and the run meter
void _DrawGUI();
// -------------------- Lua Binding Functions
/** \name Lua Access Functions
*** These methods exist not to allow outside C++ classes to access map data, but instead to
*** allow Lua to make function calls to examine and modify the map's state.
**/
//@{
void _AddGroundObject(private_map::MapObject *obj);
void _AddPassObject(private_map::MapObject *obj);
void _AddSkyObject(private_map::MapObject *obj);
void _AddZone(private_map::MapZone *zone);
uint16 _GetGeneratedObjectID()
{ return ++_lastID; }
void _SetMapState(uint8 state)
{ _map_state = state; }
void _SetCameraFocus(private_map::VirtualSprite *sprite)
{ _camera = sprite; }
uint8 _GetMapState() const
{ return _map_state; }
uint32 _GetTimeElapsed() const
{ return _time_elapsed; }
private_map::VirtualSprite* _GetCameraFocus() const
{ return _camera; }
static void _ShowDialogueIcons( bool state )
{ _show_dialogue_icons = state; }
static bool _IsShowingDialogueIcons()
{ return _show_dialogue_icons; }
//@}
}; // class MapMode
} // namespace hoa_map;
#endif