///////////////////////////////////////////////////////////////////////////////
// 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_sprites.h
*** \author Tyler Olsen, roots@allacrost.org
*** \brief Header file for map mode sprites.
*** *****************************************************************************/
#ifndef __MAP_SPRITES_HEADER__
#define __MAP_SPRITES_HEADER__
#include "utils.h"
#include "defs.h"
#include "video.h"
#include "map_actions.h"
#include "map_dialogue.h"
#include "map_objects.h"
#include "map_zones.h"
namespace hoa_map {
namespace private_map {
// *********************** SPRITE CONSTANTS **************************
/** \name Map Sprite Speeds
*** \brief Common speeds for sprite movement.
*** These values are the time (in milliseconds) that it takes a sprite to walk
*** the distance of one map grid (16 pixels).
**/
//@{
const float VERY_SLOW_SPEED = 225.0f;
const float SLOW_SPEED = 190.0f;
const float NORMAL_SPEED = 150.0f;
const float FAST_SPEED = 110.0f;
const float VERY_FAST_SPEED = 75.0f;
//@}
/** \name Sprite Direction Constants
*** \brief Constants used for setting and determining sprite directions
*** Sprites are allowed to travel in eight different directions, however the sprite itself
*** can only be facing one of four ways: north, south, east, or west. Because of this, it
*** is possible to travel, for instance, northwest facing north or northwest facing west.
*** The "NW_NORTH" constant means that the sprite is traveling to the northwest and is
*** facing towards the north.
***
*** \note The set of "FACING_DIRECTION" and "MOVING_DIRECTION" constants are only meant to be
*** used as shorthands. You shouldn't assign the MapSprite#direction member to any of these values.
**/
//@{
const uint16 NORTH = 0x0001;
const uint16 SOUTH = 0x0002;
const uint16 WEST = 0x0004;
const uint16 EAST = 0x0008;
const uint16 NW_NORTH = 0x0010;
const uint16 NW_WEST = 0x0020;
const uint16 NE_NORTH = 0x0040;
const uint16 NE_EAST = 0x0080;
const uint16 SW_SOUTH = 0x0100;
const uint16 SW_WEST = 0x0200;
const uint16 SE_SOUTH = 0x0400;
const uint16 SE_EAST = 0x0800;
const uint16 NORTHWEST = NW_NORTH | NW_WEST;
const uint16 NORTHEAST = NE_NORTH | NE_EAST;
const uint16 SOUTHWEST = SW_SOUTH | SW_WEST;
const uint16 SOUTHEAST = SE_SOUTH | SE_EAST;
const uint16 FACING_NORTH = NORTH | NW_NORTH | NE_NORTH;
const uint16 FACING_SOUTH = SOUTH | SW_SOUTH | SE_SOUTH;
const uint16 FACING_WEST = WEST | NW_WEST | SW_WEST;
const uint16 FACING_EAST = EAST | NE_EAST | SE_EAST;
const uint16 LATERAL_MOVEMENT = NORTH | SOUTH | EAST | WEST;
const uint16 DIAGONAL_MOVEMENT = NORTHWEST | NORTHEAST | SOUTHWEST | SOUTHEAST;
//@}
/** \name Map Sprite Animation Constants
*** These constants are used to index the MapSprite#animations vector to display the correct
*** animation. The first 8 entries in this vector always represent the same sets of animations
*** for each map sprite.
**/
//@{
const uint32 ANIM_STANDING_SOUTH = 0;
const uint32 ANIM_STANDING_NORTH = 1;
const uint32 ANIM_STANDING_WEST = 2;
const uint32 ANIM_STANDING_EAST = 3;
const uint32 ANIM_WALKING_SOUTH = 4;
const uint32 ANIM_WALKING_NORTH = 5;
const uint32 ANIM_WALKING_WEST = 6;
const uint32 ANIM_WALKING_EAST = 7;
const uint32 ANIM_RUNNING_SOUTH = 8;
const uint32 ANIM_RUNNING_NORTH = 9;
const uint32 ANIM_RUNNING_WEST = 10;
const uint32 ANIM_RUNNING_EAST = 11;
//@}
/** ****************************************************************************
*** \brief An invisible and possible mobile sprite on a map
***
*** The VirtualSprite is a special type of MapObject because it has no physical
*** form (no image). Virtual sprites may be manipulated to move around on the screen,
*** or they may remain stationary. VirtualSprites do take collision detection into account
*** by default, unless the no_collision member is set to true. Here are some examples of
*** where virtual sprites may be of use:
***
*** - As a mobile focusing point for the map camera
*** - As an impassible map location for ground objects in a specific context only
*** - To set impassible locations for objects in the sky layer
*** ***************************************************************************/
class VirtualSprite : public MapObject {
public:
/** \brief A bit-mask for the sprite's draw orientation and direction vector.
*** This member determines both where to move the sprite (8 directions) and
*** which way the sprite is facing (4 directions). See the Sprite Directions
*** series of constants for the values that this member may be set to.
**/
uint16 direction;
//! \brief The speed at which the sprite moves around the map.
float movement_speed;
/** \brief Set to true when the sprite is currently moving.
*** \note This does not necessarily mean that the sprite actually is moving, but rather that
*** the sprite is trying to move in a certain direction.
**/
bool moving;
//! \brief Set to true when the sprite is running rather than just walking
bool is_running;
/** \brief When set to true, indicates that the object exists on the sky object layer (default = false).
*** This member is necessary for collision detection purposes. When a sprite needs to detect
*** if it has encountered a collision, that collision must be examined with other objects on
*** the appropriate layer (the ground or sky layer).
**/
bool sky_object;
//! \brief The name of the sprite, as seen by the player in the game.
hoa_utils::ustring name;
//! \brief A pointer to the face portrait of the sprite, as seen in dialogues and menus.
hoa_video::StillImage* face_portrait;
//! \brief Set to false if the sprite contains dialogue that has not been seen by the player
bool seen_all_dialogue;
//! \brief True is sprite contains active dialogue.
bool has_active_dialogue;
/** \brief An index to the actions vector, representing the current sprite action being performed.
*** A negative value indicates that the sprite is taking no action. If the sprite has no entries
*** in its actions vector, this member should remain negative, otherwise a segmentation fault
*** will occur.
**/
int8 current_action;
// TODO: change how forced action work
int8 forced_action;
//! \brief A container for all of the actions this sprite performs.
std::vector actions;
/** \name Saved state attributes
*** These attributes are used to save and load the state of a VirtualSprite
**/
//@{
//! \brief This indicates if a state was saved or not.
bool _saved;
uint16 _saved_direction;
float _saved_movement_speed;
bool _saved_moving;
hoa_utils::ustring _saved_name;
int8 _saved_current_action;
//@}
//! \brief This vector contains all the dialogues of the sprite
std::vector dialogues;
/** \brief An index to the dialogues vector, representing the current sprite dialogue to
*** display when talked to by the player. A negative value indicates that the sprite has no dialogue.
*** \note If the sprite has no entries in its dialogues vector, this member should remain negative,
*** otherwise a segmentation fault will occur.
**/
int16 _current_dialogue;
//! \brief Indicates if the icon indicating that there is a dialogue available should be drawn or not.
bool _show_dialogue_icon;
//! \brief Used to fade the dialogue icon according to distance
hoa_video::Color _dialogue_icon_color;
// -------------------- Public methods
VirtualSprite();
~VirtualSprite();
//! \brief Updates the virtual object's position if it is moving, otherwise does nothing.
virtual void Update();
//! \brief Draws a dialogue icon over the virtual sprite if it has to.
virtual void Draw();
/** \name Lua Access Functions
*** These functions are specifically written for Lua binding, to enable Lua to access the
*** members of this class.
**/
//@{
/** \note This method takes into account the current direction when setting the new direction
*** in the case of diagonal movement. For example, if the sprite is currently facing north
*** and this function indicates that the sprite should move northwest, it will face north
*** during the northwest movement.
**/
void SetDirection(uint16 dir);
void SetMovementSpeed(float speed)
{ movement_speed = speed; }
uint16 GetDirection() const
{ return direction; }
float GetMovementSpeed() const
{ return movement_speed; }
void SetFacePortrait(std::string pn);
//@}
/** \brief This method will save the state of a sprite.
*** Attributes saved: direction, speed, moving state, name, current action.
**/
virtual void SaveState();
/** \brief This method will load the saved state of a sprite.
*** Attributes loaded: direction, speed, moving state, name, current action.
*** \return false if there was no saved state, true otherwise.
**/
virtual bool LoadState();
//! \brief Examines all dialogue owned by the sprite and sets the appropriate value of VirtualSprite#seen_all_dialogue
void UpdateSeenDialogue();
//! \brief Examines all dialogue owned by the sprite and sets the appropriate value of VirtualSprite#has_active_dialogue
void UpdateActiveDialogue();
/** \name Dialogue control methods
*** These methods are used to add and control which dialogue should the sprite speak.
**/
//@{
void AddDialogue(MapDialogue* md);
bool HasDialogue() const
//{ return (dialogues.size() > 0); }
{ if(dialogues.size() > 0) return has_active_dialogue; else return false; }
MapDialogue* GetCurrentDialogue() const
{ return dialogues[_current_dialogue]; }
void SetDialogue(const int16 dialogue)
{ if (static_cast(dialogue) >= dialogues.size()) return; else _current_dialogue = dialogue; }
void NextDialogue()
{ do { _current_dialogue++; if (static_cast(_current_dialogue) >= dialogues.size()) _current_dialogue = 0; }
while (dialogues[_current_dialogue]->IsActive() == false); }
int16 GetNumDialogues() const
{ return dialogues.size(); }
void ShowDialogueIcon(bool state)
{ _show_dialogue_icon = state; }
bool IsShowingDialogueIcon() const
{ return _show_dialogue_icon; }
//@}
/** \brief Adds a new action for the sprite to process onto the end of the sprite's action list
*** \param act A pointer to the instantiated SpriteAction object to use
**/
void AddAction(SpriteAction* act)
{ act->SetSprite(this); actions.push_back(act); }
/** \brief This static class function returns the opposite direction of the direction given in parameter.
*** \note This is mostly used as an helper function to make sprites face each other.
**/
static uint16 CalculateOppositeDirection(const uint16 direction);
/** \brief Sets the sprite's direction to a random value
*** This function is used mostly for the ActionRandomMove class.
**/
void SetRandomDirection();
}; // class VirtualSprite : public MapObject
/** ****************************************************************************
*** \brief A mobile map object with which the player can interact with.
***
*** Map sprites are animate, mobile, living map objects. Although there is
*** but this single class to represent all the map sprites in the game, they can
*** divided into types such as NPCs, friendly creatures, and enemies. The fact
*** that there is only one class for representing several sprite types is the
*** reason why many of the class members are pointers. For example, we don't
*** need dialogue for a dog sprite.
*** ***************************************************************************/
class MapSprite : public VirtualSprite {
public:
//! \brief Holds the previous value of VirtualSprite#moving from the last call to MapSprite#Update().
bool was_moving;
//! \brief Set to true if the sprite has running animations loaded
bool has_running_anim;
/** \brief The sound that will play when the sprite walks.
*** This member references the MapMode#_map_sounds vector as the sound to play. If this member
*** is less than zero, no sound is played when the object is walking.
**/
int8 walk_sound;
//! \brief The index to the animations vector containing the current sprite image to display
uint8 current_animation;
/** \brief A vector containing all the sprite's various animations.
*** The first four entries in this vector are the walking animation frames.
*** They are ordered from index 0 to 3 as: down, up, left, right. Additional
*** animations may follow.
**/
std::vector animations;
/** \name Saved state attributes
*** These attributes are used to save and load the state of a VirtualSprite
**/
//@{
bool _saved_was_moving;
int8 _saved_walk_sound;
uint8 _saved_current_animation;
//@}
// -------------------------------- Methods --------------------------------
MapSprite();
~MapSprite();
/** \brief Loads the image containing the standard animations for the sprite
*** \param filename The name of the image file holding the standard walking animations
*** \return False if there was a problem loading the sprite.
**/
bool LoadStandardAnimations(std::string filename);
/** \brief Loads the image containing the running animations for the sprite
*** \param filename The name of the image file
*** \return False if the animations were not created successfully.
**/
bool LoadRunningAnimations(std::string filename);
//! \brief Updates the sprite's position and state.
virtual void Update();
//! \brief Draws the sprite frame in the appropriate position on the screen, if it is visible.
virtual void Draw();
/** \name Lua Access Functions
*** These functions are specifically written for Lua binding, to enable Lua to access the
*** members of this class.
**/
//@{
void SetName(std::string na)
{ name = hoa_utils::MakeUnicodeString(na); }
void SetWalkSound(int8 sound)
{ walk_sound = sound; }
void SetCurrentAnimation(uint8 anim)
{ current_animation = anim; }
int8 GetWalkSound() const
{ return walk_sound; }
uint8 GetCurrentAnimation() const
{ return current_animation; }
//@}
/** \brief This method will save the state of a sprite.
*** Attributes saved: direction, speed, moving state, name, current action,
*** current animation, current walk sound.
**/
virtual void SaveState();
/** \brief This method will load the saved state of a sprite.
*** Attributes loaded: direction, speed, moving state, name, current action,
*** current animation, current walk sound.
*** \return false if there was no saved state, true otherwise.
**/
virtual bool LoadState();
}; // class MapSprite : public VirtualSprite
/** ****************************************************************************
*** \brief A mobile map object that induces a battle to occur if the player touches it
***
*** There are really two types of enemy sprites. The first type behave just like
*** map sprites and can have scripted movement sequences. The second type belong
*** to EnemyZones, where they fade into existence and pursue after the player's
*** sprite should the player enter the zone.
***
*** An enemy sprite in a zone can be in one of 3 states: SPAWNING, HOSTILE or DEAD.
*** In the spawning state, the enemy becomes gradually visible, is immobile, and
*** cannot be touched or attacked. In the hostile state, the enemies roams the map
*** and will cause a battle if touched by the player. In the dead state, the enemy
*** is invisible and waits for the EnemyZone to reset it in another position, so
*** that it may spawn once more.
*** ***************************************************************************/
class EnemySprite : public MapSprite {
private:
//! \brief The states that the enemy sprite may be in
enum STATE {
SPAWNING,
HOSTILE,
DEAD
};
public:
//! \brief The default constructor which typically requires that the user make several additional calls to setup the sprite properties
EnemySprite();
//! \brief A constructor for when the enemy sprite is stored in the definition of a single file
EnemySprite(std::string file);
//! \brief Loads the enemy's data from a file and returns true if it was successful
bool Load();
//! \brief Resets various members of the class so that the enemy is dead, invisible, and does not produce a collision
void Reset();
//! \brief Updates the sprite's position and state.
virtual void Update();
//! \brief Draws the sprite frame in the appropriate position on the screen, if it is visible.
virtual void Draw();
// TODO: eventually I would like the ability for Lua to pass in a table of ints to the AddEnemyParty function, but because I'm not quite
// sure how to do that yet, I'm writing several smaller functions so we can just get this demo released.
// void AddEnemyParty(std::vector& party);
/** \brief Adds a new empty vector to the _enemy_parties member
*** \note Make sure to populate this vector by adding at least one enemy!
**/
void NewEnemyParty()
{ _enemy_parties.push_back(std::vector()); }
/** \brief Adds an enemy with the specified ID to the last party in _enemy_parties
*** \param enemy_id The ID of the enemy to add
*** \note MapMode should have already loaded a GlobalEnemy with this ID and retained it within the MapMode#_enemies member.
*** If this is not the case, this function will print a warning message.
**/
void AddEnemy(uint32 enemy_id);
//! \brief Returns a reference to a random party of enemies
const std::vector& RetrieveRandomParty();
//! \name Class Member Access Functions
//@{
float GetAggroRange() const
{ return _aggro_range; }
uint32 GetTimeToChange() const
{ return _time_dir_change; }
uint32 GetTimeToSpawn() const
{ return _time_to_spawn; }
std::string GetBattleMusicTheme() const
{ return _music_theme; }
bool IsDead() const
{ return _state == DEAD; }
bool IsSpawning() const
{ return _state == SPAWNING; }
bool IsHostile() const
{ return _state == HOSTILE; }
void SetZone(EnemyZone* zone)
{ _zone = zone; }
void SetAggroRange(float range)
{ _aggro_range = range; }
void SetTimeToChange(uint32 time)
{ _time_dir_change = time; }
void SetTimeToSpawn(uint32 time)
{ _time_to_spawn = time; }
void SetBattleMusicTheme(const std::string & music_theme)
{ _music_theme = music_theme; }
void ChangeStateDead() {
Reset();
if( _zone )
_zone->EnemyDead();
}
void ChangeStateSpawning()
{ updatable = true; _state = SPAWNING; no_collision = false; }
void ChangeStateHostile()
{ updatable = true; _state = HOSTILE; no_collision = false; _color.SetAlpha(1.0); }
//@}
private:
//! \brief The zone that the enemy sprite belongs to
private_map::EnemyZone* _zone;
//! \brief Used to gradually fade in the sprite as it is spawning by adjusting the alpha channel
hoa_video::Color _color;
//! \brief A timer used for spawning
uint32 _time_elapsed;
//! \brief The state that the enemy sprite is in
STATE _state;
//! \brief A value which determines how close the player needs to be for the enemy to aggressively seek to confront it
float _aggro_range;
//! \brief ???
uint32 _time_dir_change;
//! \brief ???
uint32 _time_to_spawn;
//! \brief Indicates if the enemy is outside of its zone. If it is, it won't change direction until it gets back in.
bool _out_of_zone;
//! \brief The default battle music theme for the monster
std::string _music_theme;
/** \brief Contains the possible groups of enemies that may appear in a battle should the player encounter this enemy sprite
*** The numbers contained within this member are ID numbers for the enemy. If the
**/
std::vector > _enemy_parties;
}; // class EnemySprite : public MapSprite
} // namespace private_map
} // namespace hoa_map
#endif // __MAP_SPRITES_HEADER__