1 /*
2  * Copyright (C) 2006-2019 Christopho, Solarus - http://www.solarus-games.org
3  *
4  * Solarus is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * Solarus is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 #include "solarus/audio/Sound.h"
18 #include "solarus/hero/HeroSprites.h"
19 #include "solarus/core/Debug.h"
20 #include "solarus/core/Equipment.h"
21 #include "solarus/core/Game.h"
22 #include "solarus/core/Map.h"
23 #include "solarus/core/System.h"
24 #include "solarus/entities/CarriedObject.h"
25 #include "solarus/entities/Hero.h"
26 #include "solarus/graphics/Sprite.h"
27 #include "solarus/graphics/SpriteAnimationSet.h"
28 #include "solarus/lua/LuaContext.h"
29 #include <lua.hpp>
30 #include <sstream>
31 
32 namespace Solarus {
33 
34 /**
35  * \brief Associates to each movement direction the possible directions of the hero's sprites.
36  *
37  * This array indicates the possible directions of the hero's animation (from 0 to 3, or -1 for no change)
38  * for each movement direction.
39  * Each combination of directional keys can be associated to one or two directions.
40  * When one direction is specified (i.e. the second one is set to -1), the hero's sprite always takes
41  * this direction.
42  * When two directions are specified,
43  * the hero sprite takes the first direction, unless it is already under the second one
44  * (then it stays in the second one). This permits a natural behavior for diagonal directions.
45  */
46 const int HeroSprites::animation_directions[][2] = {
47   { 0, -1},  // right
48   { 0,  1},  // right-up: right or up
49   { 1, -1},  // up
50   { 2,  1},  // left-up: left or up
51   { 2, -1},  // left
52   { 2,  3},  // left-down: left or down
53   { 3, -1},  // down
54   { 0,  3}   // right-down: right or down
55 };
56 
57 /**
58  * \brief Constructor.
59  * \param hero the hero
60  * \param equipment the equipment
61  */
HeroSprites(Hero & hero,Equipment & equipment)62 HeroSprites::HeroSprites(Hero& hero, Equipment& equipment):
63   hero(hero),
64   equipment(equipment),
65   has_default_tunic_sprite(true),
66   tunic_sprite(nullptr),
67   has_default_sword_sprite(true),
68   sword_sprite(nullptr),
69   sword_stars_sprite(nullptr),
70   has_default_sword_sound(true),
71   has_default_shield_sprite(true),
72   shield_sprite(nullptr),
73   shadow_sprite(nullptr),
74   ground_sprite(nullptr),
75   trail_sprite(nullptr),
76   animation_direction_saved(0),
77   when_suspended(0),
78   blinking(false),
79   end_blink_date(0),
80   walking(false),
81   clipping_rectangle(Rectangle()),
82   lifted_item(nullptr),
83   animation_callback_ref() {
84 
85 }
86 
87 /**
88  * \brief Returns the Lua context of the hero.
89  * \return The Lua context.
90  */
get_lua_context()91 LuaContext& HeroSprites::get_lua_context() {
92   return *hero.get_lua_context();
93 }
94 
95 /**
96  * \brief Loads (or reloads) the sprites and sounds of the hero and his
97  * equipment.
98  *
99  * The sprites and sounds loaded may depend on his tunic, sword and shield as
100  * specified in the savegame.
101  * This function must be called at the game beginning
102  * and as soon as the hero's equipment is changed.
103  */
rebuild_equipment()104 void HeroSprites::rebuild_equipment() {
105 
106   // Make the tunic sprite be the default one.
107   hero.set_default_sprite_name("tunic");
108 
109   int animation_direction = -1;
110   if (tunic_sprite != nullptr) {
111     // Save the direction.
112     animation_direction = tunic_sprite->get_current_direction();
113   }
114 
115   // The hero's body.
116   if (has_default_tunic_sprite) {
117     set_tunic_sprite_id(get_default_tunic_sprite_id());
118   }
119 
120   // The hero's sword.
121   if (has_default_sword_sprite) {
122     set_sword_sprite_id(get_default_sword_sprite_id());
123   }
124 
125   if (has_default_sword_sound) {
126     set_sword_sound_id(get_default_sword_sound_id());
127   }
128 
129   const int sword_number = equipment.get_ability(Ability::SWORD);
130   if (sword_number > 0) {
131     // TODO make this sprite depend on the sword sprite: sword_sprite_id + "_stars"
132     std::ostringstream oss;
133     oss << "hero/sword_stars" << sword_number;
134     set_sword_stars_sprite_id(oss.str());
135   }
136 
137   // The hero's shield.
138   if (has_default_shield_sprite) {
139     set_shield_sprite_id(get_default_shield_sprite_id());
140   }
141 
142   // The trail.
143   trail_sprite->stop_animation();
144 
145   // Restore the animation direction.
146   if (animation_direction != -1) {
147     set_animation_direction(animation_direction);
148   }
149 }
150 
151 /**
152  * \brief Returns the animation set id used for the tunic sprite.
153  * \return The tunic sprite animation set id.
154  */
get_tunic_sprite_id() const155 const std::string& HeroSprites::get_tunic_sprite_id() const {
156 
157   return tunic_sprite_id;
158 }
159 
160 /**
161  * \brief Sets the animation set id to use for the tunic sprite.
162  * \param sprite_id The tunic sprite animation set id.
163  */
set_tunic_sprite_id(const std::string & sprite_id)164 void HeroSprites::set_tunic_sprite_id(const std::string& sprite_id) {
165 
166   if (sprite_id == this->tunic_sprite_id) {
167     return;
168   }
169 
170   this->tunic_sprite_id = sprite_id;
171 
172   int order = -1;
173   std::string animation;
174   int direction = -1;
175   if (tunic_sprite != nullptr) {
176     // Delete the previous sprite, but save its animation and direction.
177     animation = tunic_sprite->get_current_animation();
178     direction = tunic_sprite->get_current_direction();
179     order = hero.get_sprite_order(*tunic_sprite);
180     hero.remove_sprite(*tunic_sprite);
181     tunic_sprite = nullptr;
182   }
183 
184   tunic_sprite = hero.create_sprite(sprite_id, "tunic", order);
185   tunic_sprite->enable_pixel_collisions();
186   if (!animation.empty()) {
187     set_tunic_animation(animation);
188     tunic_sprite->set_current_direction(direction);
189   }
190 
191   has_default_tunic_sprite = (sprite_id == get_default_tunic_sprite_id());
192 
193   // Synchronize other sprites to the new tunic sprite.
194   if (sword_sprite != nullptr) {
195     sword_sprite->set_synchronized_to(tunic_sprite);
196   }
197   if (shield_sprite != nullptr) {
198     shield_sprite->set_synchronized_to(tunic_sprite);
199   }
200 }
201 
202 /**
203  * \brief Returns the animation set id of the default tunic sprite.
204  *
205  * The default tunic sprite id is "hero/tunicX" where X is the tunic level.
206  *
207  * \return The default tunic sprite animation set id.
208  */
get_default_tunic_sprite_id() const209 std::string HeroSprites::get_default_tunic_sprite_id() const {
210 
211   const int tunic_level = equipment.get_ability(Ability::TUNIC);
212   std::ostringstream oss;
213   oss << "hero/tunic" << tunic_level;
214   return oss.str();
215 }
216 
217 /**
218  * \brief Returns the animation set id used for the sword sprite.
219  * \return The sword sprite animation set id.
220  */
get_sword_sprite_id() const221 const std::string& HeroSprites::get_sword_sprite_id() const {
222 
223   return sword_sprite_id;
224 }
225 
226 /**
227  * \brief Sets the animation set id to use for the sword sprite.
228  * \param sprite_id The sword sprite animation set id.
229  * An empty string means no sword sprite.
230  */
set_sword_sprite_id(const std::string & sprite_id)231 void HeroSprites::set_sword_sprite_id(const std::string& sprite_id) {
232 
233   if (sprite_id == this->sword_sprite_id) {
234     return;
235   }
236 
237   this->sword_sprite_id = sprite_id;
238 
239   int order = -1;
240   std::string animation;
241   int direction = -1;
242   if (sword_sprite != nullptr) {
243     // Delete the previous sprite, but save its animation and direction.
244     if (sword_sprite->is_animation_started()) {
245       animation = sword_sprite->get_current_animation();
246       direction = sword_sprite->get_current_direction();
247     }
248     order = hero.get_sprite_order(*sword_sprite);
249     hero.remove_sprite(*sword_sprite);
250     sword_sprite = nullptr;
251   }
252 
253   if (!sprite_id.empty()) {
254     // There is a sword sprite specified.
255     sword_sprite = hero.create_sprite(sprite_id, "sword", order);
256     sword_sprite->enable_pixel_collisions();
257     sword_sprite->set_synchronized_to(tunic_sprite);
258     if (animation.empty()) {
259       sword_sprite->stop_animation();
260     }
261     else {
262       sword_sprite->set_current_animation(animation);
263       sword_sprite->set_current_direction(direction);
264     }
265   }
266 
267   has_default_sword_sprite = (sprite_id == get_default_sword_sprite_id());
268 }
269 
270 /**
271  * \brief Returns the animation set id used for the sword stars sprite.
272  * \return The sword stars sprite animation set id.
273  */
get_sword_stars_sprite_id() const274 const std::string& HeroSprites::get_sword_stars_sprite_id() const {
275 
276   return sword_stars_sprite_id;
277 }
278 
279 /**
280  * \brief Sets the animation set id to use for the sword stars sprite.
281  * \param sprite_id The sword stars sprite animation set id.
282  * An empty string means no sword stars sprite.
283  */
set_sword_stars_sprite_id(const std::string & sprite_id)284 void HeroSprites::set_sword_stars_sprite_id(const std::string& sprite_id) {
285 
286   if (sprite_id == this->sword_stars_sprite_id) {
287     return;
288   }
289 
290   this->sword_stars_sprite_id = sprite_id;
291 
292   int order = -1;
293   std::string animation;
294   int direction = -1;
295   if (sword_stars_sprite != nullptr) {
296     // Delete the previous sprite, but save its animation and direction.
297     if (sword_stars_sprite->is_animation_started()) {
298       animation = sword_stars_sprite->get_current_animation();
299       direction = sword_stars_sprite->get_current_direction();
300     }
301     order = hero.get_sprite_order(*sword_stars_sprite);
302     hero.remove_sprite(*sword_stars_sprite);
303     sword_stars_sprite = nullptr;
304   }
305 
306   if (!sprite_id.empty()) {
307     // There is a sword sprite specified.
308     sword_stars_sprite = hero.create_sprite(sprite_id, "sword_stars", order);
309     if (animation.empty()) {
310       sword_stars_sprite->stop_animation();
311     }
312     else {
313       sword_stars_sprite->set_current_animation(animation);
314       sword_stars_sprite->set_current_direction(direction);
315     }
316   }
317 }
318 
319 /**
320  * \brief Returns the animation set id of the default sword sprite.
321  *
322  * The default sword sprite id is "hero/swordX" where X is the sword level,
323  * or no sprite if the sword level is 0.
324  *
325  * \return The default sword sprite animation set id.
326  */
get_default_sword_sprite_id() const327 std::string HeroSprites::get_default_sword_sprite_id() const {
328 
329   const int sword_level = equipment.get_ability(Ability::SWORD);
330   if (sword_level == 0) {
331     return "";
332   }
333 
334   std::ostringstream oss;
335   oss << "hero/sword" << sword_level;
336   return oss.str();
337 }
338 
339 /**
340  * \brief Returns the id of the sound played when using the sword.
341  * \return The sword sound id.
342  */
get_sword_sound_id() const343 const std::string& HeroSprites::get_sword_sound_id() const {
344 
345   return sword_sound_id;
346 }
347 
348 /**
349  * \brief Sets the sound to play when using the sword.
350  * \param sound_id The sword sound id.
351  * An empty string means no sword sound.
352  */
set_sword_sound_id(const std::string & sound_id)353 void HeroSprites::set_sword_sound_id(const std::string& sound_id) {
354 
355   if (sound_id == this->sword_sound_id) {
356     return;
357   }
358 
359   this->sword_sound_id = sound_id;
360 
361   has_default_sword_sound = (sound_id == get_default_sword_sound_id());
362 }
363 
364 /**
365  * \brief Returns the id of default sound to play when using the sword.
366  *
367  * The default sword sound is "swordX" where X is the sword level,
368  * or no sound if the sword level is 0.
369  *
370  * \return The default sword sound id.
371  */
get_default_sword_sound_id() const372 std::string HeroSprites::get_default_sword_sound_id() const {
373 
374   const int sword_level = equipment.get_ability(Ability::SWORD);
375   if (sword_level == 0) {
376     return "";
377   }
378 
379   std::ostringstream oss;
380   oss << "sword" << sword_level;
381   return oss.str();
382 }
383 
384 /**
385  * \brief Returns the animation set id used for the shield sprite.
386  * \return The shield sprite animation set id.
387  */
get_shield_sprite_id() const388 const std::string& HeroSprites::get_shield_sprite_id() const {
389 
390   return shield_sprite_id;
391 }
392 
393 /**
394  * \brief Sets the animation set id to use for the shield sprite.
395  * \param sprite_id The shield sprite animation set id.
396  * An empty string means no sword sprite.
397  */
set_shield_sprite_id(const std::string & sprite_id)398 void HeroSprites::set_shield_sprite_id(const std::string& sprite_id) {
399 
400   if (sprite_id == this->shield_sprite_id) {
401     return;
402   }
403 
404   this->shield_sprite_id = sprite_id;
405 
406   int order = -1;
407   std::string animation;
408   int direction = -1;
409   if (shield_sprite != nullptr) {
410     // Delete the previous sprite, but save its animation and direction.
411     if (shield_sprite->is_animation_started()) {
412       animation = shield_sprite->get_current_animation();
413       direction = shield_sprite->get_current_direction();
414     }
415     order = hero.get_sprite_order(*shield_sprite);
416     hero.remove_sprite(*shield_sprite);
417     shield_sprite = nullptr;
418   }
419 
420   if (!sprite_id.empty()) {
421     // There is a shield sprite specified.
422     shield_sprite = hero.create_sprite(sprite_id, "shield", order);
423     shield_sprite->set_synchronized_to(tunic_sprite);
424     if (animation.empty()) {
425       shield_sprite->stop_animation();
426     }
427     else {
428       shield_sprite->set_current_animation(animation);
429       shield_sprite->set_current_direction(direction);
430     }
431   }
432 
433   has_default_shield_sprite = (sprite_id == get_default_shield_sprite_id());
434 }
435 
436 /**
437  * \brief Returns the animation set id of the default shield sprite.
438  *
439  * The default shield sprite id is "hero/shieldX" where X is the shield level,
440  * or no shield if the sword level is 0.
441  *
442  * \return The default shield sprite animation set id.
443  */
get_default_shield_sprite_id() const444 std::string HeroSprites::get_default_shield_sprite_id() const {
445 
446   const int shield_level = equipment.get_ability(Ability::SHIELD);
447   if (shield_level == 0) {
448     return "";
449   }
450 
451   std::ostringstream oss;
452   oss << "hero/shield" << shield_level;
453   return oss.str();
454 }
455 
456 /**
457  * \brief Returns whether the sword is currently displayed on the screen.
458  * \return true if the sword is currently displayed on the screen
459  */
is_sword_visible() const460 bool HeroSprites::is_sword_visible() const {
461   return equipment.has_ability(Ability::SWORD)
462       && sword_sprite != nullptr
463       && sword_sprite->is_animation_started();
464 }
465 
466 /**
467  * \brief Returns whether the stars of the sword are currently displayed on the screen.
468  * \return true if the stars of the sword are currently displayed on the screen
469  */
is_sword_stars_visible() const470 bool HeroSprites::is_sword_stars_visible() const {
471   return equipment.has_ability(Ability::SWORD)
472       && sword_stars_sprite != nullptr
473       && sword_stars_sprite->is_animation_started();
474 }
475 
476 /**
477  * \brief Returns whether the shield is currently displayed on the screen.
478  * \return true if the shield is currently displayed on the screen
479  */
is_shield_visible() const480 bool HeroSprites::is_shield_visible() const {
481   return equipment.has_ability(Ability::SHIELD)
482       && shield_sprite != nullptr
483       && shield_sprite->is_animation_started();
484 }
485 
486 /**
487  * \brief Returns whether the trail of dust is currently displayed.
488  * \return true if the trail of dust is currently displayed
489  */
is_trail_visible() const490 bool HeroSprites::is_trail_visible() const {
491   return trail_sprite->is_animation_started();
492 }
493 
494 /**
495  * \brief Returns whether a special ground is displayed under the hero.
496  * \return true if a ground is currently visible under the hero
497  */
is_ground_visible() const498 bool HeroSprites::is_ground_visible() const {
499   return hero.is_ground_visible()
500       && ground_sprite != nullptr
501       && ground_sprite->is_animation_started();
502 }
503 
504 /**
505  * \brief Stops displaying the sword and the sword stars (if any).
506  */
stop_displaying_sword()507 void HeroSprites::stop_displaying_sword() {
508 
509   if (is_sword_visible()) {
510     sword_sprite->stop_animation();
511   }
512   stop_displaying_sword_stars();
513 }
514 
515 /**
516  * \brief Stops displaying the sword stars (if any).
517  */
stop_displaying_sword_stars()518 void HeroSprites::stop_displaying_sword_stars() {
519 
520   if (is_sword_stars_visible()) {
521     sword_stars_sprite->stop_animation();
522   }
523 }
524 
525 /**
526  * \brief Stops displaying the shield (if any).
527  */
stop_displaying_shield()528 void HeroSprites::stop_displaying_shield() {
529 
530   if (equipment.has_ability(Ability::SHIELD) &&
531       shield_sprite != nullptr) {
532     shield_sprite->stop_animation();
533   }
534 }
535 
536 /**
537  * \brief Stops displaying the trail (if any).
538  */
stop_displaying_trail()539 void HeroSprites::stop_displaying_trail() {
540   if (trail_sprite != nullptr) {
541     trail_sprite->stop_animation();
542   }
543 }
544 
545 /**
546  * \brief Makes the hero blink for a while.
547  * \param duration Delay before stopping blinking.
548  * 0 means infinite.
549  */
blink(uint32_t duration)550 void HeroSprites::blink(uint32_t duration) {
551 
552   const uint32_t blink_delay = 50;
553 
554   blinking = true;
555   tunic_sprite->set_blinking(blink_delay);
556 
557   if (equipment.has_ability(Ability::SHIELD)) {
558     shield_sprite->set_blinking(blink_delay);
559   }
560   if (equipment.has_ability(Ability::SWORD)) {
561     sword_sprite->set_blinking(blink_delay);
562   }
563   trail_sprite->set_blinking(blink_delay);
564 
565   if (duration == 0) {
566     // No end date.
567     end_blink_date = 0;
568   }
569   else {
570     end_blink_date = System::now() + duration;
571   }
572 }
573 
574 /**
575  * \brief Stops making the hero's sprites blink.
576  */
stop_blinking()577 void HeroSprites::stop_blinking() {
578 
579   blinking = false;
580   end_blink_date = 0;
581 
582   tunic_sprite->set_blinking(0);
583 
584   if (equipment.has_ability(Ability::SHIELD)) {
585     shield_sprite->set_blinking(0);
586   }
587   if (equipment.has_ability(Ability::SWORD)) {
588     sword_sprite->set_blinking(0);
589   }
590   trail_sprite->set_blinking(0);
591 }
592 
593 /**
594  * \brief Returns whether the hero's sprites are currently blinking.
595  * \return \c true if the hero's sprites are currently blinking.
596  */
is_blinking() const597 bool HeroSprites::is_blinking() const {
598   return blinking;
599 }
600 
601 /**
602  * \brief Sets a rectangle of the map where the drawing of the hero's sprite will be restricted to.
603  *
604  * A (0,0,0,0) rectangle means that the sprite is not restricted to a subarea of the map.
605  *
606  * \param clipping_rectangle a subarea of the map to restrict the drawing to
607  */
set_clipping_rectangle(const Rectangle & clipping_rectangle)608 void HeroSprites::set_clipping_rectangle(const Rectangle& clipping_rectangle) {
609   this->clipping_rectangle = clipping_rectangle;
610 }
611 
612 /**
613  * \brief Returns whether the sprites have currently a walking animation.
614  * \return true if the sprites are walking
615  */
is_walking() const616 bool HeroSprites::is_walking() const {
617   return walking;
618 }
619 
620 /**
621  * \brief Returns the direction of the hero's sprites.
622  *
623  * It is different from the movement direction.
624  *
625  * \return the direction of the sprites (0 to 3)
626  */
get_animation_direction() const627 int HeroSprites::get_animation_direction() const {
628   return tunic_sprite->get_current_direction();
629 }
630 
631 /**
632  * \brief Returns the direction of the hero's sprites.
633  *
634  * It is different from the movement direction.
635  *
636  * \return the direction of the sprites (0 to 7, except diagonal directions)
637  */
get_animation_direction8() const638 int HeroSprites::get_animation_direction8() const {
639   return get_animation_direction() * 2;
640 }
641 
642 /**
643  * \brief Returns the direction that the hero's sprites should take.
644  *
645  * This function returns the direction that the hero's sprites should take depending on the direction wanted
646  * by the player and the real movement direction.
647  * For diagonal directions, the direction returned depends
648  * on the current real direction of the hero's sprites.
649  *
650  * \param keys_direction the direction defined by the combination of directional keys pressed (0 to 7),
651  * or -1 if this is not a valid direction
652  * \param real_movement_direction the direction of the hero's actual movement (may be different from keys_direction)
653  * \return the direction of the sprites corresponding to these arrows (0 to 3),
654  * or -1 if the directional keys combination is illegal
655  */
get_animation_direction(int keys_direction,int real_movement_direction) const656 int HeroSprites::get_animation_direction(
657     int keys_direction, int real_movement_direction) const {
658 
659   int result;
660 
661   if (keys_direction == -1) {
662     // the player is not pressing a valid combination of directional keys: don't change the sprite's direction
663     result = -1;
664   }
665   else if (keys_direction % 2 == 0) {
666     // the player is pressing only one of the four main directions
667     // (i.e. he is not trying to make a diagonal move, even if the real movement is diagonal)
668     // we just give the sprite this direction
669     result = keys_direction / 2;
670   }
671   // the movement is diagonal: we have to choose between two directions
672   else if (animation_directions[real_movement_direction][1] == get_animation_direction()) {
673     // we choose the second direction if it was already the sprite's direction
674     result = animation_directions[real_movement_direction][1];
675   }
676   else {
677     // otherwise we choose the first direction
678     result = animation_directions[real_movement_direction][0];
679   }
680 
681   return result;
682 }
683 
684 /**
685  * \brief Changes the direction of the hero's sprites.
686  *
687  * It is different from the movement direction.
688  *
689  * \param direction the direction to set (0 to 3)
690  */
set_animation_direction(int direction)691 void HeroSprites::set_animation_direction(int direction) {
692 
693   Debug::check_assertion(direction >= 0 && direction < 4,
694     "Invalid direction for set_animation_direction");
695 
696   if (tunic_sprite != nullptr) {
697     tunic_sprite->set_current_direction(direction);
698   }
699 
700   if (is_sword_visible()) {
701     sword_sprite->set_current_direction(direction);
702   }
703 
704   if (is_sword_stars_visible()) {
705     sword_stars_sprite->set_current_direction(direction);
706   }
707 
708   if (is_shield_visible()) {
709     shield_sprite->set_current_direction(direction);
710   }
711 
712   if (is_trail_visible()) {
713     trail_sprite->set_current_direction(direction);
714   }
715 
716   if (lifted_item != nullptr) {
717     const SpritePtr& sprite = lifted_item->get_sprite();
718     if (sprite != nullptr) {
719       sprite->restart_animation();
720       if (direction < sprite->get_nb_directions()) {
721         sprite->set_current_direction(direction);
722       }
723     }
724     const SpritePtr& shadow_sprite = lifted_item->get_sprite("shadow");
725     if (shadow_sprite != nullptr && direction < shadow_sprite->get_nb_directions()) {
726       shadow_sprite->set_current_direction(direction);
727     }
728   }
729 }
730 
731 /**
732  * \brief Changes the direction of the hero's sprites.
733  *
734  * The direction specified is one of the 8 possible movement directions of the hero.
735  * The hero's sprites only have four directions, so when
736  * the specified direction is a diagonal one,
737  * one of the two closest main directions is picked.
738  *
739  * \param direction the movement direction (0 to 7)
740  */
set_animation_direction8(int direction)741 void HeroSprites::set_animation_direction8(int direction) {
742 
743   if (get_animation_direction() != animation_directions[direction][1]) {
744     set_animation_direction(animation_directions[direction][0]);
745   }
746 }
747 
748 /**
749  * \brief Returns whether the sprites animations are finished.
750  * \return true if the animation is finished
751  */
is_animation_finished() const752 bool HeroSprites::is_animation_finished() const {
753   return tunic_sprite->is_animation_finished();
754 }
755 
756 /**
757  * \brief Returns the current frame of the tunic sprite.
758  * \return the current frame
759  */
get_current_frame() const760 int HeroSprites::get_current_frame() const {
761   return tunic_sprite->get_current_frame();
762 }
763 
764 /**
765  * \brief Saves the current direction of the the sprite.
766  *
767  * Call restore_animation_direction() to restore the direction saved here.
768  */
save_animation_direction()769 void HeroSprites::save_animation_direction() {
770   this->animation_direction_saved = get_animation_direction();
771 }
772 
773 /**
774  * \brief Restores the direction of the hero's sprite saved by the last
775  * call to save_animation_direction().
776  */
restore_animation_direction()777 void HeroSprites::restore_animation_direction() {
778   set_animation_direction(animation_direction_saved);
779 }
780 
781 /**
782  * \brief Updates the animation of the hero's sprites if necessary.
783  */
update()784 void HeroSprites::update() {
785 
786   if (hero.is_shadow_visible()) {
787     if (!shadow_sprite->is_animation_started()) {
788       shadow_sprite->set_current_animation("big");
789     }
790     shadow_sprite->set_xy(hero.get_xy() - hero.get_displayed_xy());
791   } else {
792     if (shadow_sprite->is_animation_started()) {
793       shadow_sprite->stop_animation();
794     }
795   }
796 
797   if (ground_sprite != nullptr && !hero.is_ground_visible()) {
798     destroy_ground();
799   }
800 
801   hero.update_sprites();
802 
803   // Blinking.
804   if (is_blinking()
805       && end_blink_date != 0
806       && System::now() >= end_blink_date) {
807     stop_blinking();
808   }
809 
810   // Lua callback.
811   if (tunic_sprite->is_animation_finished() &&
812       !animation_callback_ref.is_empty()) {
813     animation_callback_ref.clear_and_call("hero animation callback");
814   }
815 }
816 
817 /**
818  * \brief Called after sprites of the hero were drawn on the camera.
819  * \param camera The camera where to draw.
820  */
draw_on_map()821 void HeroSprites::draw_on_map() {
822 
823   const CameraPtr& camera = hero.get_map().get_camera();
824   if (camera == nullptr) {
825     return;
826   }
827   hero.draw_sprites(*camera, clipping_rectangle);
828   if (lifted_item != nullptr) {
829     lifted_item->draw(*camera);
830   }
831 }
832 
833 /**
834  * \brief Suspends or resumes the animation of the hero's sprites.
835  *
836  * This function is called when the hero is suspended or resumed.
837  *
838  * \param suspended \c true to suspend the hero's sprites, \c false to resume them.
839  */
set_suspended(bool suspended)840 void HeroSprites::set_suspended(bool suspended) {
841 
842   hero.set_sprites_suspended(suspended);
843 
844   // Timer.
845   uint32_t now = System::now();
846   if (suspended) {
847     when_suspended = now;
848   }
849   else if (end_blink_date != 0) {
850     end_blink_date += now - when_suspended;
851   }
852 }
853 
854 /**
855  * \brief Called when the hero it is being created on a map and the map is ready.
856  */
notify_creating()857 void HeroSprites::notify_creating() {
858 
859   // Create sprites only now because some of them may be tileset dependent.
860   // Built-in order:
861   // Shadow, tunic, trail, ground, sword, sword stars, shield.
862   hero.set_default_sprite_name("tunic");
863   shadow_sprite = hero.create_sprite("entities/shadow", "shadow");
864   shadow_sprite->stop_animation();
865   set_tunic_sprite_id(get_default_tunic_sprite_id());
866   trail_sprite = hero.create_sprite("hero/trail", "trail");
867   trail_sprite->stop_animation();
868   create_ground(Ground::SHALLOW_WATER);
869   ground_sprite->stop_animation();
870   set_sword_sprite_id(get_default_sword_sprite_id());
871   sword_stars_sprite = hero.create_sprite("hero/sword_stars1", "sword_stars");
872   sword_stars_sprite->stop_animation();
873   set_shield_sprite_id(get_default_shield_sprite_id());
874 
875   rebuild_equipment();
876 }
877 
878 /**
879  * \brief Notifies the hero's sprites that the tileset has just changed.
880  */
notify_tileset_changed()881 void HeroSprites::notify_tileset_changed() {
882 
883   // Some sprites may be tileset dependent.
884   if (lifted_item != nullptr) {
885     lifted_item->notify_tileset_changed();
886   }
887 
888   if (is_ground_visible()) {
889     ground_sprite->set_tileset(hero.get_map().get_tileset());
890   }
891 }
892 
893 /**
894  * \brief Restarts the animation of the hero's sprites.
895  *
896  * This function is called when the sprites have to
897  * get back to their first frame.
898  */
restart_animation()899 void HeroSprites::restart_animation() {
900 
901   tunic_sprite->restart_animation();
902 
903   if (is_sword_visible()) {
904     sword_sprite->restart_animation();
905   }
906 
907   if (is_sword_stars_visible()) {
908     sword_stars_sprite->restart_animation();
909   }
910 
911   if (is_shield_visible()) {
912     shield_sprite->restart_animation();
913   }
914 
915   if (is_trail_visible()) {
916     trail_sprite->restart_animation();
917   }
918 
919   if (is_ground_visible()) {
920     ground_sprite->restart_animation();
921   }
922 }
923 
924 /**
925  * \brief Sets whether the hero's sprite should keep playing their animation
926  * when the game is suspended.
927  * \param ignore_suspend true to make the sprites continue their animation even
928  * when the game is suspended
929  */
set_ignore_suspend(bool ignore_suspend)930 void HeroSprites::set_ignore_suspend(bool ignore_suspend) {
931 
932   tunic_sprite->set_ignore_suspend(ignore_suspend);
933 
934   if (is_sword_visible()) {
935     sword_sprite->set_ignore_suspend(ignore_suspend);
936   }
937 
938   if (is_sword_stars_visible()) {
939     sword_stars_sprite->set_ignore_suspend(ignore_suspend);
940   }
941 
942   if (is_shield_visible()) {
943     shield_sprite->set_ignore_suspend(ignore_suspend);
944   }
945 
946   if (is_trail_visible()) {
947     trail_sprite->set_ignore_suspend(ignore_suspend);
948   }
949 
950   if (is_ground_visible()) {
951     ground_sprite->set_ignore_suspend(ignore_suspend);
952   }
953 }
954 
955 /**
956  * \brief This function is called when the sprites take a "stopped" animation.
957  *
958  * It makes instructions common to all states having a "stopped" animation.
959  * (e.g. free or carrying).
960  */
set_animation_stopped_common()961 void HeroSprites::set_animation_stopped_common() {
962 
963   if (is_ground_visible()
964       && hero.get_ground_below() != Ground::SHALLOW_WATER) {
965     ground_sprite->set_current_animation("stopped");
966   }
967   walking = false;
968 }
969 
970 /**
971  * \brief Starts the basic "stopped" animation of the hero's sprites.
972  */
set_animation_stopped_normal()973 void HeroSprites::set_animation_stopped_normal() {
974 
975   set_animation_stopped_common();
976 
977   if (equipment.has_ability(Ability::SHIELD)) {
978 
979     set_tunic_animation("stopped_with_shield");
980     if (shield_sprite != nullptr) {
981       shield_sprite->set_current_animation("stopped");
982       shield_sprite->set_current_direction(get_animation_direction());
983     }
984   }
985   else {
986     set_tunic_animation("stopped");
987   }
988   stop_displaying_sword();
989   stop_displaying_trail();
990 }
991 
992 /**
993  * \brief Starts the "stopped" animation of the hero's sprites with the sword loading.
994  */
set_animation_stopped_sword_loading()995 void HeroSprites::set_animation_stopped_sword_loading() {
996 
997   set_animation_stopped_common();
998 
999   int direction = get_animation_direction();
1000 
1001   set_tunic_animation("sword_loading_stopped");
1002   sword_sprite->set_current_animation("sword_loading_stopped");
1003   sword_sprite->set_current_direction(direction);
1004   sword_stars_sprite->set_current_animation("loading");
1005   sword_stars_sprite->set_current_direction(direction);
1006 
1007   if (equipment.has_ability(Ability::SHIELD) &&
1008       shield_sprite != nullptr) {
1009     shield_sprite->set_current_animation("sword_loading_stopped");
1010     shield_sprite->set_current_direction(direction);
1011   }
1012   stop_displaying_trail();
1013 }
1014 
1015 /**
1016  * \brief Starts the "stopped" animation with sprites that represent
1017  * the hero carrying something.
1018  *
1019  * If the hero actually carries an item, the carried object also takes a "stopped" animation.
1020  */
set_animation_stopped_carrying()1021 void HeroSprites::set_animation_stopped_carrying() {
1022 
1023   set_animation_stopped_common();
1024   set_tunic_animation("carrying_stopped");
1025 
1026   if (lifted_item != nullptr) {
1027     lifted_item->set_animation_stopped();
1028   }
1029   stop_displaying_trail();
1030 }
1031 
1032 /**
1033  * \brief Starts the "stopped" animation with sprites that represent
1034  * the hero swimming.
1035  */
set_animation_stopped_swimming()1036 void HeroSprites::set_animation_stopped_swimming() {
1037 
1038   set_animation_stopped_common();
1039   set_tunic_animation("swimming_stopped");
1040   stop_displaying_sword();
1041   stop_displaying_shield();
1042   stop_displaying_trail();
1043 }
1044 
1045 /**
1046  * \brief This function is called when the sprites take a "walking" animation.
1047  *
1048  * It makes instructions common to all states having a "walking" animation.
1049  * (e.g. free or carrying).
1050  */
set_animation_walking_common()1051 void HeroSprites::set_animation_walking_common() {
1052 
1053   if (is_ground_visible() && hero.get_ground_below() != Ground::SHALLOW_WATER) {
1054     ground_sprite->set_current_animation("walking");
1055   }
1056 
1057   walking = true;
1058 }
1059 
1060 /**
1061  * \brief Starts the normal "walking" animation of the hero's sprites.
1062  */
set_animation_walking_normal()1063 void HeroSprites::set_animation_walking_normal() {
1064 
1065   set_animation_walking_common();
1066 
1067   if (equipment.has_ability(Ability::SHIELD)) {
1068 
1069     set_tunic_animation("walking_with_shield");
1070 
1071     shield_sprite->set_current_animation("walking");
1072     shield_sprite->set_current_direction(get_animation_direction());
1073   }
1074   else {
1075     set_tunic_animation("walking");
1076   }
1077   stop_displaying_sword();
1078   stop_displaying_trail();
1079 }
1080 
1081 /**
1082  * \brief Starts the "walking" animation of the hero's sprites with the sword loading.
1083  */
set_animation_walking_sword_loading()1084 void HeroSprites::set_animation_walking_sword_loading() {
1085 
1086   set_animation_walking_common();
1087 
1088   int direction = get_animation_direction();
1089 
1090   set_tunic_animation("sword_loading_walking");
1091   if (equipment.has_ability(Ability::SWORD)) {
1092     sword_sprite->set_current_animation("sword_loading_walking");
1093     sword_sprite->set_current_direction(direction);
1094     sword_stars_sprite->set_current_animation("loading");
1095     sword_stars_sprite->set_current_direction(direction);
1096   }
1097 
1098   if (equipment.has_ability(Ability::SHIELD)) {
1099     shield_sprite->set_current_animation("sword_loading_walking");
1100     shield_sprite->set_current_direction(direction);
1101   }
1102   stop_displaying_trail();
1103 }
1104 
1105 /**
1106  * \brief Starts the "walking" animation with sprites that represent
1107  * the hero carrying something.
1108  *
1109  * If the hero actually carries an item, the carried object also takes a "walking" animation.
1110  */
set_animation_walking_carrying()1111 void HeroSprites::set_animation_walking_carrying() {
1112 
1113   set_animation_walking_common();
1114 
1115   set_tunic_animation("carrying_walking");
1116 
1117   if (lifted_item != nullptr) {
1118     lifted_item->set_animation_walking();
1119   }
1120   stop_displaying_shield();
1121   stop_displaying_trail();
1122 }
1123 
1124 /**
1125  * \brief Starts the "swimming_slow" animation of the sprites.
1126  */
set_animation_swimming_slow()1127 void HeroSprites::set_animation_swimming_slow() {
1128 
1129   set_animation_walking_common();
1130 
1131   set_tunic_animation("swimming_slow");
1132   stop_displaying_sword();
1133   stop_displaying_shield();
1134   stop_displaying_trail();
1135 }
1136 
1137 /**
1138  * \brief Starts the "swimming_fast" animation of the sprites.
1139  */
set_animation_swimming_fast()1140 void HeroSprites::set_animation_swimming_fast() {
1141 
1142   set_animation_walking_common();
1143 
1144   set_tunic_animation("swimming_fast");
1145   stop_displaying_sword();
1146   stop_displaying_shield();
1147   stop_displaying_trail();
1148 }
1149 
1150 /**
1151  * \brief Starts the "walking_diagonal" animation of the hero's sprites.
1152  * \param direction8 the diagonal direction to take (1, 3, 5 or 7)
1153  */
set_animation_walking_diagonal(int direction8)1154 void HeroSprites::set_animation_walking_diagonal(int direction8) {
1155 
1156   stop_displaying_sword();
1157   stop_displaying_shield();
1158   stop_displaying_trail();
1159   set_tunic_animation("walking_diagonal");
1160   tunic_sprite->set_current_direction(direction8 / 2);
1161 }
1162 
1163 /**
1164  * \brief Starts (or restarts) the "sword" animation of the hero's sprites.
1165  */
set_animation_sword()1166 void HeroSprites::set_animation_sword() {
1167 
1168   int direction = get_animation_direction();
1169 
1170   set_tunic_animation("sword");
1171   tunic_sprite->restart_animation();
1172 
1173   sword_sprite->set_current_animation("sword");
1174   sword_sprite->set_current_direction(direction);
1175   sword_sprite->restart_animation();
1176   sword_stars_sprite->stop_animation();
1177 
1178   if (equipment.has_ability(Ability::SHIELD)) {
1179 
1180     shield_sprite->set_current_animation("sword");
1181     if (shield_sprite->get_nb_directions() == 2) {
1182       // Legacy behavior: only two directions (right is 0 and left is 1).
1183       if (direction % 2 != 0) {
1184         shield_sprite->set_current_direction(direction / 2);
1185         shield_sprite->restart_animation();
1186       }
1187       else {
1188         stop_displaying_shield();
1189       }
1190     }
1191     else {
1192       shield_sprite->set_current_direction(direction);
1193       shield_sprite->restart_animation();
1194     }
1195   }
1196 
1197   stop_displaying_trail();
1198 }
1199 
1200 /**
1201  * \brief Plays the sound corresponding to the current sword.
1202  */
play_sword_sound()1203 void HeroSprites::play_sword_sound() {
1204   Sound::play(sword_sound_id);
1205 }
1206 
1207 /**
1208  * \brief Starts (or restarts) the "sword tapping" animation of the hero's sprites.
1209  */
set_animation_sword_tapping()1210 void HeroSprites::set_animation_sword_tapping() {
1211 
1212   int direction = get_animation_direction();
1213 
1214   set_tunic_animation("sword_tapping");
1215   tunic_sprite->restart_animation();
1216 
1217   sword_sprite->set_current_animation("sword_tapping");
1218   sword_sprite->set_current_direction(direction);
1219   sword_sprite->restart_animation();
1220   sword_stars_sprite->stop_animation();
1221 
1222   if (equipment.has_ability(Ability::SHIELD)) {
1223 
1224     shield_sprite->set_current_animation("sword_tapping");
1225     shield_sprite->set_current_direction(direction);
1226     shield_sprite->restart_animation();
1227   }
1228   stop_displaying_trail();
1229 }
1230 
1231 /**
1232  * \brief Starts (or restarts) the "spin_attack" animation of the hero's sprites.
1233  */
set_animation_spin_attack()1234 void HeroSprites::set_animation_spin_attack() {
1235 
1236   set_tunic_animation("spin_attack");
1237   sword_sprite->set_current_animation("spin_attack");
1238   stop_displaying_sword_stars();
1239   stop_displaying_shield();
1240   stop_displaying_trail();
1241 }
1242 
1243 /**
1244  * \brief Starts (or restarts) the "super_spin_attack" animation of the hero's sprites.
1245  */
set_animation_super_spin_attack()1246 void HeroSprites::set_animation_super_spin_attack() {
1247 
1248   set_tunic_animation("super_spin_attack");
1249   sword_sprite->set_current_animation("super_spin_attack");
1250   stop_displaying_sword_stars();
1251   stop_displaying_shield();
1252   stop_displaying_trail();
1253 }
1254 
1255 /**
1256  * \brief Starts the "grabbing" animation of the hero's sprites.
1257  */
set_animation_grabbing()1258 void HeroSprites::set_animation_grabbing() {
1259 
1260   set_tunic_animation("grabbing");
1261   stop_displaying_shield();
1262   stop_displaying_trail();
1263 }
1264 
1265 /**
1266  * \brief Starts the "pulling" animation of the hero's sprites.
1267  */
set_animation_pulling()1268 void HeroSprites::set_animation_pulling() {
1269 
1270   set_tunic_animation("pulling");
1271   stop_displaying_shield();
1272   stop_displaying_trail();
1273 }
1274 
1275 /**
1276  * \brief Starts the "pushing" animation of the hero's sprites.
1277  */
set_animation_pushing()1278 void HeroSprites::set_animation_pushing() {
1279 
1280   set_tunic_animation("pushing");
1281   stop_displaying_shield();
1282   stop_displaying_trail();
1283 }
1284 
1285 /**
1286  * \brief Starts the "lifting" animation of the hero's sprites.
1287  */
set_animation_lifting()1288 void HeroSprites::set_animation_lifting() {
1289 
1290   set_tunic_animation("lifting");
1291   stop_displaying_shield();
1292   stop_displaying_trail();
1293 }
1294 
1295 /**
1296  * \brief Starts the "jumping" animation of the hero's sprites.
1297  */
set_animation_jumping()1298 void HeroSprites::set_animation_jumping() {
1299 
1300   set_tunic_animation("jumping");
1301 
1302   if (equipment.has_ability(Ability::SHIELD)) {
1303     shield_sprite->set_current_animation("stopped");
1304     shield_sprite->set_current_direction(get_animation_direction());
1305   }
1306   stop_displaying_sword();
1307   stop_displaying_trail();
1308 }
1309 
1310 /**
1311  * \brief Starts the "hurt" animation of the hero's sprites.
1312  */
set_animation_hurt()1313 void HeroSprites::set_animation_hurt() {
1314 
1315   set_tunic_animation("hurt");
1316   stop_displaying_sword();
1317   stop_displaying_shield();
1318   stop_displaying_trail();
1319 }
1320 
1321 /**
1322  * \brief Starts the "falling" animation of the hero's sprites.
1323  */
set_animation_falling()1324 void HeroSprites::set_animation_falling() {
1325 
1326   // show the animation
1327   set_tunic_animation("falling");
1328   stop_displaying_sword();
1329   stop_displaying_shield();
1330   stop_displaying_trail();
1331 }
1332 
1333 /**
1334  * \brief Starts the "brandish" animation of the hero's sprites.
1335  */
set_animation_brandish()1336 void HeroSprites::set_animation_brandish() {
1337 
1338   set_tunic_animation("brandish");
1339   tunic_sprite->set_current_direction(1);
1340   stop_displaying_sword();
1341   stop_displaying_shield();
1342   stop_displaying_trail();
1343 }
1344 
1345 /**
1346  * \brief Starts the "victory" animation of the hero's sprites.
1347  */
set_animation_victory()1348 void HeroSprites::set_animation_victory() {
1349 
1350   set_tunic_animation("victory");
1351   tunic_sprite->set_current_direction(1);
1352   if (sword_sprite != nullptr) {
1353     sword_sprite->set_current_animation("victory");
1354     sword_sprite->set_current_direction(1);
1355   }
1356   stop_displaying_sword_stars();
1357   stop_displaying_shield();
1358   stop_displaying_trail();
1359 }
1360 
1361 /**
1362  * \brief Starts the "prepare running" animation of the hero's sprites.
1363  */
set_animation_prepare_running()1364 void HeroSprites::set_animation_prepare_running() {
1365 
1366   set_animation_walking_normal();
1367   trail_sprite->set_current_animation("running");
1368   if (tunic_sprite->get_current_direction() < trail_sprite->get_nb_directions()) {
1369     trail_sprite->set_current_direction(tunic_sprite->get_current_direction());
1370   }
1371 }
1372 
1373 /**
1374  * \brief Starts the "running" animation of the hero's sprites.
1375  */
set_animation_running()1376 void HeroSprites::set_animation_running() {
1377 
1378   set_animation_walking_sword_loading();
1379   stop_displaying_sword_stars();
1380   trail_sprite->set_current_animation("running");
1381   if (tunic_sprite->get_current_direction() < trail_sprite->get_nb_directions()) {
1382     trail_sprite->set_current_direction(tunic_sprite->get_current_direction());
1383   }
1384 }
1385 
1386 /**
1387  * \brief Starts the "boomerang" animation of the hero's sprites.
1388  * \param tunic_preparing_animation Animation name of the hero's tunic sprite
1389  * when preparing the boomerang.
1390  */
set_animation_boomerang(const std::string & tunic_preparing_animation)1391 void HeroSprites::set_animation_boomerang(
1392     const std::string& tunic_preparing_animation) {
1393 
1394   set_tunic_animation(tunic_preparing_animation);
1395 
1396   if (shield_sprite != nullptr
1397       && shield_sprite->has_animation("boomerang")) {
1398     shield_sprite->set_current_animation("boomerang");
1399   }
1400   else {
1401     stop_displaying_shield();
1402   }
1403   stop_displaying_sword();
1404   stop_displaying_trail();
1405 }
1406 
1407 /**
1408  * \brief Returns whether the specified animation exists in the tunic sprite.
1409  * \param animation Name of the animation to check.
1410  * \return \c true if the tunic sprite has an animation with this name.
1411  */
has_tunic_animation(const std::string & animation) const1412 bool HeroSprites::has_tunic_animation(const std::string& animation) const {
1413 
1414   return tunic_sprite->has_animation(animation);
1415 }
1416 
1417 /**
1418  * \brief Returns the current animation of the tunic sprite.
1419  * \return The animation name of the tunic sprite.
1420  */
get_tunic_animation() const1421 const std::string& HeroSprites::get_tunic_animation() const {
1422 
1423   return tunic_sprite->get_current_animation();
1424 }
1425 
1426 /**
1427  * \brief Changes the animation of the tunic sprite.
1428  *
1429  * Cancels the Lua callback if any.
1430  *
1431  * \param animation The animation name of the tunic sprite.
1432  */
set_tunic_animation(const std::string & animation)1433 void HeroSprites::set_tunic_animation(const std::string& animation) {
1434 
1435   set_tunic_animation(animation, ScopedLuaRef());
1436 }
1437 
1438 
1439 /**
1440  * \brief Changes the animation of the tunic sprite.
1441  *
1442  * Cancels the Lua callback if any.
1443  *
1444  * \param animation The animation name of the tunic sprite.
1445  * \param callback_ref Lua ref of a function to call when the animation ends
1446  * or an empty ref.
1447  */
set_tunic_animation(const std::string & animation,const ScopedLuaRef & callback_ref)1448 void HeroSprites::set_tunic_animation(
1449     const std::string& animation,
1450     const ScopedLuaRef& callback_ref
1451 ) {
1452 
1453   this->animation_callback_ref = callback_ref;
1454 
1455   if (tunic_sprite != nullptr) {
1456     tunic_sprite->set_current_animation(animation);
1457   }
1458 }
1459 
1460 /**
1461  * \brief Starts a custom animation of the hero's sprites.
1462  *
1463  * All sprites of the hero that have an animation with this name take the
1464  * animation. The ones that don't have such an animation are not displayed.
1465  * Many simple animations can be started with this function.
1466  * More complex one have dedicated functions.
1467  *
1468  * \param animation Name of the animation to give to the hero's sprites.
1469  */
set_animation(const std::string & animation)1470 void HeroSprites::set_animation(const std::string& animation) {
1471 
1472   set_animation(animation, ScopedLuaRef());
1473 }
1474 
1475 /**
1476  * \brief Starts a custom animation of the hero's sprites.
1477  *
1478  * All sprites of the hero that have an animation with this name take the
1479  * animation. The ones that don't have such an animation are not displayed.
1480  * Many simple animations can be started with this function.
1481  * More complex one have dedicated functions.
1482  *
1483  * \param animation Name of the animation to give to the hero's sprites.
1484  * \param callback_ref Lua ref of a function to call when the animation ends
1485  * or an empty ref.
1486  */
set_animation(const std::string & animation,const ScopedLuaRef & callback_ref)1487 void HeroSprites::set_animation(
1488     const std::string& animation,
1489     const ScopedLuaRef& callback_ref
1490 ) {
1491 
1492   if (tunic_sprite->has_animation(animation)) {
1493     set_tunic_animation(animation, callback_ref);
1494   }
1495   else {
1496     Debug::error("Sprite '" + tunic_sprite->get_animation_set_id() + "': Animation '" + animation + "' not found.");
1497   }
1498 
1499   if (shield_sprite != nullptr
1500       && shield_sprite->has_animation(animation)) {
1501     shield_sprite->set_current_animation(animation);
1502   }
1503   else {
1504     stop_displaying_shield();
1505   }
1506 
1507   if (sword_sprite != nullptr
1508       && sword_sprite->has_animation(animation)) {
1509     sword_sprite->set_current_animation(animation);
1510   }
1511   else {
1512     stop_displaying_sword();
1513   }
1514 
1515   if (sword_stars_sprite != nullptr
1516       && sword_stars_sprite->has_animation(animation)) {
1517     sword_stars_sprite->set_current_animation(animation);
1518   }
1519   else {
1520     stop_displaying_sword_stars();
1521   }
1522 
1523   if (trail_sprite != nullptr
1524       && trail_sprite->has_animation(animation)) {
1525     trail_sprite->set_current_animation(animation);
1526   }
1527   else {
1528     stop_displaying_trail();
1529   }
1530 }
1531 
1532 /**
1533  * \brief Creates the ground sprite and sound corresponding to the specified
1534  * ground.
1535  * \param ground A ground.
1536  */
create_ground(Ground ground)1537 void HeroSprites::create_ground(Ground ground) {
1538 
1539   int order = -1;
1540   if (ground_sprite != nullptr) {
1541     order = hero.get_sprite_order(*ground_sprite);
1542     hero.remove_sprite(*ground_sprite);
1543   }
1544   ground_sprite = nullptr;
1545 
1546   std::string sprite_id;
1547   if (ground == Ground::GRASS) {
1548     sprite_id = "hero/ground1";
1549     ground_sound_id = "walk_on_grass";
1550   }
1551   else if (ground == Ground::SHALLOW_WATER) {
1552     sprite_id = "hero/ground2";
1553     ground_sound_id = "walk_on_water";
1554   }
1555 
1556   ground_sprite = hero.create_sprite(sprite_id, "ground", order);
1557   ground_sprite->set_tileset(hero.get_map().get_tileset());
1558   if (ground != Ground::SHALLOW_WATER) {
1559     ground_sprite->set_current_animation(walking ? "walking" : "stopped");
1560   }
1561 }
1562 
1563 /**
1564  * \brief Deletes the ground sprite.
1565  */
destroy_ground()1566 void HeroSprites::destroy_ground() {
1567 
1568   if (ground_sprite != nullptr) {
1569     hero.remove_sprite(*ground_sprite);
1570     ground_sprite = nullptr;
1571   }
1572 }
1573 
1574 /**
1575  * \brief Plays a sound for the ground displayed under the hero.
1576  */
play_ground_sound()1577 void HeroSprites::play_ground_sound() {
1578   Sound::play(ground_sound_id);
1579 }
1580 
1581 /**
1582  * \brief Indicates a lifted item to display with the hero's sprites.
1583  *
1584  * Calling this function makes this class display the lifted item and
1585  * give it the appropriate animation, so that you don't have to make it yourself.
1586  * However, this class only handles displaying:
1587  * you still have to update it and make it follow the hero.
1588  *
1589  * \param lifted_item the item to display, or nullptr to stop displaying a lifted item
1590  */
set_lifted_item(const std::shared_ptr<CarriedObject> & lifted_item)1591 void HeroSprites::set_lifted_item(
1592     const std::shared_ptr<CarriedObject>& lifted_item
1593 ) {
1594   this->lifted_item = lifted_item;
1595 }
1596 
1597 }
1598 
1599