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