1 /////////////////////////////////////////////////////////////////////////////// 2 // Copyright (C) 2004-2011 by The Allacrost Project 3 // Copyright (C) 2012-2016 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_ENEMY_SPRITE_HEADER__ 12 #define __MAP_ENEMY_SPRITE_HEADER__ 13 14 #include "modes/map/map_sprites/map_sprite.h" 15 16 #include "modes/battle/battle_enemy_info.h" 17 18 namespace vt_map 19 { 20 21 namespace private_map 22 { 23 24 class SpriteEvent; 25 class EnemyZone; 26 27 //! Standard time values for spawning enemies on a map. All values are in number of milliseconds. 28 //@{ 29 //! \brief The time to spawn an enemy when the player first enters a map 30 const uint32_t STANDARD_ENEMY_FIRST_SPAWN_TIME = 1000; 31 //! \brief The standard amount of time it takes an enemy to change state from "spawning" to "hostile" 32 const uint32_t STANDARD_ENEMY_SPAWN_TIME = 5000; 33 //! \brief The duration that an enemy stays in the dead state after it has been defeated 34 const uint32_t STANDARD_ENEMY_DEAD_TIME = 5000; 35 //@} 36 37 /** **************************************************************************** 38 *** \brief A mobile map object that induces a battle to occur if the player touches it 39 *** 40 *** There are really two types of enemy sprites. The first type behave just like 41 *** map sprites and can have scripted movement sequences. The second type belong 42 *** to EnemyZones, where they fade into existence and pursue after the player's 43 *** sprite should the player enter the zone. 44 *** 45 *** An enemy sprite in a zone can be in one of 3 states: SPAWNING, HOSTILE or DEAD. 46 *** In the spawning state, the enemy becomes gradually visible, is immobile, and 47 *** cannot be touched or attacked. In the hostile state, the enemies roams the map 48 *** and will cause a battle if touched by the player. In the dead state, the enemy 49 *** is invisible and waits for the EnemyZone to reset it in another position, so 50 *** that it may spawn once more. 51 *** ***************************************************************************/ 52 class EnemySprite : public MapSprite 53 { 54 private: 55 //! \brief The states that the enemy sprite may be in 56 enum STATE { 57 SPAWNING, 58 HOSTILE, 59 DEAD 60 }; 61 62 public: 63 //! \brief The default constructor 64 EnemySprite(); 65 virtual ~EnemySprite() override; 66 67 //! \brief A C++ wrapper made to create a new object from scripting, 68 //! without letting Lua handling the object life-cycle. 69 //! \note We don't permit luabind to use constructors here as it can't currently 70 //! give the object ownership at construction time. 71 static EnemySprite* Create(); 72 73 //! \brief Resets various members of the class so that the enemy is dead, invisible, and does not produce a collision 74 void Reset(); 75 76 //! \brief Updates the sprite's position and state. 77 virtual void Update() override; 78 79 //! \brief Draws the sprite frame in the appropriate position on the screen, if it is visible. 80 virtual void Draw() override; 81 82 /** \brief Adds a new empty vector to the _enemy_parties member 83 *** \note Make sure to populate this vector by adding at least one enemy! 84 **/ NewEnemyParty()85 void NewEnemyParty() { 86 _enemy_parties.push_back(std::vector<vt_battle::BattleEnemyInfo>()); 87 } 88 89 /** \brief Adds an enemy with the specified ID to the last party in _enemy_parties 90 *** \param enemy_id The ID of the enemy to add 91 *** \param position_x, position_y The enemy sprite position on the battle ground in pixels 92 *** \note MapMode should have already loaded a GlobalEnemy with this ID and retained it within the MapMode#_enemies member. 93 *** If this is not the case, this function will print a warning message. 94 **/ 95 void AddEnemy(uint32_t enemy_id, float position_x, float position_y); 96 //! \brief A simpler function used to auto set default enemy position on the battle ground AddEnemy(uint32_t enemy_id)97 void AddEnemy(uint32_t enemy_id) { 98 AddEnemy(enemy_id, 0.0f, 0.0f); 99 } 100 101 //! \brief Returns a reference to a random party of enemies 102 const std::vector<vt_battle::BattleEnemyInfo>& RetrieveRandomParty() const; 103 104 //! \brief Returns the enemy's encounter event id. 105 //! If this event is not empty, it is triggered instead of a battle, 106 //! when encountering an enemy sprite in the map mode. GetEncounterEvent()107 const std::string& GetEncounterEvent() const { 108 return _encounter_event; 109 } 110 111 //! \brief Sets the enemy's encounter event id. SetEncounterEvent(const std::string & event)112 void SetEncounterEvent(const std::string& event) { 113 _encounter_event = event; 114 } 115 116 //! \name Class Member Access Functions 117 //@{ GetAggroRange()118 float GetAggroRange() const { 119 return _aggro_range; 120 } 121 GetTimeBeforeNewDestination()122 uint32_t GetTimeBeforeNewDestination() const { 123 return _time_before_new_destination; 124 } 125 GetTimeToSpawn()126 uint32_t GetTimeToSpawn() const { 127 return _time_to_spawn; 128 } 129 GetBattleMusicTheme()130 const std::string &GetBattleMusicTheme() const { 131 return _music_theme; 132 } 133 GetBattleBackground()134 const std::string &GetBattleBackground() const { 135 return _bg_file; 136 } 137 GetBattleScripts()138 const std::vector<std::string>& GetBattleScripts() const { 139 return _script_files; 140 } 141 IsDead()142 bool IsDead() const { 143 return _state == DEAD; 144 } 145 IsSpawning()146 bool IsSpawning() const { 147 return _state == SPAWNING; 148 } 149 IsHostile()150 bool IsHostile() const { 151 return _state == HOSTILE; 152 } 153 IsBoss()154 bool IsBoss() const { 155 return _is_boss; 156 } 157 SetZone(EnemyZone * zone)158 void SetZone(EnemyZone *zone) { 159 _zone = zone; 160 } 161 GetEnemyZone()162 EnemyZone* GetEnemyZone() { 163 return _zone; 164 } 165 SetAggroRange(float range)166 void SetAggroRange(float range) { 167 _aggro_range = range; 168 } 169 SetTimeBeforeNewDestination(uint32_t time)170 void SetTimeBeforeNewDestination(uint32_t time) { 171 _time_before_new_destination = time; 172 } 173 SetTimeToRespawn(uint32_t time)174 void SetTimeToRespawn(uint32_t time) { 175 _time_to_respawn = time; 176 } 177 SetBoss(bool is_boss)178 void SetBoss(bool is_boss) { 179 _is_boss = is_boss; 180 } 181 SetBattleMusicTheme(const std::string & music_theme)182 void SetBattleMusicTheme(const std::string &music_theme) { 183 _music_theme = music_theme; 184 } 185 SetBattleBackground(const std::string & bg_file)186 void SetBattleBackground(const std::string &bg_file) { 187 _bg_file = bg_file; 188 } 189 AddBattleScript(const std::string & script_file)190 void AddBattleScript(const std::string &script_file) { 191 _script_files.push_back(script_file); 192 } 193 194 void ChangeStateDead(); 195 ChangeStateSpawning()196 void ChangeStateSpawning() { 197 _updatable = true; 198 _state = SPAWNING; 199 _collision_mask = NO_COLLISION; 200 } 201 202 void ChangeStateHostile(); 203 204 //! Makes an enemy follow way point when not running after a hero 205 //! \note You'll have to add at least two valid way point to make those 206 //! taken into account by the enemy sprite. 207 void AddWayPoint(float destination_x, float destination_y); 208 //@} 209 210 private: 211 //! \brief The zone that the enemy sprite belongs to 212 private_map::EnemyZone *_zone; 213 214 //! \brief Used to gradually fade in the sprite as it is spawning by adjusting the alpha channel 215 vt_video::Color _color; 216 217 //! \brief A timer used for spawning 218 uint32_t _time_elapsed; 219 220 //! \brief The state that the enemy sprite is in 221 STATE _state; 222 223 //! \brief A value which determines how close the player needs to be for the enemy to aggressively seek to confront it 224 float _aggro_range; 225 226 //! \brief Tells the time the sprite is waiting before going to a new destination. 227 uint32_t _time_before_new_destination; 228 229 //! \brief Tells the actual time in milliseconds the sprite will use to respawn. This will set up the fade in speed. 230 uint32_t _time_to_spawn; 231 232 //! \brief the default time used to respawn (Set to STANDARD_ENEMY_SPAWN_TIME by default) 233 uint32_t _time_to_respawn; 234 235 //! \brief The default battle music theme for the monster 236 std::string _music_theme; 237 238 //! \brief The default background for the battle 239 std::string _bg_file; 240 241 //! \brief The filenames of the script to pass to the battle 242 std::vector<std::string> _script_files; 243 244 //! \brief Tells whether the sprite is a boss. 245 bool _is_boss; 246 247 /** \brief Contains the possible groups of enemies that may appear in a battle should the player encounter this enemy sprite 248 *** The numbers contained within this member are ID numbers for the enemy. 249 **/ 250 std::vector<std::vector<vt_battle::BattleEnemyInfo> > _enemy_parties; 251 252 //! \brief The enemy's encounter event. 253 //! If this event is not empty, it is triggered instead of a battle. 254 std::string _encounter_event; 255 256 //! \brief Tells whether pathfinding is used to compute the enemy movement. 257 bool _use_path; 258 259 //! \brief Used to store the previous coordinates of the sprite during path movement, 260 //! so as to set the proper direction of the sprite as it moves 261 vt_common::Position2D _last_node_position; 262 263 //! \brief Used to store the current node collision position (with offset) 264 vt_common::Position2D _current_node; 265 266 //! \brief An index to the path vector containing the node that the sprite currently occupies 267 uint32_t _current_node_id; 268 269 //! \brief The current destination of the sprite. 270 vt_common::Position2D _destination; 271 272 //! \brief Holds the path needed to traverse from source to destination 273 Path _path; 274 275 //! \brief Way points used by the enemy when not hostile 276 std::vector<vt_common::Position2D> _way_points; 277 uint32_t _current_way_point_id; 278 279 //! \brief Set the new path destination of the sprite. 280 //! \param destination_x The pixel x destination to find a path to. 281 //! \param destination_y The pixel y destination to find a path to. 282 //! \param max_cost More or less the path max length in nodes or 0 if no limitations. 283 //! Use this to avoid heavy computations. 284 //! \return whether it failed. 285 bool _SetDestination(float destination_x, float destination_y, uint32_t max_cost = 20); 286 287 //! \brief Set the actual sprite direction according to the current path node. 288 void _SetSpritePathDirection(); 289 290 //! \brief Update the sprite direction according to the current path. 291 void _UpdatePath(); 292 293 //! \brief Set a path for the sprite being the next way point given. 294 //! \return whether it failed. 295 bool _SetPathToNextWayPoint(); 296 297 //! \brief Handles behavior when the enemy is in hostile state (seeking for characters) 298 void _HandleHostileUpdate(); 299 300 }; 301 302 } // namespace private_map 303 304 } // namespace vt_map 305 306 #endif // __MAP_ENEMY_SPRITE_HEADER__ 307