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/core/Debug.h"
19 #include "solarus/core/Equipment.h"
20 #include "solarus/core/Game.h"
21 #include "solarus/core/Geometry.h"
22 #include "solarus/core/Map.h"
23 #include "solarus/core/QuestFiles.h"
24 #include "solarus/core/Random.h"
25 #include "solarus/core/Savegame.h"
26 #include "solarus/core/System.h"
27 #include "solarus/entities/Block.h"
28 #include "solarus/entities/CarriedObject.h"
29 #include "solarus/entities/CrystalBlock.h"
30 #include "solarus/entities/Destructible.h"
31 #include "solarus/entities/Enemy.h"
32 #include "solarus/entities/Entities.h"
33 #include "solarus/entities/Fire.h"
34 #include "solarus/entities/Hero.h"
35 #include "solarus/entities/Pickable.h"
36 #include "solarus/entities/Stream.h"
37 #include "solarus/graphics/Sprite.h"
38 #include "solarus/graphics/SpriteAnimationSet.h"
39 #include "solarus/lua/LuaContext.h"
40 #include "solarus/movements/FallingHeight.h"
41 #include "solarus/movements/StraightMovement.h"
42 #include <memory>
43
44 namespace Solarus {
45
46 const std::map<EnemyAttack, std::string> Enemy::attack_names = {
47 { EnemyAttack::SWORD, "sword" },
48 { EnemyAttack::THROWN_ITEM, "thrown_item" },
49 { EnemyAttack::EXPLOSION, "explosion" },
50 { EnemyAttack::ARROW, "arrow" },
51 { EnemyAttack::HOOKSHOT, "hookshot" },
52 { EnemyAttack::BOOMERANG, "boomerang" },
53 { EnemyAttack::FIRE, "fire" },
54 { EnemyAttack::SCRIPT, "script" }
55 };
56
57 const std::map<Enemy::HurtStyle, std::string> Enemy::hurt_style_names = {
58 { HurtStyle::NORMAL, "normal" },
59 { HurtStyle::MONSTER, "monster" },
60 { HurtStyle::BOSS, "boss" }
61 };
62
63 const std::map<Enemy::ObstacleBehavior, std::string> Enemy::obstacle_behavior_names = {
64 { ObstacleBehavior::NORMAL, "normal" },
65 { ObstacleBehavior::FLYING, "flying" },
66 { ObstacleBehavior::SWIMMING, "swimming" }
67 };
68
69 /**
70 * \brief Creates an enemy.
71 * \param game The game.
72 * \param name Name identifying the enemy or an empty string.
73 * \param layer The layer on the map.
74 * \param xy Coordinates on the map.
75 * \param breed Breed of the enemy.
76 * \param treasure Treasure dropped when the enemy is killed.
77 */
Enemy(Game &,const std::string & name,int layer,const Point & xy,const std::string & breed,const Treasure & treasure)78 Enemy::Enemy(
79 Game& /* game */,
80 const std::string& name,
81 int layer,
82 const Point& xy,
83 const std::string& breed,
84 const Treasure& treasure
85 ):
86 Entity(name, 0, layer, xy, Size(0, 0)),
87 breed(breed),
88 damage_on_hero(1),
89 life(1),
90 hurt_style(HurtStyle::NORMAL),
91 dying_sprite_id("enemies/enemy_killed"),
92 pushed_back_when_hurt(true),
93 push_hero_on_sword(false),
94 can_hurt_hero_running(false),
95 minimum_shield_needed(0),
96 savegame_variable(),
97 traversable(true),
98 attacking_collision_mode(CollisionMode::COLLISION_SPRITE),
99 obstacle_behavior(ObstacleBehavior::NORMAL),
100 being_hurt(false),
101 stop_hurt_date(0),
102 invulnerable(false),
103 vulnerable_again_date(0),
104 can_attack(true),
105 can_attack_again_date(0),
106 immobilized(false),
107 start_shaking_date(0),
108 end_shaking_date(0),
109 dying_animation_started(false),
110 treasure(treasure),
111 exploding(false),
112 nb_explosions(0),
113 next_explosion_date(0) {
114
115 set_collision_modes(
116 CollisionMode::COLLISION_OVERLAPPING | // Also for some entities like the boomerang.
117 CollisionMode::COLLISION_SPRITE // For collisions with the hero by default.
118 );
119 set_size(16, 16);
120 set_origin(8, 13);
121 set_drawn_in_y_order(true);
122 }
123
124 /**
125 * \brief Creates an enemy.
126 *
127 * This method acts like a constructor, and usually returns an enemy.
128 * However, if the enemy is already dead and cannot be killed again,
129 * this function returns:
130 * - nullptr if the enemy has no treasure (or its treasure was already picked)
131 * - or a pickable treasure if the enemy has one
132 *
133 * \param game the current game
134 * \param breed breed of the enemy to create
135 * \param name a name identifying the enemy
136 * \param savegame_variable name of the boolean variable indicating that the enemy is dead
137 * \param layer layer of the enemy on the map
138 * \param xy Coordinates of the enemy on the map.
139 * \param direction initial direction of the enemy on the map (0 to 3)
140 * \param treasure the pickable item that the enemy drops
141 * \return the enemy created (may also be a Pickable or nullptr)
142 */
create(Game & game,const std::string & breed,const std::string & savegame_variable,const std::string & name,int layer,const Point & xy,int direction,const Treasure & treasure)143 EntityPtr Enemy::create(
144 Game& game,
145 const std::string& breed,
146 const std::string& savegame_variable,
147 const std::string& name,
148 int layer,
149 const Point& xy,
150 int direction,
151 const Treasure& treasure
152 ) {
153 // see if the enemy is dead
154 if (!savegame_variable.empty()
155 && game.get_savegame().get_boolean(savegame_variable)) {
156
157 // the enemy is dead: create its pickable treasure (if any) instead
158 if (treasure.is_saved() && !game.get_savegame().get_boolean(treasure.get_savegame_variable())) {
159 return Pickable::create(game, "", layer, xy, treasure, FALLING_NONE, true);
160 }
161 return nullptr;
162 }
163
164 // create the enemy
165 std::shared_ptr<Enemy> enemy = std::make_shared<Enemy>(
166 game, name, layer, xy, breed, treasure
167 );
168
169 // initialize the fields
170 enemy->set_direction(direction);
171 enemy->savegame_variable = savegame_variable;
172 enemy->set_default_attack_consequences();
173
174 return enemy;
175 }
176
177 /**
178 * \brief Returns the type of entity.
179 * \return the type of entity
180 */
get_type() const181 EntityType Enemy::get_type() const {
182 return ThisType;
183 }
184
185 /**
186 * \brief Returns whether this entity is sensible to the ground below it.
187 * \return \c true if this entity is sensible to its ground.
188 */
is_ground_observer() const189 bool Enemy::is_ground_observer() const {
190 return true; // To make enemies fall into holes, water, etc.
191 }
192
193 /**
194 * \copydoc Entity::notify_creating
195 */
notify_creating()196 void Enemy::notify_creating() {
197
198 get_lua_context()->run_enemy(*this);
199 }
200
201 /**
202 * \copydoc Entity::notify_created
203 */
notify_created()204 void Enemy::notify_created() {
205
206 Entity::notify_created();
207
208 // At this point, enemy:on_created() was called.
209 enable_pixel_collisions();
210
211 // Give sprites their initial direction.
212 int initial_direction = get_direction();
213 for (const SpritePtr& sprite: get_sprites()) {
214 sprite->set_current_direction(initial_direction);
215 }
216
217 if (is_enabled()) {
218 restart();
219 }
220 }
221
222 /**
223 * \brief Returns the breed of this enemy.
224 * \return The breed.
225 */
get_breed() const226 const std::string& Enemy::get_breed() const {
227 return breed;
228 }
229
230 /**
231 * \brief Returns whether the state of this enemy is saved.
232 * \return true if this enemy is saved.
233 */
is_saved() const234 bool Enemy::is_saved() const {
235 return !savegame_variable.empty();
236 }
237
238 /**
239 * \brief Returns whether this entity is an obstacle for another one.
240 * \param other Another entity.
241 * \return \c true if this entity is an obstacle for the other one.
242 */
is_obstacle_for(Entity & other)243 bool Enemy::is_obstacle_for(Entity& other) {
244
245 if (!is_enabled()) {
246 return false;
247 }
248
249 return !is_traversable() || other.is_enemy_obstacle(*this);
250 }
251
252 /**
253 * \brief Returns whether a low wall is currently considered as an obstacle
254 * by this entity.
255 * \return \c true if low walls are currently obstacle for this entity.
256 */
is_low_wall_obstacle() const257 bool Enemy::is_low_wall_obstacle() const {
258
259 // Flying enemies can traverse low walls.
260 return obstacle_behavior != ObstacleBehavior::FLYING;
261 }
262
263 /**
264 * \brief Returns whether a destructible item is currently considered as an obstacle for this entity.
265 * \param destructible a destructible item
266 * \return true if the destructible item is currently an obstacle this entity
267 */
is_destructible_obstacle(Destructible & destructible)268 bool Enemy::is_destructible_obstacle(Destructible& destructible) {
269
270 // The destructible object is an obstacle unless the enemy is already
271 // overlapping it, which is possible with destructibles that can regenerate.
272 if (this->overlaps(destructible)) {
273 return false;
274 }
275 return obstacle_behavior != ObstacleBehavior::FLYING;
276 }
277
278 /**
279 * \copydoc Entity::is_block_obstacle
280 */
is_block_obstacle(Block & block)281 bool Enemy::is_block_obstacle(Block& block) {
282
283 // The block is an obstacle unless the enemy is already overlapping it,
284 // which is easily possible with blocks created by the hero.
285 if (this->overlaps(block)) {
286 return false;
287 }
288 return true;
289 }
290
291 /**
292 * \brief Returns whether a teletransporter is currently considered as an obstacle.
293 * \param teletransporter a teletransporter
294 * \return true if the teletransporter is currently an obstacle for this entity
295 */
is_teletransporter_obstacle(Teletransporter &)296 bool Enemy::is_teletransporter_obstacle(Teletransporter& /* teletransporter */) {
297 return false;
298 }
299
300 /**
301 * \brief Returns whether a raised crystal block is currently considered as an
302 * obstacle by this entity.
303 * \param raised_block A crystal block raised.
304 * \return \c true if the raised block is currently an obstacle for this entity.
305 */
is_raised_block_obstacle(CrystalBlock & raised_block)306 bool Enemy::is_raised_block_obstacle(CrystalBlock& raised_block) {
307
308 // The crystal block is an obstacle unless the enemy is already on it.
309 if (this->overlaps(raised_block)) {
310 return false;
311 }
312
313 return true;
314 }
315
316 /**
317 * \copydoc Entity::is_stream_obstacle
318 */
is_stream_obstacle(Stream & stream)319 bool Enemy::is_stream_obstacle(Stream& stream) {
320
321 // Enemies can move on non-blocking streams only.
322 if (!stream.get_allow_movement()) {
323 return true;
324 }
325
326 return false;
327 }
328
329 /**
330 * \brief Returns whether a deep water tile is currently considered as an obstacle by this entity.
331 * \return true if the deep water tiles are currently an obstacle for this entity
332 */
is_deep_water_obstacle() const333 bool Enemy::is_deep_water_obstacle() const {
334
335 if (obstacle_behavior == ObstacleBehavior::FLYING
336 || obstacle_behavior == ObstacleBehavior::SWIMMING) {
337 return false;
338 }
339
340 if (is_being_hurt()) {
341 return false;
342 }
343
344 const int layer = get_layer();
345 const int x = get_top_left_x();
346 const int y = get_top_left_y();
347 if (get_map().get_ground(layer, x, y, this) == Ground::DEEP_WATER
348 || get_map().get_ground(layer, x + get_width() - 1, y, this) == Ground::DEEP_WATER
349 || get_map().get_ground(layer, x, y + get_height() - 1, this) == Ground::DEEP_WATER
350 || get_map().get_ground(layer, x + get_width() - 1, y + get_height() - 1, this) == Ground::DEEP_WATER) {
351 return false;
352 }
353
354 return true;
355 }
356
357 /**
358 * \brief Returns whether a shallow water tile is currently considered as an obstacle by this entity.
359 * \return true if the shallow water tiles are currently an obstacle for this entity
360 */
is_shallow_water_obstacle() const361 bool Enemy::is_shallow_water_obstacle() const {
362 return false;
363 }
364
365 /**
366 * \brief Returns whether a hole is currently considered as an obstacle by this entity.
367 * \return true if the holes are currently an obstacle for this entity
368 */
is_hole_obstacle() const369 bool Enemy::is_hole_obstacle() const {
370
371 if (obstacle_behavior == ObstacleBehavior::FLYING) {
372 return false;
373 }
374
375 if (is_being_hurt()) {
376 return false;
377 }
378
379 const int layer = get_layer();
380 const int x = get_top_left_x();
381 const int y = get_top_left_y();
382 if (get_map().get_ground(layer, x, y, this) == Ground::HOLE
383 || get_map().get_ground(layer, x + get_width() - 1, y, this) == Ground::HOLE
384 || get_map().get_ground(layer, x, y + get_height() - 1, this) == Ground::HOLE
385 || get_map().get_ground(layer, x + get_width() - 1, y + get_height() - 1, this) == Ground::HOLE) {
386 return false;
387 }
388
389 return true;
390 }
391
392 /**
393 * \brief Returns whether prickles are currently considered as obstacle by this entity.
394 * \return true if prickles are currently obstacle for this entity
395 */
is_prickle_obstacle() const396 bool Enemy::is_prickle_obstacle() const {
397 return false;
398 }
399
400 /**
401 * \brief Returns whether lava is currently considered as obstacle by this entity.
402 * \return true if lava is currently obstacle for this entity
403 */
is_lava_obstacle() const404 bool Enemy::is_lava_obstacle() const {
405
406 if (obstacle_behavior == ObstacleBehavior::FLYING) {
407 return false;
408 }
409
410 if (is_being_hurt()) {
411 return false;
412 }
413
414 const int layer = get_layer();
415 const int x = get_top_left_x();
416 const int y = get_top_left_y();
417 if (get_map().get_ground(layer, x, y, this) == Ground::LAVA
418 || get_map().get_ground(layer, x + get_width() - 1, y, this) == Ground::LAVA
419 || get_map().get_ground(layer, x, y + get_height() - 1, this) == Ground::LAVA
420 || get_map().get_ground(layer, x + get_width() - 1, y + get_height() - 1, this) == Ground::LAVA) {
421 return false;
422 }
423
424 return true;
425 }
426
427 /**
428 * \brief Returns the amount of damage this kind of enemy can make to the hero.
429 * \return Number of life points the player loses.
430 */
get_damage() const431 int Enemy::get_damage() const {
432 return damage_on_hero;
433 }
434
435 /**
436 * \brief Sets the amount of damage this kind of enemy can make to the hero.
437 * \param damage_on_hero Number of life points the player loses.
438 */
set_damage(int damage_on_hero)439 void Enemy::set_damage(int damage_on_hero) {
440 this->damage_on_hero = damage_on_hero;
441 }
442
443 /**
444 * \brief Returns the number of health points of the enemy.
445 * \return number of health points of the enemy
446 */
get_life() const447 int Enemy::get_life() const {
448 return life;
449 }
450
451 /**
452 * \brief Sets the number of health points of the enemy.
453 * \param life number of health points of the enemy
454 */
set_life(int life)455 void Enemy::set_life(int life) {
456
457 this->life = life;
458 if (!being_hurt && this->life <= 0) {
459 get_lua_context()->enemy_on_dying(*this);
460 kill();
461 }
462 }
463
464 /**
465 * \brief Returns the style of sounds and animations when this enemy is hurt.
466 * \return The style when hurt.
467 */
get_hurt_style() const468 Enemy::HurtStyle Enemy::get_hurt_style() const {
469 return hurt_style;
470 }
471
472 /**
473 * \brief Sets the style of sounds and animations when this enemy is hurt.
474 * \param hurt_style The style when hurt.
475 */
set_hurt_style(HurtStyle hurt_style)476 void Enemy::set_hurt_style(HurtStyle hurt_style) {
477 this->hurt_style = hurt_style;
478 }
479
480 /**
481 * \brief Returns the id of the sprite to show during the normal dying animation.
482 * \return The dying sprite id or an empty string.
483 */
get_dying_sprite_id() const484 std::string Enemy::get_dying_sprite_id() const {
485 return dying_sprite_id;
486 }
487
488 /**
489 * \brief Sets the id of the sprite to show during the normal dying animation.
490 * \param dying_sprite_id The dying sprite id or an empty string.
491 */
set_dying_sprite_id(const std::string & dying_sprite_id)492 void Enemy::set_dying_sprite_id(const std::string& dying_sprite_id) {
493 this->dying_sprite_id = dying_sprite_id;
494 }
495
496 /**
497 * \brief Returns whether this enemy can currently attack the hero.
498 * \return true if this enemy can currently attack the hero
499 */
get_can_attack() const500 bool Enemy::get_can_attack() const {
501 return can_attack;
502 }
503
504 /**
505 * \brief Sets whether this enemy can attack the hero.
506 * \param can_attack true to allow this enemy to attack the hero
507 */
set_can_attack(bool can_attack)508 void Enemy::set_can_attack(bool can_attack) {
509
510 this->can_attack = can_attack;
511 if (!can_attack) {
512 can_attack_again_date = 0;
513 }
514 }
515
516 /**
517 * \brief Returns the current behavior with obstacles for this enemy.
518 * \return the behavior with obstacles
519 */
get_obstacle_behavior() const520 Enemy::ObstacleBehavior Enemy::get_obstacle_behavior() const {
521 return obstacle_behavior;
522 }
523
524 /**
525 * \brief Sets the behavior with obstacles for this enemy.
526 * \param obstacle_behavior the behavior with obstacles
527 */
set_obstacle_behavior(ObstacleBehavior obstacle_behavior)528 void Enemy::set_obstacle_behavior(ObstacleBehavior obstacle_behavior) {
529 this->obstacle_behavior = obstacle_behavior;
530 }
531
532 /**
533 * \brief Returns whether this enemy is traversable by other entities.
534 *
535 * If the enemy is not traversable, is_obstacle_for() will always return
536 * \c false.
537 * If the enemy is traversable, is_obstacle_for() will call
538 * is_enemy_obstacle() on the entity to test.
539 *
540 * \return \c true if this enemy is traversable.
541 */
is_traversable() const542 bool Enemy::is_traversable() const {
543 return traversable;
544 }
545
546 /**
547 * \brief Sets whether this enemy is traversable by other entities.
548 *
549 * If the enemy is not traversable, is_obstacle_for() will always return
550 * \c false.
551 * If the enemy is traversable, is_obstacle_for() will call
552 * is_enemy_obstacle() on the entity to test.
553 *
554 * \param traversable \c true to make this enemy traversable.
555 */
set_traversable(bool traversable)556 void Enemy::set_traversable(bool traversable) {
557 this->traversable = traversable;
558 }
559
560 /**
561 * \brief Sets the collision test used to detect when attacking the hero.
562 * \return The attacking collision mode.
563 */
get_attacking_collision_mode() const564 CollisionMode Enemy::get_attacking_collision_mode() const {
565 return attacking_collision_mode;
566 }
567
568 /**
569 * \brief Returns the collision test used to detect when attacking the hero.
570 * \param attacking_collision_mode The attacking collision mode.
571 */
set_attacking_collision_mode(CollisionMode attacking_collision_mode)572 void Enemy::set_attacking_collision_mode(CollisionMode attacking_collision_mode) {
573 this->attacking_collision_mode = attacking_collision_mode;
574 set_collision_modes(
575 CollisionMode::COLLISION_OVERLAPPING |
576 CollisionMode::COLLISION_SPRITE |
577 attacking_collision_mode);
578 }
579
580 /**
581 * \brief Returns whether the enemy is pushed back when it gets hurt by the hero.
582 * \return \c true if the enemy is pushed back when it gets hurt.
583 */
get_pushed_back_when_hurt() const584 bool Enemy::get_pushed_back_when_hurt() const {
585 return pushed_back_when_hurt;
586 }
587
588 /**
589 * \brief Sets whether the enemy is pushed back when it gets hurt by the hero.
590 * \param pushed_back_when_hurt true to make the enemy pushed back when it gets hurt.
591 */
set_pushed_back_when_hurt(bool pushed_back_when_hurt)592 void Enemy::set_pushed_back_when_hurt(bool pushed_back_when_hurt) {
593 this->pushed_back_when_hurt = pushed_back_when_hurt;
594 }
595
596 /**
597 * \brief Returns whether the hero is pushed when he strikes the enemy with his sword.
598 * \return true if the hero is pushed away when he strkes the enemy with his sword
599 */
get_push_hero_on_sword() const600 bool Enemy::get_push_hero_on_sword() const {
601 return push_hero_on_sword;
602 }
603
604 /**
605 * \brief Sets whether the hero is pushed when he hurts the enemy with his sword.
606 * \param push_hero_on_sword true to make the hero pushed back when he hurts the enemy with his sword
607 */
set_push_hero_on_sword(bool push_hero_on_sword)608 void Enemy::set_push_hero_on_sword(bool push_hero_on_sword) {
609 this->push_hero_on_sword = push_hero_on_sword;
610 }
611
612 /**
613 * \brief Returns whether this enemy can hurt the hero even if the hero is running.
614 * \return true if this enemy can attack the hero while he is running
615 */
get_can_hurt_hero_running() const616 bool Enemy::get_can_hurt_hero_running() const {
617 return can_hurt_hero_running;
618 }
619
620 /**
621 * \brief Sets whether this enemy can hurt the hero even if the hero is running.
622 * \param can_hurt_hero_running true to allow this enemy to attack the hero while he is running
623 */
set_can_hurt_hero_running(bool can_hurt_hero_running)624 void Enemy::set_can_hurt_hero_running(bool can_hurt_hero_running) {
625 this->can_hurt_hero_running = can_hurt_hero_running;
626 }
627
628 /**
629 * \brief Returns the shield level required to avoid attacks of this enemy.
630 * \return The minimum shield needed (\c 0 means unavoidable attacks).
631 */
get_minimum_shield_needed() const632 int Enemy::get_minimum_shield_needed() const {
633 return minimum_shield_needed;
634 }
635
636 /**
637 * \brief Sets the shield level required to avoid attacks of this enemy.
638 * \param minimum_shield_needed The minimum shield needed (\c 0 means unavoidable attacks).
639 */
set_minimum_shield_needed(int minimum_shield_needed)640 void Enemy::set_minimum_shield_needed(int minimum_shield_needed) {
641 this->minimum_shield_needed = minimum_shield_needed;
642 }
643
644 /**
645 * \brief Returns the reaction corresponding to an attack on a sprite of this enemy.
646 * \param attack an attack this enemy receives
647 * \param this_sprite the sprite attacked, or nullptr if the attack does not come from
648 * a pixel-precise collision test
649 * \return the corresponding reaction
650 */
get_attack_consequence(EnemyAttack attack,const Sprite * this_sprite) const651 EnemyReaction::Reaction Enemy::get_attack_consequence(
652 EnemyAttack attack,
653 const Sprite* this_sprite) const {
654
655 const auto& it = attack_reactions.find(attack);
656 if (it == attack_reactions.end()) {
657 // Attack consequence was not initialized. Return a default value.
658 return EnemyReaction::Reaction();
659 }
660 return it->second.get_reaction(this_sprite);
661 }
662
663 /**
664 * \brief Sets how the enemy reacts to an attack.
665 *
666 * This reaction will be used unless the attack is received by a sprite
667 * that has a specific reaction (see set_attack_consequence_sprite()).
668 *
669 * \param attack an attack
670 * \param reaction how the enemy will react
671 * \param life_lost number of life points lost with this attack (possibly zero)
672 */
set_attack_consequence(EnemyAttack attack,EnemyReaction::ReactionType reaction,int life_lost,const ScopedLuaRef & callback)673 void Enemy::set_attack_consequence(
674 EnemyAttack attack,
675 EnemyReaction::ReactionType reaction,
676 int life_lost,
677 const ScopedLuaRef& callback) {
678
679 attack_reactions[attack].set_general_reaction(reaction, life_lost, callback);
680 }
681
682 /**
683 * \brief Sets how the enemy reacts to an attack on a particular sprite.
684 * \param sprite a sprite of this enemy
685 * \param attack an attack
686 * \param reaction how the enemy will react
687 * \param life_lost number of life points lost with this attack (possibly zero)
688 */
set_attack_consequence_sprite(const Sprite & sprite,EnemyAttack attack,EnemyReaction::ReactionType reaction,int life_lost,const ScopedLuaRef & callback)689 void Enemy::set_attack_consequence_sprite(
690 const Sprite& sprite,
691 EnemyAttack attack,
692 EnemyReaction::ReactionType reaction,
693 int life_lost,
694 const ScopedLuaRef& callback) {
695
696 attack_reactions[attack].set_sprite_reaction(&sprite, reaction, life_lost, callback);
697 }
698
699 /**
700 * \brief Sets the enemy insensible to all attacks.
701 */
set_no_attack_consequences()702 void Enemy::set_no_attack_consequences() {
703
704 for (const auto& kvp : attack_names) {
705 set_attack_consequence(kvp.first, EnemyReaction::ReactionType::IGNORED);
706 }
707 }
708
709 /**
710 * \brief Sets a particular sprite of the enemy insensible to all attacks.
711 * \param sprite a sprite of this enemy
712 */
set_no_attack_consequences_sprite(const Sprite & sprite)713 void Enemy::set_no_attack_consequences_sprite(const Sprite& sprite) {
714
715 for (const auto& kvp : attack_names) {
716 EnemyAttack attack = kvp.first;
717 set_attack_consequence_sprite(sprite, attack, EnemyReaction::ReactionType::IGNORED);
718 }
719 }
720
721 /**
722 * \brief Sets some default values for the reactions of the attacks.
723 */
set_default_attack_consequences()724 void Enemy::set_default_attack_consequences() {
725
726 for (const auto& kvp : attack_names) {
727 EnemyAttack attack = kvp.first;
728 attack_reactions[attack].set_default_reaction();
729 }
730 set_attack_consequence(EnemyAttack::SWORD, EnemyReaction::ReactionType::HURT, 1); // multiplied by the sword strength
731 set_attack_consequence(EnemyAttack::THROWN_ITEM, EnemyReaction::ReactionType::HURT, 1); // multiplied depending on the item
732 set_attack_consequence(EnemyAttack::EXPLOSION, EnemyReaction::ReactionType::HURT, 2);
733 set_attack_consequence(EnemyAttack::ARROW, EnemyReaction::ReactionType::HURT, 2);
734 set_attack_consequence(EnemyAttack::HOOKSHOT, EnemyReaction::ReactionType::IMMOBILIZED);
735 set_attack_consequence(EnemyAttack::BOOMERANG, EnemyReaction::ReactionType::IMMOBILIZED);
736 set_attack_consequence(EnemyAttack::FIRE, EnemyReaction::ReactionType::HURT, 3);
737 }
738
739 /**
740 * \brief Set some default values for the reactions of the attacks
741 * on a particular sprite of this enemy.
742 * \param sprite a sprite of this enemy
743 */
set_default_attack_consequences_sprite(const Sprite & sprite)744 void Enemy::set_default_attack_consequences_sprite(const Sprite& sprite) {
745
746 for (const auto& kvp : attack_names) {
747 EnemyAttack attack = kvp.first;
748 set_attack_consequence_sprite(sprite, attack, EnemyReaction::ReactionType::HURT, 1);
749 }
750 set_attack_consequence_sprite(sprite, EnemyAttack::EXPLOSION, EnemyReaction::ReactionType::HURT, 2);
751 set_attack_consequence_sprite(sprite, EnemyAttack::HOOKSHOT, EnemyReaction::ReactionType::IMMOBILIZED);
752 set_attack_consequence_sprite(sprite, EnemyAttack::BOOMERANG, EnemyReaction::ReactionType::IMMOBILIZED);
753 }
754
755 /**
756 * \brief Returns the current animation of the first sprite of the enemy.
757 *
758 * This function is useful when the enemy has several sprites.
759 *
760 * \return name of the current animation of the first sprite
761 */
get_animation() const762 std::string Enemy::get_animation() const {
763
764 const SpritePtr& sprite = get_sprite();
765 if (sprite == nullptr) {
766 return "";
767 }
768
769 return sprite->get_current_animation();
770 }
771
772 /**
773 * \brief Changes the animation of this enemy's sprites.
774 *
775 * This function is useful when the enemy has several sprites.
776 *
777 * \param animation name of the animation to set
778 */
set_animation(const std::string & animation)779 void Enemy::set_animation(const std::string& animation) {
780
781 for (const SpritePtr& sprite: get_sprites()) {
782 sprite->set_current_animation(animation);
783 }
784 }
785
786 /**
787 * \brief Updates the enemy.
788 */
update()789 void Enemy::update() {
790
791 Entity::update();
792
793 if (is_suspended() || !is_enabled()) {
794 return;
795 }
796
797 uint32_t now = System::now();
798
799 if (being_hurt) {
800
801 // see if we should stop the animation "hurt"
802 if (now >= stop_hurt_date) {
803 being_hurt = false;
804 set_movement_notifications_enabled(true);
805
806 if (life <= 0) {
807 kill();
808 }
809 else if (is_immobilized()) {
810 clear_movement();
811 set_animation("immobilized");
812 notify_immobilized();
813 }
814 else {
815 clear_movement();
816 restart();
817 }
818 }
819 }
820
821 if (life > 0 && invulnerable && now >= vulnerable_again_date && !being_hurt) {
822 invulnerable = false;
823 }
824
825 if (life > 0 && !can_attack && !is_immobilized()
826 && can_attack_again_date != 0 && now >= can_attack_again_date) {
827 can_attack = true;
828 }
829
830 if (is_immobilized() &&
831 !is_killed() &&
832 now >= end_shaking_date &&
833 get_animation() == "shaking"
834 ) {
835 restart();
836 }
837
838 if (is_immobilized() &&
839 !is_killed() &&
840 !is_being_hurt() &&
841 now >= start_shaking_date &&
842 !get_animation().empty() &&
843 get_animation() != "shaking"
844 ) {
845
846 end_shaking_date = now + 2000;
847 set_animation("shaking");
848 }
849
850 if (exploding) {
851 uint32_t now = System::now();
852 if (now >= next_explosion_date) {
853
854 // create an explosion
855 Point xy;
856 xy.x = get_top_left_x() + Random::get_number(get_width());
857 xy.y = get_top_left_y() + Random::get_number(get_height());
858 get_entities().add_entity(std::make_shared<Explosion>(
859 "", get_map().get_max_layer(), xy, false
860 ));
861 Sound::play("explosion");
862
863 next_explosion_date = now + 200;
864 nb_explosions++;
865
866 if (nb_explosions >= 15) {
867 exploding = false;
868 }
869 }
870 }
871
872 if (is_killed() && is_dying_animation_finished()) {
873
874 // Create the pickable treasure if any.
875 get_entities().add_entity(Pickable::create(
876 get_game(),
877 "",
878 get_layer(),
879 get_xy(),
880 treasure,
881 FALLING_HIGH,
882 false
883 ));
884
885 // Remove the enemy.
886 remove_from_map();
887
888 // Notify Lua that this enemy is dead.
889 // We need to do this after remove_from_map() so that this enemy is
890 // considered dead in functions like map:has_entities(prefix).
891 notify_dead();
892 }
893
894 get_lua_context()->entity_on_update(*this);
895 }
896
897 /**
898 * \brief Suspends or resumes the entity.
899 * \param suspended true to suspend the entity, false to resume it
900 */
set_suspended(bool suspended)901 void Enemy::set_suspended(bool suspended) {
902
903 Entity::set_suspended(suspended);
904
905 if (!suspended) {
906 uint32_t diff = System::now() - get_when_suspended();
907 stop_hurt_date += diff;
908 vulnerable_again_date += diff;
909 if (can_attack_again_date != 0) {
910 can_attack_again_date += diff;
911 }
912 start_shaking_date += diff;
913 end_shaking_date += diff;
914 next_explosion_date += diff;
915 }
916 }
917
918 /**
919 * \copydoc Entity::notify_enabled
920 */
notify_enabled(bool enabled)921 void Enemy::notify_enabled(bool enabled) {
922
923 Entity::notify_enabled(enabled);
924
925 if (!is_on_map()) {
926 return;
927 }
928
929 if (enabled) {
930 restart();
931 }
932 }
933
934 /**
935 * \copydoc Entity::notify_ground_below_changed
936 */
notify_ground_below_changed()937 void Enemy::notify_ground_below_changed() {
938
939 Entity::notify_ground_below_changed();
940
941 // React to bad ground.
942
943 if (!is_initialized()) {
944 // Still initializing the enemy.
945 // Maybe the obstacle behavior is not even set yet.
946 return;
947 }
948
949 if (is_suspended()) {
950 return;
951 }
952
953 if (get_obstacle_behavior() != ObstacleBehavior::NORMAL
954 || get_life() <= 0) {
955 return;
956 }
957
958 Ground ground = get_ground_below();
959 switch (ground) {
960
961 case Ground::HOLE:
962 case Ground::LAVA:
963 case Ground::DEEP_WATER:
964 // Kill the enemy.
965 set_life(0);
966 break;
967
968 default:
969 break;
970 }
971 }
972
973 /**
974 * \copydoc Entity::notify_collision(Entity&, CollisionMode)
975 */
notify_collision(Entity & entity_overlapping,CollisionMode collision_mode)976 void Enemy::notify_collision(Entity& entity_overlapping, CollisionMode collision_mode) {
977
978 entity_overlapping.notify_collision_with_enemy(*this, collision_mode);
979 }
980
981 /**
982 * \copydoc Entity::notify_collision(Entity&, Sprite&, Sprite&)
983 */
notify_collision(Entity & other_entity,Sprite & this_sprite,Sprite & other_sprite)984 void Enemy::notify_collision(Entity& other_entity, Sprite& this_sprite, Sprite& other_sprite) {
985
986 other_entity.notify_collision_with_enemy(*this, other_sprite, this_sprite);
987 }
988
989 /**
990 * \brief This function is called when an explosion's sprite detects a collision
991 * with a sprite of this enemy.
992 * \param explosion the explosion
993 * \param sprite_overlapping the sprite of this enemy that collides with the explosion
994 */
notify_collision_with_explosion(Explosion & explosion,Sprite & sprite_overlapping)995 void Enemy::notify_collision_with_explosion(Explosion& explosion, Sprite& sprite_overlapping) {
996
997 explosion.try_attack_enemy(*this, sprite_overlapping);
998 }
999
1000 /**
1001 * \brief Notifies this entity that a sprite of fire
1002 * detects a pixel-precise collision with a sprite of this entity.
1003 * \param fire the fire
1004 * \param sprite_overlapping the sprite of the current entity that collides with the fire
1005 */
notify_collision_with_fire(Fire & fire,Sprite & sprite_overlapping)1006 void Enemy::notify_collision_with_fire(Fire& fire, Sprite& sprite_overlapping) {
1007
1008 try_hurt(EnemyAttack::FIRE, fire, &sprite_overlapping);
1009 }
1010
1011 /**
1012 * \copydoc Entity::notify_collision_with_enemy(Enemy&, Sprite&, Sprite&)
1013 */
notify_collision_with_enemy(Enemy & other,Sprite & this_sprite,Sprite & other_sprite)1014 void Enemy::notify_collision_with_enemy(Enemy& other,
1015 Sprite& this_sprite, Sprite& other_sprite) {
1016
1017 if (is_in_normal_state()) {
1018 get_lua_context()->enemy_on_collision_enemy(
1019 *this, other, other_sprite, this_sprite);
1020 }
1021 }
1022
1023 /**
1024 * \brief Attacks the hero if possible.
1025 *
1026 * This function is called when there is a collision between the enemy and the hero.
1027 *
1028 * \param hero The hero to attack.
1029 * \param this_sprite The sprite of this enemy that detected the collision with the hero,
1030 * or nullptr if it was not a pixel-precise collision.
1031 */
attack_hero(Hero & hero,Sprite * this_sprite)1032 void Enemy::attack_hero(Hero& hero, Sprite* this_sprite) {
1033
1034 if (!is_immobilized()
1035 && can_attack
1036 && hero.can_be_hurt(this)) {
1037
1038 bool hero_protected = false;
1039 if (minimum_shield_needed != 0
1040 && get_equipment().has_ability(Ability::SHIELD, minimum_shield_needed)
1041 && hero.can_use_shield()) {
1042
1043 // Compute the direction corresponding to the angle between the enemy and the hero.
1044 double angle = hero.get_angle(*this, nullptr, this_sprite);
1045 int protected_direction4 = (int) ((angle + Geometry::PI_OVER_2 / 2.0) * 4 / Geometry::TWO_PI);
1046 protected_direction4 = (protected_direction4 + 4) % 4;
1047
1048 // Also get the direction of the enemy's sprite.
1049 int sprite_opposite_direction4 = -1;
1050 if (this_sprite != nullptr) {
1051 sprite_opposite_direction4 = (this_sprite->get_current_direction() + 2) % 4;
1052 }
1053
1054 // The hero is protected if he is facing the opposite of one of these directions.
1055 hero_protected = hero.is_facing_direction4(protected_direction4) ||
1056 hero.is_facing_direction4(sprite_opposite_direction4);
1057 }
1058
1059 if (hero_protected) {
1060 attack_stopped_by_hero_shield();
1061 }
1062 else {
1063 // Let the enemy script handle this if it wants.
1064 const bool handled = get_lua_context()->enemy_on_attacking_hero(
1065 *this, hero, this_sprite
1066 );
1067 if (!handled) {
1068 // Scripts did not customize the attack:
1069 // do the built-in hurt state of the hero.
1070 hero.hurt(*this, this_sprite, damage_on_hero);
1071 }
1072 }
1073 }
1074 }
1075
1076 /**
1077 * \brief This function is called when the hero stops an attack with his shield.
1078 *
1079 * By default, the shield sound is played and the enemy cannot attack again for a while.
1080 */
attack_stopped_by_hero_shield()1081 void Enemy::attack_stopped_by_hero_shield() {
1082
1083 Sound::play("shield");
1084
1085 uint32_t now = System::now();
1086 can_attack = false;
1087 can_attack_again_date = now + 1000;
1088
1089 get_equipment().notify_ability_used(Ability::SHIELD);
1090 }
1091
1092 /**
1093 * \brief Plays the appropriate sound when the enemy is hurt.
1094 */
play_hurt_sound()1095 void Enemy::play_hurt_sound() {
1096
1097 std::string sound_id = "";
1098 switch (hurt_style) {
1099
1100 case HurtStyle::NORMAL:
1101 sound_id = "enemy_hurt";
1102 break;
1103
1104 case HurtStyle::MONSTER:
1105 sound_id = "monster_hurt";
1106 break;
1107
1108 case HurtStyle::BOSS:
1109 sound_id = (life > 0) ? "boss_hurt" : "boss_killed";
1110 break;
1111
1112 }
1113
1114 Sound::play(sound_id);
1115 }
1116
1117 /**
1118 * \brief Notifies this enemy that it should restart his movement.
1119 *
1120 * This function is called when the enemy needs to restart its movement
1121 * because something happened (for example the enemy has just been created,
1122 * or it was just hurt).
1123 * By default, the "walking" animation is set on the enemy's sprites.
1124 *
1125 * Nothing happens if the enemy is dying.
1126 */
restart()1127 void Enemy::restart() {
1128
1129 if (is_dying()) {
1130 return;
1131 }
1132
1133 if (is_immobilized()) {
1134 stop_immobilized();
1135 }
1136 set_animation("walking");
1137 get_lua_context()->enemy_on_restarted(*this);
1138 }
1139
1140 /**
1141 * \brief Returns whether this enemy is in a normal state.
1142 *
1143 * The enemy is considered to be in its normal state if
1144 * it is not disabled, dying, being hurt or immobilized.
1145 * When this method returns false, scripts
1146 * cannot hurt or immobilized the enemy.
1147 *
1148 * \return true if this enemy is in a normal state
1149 */
is_in_normal_state() const1150 bool Enemy::is_in_normal_state() const {
1151 return is_enabled()
1152 && !is_being_hurt()
1153 && get_life() > 0
1154 && !is_immobilized()
1155 && !is_being_removed();
1156 }
1157
1158 /**
1159 * \brief Returns whether this enemy is currently invulnerable.
1160 * \return \c true if this enemy cannot be hurt for now.
1161 */
is_invulnerable() const1162 bool Enemy::is_invulnerable() const {
1163 return invulnerable;
1164 }
1165
1166 /**
1167 * \brief Makes the enemy receive an attack.
1168 *
1169 * He might resist to the attack or get hurt.
1170 *
1171 * \param attack type of attack
1172 * \param source the entity attacking the enemy (often the hero)
1173 * \param this_sprite the sprite of this enemy that received the attack, or nullptr
1174 * if the attack comes from a non pixel-precise collision test
1175 */
try_hurt(EnemyAttack attack,Entity & source,Sprite * this_sprite)1176 void Enemy::try_hurt(EnemyAttack attack, Entity& source, Sprite* this_sprite) {
1177
1178 EnemyReaction::Reaction reaction = get_attack_consequence(attack, this_sprite);
1179 if (invulnerable || reaction.type == EnemyReaction::ReactionType::IGNORED) {
1180 // ignore the attack
1181 return;
1182 }
1183
1184 if (reaction.type != EnemyReaction::ReactionType::LUA_CALLBACK) {
1185 // Make the enemy invulnerable for a while except if the reaction
1186 // is a callback, in which case the user decides what to do.
1187 // Ideally, ReactionType::CUSTOM should not make the enemy invulnerable
1188 // either, but we don't want to break the behavior of existing scripts.
1189 invulnerable = true;
1190 vulnerable_again_date = System::now() + 500;
1191 }
1192
1193 switch (reaction.type) {
1194
1195 case EnemyReaction::ReactionType::PROTECTED:
1196 // attack failure sound
1197 Sound::play("sword_tapping");
1198 break;
1199
1200 case EnemyReaction::ReactionType::IMMOBILIZED:
1201 // get immobilized
1202 being_hurt = true;
1203 hurt(source, this_sprite);
1204 immobilize();
1205 break;
1206
1207 case EnemyReaction::ReactionType::CUSTOM:
1208 // Lua event enemy:on_custom_attack_received.
1209 if (is_in_normal_state()) {
1210 custom_attack(attack, this_sprite);
1211 }
1212 else {
1213 // no attack was made: notify the source correctly
1214 reaction.type = EnemyReaction::ReactionType::IGNORED;
1215 invulnerable = false;
1216 }
1217 break;
1218
1219 case EnemyReaction::ReactionType::LUA_CALLBACK:
1220 // Lua callback.
1221 if (is_in_normal_state()) {
1222 reaction.callback.call("Enemy reaction callback");
1223 }
1224 else {
1225 // no attack was made: notify the source correctly
1226 reaction.type = EnemyReaction::ReactionType::IGNORED;
1227 invulnerable = false;
1228 }
1229 break;
1230
1231 case EnemyReaction::ReactionType::HURT:
1232
1233 if (is_immobilized() && get_animation() == "shaking") {
1234 stop_immobilized();
1235 }
1236
1237 // Compute the number of health points lost by the enemy.
1238
1239 being_hurt = true;
1240 if (attack == EnemyAttack::SWORD) {
1241
1242 Hero& hero = static_cast<Hero&>(source);
1243
1244 // Sword attacks only use pixel-precise collisions.
1245 Debug::check_assertion(this_sprite != nullptr,
1246 "Missing enemy sprite for sword attack"
1247 );
1248
1249 // For a sword attack, the damage may be something customized.
1250 bool customized = get_lua_context()->enemy_on_hurt_by_sword(
1251 *this, hero, *this_sprite);
1252
1253 if (customized) {
1254 reaction.life_lost = 0; // Already done by the script.
1255 }
1256 else {
1257 // If this is not customized, the default it to multiply the reaction
1258 // by a factor that depends on the sword.
1259 reaction.life_lost *= hero.get_sword_damage_factor();
1260 }
1261 }
1262 else if (attack == EnemyAttack::THROWN_ITEM) {
1263 reaction.life_lost *= static_cast<CarriedObject&>(source).get_damage_on_enemies();
1264 }
1265 life -= reaction.life_lost;
1266
1267 hurt(source, this_sprite);
1268 notify_hurt(source, attack);
1269 break;
1270
1271 case EnemyReaction::ReactionType::IGNORED:
1272 return;
1273 }
1274
1275 // notify the source
1276 source.notify_attacked_enemy(
1277 attack,
1278 *this,
1279 this_sprite,
1280 reaction,
1281 get_life() <= 0
1282 );
1283 }
1284
1285 /**
1286 * \brief Hurts the enemy.
1287 *
1288 * Updates its state, its sprite and plays the sound.
1289 *
1290 * \param source The entity attacking the enemy (often the hero).
1291 * \param this_sprite The sprite of this enemy that received the attack, or nullptr
1292 * if the attack comes from a non pixel-precise collision test.
1293 */
hurt(Entity & source,Sprite * this_sprite)1294 void Enemy::hurt(Entity& source, Sprite* this_sprite) {
1295
1296 uint32_t now = System::now();
1297
1298 // update the enemy state
1299 set_movement_notifications_enabled(false);
1300
1301 can_attack = false;
1302 can_attack_again_date = now + 300;
1303
1304 // graphics and sounds
1305 set_animation("hurt");
1306 play_hurt_sound();
1307
1308 // stop any movement
1309 clear_movement();
1310
1311 // push the enemy back
1312 if (pushed_back_when_hurt) {
1313 double angle = source.get_angle(*this, nullptr, this_sprite);
1314 std::shared_ptr<StraightMovement> movement =
1315 std::make_shared<StraightMovement>(false, true);
1316 movement->set_max_distance(24);
1317 movement->set_speed(120);
1318 movement->set_angle(angle);
1319 set_movement(movement);
1320 }
1321
1322 stop_hurt_date = now + 300;
1323 }
1324
1325 /**
1326 * \brief This function is called when the enemy has just been hurt.
1327 * \param source The source of the attack.
1328 * \param attack The attack that was just successful.
1329 */
notify_hurt(Entity &,EnemyAttack attack)1330 void Enemy::notify_hurt(Entity& /* source */, EnemyAttack attack) {
1331
1332 get_lua_context()->enemy_on_hurt(*this, attack);
1333 if (get_life() <= 0) {
1334 get_lua_context()->enemy_on_dying(*this);
1335 }
1336 }
1337
1338 /**
1339 * \brief This function is called when the enemy has just finished dying.
1340 */
notify_dead()1341 void Enemy::notify_dead() {
1342
1343 get_lua_context()->enemy_on_dead(*this);
1344 }
1345
1346 /**
1347 * \brief This function is called when the enemy is immobilized,
1348 * after the hurt animation.
1349 */
notify_immobilized()1350 void Enemy::notify_immobilized() {
1351
1352 get_lua_context()->enemy_on_immobilized(*this);
1353 }
1354
1355 /**
1356 * \brief Kills the enemy.
1357 *
1358 * This function is called when the enemy has no more health points.
1359 */
kill()1360 void Enemy::kill() {
1361
1362 // stop any movement and disable attacks
1363 set_collision_modes(COLLISION_NONE);
1364 clear_movement();
1365 invulnerable = true;
1366 can_attack = false;
1367 can_attack_again_date = 0;
1368 dying_animation_started = true;
1369
1370 if (hurt_style == HurtStyle::BOSS) {
1371 // A boss: create some explosions.
1372 exploding = true;
1373 nb_explosions = 0;
1374 next_explosion_date = System::now() + 2000;
1375 }
1376 else {
1377 // Replace the enemy sprites.
1378 clear_sprites();
1379 bool special_ground = false;
1380 switch (get_ground_below()) {
1381
1382 case Ground::HOLE:
1383 if (get_obstacle_behavior() != ObstacleBehavior::FLYING) {
1384 // TODO animation of falling into a hole.
1385 special_ground = true;
1386 Sound::play("jump");
1387 clear_treasure();
1388 }
1389 break;
1390
1391 case Ground::DEEP_WATER:
1392 if (get_obstacle_behavior() != ObstacleBehavior::FLYING &&
1393 get_obstacle_behavior() != ObstacleBehavior::SWIMMING) {
1394 // TODO water animation.
1395 special_ground = true;
1396 Sound::play("splash");
1397 clear_treasure();
1398 }
1399 break;
1400
1401 case Ground::LAVA:
1402 if (get_obstacle_behavior() != ObstacleBehavior::FLYING &&
1403 get_obstacle_behavior() != ObstacleBehavior::SWIMMING) {
1404 // TODO lava animation.
1405 special_ground = true;
1406 Sound::play("splash");
1407 clear_treasure();
1408 }
1409 break;
1410
1411 default:
1412 break;
1413 }
1414
1415 if (!special_ground) {
1416 // Normal dying animation.
1417 if (!dying_sprite_id.empty()) {
1418 if (!QuestFiles::data_file_exists("sprites/" + dying_sprite_id + ".dat")) {
1419 Debug::error("No such sprite for enemy dying animation: '" + dying_sprite_id + "'");
1420 }
1421 create_sprite(dying_sprite_id);
1422 }
1423 Sound::play("enemy_killed");
1424 }
1425 }
1426
1427 // save the enemy state if required
1428 if (is_saved()) {
1429 get_savegame().set_boolean(savegame_variable, true);
1430 }
1431 }
1432
1433 /**
1434 * \brief Returns whether the enemy is being hurt.
1435 * \return true if the enemy is being hurt
1436 */
is_being_hurt() const1437 bool Enemy::is_being_hurt() const {
1438 return being_hurt;
1439 }
1440
1441 /**
1442 * \brief Returns whether the enemy is killed.
1443 *
1444 * An enemy is considered as killed if he has no more life and its dying
1445 * animation has started.
1446 *
1447 * \return true if the enemy is killed
1448 */
is_killed() const1449 bool Enemy::is_killed() const {
1450 return life <= 0 && dying_animation_started;
1451 }
1452
1453 /**
1454 * \brief When the enemy is killed, returns whether the dying animation is finished.
1455 * \return true if the dying animation is finished
1456 */
is_dying_animation_finished() const1457 bool Enemy::is_dying_animation_finished() const {
1458
1459 if (!is_dying()) {
1460 // The enemy is still alive.
1461 return false;
1462 }
1463
1464 if (nb_explosions > 0) {
1465 // The dying animation is some explosions.
1466 return !exploding;
1467 }
1468
1469 const SpritePtr& sprite = get_sprite();
1470 if (sprite != nullptr) {
1471 // The dying animation is the usual "enemy_killed" sprite.
1472 return sprite->is_animation_finished();
1473 }
1474
1475 // There is no dying animation (case of bad ground or empty dying sprite id).
1476 return true;
1477 }
1478
1479 /**
1480 * \brief Returns whether the enemy is dying, i.e. his life has reached zero and the dying animation is playing.
1481 * \return true if the enemy is dying
1482 */
is_dying() const1483 bool Enemy::is_dying() const {
1484
1485 return get_life() <= 0;
1486 }
1487
1488 /**
1489 * \brief Returns the treasure dropped by this enemy.
1490 * \return The treasure.
1491 */
get_treasure() const1492 const Treasure& Enemy::get_treasure() const {
1493 return treasure;
1494 }
1495
1496 /**
1497 * \brief Sets the treasure dropped by this enemy.
1498 * \param treasure The treasure to set.
1499 */
set_treasure(const Treasure & treasure)1500 void Enemy::set_treasure(const Treasure& treasure) {
1501 this->treasure = treasure;
1502 }
1503
1504 /**
1505 * \brief Sets the treasure dropped by this enemy to nothing.
1506 */
clear_treasure()1507 void Enemy::clear_treasure() {
1508 this->treasure = Treasure(get_game(), "", 1, "");
1509 }
1510
1511 /**
1512 * \brief Returns true if the current sprite animation is finished or is looping.
1513 * \return true if the current sprite animation is finished or is looping
1514 */
is_sprite_finished_or_looping() const1515 bool Enemy::is_sprite_finished_or_looping() const {
1516
1517 const SpritePtr& sprite = get_sprite();
1518 if (sprite == nullptr) {
1519 return true;
1520 }
1521
1522 return sprite->is_animation_finished() || sprite->is_animation_looping();
1523 }
1524
1525 /**
1526 * \brief Immobilizes this enemy.
1527 */
immobilize()1528 void Enemy::immobilize() {
1529
1530 immobilized = true;
1531 start_shaking_date = System::now() + 5000;
1532 }
1533
1534 /**
1535 * \brief Stops immobilizing the enemy.
1536 */
stop_immobilized()1537 void Enemy::stop_immobilized() {
1538
1539 immobilized = false;
1540 end_shaking_date = 0;
1541 }
1542
1543 /**
1544 * \brief Returns whether this enemy is immobilized.
1545 * \return true if this enemy is immobilized
1546 */
is_immobilized() const1547 bool Enemy::is_immobilized() const {
1548
1549 return immobilized;
1550 }
1551
1552 /**
1553 * \brief This function is called when the enemy is attacked by a custom effect attack.
1554 * \param attack the attack
1555 * \param this_sprite the sprite of this enemy subject to the attack, or nullptr
1556 * if the attack does not come from a pixel-precise collision test
1557 */
custom_attack(EnemyAttack attack,Sprite * this_sprite)1558 void Enemy::custom_attack(EnemyAttack attack, Sprite* this_sprite) {
1559
1560 get_lua_context()->enemy_on_custom_attack_received(*this, attack, this_sprite);
1561 }
1562
1563 }
1564
1565