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_sprites.h
12 *** \author  Tyler Olsen, roots@allacrost.org
13 *** \brief   Header file for map mode sprite code.
14 *** *****************************************************************************/
15 
16 #ifndef __MAP_SPRITES_HEADER__
17 #define __MAP_SPRITES_HEADER__
18 
19 // Allacrost utilities
20 #include "utils.h"
21 #include "defs.h"
22 
23 // Allacrost engines
24 #include "video.h"
25 
26 #include "battle_events.h"
27 
28 // Local map mode headers
29 #include "map_utils.h"
30 #include "map_objects.h"
31 #include "map_dialogue.h"
32 #include "map_zones.h"
33 
34 namespace hoa_map {
35 
36 namespace private_map {
37 
38 /** ****************************************************************************
39 *** \brief A special type of sprite with no physical image
40 ***
41 *** The VirtualSprite is a special type of MapObject because it has no physical
42 *** form (no image). Virtual sprites may be manipulated to move around on the screen
43 *** just like any other sprite. VirtualSprites do take collision detection into account
44 *** by default, unless the no_collision member is set to true. Here are some examples of
45 *** where virtual sprites may be of use:
46 ***
47 *** - As a mobile focusing point for the map camera
48 *** - As an impassible map location for ground objects in a specific context only
49 *** - To set impassible locations for objects in the sky layer
50 ***
51 *** \note The VirtualSprite class serves as a base class for all other types of
52 *** sprites.
53 *** ***************************************************************************/
54 class VirtualSprite : public MapObject {
55 public:
56 	VirtualSprite();
57 
58 	~VirtualSprite();
59 
60 	// ---------- Public Members: Orientation and Movement
61 
62 	/** \brief A bit-mask for the sprite's draw orientation and direction vector.
63 	*** This member determines both where to move the sprite (8 directions) and
64 	*** which way the sprite is facing (4 directions). See the Sprite direction
65 	*** constants for the values that this member may be set to.
66 	**/
67 	uint16 direction;
68 
69 	//! \brief The speed at which the sprite moves around the map.
70 	float movement_speed;
71 
72 	/** \brief Set to true when the sprite is currently in motio.
73 	*** This does not necessarily mean that the sprite actually is moving, but rather
74 	*** that the sprite is <i>trying</i> to move in a certain direction.
75 	**/
76 	bool moving;
77 
78 	/** \brief Set to true whenever the sprite's position was changed due to movement
79 	*** This is distinctly different than the moving member. Whereas the moving member
80 	*** indicates desired movement, this member indicates that positionaly change due to
81 	*** movement actually occurred. It is used for drawing functions to determine if they
82 	*** should draw the sprite in motion or not in motion
83 	**/
84 	bool moved_position;
85 
86 	//! \brief Set to true when the sprite is running rather than walking
87 	bool is_running;
88 
89 	// ---------- Public Members: Events
90 
91 	//! \brief A pointer to the event that is controlling the action of this sprite
92 	SpriteEvent* control_event;
93 
94 	// ---------- Public methods
95 
96 	//! \brief Updates the virtual object's position if it is moving, otherwise does nothing.
97 	virtual void Update();
98 
99 	//! \brief Does nothing since virtual sprites have no image to draw
Draw()100 	virtual void Draw()
101 		{}
102 
103 	/** \note This method takes into account the current direction when setting the new direction
104 	*** in the case of diagonal movement. For example, if the sprite is currently facing north
105 	*** and this function indicates that the sprite should move northwest, it will face north
106 	*** during the northwest movement.
107 	**/
108 	void SetDirection(uint16 dir);
109 
110 	/** \brief Sets the sprite's direction to a random value
111 	*** This function is used mostly for the ActionRandomMove class.
112 	**/
113 	void SetRandomDirection();
114 
115 	/** \brief Calculates the distance the sprite should move given its velocity (speed and direction)
116 	*** \return A floating point value representing the distance moved
117 	*** \note This method does not check if the "moving" member is true but does factor in the "is_running"
118 	*** member in its calculation.
119 	**/
120 	float CalculateDistanceMoved();
121 
122 	/** \brief Declares that an event is taking control over the sprite
123 	*** \param event The sprite event that is assuming control
124 	*** This function is not safe to call when there is an event already controlling the sprite.
125 	*** The previously controlling event should first release control (which will set the control_event
126 	*** member to NULL) before a new event acquires it. The acquisition will be successful regardless
127 	*** of whether there is currently a controlling event or not, but a warning will be printed in the
128 	*** improper case.
129 	**/
130 	void AcquireControl(SpriteEvent* event);
131 
132 	/** \brief Declares that an event is releasing control over the sprite
133 	*** \param event The sprite event that is releasing control
134 	*** The reason why the SpriteEvent has to pass a pointer to itself in this call is to make sure
135 	*** that this event is still controlling the sprite. If the control has switched to another event
136 	*** (because another event acquired it before this event released it), a warning will be printed
137 	*** and no change will be made (the control event will not change).
138 	**/
139 	void ReleaseControl(SpriteEvent* event);
140 
141 	/** \brief Saves the state of the sprite
142 	*** Attributes saved: direction, speed, moving state
143 	**/
144 	virtual void SaveState();
145 
146 	/** \brief Restores the saved state of the sprite
147 	*** Attributes restored: direction, speed, moving state
148 	**/
149 	virtual void RestoreState();
150 
151 	/** \name Lua Access Functions
152 	*** These functions are specifically written to enable Lua to access the members of this class.
153 	**/
154 	//@{
IsStateSaved()155 	bool IsStateSaved() const
156 		{ return _state_saved; }
157 
SetMovementSpeed(float speed)158 	void SetMovementSpeed(float speed)
159 		{ movement_speed = speed; }
160 
GetDirection()161 	uint16 GetDirection() const
162 		{ return direction; }
163 
GetMovementSpeed()164 	float GetMovementSpeed() const
165 		{ return movement_speed; }
166 	//@}
167 
168 protected:
169 	/** \brief Determines an appropriate resolution when the sprite collides with an obstruction
170 	*** \param coll_type The type of collision that has occurred
171 	*** \param coll_obj A pointer to the MapObject that the sprite has collided with, if any
172 	**/
173 	void _ResolveCollision(COLLISION_TYPE coll_type, MapObject* coll_obj);
174 
175 	/** \name Saved state attributes
176 	*** These attributes are used to save and restore the state of a VirtualSprite
177 	**/
178 	//@{
179 	//! \brief Indicates if the other saved members are valid because the state has recently been saved
180 	bool _state_saved;
181 	uint16 _saved_direction;
182 	float _saved_movement_speed;
183 	bool _saved_moving;
184 	//@}
185 }; // class VirtualSprite : public MapObject
186 
187 
188 /** ****************************************************************************
189 *** \brief A mobile map object with which the player can interact with.
190 ***
191 *** Map sprites are animate, mobile, living map objects. Although there is
192 *** but this single class to represent all the map sprites in the game, they can
193 *** divided into types such as NPCs, friendly creatures, and enemies. The fact
194 *** that there is only one class for representing several sprite types is the
195 *** reason why many of the class members are pointers. For example, we don't
196 *** need dialogue for a dog sprite.
197 *** ***************************************************************************/
198 class MapSprite : public VirtualSprite {
199 public:
200 	MapSprite();
201 
202 	~MapSprite();
203 
204 	// ---------- Public methods
205 
206 	/** \brief Loads the image containing the standard animations for the sprite
207 	*** \param filename The name of the image file holding the standard walking animations
208 	*** \return False if there was a problem loading the sprite.
209 	**/
210 	bool LoadStandardAnimations(std::string filename);
211 
212 	/** \brief Loads the image containing the running animations for the sprite
213 	*** \param filename The name of the image file
214 	*** \return False if the animations were not created successfully.
215 	**/
216 	bool LoadRunningAnimations(std::string filename);
217 
218 	/** \brief Loads the image containing the attack animations for the sprite
219 	*** \param filename The name of the image file
220 	*** \return False if the animations were not created successfully.
221 	**/
222 	bool LoadAttackAnimations(std::string filename);
223 
224 	void LoadFacePortrait(std::string pn);
225 
226 	//! \brief Updates the sprite's position and state.
227 	virtual void Update();
228 
229 	//! \brief Draws the sprite frame in the appropriate position on the screen, if it is visible.
230 	virtual void Draw();
231 
232 	/** \brief Adds a new reference to a dialogue that the sprite uses
233 	*** \param dialogue_id The ID number of the dialogue
234 	*** \note It is valid for a dialogue to be referenced more than once by a sprite
235 	**/
236 	void AddDialogueReference(uint32 dialogue_id);
237 
238 	//! \brief Updates all dialogue status members based on the status of all referenced dialogues
239 	void UpdateDialogueStatus();
240 
241 	//! \brief Increments the next_dialogue member to index the proceeding dialogue
242 	void IncrementNextDialogue();
243 
244 	/** \brief Sets the next dialogue member for the sprite
245 	*** \param next The index value of the dialogue_references vector to set the next_dialogue member to
246 	*** \note You can not set the next_dialogue member to a negative number. This could cause run-time errors if it was supported here.
247 	**/
248 	void SetNextDialogue(uint16 next);
249 
250 	/** \brief This method will save the state of a sprite.
251 	*** Attributes saved: direction, speed, moving state, name
252 	*** current animation.
253 	**/
254 	virtual void SaveState();
255 
256 	/** \brief This method will load the saved state of a sprite.
257 	*** Attributes loaded: direction, speed, moving state, name
258 	*** current animation.
259 	*** \return false if there was no saved state, true otherwise.
260 	**/
261 	virtual void RestoreState();
262 
263 	/** \name Lua Access Functions
264 	*** These functions are specifically written to enable Lua to access the members of this class.
265 	**/
266 	//@{
267 	// TODO: needs to be a ustring
SetName(std::string na)268 	void SetName(std::string na)
269 		{ _name = hoa_utils::MakeUnicodeString(na); }
270 
SetCurrentAnimation(uint8 anim)271 	void SetCurrentAnimation(uint8 anim)
272 		{ _current_animation = anim; }
273 
GetCurrentAnimation()274 	uint8 GetCurrentAnimation() const
275 		{ return _current_animation; }
276 
HasAvailableDialogue()277 	bool HasAvailableDialogue() const
278 		{ return _has_available_dialogue; }
279 
HasUnseenDialogue()280 	bool HasUnseenDialogue() const
281 		{ return _has_unseen_dialogue; }
282 
GetName()283 	hoa_utils::ustring& GetName()
284 		{ return _name; }
285 
GetFacePortrait()286 	hoa_video::StillImage* GetFacePortrait() const
287 		{ return _face_portrait; }
288 
289 	//! \brief Returns the next dialogue to reference (negative value returned if no dialogues are referenced)
GetNextDialogue()290 	int16 GetNextDialogue() const
291 		{ return _next_dialogue; }
292 
293 	//! \brief Gets the ID value of the dialogue that will be the next to be referenced by the sprite
GetNextDialogueID()294 	uint32 GetNextDialogueID() const // TODO: check invalid indexing
295 		{ return _dialogue_references[_next_dialogue]; }
296 
297 	//! \brief Returns the number of dialogues referenced by the sprite (including duplicates)
GetNumberDialogueReferences()298 	uint16 GetNumberDialogueReferences() const
299 		{ return _dialogue_references.size(); }
300 
301 	//! \brief Set to true for a custom animation
SetCustomAnimation(bool on_or_off)302 	void SetCustomAnimation(bool on_or_off)
303 		{ _custom_animation_on = on_or_off; }
304 	//@}
305 
306 
307 protected:
308 	//! \brief The name of the sprite, as seen by the player in the game.
309 	hoa_utils::ustring _name;
310 
311 	/** \brief A pointer to the face portrait of the sprite, as seen in dialogues and menus.
312 	*** \note Not all sprites have portraits, in which case this member will be NULL
313 	**/
314 	hoa_video::StillImage* _face_portrait;
315 
316 	//! \brief Set to true if the sprite has running animations loaded
317 	bool _has_running_animations;
318 
319 	//! \brief The index to the animations vector containing the current sprite image to display
320 	uint8 _current_animation;
321 
322 	/** \brief A vector containing all the sprite's various animations.
323 	*** The first four entries in this vector are the walking animation frames.
324 	*** They are ordered from index 0 to 3 as: down, up, left, right. Additional
325 	*** animations may follow.
326 	**/
327 	std::vector<hoa_video::AnimatedImage> _animations;
328 
329 	//! \brief Contains the id values of all dialogues refenced by the sprite
330 	std::vector<uint32> _dialogue_references;
331 
332 	/** \brief An index to the dialogue_references vector, representing the next dialogue the sprite should reference
333 	*** A negative value indicates that the sprite has no dialogue.
334 	**/
335 	int16 _next_dialogue;
336 
337 	/** \brief True is sprite references at least one available dialogue
338 	*** \note A dialogue may become unavailable if it reaches its max view count
339 	**/
340 	bool _has_available_dialogue;
341 
342 	//! \brief True if at least one dialogue referenced by this sprite has not yet been viewed -and- is available to be viewed
343 	bool _has_unseen_dialogue;
344 
345 	//! \brief True if a custom animation is in use
346 	bool _custom_animation_on;
347 
348 	/** \name Saved state attributes
349 	*** These attributes are used to save and load the state of a VirtualSprite
350 	**/
351 	//@{
352 	uint8 _saved_current_animation;
353 	//@}
354 }; // class MapSprite : public VirtualSprite
355 
356 
357 /** ****************************************************************************
358 *** \brief A mobile map object that induces a battle to occur if the player touches it
359 ***
360 *** There are really two types of enemy sprites. The first type behave just like
361 *** map sprites and can have scripted movement sequences. The second type belong
362 *** to EnemyZones, where they fade into existence and pursue after the player's
363 *** sprite should the player enter the zone.
364 ***
365 *** An enemy sprite in a zone can be in one of 3 states: SPAWNING, HOSTILE or DEAD.
366 *** In the spawning state, the enemy becomes gradually visible, is immobile, and
367 *** cannot be touched or attacked. In the hostile state, the enemies roams the map
368 *** and will cause a battle if touched by the player. In the dead state, the enemy
369 *** is invisible and waits for the EnemyZone to reset it in another position, so
370 *** that it may spawn once more.
371 *** ***************************************************************************/
372 class EnemySprite : public MapSprite {
373 private:
374 	//! \brief The states that the enemy sprite may be in
375 	enum STATE {
376 		SPAWNING,
377 		HOSTILE,
378 		DEAD
379 	};
380 
381 public:
382 
383 	std::string filename;
384 
385 	//! \brief The default constructor which typically requires that the user make several additional calls to setup the sprite properties
386 	EnemySprite();
387 
388 	//! \brief A constructor for when the enemy sprite is stored in the definition of a single file
389 	EnemySprite(std::string file);
390 
391 	//! \brief Loads the enemy's data from a file and returns true if it was successful
392 	bool Load();
393 
394 	//! \brief Resets various members of the class so that the enemy is dead, invisible, and does not produce a collision
395 	void Reset();
396 
397 	//! \brief Updates the sprite's position and state.
398 	virtual void Update();
399 
400 	//! \brief Draws the sprite frame in the appropriate position on the screen, if it is visible.
401 	virtual void Draw();
402 
403 	// 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
404 	// sure how to do that yet, I'm writing several smaller functions so we can just get this demo released.
405 
406 	// void AddEnemyParty(std::vector<uint32>& party);
407 
408 	/** \brief Adds a new empty vector to the _enemy_parties member
409 	*** \note Make sure to populate this vector by adding at least one enemy!
410 	**/
NewEnemyParty()411 	void NewEnemyParty()
412 		{ _enemy_parties.push_back(std::vector<uint32>()); }
413 
414 	/** \brief Adds an enemy with the specified ID to the last party in _enemy_parties
415 	*** \param enemy_id The ID of the enemy to add
416 	*** \note MapMode should have already loaded a GlobalEnemy with this ID and retained it within the MapMode#_enemies member.
417 	*** If this is not the case, this function will print a warning message.
418 	**/
419 	void AddEnemy(uint32 enemy_id);
420 
421 	//! \brief Returns a reference to a random party of enemies
422 	const std::vector<uint32>& RetrieveRandomParty();
423 
424 	//! \name Class Member Access Functions
425 	//@{
GetAggroRange()426 	float GetAggroRange() const
427 		{ return _aggro_range; }
428 
GetTimeToChange()429 	uint32 GetTimeToChange() const
430 		{ return _time_dir_change; }
431 
GetTimeToSpawn()432 	uint32 GetTimeToSpawn() const
433 		{ return _time_to_spawn; }
434 
GetBattleMusicTheme()435 	std::string GetBattleMusicTheme() const
436 		{ return _music_theme; }
437 
GetBattleBackground()438 	std::string GetBattleBackground() const
439 		{ return _bg_file; }
440 
IsDead()441 	bool IsDead() const
442 		{ return _state == DEAD; }
443 
IsSpawning()444 	bool IsSpawning() const
445 		{ return _state == SPAWNING; }
446 
IsHostile()447 	bool IsHostile() const
448 		{ return _state == HOSTILE; }
449 
SetZone(EnemyZone * zone)450 	void SetZone(EnemyZone* zone)
451 		{ _zone = zone; }
452 
SetAggroRange(float range)453 	void SetAggroRange(float range)
454 		{ _aggro_range = range; }
455 
SetTimeToChange(uint32 time)456 	void SetTimeToChange(uint32 time)
457 		{ _time_dir_change = time; }
458 
SetTimeToSpawn(uint32 time)459 	void SetTimeToSpawn(uint32 time)
460 		{ _time_to_spawn = time; }
461 
SetBattleMusicTheme(const std::string & music_theme)462 	void SetBattleMusicTheme(const std::string& music_theme)
463 		{ _music_theme = music_theme; }
464 
SetBattleBackground(const std::string & bg_file)465 	void SetBattleBackground(const std::string& bg_file)
466 		{ _bg_file = bg_file; }
467 
ChangeStateDead()468 	void ChangeStateDead()
469 		{ Reset(); if (_zone) _zone->EnemyDead(); }
470 
ChangeStateSpawning()471 	void ChangeStateSpawning()
472 		{ updatable = true; _state = SPAWNING; no_collision = false; }
473 
ChangeStateHostile()474 	void ChangeStateHostile()
475 		{ updatable = true; _state = HOSTILE; no_collision = false; _color.SetAlpha(1.0); }
476 
AddBattleEvent(uint32 n)477 	void AddBattleEvent(uint32 n)
478 		{ hoa_battle::BattleEvent* thisEvent = new hoa_battle::BattleEvent(n); _battle_events.push_back(thisEvent); }
479 
GetBattleEvents()480 	std::vector<hoa_battle::BattleEvent*> GetBattleEvents() { return _battle_events; }
481 	//@}
482 
483 private:
484 	//! \brief The zone that the enemy sprite belongs to
485 	private_map::EnemyZone* _zone;
486 
487 	//! \brief Used to gradually fade in the sprite as it is spawning by adjusting the alpha channel
488 	hoa_video::Color _color;
489 
490 	//! \brief A timer used for spawning
491 	uint32 _time_elapsed;
492 
493 	//! \brief The state that the enemy sprite is in
494 	STATE _state;
495 
496 	//! \brief A value which determines how close the player needs to be for the enemy to aggressively seek to confront it
497 	float _aggro_range;
498 
499 	//! \brief ???
500 	uint32 _time_dir_change;
501 
502 	//! \brief ???
503 	uint32 _time_to_spawn;
504 
505 	//! \brief Indicates if the enemy is outside of its zone. If it is, it won't change direction until it gets back in.
506 	bool _out_of_zone;
507 
508 	//! \brief The default battle music theme for the monster
509 	std::string _music_theme;
510 
511 	//! \brief The default background for the battle
512 	std::string _bg_file;
513 
514 	/** \brief Contains the possible groups of enemies that may appear in a battle should the player encounter this enemy sprite
515 	*** The numbers contained within this member are ID numbers for the enemy. If the
516 	**/
517 	std::vector<std::vector<uint32> > _enemy_parties;
518 
519 	//! \brief Vector containing custom scripts for this battle
520 	std::vector<hoa_battle::BattleEvent*> _battle_events;
521 }; // class EnemySprite : public MapSprite
522 
523 } // namespace private_map
524 
525 } // namespace hoa_map
526 
527 #endif // __MAP_SPRITES_HEADER__
528