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/MainLoop.h"
23 #include "solarus/core/Map.h"
24 #include "solarus/core/System.h"
25 #include "solarus/entities/CollisionMode.h"
26 #include "solarus/entities/Destructible.h"
27 #include "solarus/entities/Door.h"
28 #include "solarus/entities/Entities.h"
29 #include "solarus/entities/Entity.h"
30 #include "solarus/entities/EntityState.h"
31 #include "solarus/entities/Hero.h"
32 #include "solarus/entities/Npc.h"
33 #include "solarus/entities/Separator.h"
34 #include "solarus/entities/SeparatorPtr.h"
35 #include "solarus/entities/StreamAction.h"
36 #include "solarus/entities/Switch.h"
37 #include "solarus/entities/Tileset.h"
38 #include "solarus/graphics/Sprite.h"
39 #include "solarus/graphics/SpriteAnimationSet.h"
40 #include "solarus/lua/LuaContext.h"
41 #include "solarus/lua/LuaTools.h"
42 #include "solarus/movements/Movement.h"
43 #include <algorithm>
44 #include <iterator>
45 #include <list>
46 #include <utility>
47
48 namespace Solarus {
49
50 /**
51 * \brief Creates an entity, specifying its position, its name and its direction.
52 * \param name Name identifying the entity on the map or an empty string.
53 * \param direction Direction of the entity.
54 * \param layer Layer of the entity.
55 * \param xy Coordinates where to create the entity.
56 * \param size Size of the entity.
57 */
Entity(const std::string & name,int direction,int layer,const Point & xy,const Size & size)58 Entity::Entity(
59 const std::string& name,
60 int direction,
61 int layer,
62 const Point& xy,
63 const Size& size
64 ):
65 main_loop(nullptr),
66 map(nullptr),
67 layer(layer),
68 z(0),
69 bounding_box(xy, size),
70 ground_below(Ground::EMPTY),
71 origin(0, 0),
72 name(name),
73 direction(direction),
74 user_properties(),
75 sprites(),
76 default_sprite_name(),
77 visible(true),
78 tiled(false),
79 drawn_in_y_order(false),
80 draw_override(),
81 movement(nullptr),
82 movement_notifications_enabled(true),
83 facing_entity(nullptr),
84 collision_modes(CollisionMode::COLLISION_NONE),
85 layer_independent_collisions(false),
86 weight(-1),
87 stream_action(nullptr),
88 initialized(false),
89 being_removed(false),
90 enabled(true),
91 suspended(false),
92 when_suspended(0),
93 optimization_distance(default_optimization_distance),
94 optimization_distance2(default_optimization_distance * default_optimization_distance) {
95
96 Debug::check_assertion(size.width >= 0 && size.height >= 0,
97 "Invalid entity size: width and height must be positive");
98 }
99
100 /**
101 * \brief Destructor.
102 *
103 * The sprite and the movement of the entity are deleted (if any).
104 */
~Entity()105 Entity::~Entity() {
106
107 stop_stream_action();
108
109 clear_sprites();
110 clear_old_sprites();
111 clear_movement();
112 clear_old_movements();
113 }
114
115 /**
116 * \brief Returns the name identifying this type in Lua.
117 *
118 * This is the internal name of the metatable for the entity.
119 *
120 * \return The name identifying this type in Lua.
121 */
get_lua_type_name() const122 const std::string& Entity::get_lua_type_name() const {
123 return LuaContext::get_entity_internal_type_name(get_type());
124 }
125
126 /**
127 * \brief Returns whether this entity is the hero controlled by the player.
128 * \return true if this entity is the hero
129 */
is_hero() const130 bool Entity::is_hero() const {
131 return get_type() == EntityType::HERO;
132 }
133
134 /**
135 * \brief Returns whether this entity is sensible to the ground below it.
136 *
137 * This function returns \c false by default.
138 * If this function returns \c true,
139 * notify_ground_below_changed() will be called when it changes.
140 *
141 * \return \c true if this entity is sensible to its ground.
142 */
is_ground_observer() const143 bool Entity::is_ground_observer() const {
144 return false;
145 }
146
147 /**
148 * \brief Returns whether this entity overrides the ground
149 * of where it is placed.
150 *
151 * This is equivalent to get_modified_ground() != Ground::EMPTY.
152 *
153 * \return \c true if this entity changes the ground.
154 */
is_ground_modifier() const155 bool Entity::is_ground_modifier() const {
156 return get_modified_ground() != Ground::EMPTY;
157 }
158
159 /**
160 * \brief Returns the ground defined by this entity.
161 *
162 * If a value other than Ground::EMPTY is returned, it means that this
163 * entity modifies the ground of the map where it is placed.
164 *
165 * \return The ground defined by this entity.
166 */
get_modified_ground() const167 Ground Entity::get_modified_ground() const {
168 return Ground::EMPTY;
169 }
170
171 /**
172 * \brief Inform entities sensible to their ground that it may have just
173 * changed because of this entity.
174 *
175 * This does the work even if this entity is not a ground modifier,
176 * because this is necessary in case it just stopped being one.
177 */
update_ground_observers()178 void Entity::update_ground_observers() {
179
180 // Update overlapping entities that are sensible to their ground.
181 const Rectangle& box = get_bounding_box();
182 std::vector<EntityPtr> entities_nearby;
183 get_entities().get_entities_in_rectangle_z_sorted(box, entities_nearby);
184 for (const EntityPtr& entity_nearby: entities_nearby) {
185
186 if (!entity_nearby->is_ground_observer()) {
187 // The entity does not care about the ground below it.
188 continue;
189 }
190
191 // Update the ground of observers that overlap or were just overlapping this one.
192 if (entity_nearby->get_layer() == get_layer() &&
193 (overlaps(entity_nearby->get_ground_point()) || overlaps(*entity_nearby))
194 // FIXME this is not precise and does not work for entities that disappear.
195 ) {
196 entity_nearby->update_ground_below();
197 }
198 }
199 }
200
201 /**
202 * \brief Returns the ground where this entity is.
203 * \return The ground under this entity.
204 */
get_ground_below() const205 Ground Entity::get_ground_below() const {
206
207 if (is_ground_observer()) {
208 // The information is already known.
209 return ground_below;
210 }
211
212 return get_map().get_ground(
213 get_layer(), get_ground_point(), this
214 );
215 }
216
217 /**
218 * \brief Recomputes the kind of ground below this entity.
219 *
220 * This function does nothing if the entity is not sensible to its ground.
221 */
update_ground_below()222 void Entity::update_ground_below() {
223
224 if (!is_ground_observer()) {
225 // This entity does not care about the ground below it.
226 return;
227 }
228
229 if (!is_enabled() ||
230 is_being_removed()) {
231 return;
232 }
233 // Note that even if the entity is suspended,
234 // the user might want to know the ground below it.
235
236 if (map->test_collision_with_border(get_ground_point())) {
237 // If the entity is outside the map, which is legal during a scrolling
238 // transition, don't try to determine any ground.
239 return;
240 }
241
242 Ground previous_ground = this->ground_below;
243 this->ground_below = get_map().get_ground(
244 get_layer(), get_ground_point(), this
245 );
246 if (this->ground_below != previous_ground) {
247 notify_ground_below_changed();
248 }
249 }
250
251 /**
252 * \brief Returns whether entities of this type can be drawn.
253 *
254 * This function returns \c true by default. Redefine it to return
255 * \c false if your type of entity has nothing to display.
256 *
257 * \return true if this type of entity can be drawn
258 */
can_be_drawn() const259 bool Entity::can_be_drawn() const {
260 return true;
261 }
262
263 /**
264 * \brief This function is called when a game command is pressed
265 * and the game is not suspended.
266 * \param command The command pressed.
267 */
notify_command_pressed(GameCommand)268 void Entity::notify_command_pressed(GameCommand /* game_command */) {
269 }
270
271 /**
272 * \brief This function is called when a game command is released
273 * if the game is not suspended.
274 * \param command The command released.
275 */
notify_command_released(GameCommand)276 void Entity::notify_command_released(GameCommand /* game_command */) {
277 }
278
279 /**
280 * \brief Returns whether this entity is on a map, that is,
281 * whether set_map() has been called.
282 * \return true if the entity is on a map
283 */
is_on_map() const284 bool Entity::is_on_map() const {
285 return map != nullptr && map->is_loaded();
286 }
287
288 /**
289 * \brief Sets the map where this entity is.
290 *
291 * Warning: when this function is called during the initialization of a new map,
292 * the current map of the game is still the old one.
293 *
294 * \param map The map.
295 */
set_map(Map & map)296 void Entity::set_map(Map& map) {
297
298 this->main_loop = &map.get_game().get_main_loop();
299 this->map = ↦
300 set_lua_context(&main_loop->get_lua_context());
301 if (&get_game().get_current_map() == &map) {
302 notify_tileset_changed();
303 }
304
305 this->ground_below = Ground::EMPTY;
306
307 if (!initialized && map.is_loaded()) {
308 // The entity is being created on a map already running.
309 // In this case, we are ready to finish the initialization right now.
310 finish_initialization();
311 }
312 }
313
314 /**
315 * @brief Returns whether this entity is fully initialized.
316 *
317 * This becomes true after entity:on_created() is called.
318 *
319 * @return @c true if the entity is initialized.
320 */
is_initialized() const321 bool Entity::is_initialized() const {
322 return initialized;
323 }
324
325 /**
326 * \brief Finishes the initialization of this entity once the map is loaded.
327 *
328 * This function must be called once the map is ready.
329 * It calls notify_creating(), then the Lua event entity:on_created(),
330 * and then notify_created().
331 */
finish_initialization()332 void Entity::finish_initialization() {
333
334 Debug::check_assertion(!initialized, "Entity is already initialized");
335 Debug::check_assertion(is_on_map(), "Missing map");
336 Debug::check_assertion(get_map().is_loaded(), "Map is not ready");
337
338 notify_creating();
339 get_lua_context()->entity_on_created(*this);
340 notify_created();
341
342 initialized = true;
343 }
344
345 /**
346 * \brief Notifies this entity that it is being created on a map.
347 *
348 * At this point, the map is already loaded and running,
349 * including if the entity was created from the map data file.
350 * Here, you can perform initializations that your entity need to do once the
351 * map is known and running.
352 * The entity:on_created() event will be called after this.
353 */
notify_creating()354 void Entity::notify_creating() {
355
356 }
357
358 /**
359 * \brief Notifies this entity that it has just been created on a map.
360 *
361 * At this point, the map is already loaded and running,
362 * including if the entity was created from the map data file.
363 * The entity:on_created() event has just been called.
364 * You can redefine this function to perform additional initializations
365 * after entity:on_created().
366 */
notify_created()367 void Entity::notify_created() {
368
369 if (state != nullptr) {
370 get_lua_context()->entity_on_state_changed(*this, get_state_name());
371 }
372 }
373
374 /**
375 * \brief Notifies this entity that its map is just starting.
376 *
377 * The entities are all loaded and the map is now ready.
378 * The map script has not been executed yet at this point.
379 *
380 * \param map The map.
381 * \param destination Destination entity where the hero is placed or nullptr.
382 */
notify_map_starting(Map &,const std::shared_ptr<Destination> &)383 void Entity::notify_map_starting(
384 Map& /* map */, const std::shared_ptr<Destination>& /* destination */) {
385
386 if (!initialized) {
387 // The map is now ready: we can finish the initialization of the entity.
388 finish_initialization();
389 }
390 }
391
392 /**
393 * \brief Notifies this entity that its map was just started.
394 *
395 * The map script has been executed already at this point.
396 *
397 * \param map The map.
398 * \param destination Destination entity where the hero is placed or nullptr.
399 */
notify_map_started(Map &,const std::shared_ptr<Destination> &)400 void Entity::notify_map_started(
401 Map& /* map */, const std::shared_ptr<Destination>& /* destination */) {
402 }
403
404 /**
405 * \brief Notifies this entity that the opening transition
406 * of the map is finishing.
407 *
408 * map:on_opening_transition_finished() has not been called yet at this point.
409 *
410 * \param map The map.
411 * \param destination Destination entity where the hero is placed or nullptr.
412 */
notify_map_opening_transition_finishing(Map &,const std::shared_ptr<Destination> &)413 void Entity::notify_map_opening_transition_finishing(
414 Map& /* map */, const std::shared_ptr<Destination>& /* destination */) {
415
416 if (is_ground_observer()) {
417 update_ground_below();
418 }
419 }
420
421 /**
422 * \brief Notifies this entity that the opening transition
423 * of the map is finished.
424 *
425 * map:on_opening_transition_finished() has been called already at this point.
426 *
427 * \param map The map.
428 * \param destination Destination entity where the hero is placed or nullptr.
429 */
notify_map_opening_transition_finished(Map &,const std::shared_ptr<Destination> &)430 void Entity::notify_map_opening_transition_finished(
431 Map& /* map */, const std::shared_ptr<Destination>& /* destination */) {
432 }
433
434 /**
435 * \brief Notifies this entity that the map is being stopped.
436 */
notify_map_finished()437 void Entity::notify_map_finished() {
438 }
439
440 /**
441 * \brief Notifies this entity that the tileset of the map has just changed.
442 *
443 * This is useful for tileset-dependent sprites such as doors and blocks.
444 */
notify_tileset_changed()445 void Entity::notify_tileset_changed() {
446
447 for (const SpritePtr& sprite: get_sprites()) {
448 sprite->set_tileset(get_map().get_tileset());
449 }
450 }
451
452 /**
453 * \brief Returns the map where this entity is.
454 * \return the map
455 */
get_map() const456 Map& Entity::get_map() const {
457 return *map;
458 }
459
460 /**
461 * \brief Returns the game that is running the map where this entity is.
462 * \return The game.
463 */
get_game()464 Game& Entity::get_game() {
465 SOLARUS_ASSERT(map != nullptr, "No map was set");
466 return map->get_game();
467 }
468
469 /**
470 * \brief Returns the game that is running the map where this entity is.
471 * \return The game.
472 */
get_game() const473 const Game& Entity::get_game() const {
474 SOLARUS_ASSERT(map != nullptr, "No map was set");
475 return map->get_game();
476 }
477
478 /**
479 * \brief Returns the entities of the current map.
480 * \return The entities.
481 */
get_entities() const482 const Entities& Entity::get_entities() const {
483 SOLARUS_ASSERT(map != nullptr, "No map was set");
484 return map->get_entities();
485 }
486
487 /**
488 * \overload Non-const version.
489 */
get_entities()490 Entities& Entity::get_entities() {
491 SOLARUS_ASSERT(map != nullptr, "No map was set");
492 return map->get_entities();
493 }
494
495 /**
496 * \brief Returns the current equipment.
497 * \return The equipment.
498 */
get_equipment()499 Equipment& Entity::get_equipment() {
500 return get_game().get_equipment();
501 }
502
503 /**
504 * \brief Returns the current equipment.
505 * \return The equipment.
506 */
get_equipment() const507 const Equipment& Entity::get_equipment() const {
508 return get_game().get_equipment();
509 }
510
511 /**
512 * \brief Returns the keys effect manager.
513 * \return the keys effect
514 */
get_commands_effects()515 CommandsEffects& Entity::get_commands_effects() {
516 return get_game().get_commands_effects();
517 }
518
519 /**
520 * \brief Returns the game commands.
521 * \return The commands.
522 */
get_commands()523 GameCommands& Entity::get_commands() {
524 return get_game().get_commands();
525 }
526
527 /**
528 * \brief Returns the savegame.
529 * \return The savegame.
530 */
get_savegame()531 Savegame& Entity::get_savegame() {
532 return get_game().get_savegame();
533 }
534
535 /**
536 * \brief Returns the savegame.
537 * \return The savegame.
538 */
get_savegame() const539 const Savegame& Entity::get_savegame() const {
540 return get_game().get_savegame();
541 }
542
543 /**
544 * \brief Returns the hero
545 * \return The hero.
546 */
get_hero()547 Hero& Entity::get_hero() {
548 return get_entities().get_hero();
549 }
550
551 /**
552 * \brief Schedules this entity for removal.
553 *
554 * The entity will be removed from the map and destroyed.
555 * This function is equivalent to calling map->get_entities()->remove_entity(this).
556 */
remove_from_map()557 void Entity::remove_from_map() {
558
559 get_entities().remove_entity(*this);
560 }
561
562 /**
563 * \brief Notifies this entity that it is about to be removed.
564 *
565 * This function is called when the entity has just been added
566 * to the list of entities that will be removed from the map
567 * and deleted from the memory as soon as possible.
568 */
notify_being_removed()569 void Entity::notify_being_removed() {
570
571 get_lua_context()->entity_on_removed(*this);
572 this->being_removed = true;
573
574 // If this entity defines a ground, tell people that it is disappearing.
575 if (is_on_map() &&
576 map->is_started() &&
577 is_ground_modifier()
578 ) {
579 update_ground_observers();
580 }
581
582 if (get_hero().get_facing_entity() == this) {
583 get_hero().set_facing_entity(nullptr);
584 }
585 }
586
587 /**
588 * \brief Sets the layer of the entity on the map.
589 *
590 * If the entity is stored on the map in the class MapEntities,
591 * you should not call this function directly: call
592 * MapEntities::set_entity_layer() instead because the class MapEntities
593 * stores different lists of entities for each layer.
594 * TODO: use notify_layer_changed to update MapEntities instead
595 *
596 * \param layer The layer of the entity on the map.
597 */
set_layer(int layer)598 void Entity::set_layer(int layer) {
599
600 this->layer = layer;
601 notify_layer_changed();
602 }
603
604 /**
605 * \brief This function is called when the layer of this entity has just changed.
606 *
607 * Redefine it if you need to be notified.
608 */
notify_layer_changed()609 void Entity::notify_layer_changed() {
610
611 if (!is_on_map()) {
612 return;
613 }
614
615 if (is_detector()) {
616 // Since this entity is a detector, all entities need to check
617 // their collisions with it.
618 get_map().check_collision_from_detector(*this);
619 }
620
621 // Check collisions between this entity and other detectors.
622 check_collision_with_detectors();
623
624 // Update the ground.
625 if (is_ground_modifier()) {
626 update_ground_observers();
627 }
628 update_ground_below();
629
630 // Notify Lua.
631 if (are_movement_notifications_enabled()) {
632 get_lua_context()->entity_on_position_changed(*this, get_xy(), get_layer());
633 }
634 }
635
636 /**
637 * \brief This function is called when the ground below this entity has
638 * just changed.
639 */
notify_ground_below_changed()640 void Entity::notify_ground_below_changed() {
641 }
642
643 /**
644 * \brief Returns the direction of the entity.
645 *
646 * This direction is not used by all kinds of entities
647 * since some of them only use the direction property of their sprites
648 * and/or their movements.
649 *
650 * \return the direction of the entity
651 */
get_direction() const652 int Entity::get_direction() const {
653 return direction;
654 }
655
656 /**
657 * \brief Sets the direction property of this entity.
658 * \param direction the direction
659 */
set_direction(int direction)660 void Entity::set_direction(int direction) {
661
662 if (direction != this->direction) {
663 this->direction = direction;
664 notify_direction_changed();
665 }
666 }
667
668 /**
669 * \brief Notifies this entity that its direction property has changed.
670 */
notify_direction_changed()671 void Entity::notify_direction_changed() {
672 }
673
674 /**
675 * \brief Returns the current x position of the entity.
676 * \return the x position of the entity
677 */
get_x() const678 int Entity::get_x() const {
679 return bounding_box.get_x() + origin.x;
680 }
681
682 /**
683 * \brief Returns the current y position of the entity.
684 * \return the y position of the entity
685 */
get_y() const686 int Entity::get_y() const {
687 return bounding_box.get_y() + origin.y;
688 }
689
690 /**
691 * \brief Sets the x position of the entity.
692 *
693 * This function is called by the movement object of this entity.
694 *
695 * \param x the new x position
696 */
set_x(int x)697 void Entity::set_x(int x) {
698 bounding_box.set_x(x - origin.x);
699 }
700
701 /**
702 * \brief Sets the y position of the entity.
703 *
704 * This function is called by the movement object of this entity.
705 *
706 * \param y the new y position
707 */
set_y(int y)708 void Entity::set_y(int y) {
709 bounding_box.set_y(y - origin.y);
710 }
711
712 /**
713 * \brief Returns the coordinates of the origin point of the entity, relative to the map.
714 *
715 * These are the coordinates of the point as returned by get_x() and get_y().
716 *
717 * \return the coordinates of the entity on the map
718 */
get_xy() const719 Point Entity::get_xy() const {
720 return { get_x(), get_y() };
721 }
722
723 /**
724 * \brief Sets the coordinates of the origin point of the entity, relative to the map.
725 *
726 * This function sets the coordinates of the point as returned by get_x() and get_y().
727 *
728 * \param x the new x coordinate of the entity on the map
729 * \param y the new y coordinate of the entity on the map
730 */
set_xy(int x,int y)731 void Entity::set_xy(int x, int y) {
732 set_x(x);
733 set_y(y);
734 }
735
736 /**
737 * \brief Sets the coordinates of the origin point of the entity, relative to the map.
738 *
739 * This function sets the coordinates of the point as returned by get_x() and get_y().
740 *
741 * \param xy the new coordinates of the entity on the map.
742 */
set_xy(const Point & xy)743 void Entity::set_xy(const Point& xy) {
744 set_xy(xy.x, xy.y);
745 }
746
747 /**
748 * \brief Returns the x position of the entity's top-left corner.
749 * \return the x position of the entity's top-left corner
750 */
get_top_left_x() const751 int Entity::get_top_left_x() const {
752 return bounding_box.get_x();
753 }
754
755 /**
756 * \brief Returns the y position of the entity's top-left corner.
757 * \return the y position of the entity's top-left corner
758 */
get_top_left_y() const759 int Entity::get_top_left_y() const {
760 return bounding_box.get_y();
761 }
762
763 /**
764 * \brief Returns the position of the entity's top-left corner.
765 * \return The position of the entity's top-left corner.
766 */
get_top_left_xy() const767 Point Entity::get_top_left_xy() const {
768 return { get_top_left_x(), get_top_left_y() };
769 }
770
771 /**
772 * \brief Sets the x position of the entity's top-left corner.
773 * \param x the new top-left x position
774 */
set_top_left_x(int x)775 void Entity::set_top_left_x(int x) {
776 bounding_box.set_x(x);
777 }
778
779 /**
780 * \brief Sets the y position of the entity's top-left corner.
781 * \param y the new top-left y position
782 */
set_top_left_y(int y)783 void Entity::set_top_left_y(int y) {
784 bounding_box.set_y(y);
785 }
786
787 /**
788 * \brief Sets the position of the entity.
789 *
790 * This function sets the coordinates of the rectangle's top-left corner.
791 *
792 * \param x x position of the entity
793 * \param y y position of the entity
794 */
set_top_left_xy(int x,int y)795 void Entity::set_top_left_xy(int x, int y) {
796 set_top_left_x(x);
797 set_top_left_y(y);
798 }
799
800 /**
801 * \brief Sets the position of the entity's top-left corner.
802 * \param xy The new top-left position.
803 */
set_top_left_xy(const Point & xy)804 void Entity::set_top_left_xy(const Point& xy) {
805 set_top_left_xy(xy.x, xy.y);
806 }
807
808 /**
809 * \brief Returns the coordinates where this entity should be drawn.
810 *
811 * Most of the time, this function just returns get_xy().
812 * But when the entity is moving, the movement may decide to display the
813 * entity at a different position.
814 *
815 * \return the coordinates of the entity on the map
816 */
get_displayed_xy() const817 Point Entity::get_displayed_xy() const {
818
819 if (get_movement() == nullptr) {
820 return get_xy();
821 }
822
823 return get_movement()->get_displayed_xy();
824 }
825
826 /**
827 * \brief Returns the width of the entity.
828 * \return the width of the entity
829 */
get_width() const830 int Entity::get_width() const {
831 return bounding_box.get_width();
832 }
833
834 /**
835 * \brief Returns the height of the entity.
836 * \return the height of the entity
837 */
get_height() const838 int Entity::get_height() const {
839 return bounding_box.get_height();
840 }
841
842 /**
843 * \brief Returns the size of the entity.
844 * \return the size of the entity
845 */
get_size() const846 Size Entity::get_size() const {
847 return bounding_box.get_size();
848 }
849
850 /**
851 * \brief Sets the size of the entity.
852 * \param width the entity's width
853 * \param height the entity's height
854 */
set_size(int width,int height)855 void Entity::set_size(int width, int height) {
856
857 Debug::check_assertion(width >= 0 && height >= 0,
858 "Invalid entity size: width and height must be positive");
859 bounding_box.set_size(width, height);
860
861 notify_size_changed();
862 }
863
864 /**
865 * \brief Sets the size of the entity.
866 * \param size to set to the entity
867 */
set_size(const Size & size)868 void Entity::set_size(const Size& size) {
869
870 set_size(size.width, size.height);
871 }
872
873 /**
874 * \brief Notifies this entity that its size has just changed.
875 */
notify_size_changed()876 void Entity::notify_size_changed() {
877
878 notify_bounding_box_changed();
879 }
880
881 /**
882 * \brief Returns the bounding box of the entity.
883 *
884 * This function returns the rectangle defined by
885 * get_top_left_x(), get_top_left_y(), get_width() and get_height().
886 * The sprites of this entity may exceed the bounding box:
887 * if you want a bounding box that takes sprites into account,
888 * call get_max_bounding_box().
889 *
890 * \return The position and size of the entity.
891 */
get_bounding_box() const892 const Rectangle& Entity::get_bounding_box() const {
893 return bounding_box;
894 }
895
896 /**
897 * \brief Sets the bounding box of the entity.
898 *
899 * This function sets the rectangle defined by
900 * get_top_left_x(), get_top_left_y(), get_width() and get_height().
901 *
902 * \param bounding_box The new position and size of the entity.
903 */
set_bounding_box(const Rectangle & bounding_box)904 void Entity::set_bounding_box(const Rectangle &bounding_box) {
905 this->bounding_box = bounding_box;
906 }
907
908 /**
909 * \brief Returns the bounding box of the entity extended with some margin.
910 * \param margin Margin to add to every side.
911 * \return The extended bounding box.
912 */
get_extended_bounding_box(int margin) const913 Rectangle Entity::get_extended_bounding_box(int margin) const {
914
915 Rectangle extended_box = get_bounding_box();
916 extended_box.set_xy(extended_box.get_xy() - Point(margin, margin));
917 extended_box.set_size(extended_box.get_size() + 2 * Size(margin, margin));
918 return extended_box;
919 }
920
921 /**
922 * \brief Returns the bounding box of the entity including its sprites.
923 *
924 * The default implementation takes into account the bounding box of sprites
925 * created with create_sprite().
926 * Subclasses that manage sprites without create_sprite() should reimplement
927 * this function to return a correct bounding box, otherwise sprite collisions
928 * may fail to be detected.
929 *
930 * \return The bounding box of the entity including its sprites.
931 */
get_max_bounding_box() const932 Rectangle Entity::get_max_bounding_box() const {
933
934 Rectangle result = get_bounding_box();
935 for (const SpritePtr& sprite: get_sprites()) {
936 Rectangle box = sprite->get_max_bounding_box();
937 box.add_xy(sprite->get_xy()); // Take into account the sprite's own offset.
938 box.add_xy(get_xy()); // Take into account the coordinates of the entity.
939 result |= box;
940 // TODO when the sprite's offset changes, update the bounding box
941 }
942 return result;
943 }
944
945 /**
946 * \brief Notifies this entity that its bounding box may have changed.
947 *
948 * This function should be called when the value of get_bounding_box() or
949 * get_max_bounding_box() changes.
950 */
notify_bounding_box_changed()951 void Entity::notify_bounding_box_changed() {
952
953 if (is_on_map()) {
954 get_entities().notify_entity_bounding_box_changed(*this);
955 }
956 }
957
958 /**
959 * \brief Returns whether the entity's bounding box is aligned with the 8*8 grid of the map.
960 * \return true if the entity's bounding box is aligned
961 */
is_aligned_to_grid() const962 bool Entity::is_aligned_to_grid() const {
963 return is_aligned_to_grid_x() && is_aligned_to_grid_y();
964 }
965
966 /**
967 * \brief Returns whether the entity's top-left corner is aligned
968 * horizontally with the 8*8 grid of the map.
969 * \return true if the entity's top-left corner is aligned hotizontally
970 */
is_aligned_to_grid_x() const971 bool Entity::is_aligned_to_grid_x() const {
972 return get_top_left_x() % 8 == 0;
973 }
974
975 /**
976 * \brief Returns whether the entity's top-left corner is aligned
977 * vertically with the 8*8 grid of the map.
978 * \return true if the entity's top-left corner is aligned vertically
979 */
is_aligned_to_grid_y() const980 bool Entity::is_aligned_to_grid_y() const {
981 return get_top_left_y() % 8 == 0;
982 }
983
984 /**
985 * \brief Makes the entity's top-left corner aligned with the 8*8 grid of the map.
986 *
987 * Be careful: This function does not check the collisions with obstacles.
988 */
set_aligned_to_grid()989 void Entity::set_aligned_to_grid() {
990
991 set_aligned_to_grid_x();
992 set_aligned_to_grid_y();
993 }
994
995 /**
996 * \brief Makes the entity's top-left corner aligned horizontally
997 * with the 8*8 grid of the map.
998 *
999 * Be careful: This function does not check the collisions with obstacles.
1000 */
set_aligned_to_grid_x()1001 void Entity::set_aligned_to_grid_x() {
1002
1003 int x = get_top_left_x() + 4;
1004 x -= x % 8;
1005 set_top_left_x(x);
1006 }
1007
1008 /**
1009 * \brief Makes the entity's top-left corner aligned vertically
1010 * with the 8*8 grid of the map.
1011 *
1012 * Be careful: This function does not check the collisions with obstacles.
1013 */
set_aligned_to_grid_y()1014 void Entity::set_aligned_to_grid_y() {
1015
1016 int y = get_top_left_y() + 4;
1017 y -= y % 8;
1018 set_top_left_y(y);
1019 }
1020
1021 /**
1022 * \brief Returns the coordinates of the point the entity is looking at.
1023 *
1024 * By default, this point depends on the direction of the sprite if any.
1025 * If there is no sprite, or if the sprite has not 4 directions,
1026 * then the movement is considered.
1027 * If there is no movement either, the entity is assumed to look to the north.
1028 * You can redefine this method to change what is a facing point for your
1029 * subclass.
1030 *
1031 * \return The coordinates of the point the entity is looking at.
1032 */
get_facing_point() const1033 Point Entity::get_facing_point() const {
1034
1035 int direction4 = 1; // North by default.
1036 const SpritePtr& sprite = get_sprite();
1037 if (sprite != nullptr && sprite->get_nb_directions() == 4) {
1038 // Use the sprite to decide where the entity is looking to.
1039 direction4 = sprite->get_current_direction();
1040 }
1041 else {
1042 if (get_movement() != nullptr) {
1043 // Otherwise use the movement.
1044 direction4 = get_movement()->get_displayed_direction4();
1045 }
1046 }
1047
1048 return get_touching_point(direction4);
1049 }
1050
1051 /**
1052 * \brief Returns the coordinates of the point the entity would be facing
1053 * if it was looking towards the specified direction.
1054 * \param direction A direction (0 to 3).
1055 * \return The point the entity touching this direction.
1056 */
get_touching_point(int direction) const1057 Point Entity::get_touching_point(int direction) const {
1058
1059 Point touching_point = get_center_point();
1060
1061 switch (direction) {
1062
1063 // right
1064 case 0:
1065 touching_point.x += get_width() / 2;
1066 break;
1067
1068 // up
1069 case 1:
1070 touching_point.y += -get_height() / 2 - 1;
1071 break;
1072
1073 // left
1074 case 2:
1075 touching_point.x += -get_width() / 2 - 1;
1076 break;
1077
1078 // down
1079 case 3:
1080 touching_point.y += get_height() / 2;
1081 break;
1082
1083 default:
1084 Debug::die("Invalid direction for Entity::get_touching_point()");
1085 }
1086 return touching_point;
1087 }
1088
1089 /**
1090 * \brief Returns the detector in front of this entity.
1091 * \return The detector this entity is facing, or nullptr if there is no detector in front of him.
1092 */
get_facing_entity()1093 Entity* Entity::get_facing_entity() {
1094 return facing_entity;
1095 }
1096
1097 /**
1098 * \brief Returns the detector in front of this entity.
1099 * \return The detector this entity is facing, or nullptr if there is no detector in front of him.
1100 */
get_facing_entity() const1101 const Entity* Entity::get_facing_entity() const {
1102 return facing_entity;
1103 }
1104
1105 /**
1106 * \brief Sets the entity this entity is currently facing.
1107 *
1108 * This function is called when this entity is facing a new detector.
1109 *
1110 * \param facing_entity The detector this entity is now facing (possibly nullptr).
1111 */
set_facing_entity(Entity * facing_entity)1112 void Entity::set_facing_entity(Entity* facing_entity) {
1113
1114 this->facing_entity = facing_entity;
1115 notify_facing_entity_changed(facing_entity);
1116 }
1117
1118 /**
1119 * \brief Notifies this entity that its facing entity has just changed.
1120 * \param facing_entity The detector this entity is now facing (possibly nullptr).
1121 */
notify_facing_entity_changed(Entity *)1122 void Entity::notify_facing_entity_changed(Entity* /* facing_entity */) {
1123 }
1124
1125 /**
1126 * \brief Returns the point used to determine which ground is below this entity.
1127 * \return The point used to determine the ground (relative to the map).
1128 */
get_ground_point() const1129 Point Entity::get_ground_point() const {
1130
1131 // Return a point slightly above the origin point, otherwise the hero
1132 // falls too easily in bad grounds to the South.
1133 return { get_x(), get_y() - 2 };
1134 }
1135
1136 /**
1137 * \brief Returns the coordinates of the center point of the entity's rectangle.
1138 * \return The coordinates of the center point of the entity.
1139 */
get_center_point() const1140 Point Entity::get_center_point() const {
1141 return bounding_box.get_center();
1142 }
1143
1144 /**
1145 * \brief Returns the name of the entity (if any).
1146 * \return the name of the entity, or an empty string if
1147 * the entity has no name.
1148 */
get_name() const1149 const std::string& Entity::get_name() const {
1150 return name;
1151 }
1152
1153 /**
1154 * \brief Sets the name of the entity.
1155 * \param name The name of the entity, or an empty string to unset the name.
1156 */
set_name(const std::string & name)1157 void Entity::set_name(const std::string& name) {
1158
1159 this->name = name;
1160 }
1161
1162 /**
1163 * \brief Returns whether this entity has a name.
1164 * \return \c true if the name is not empty.
1165 */
has_name() const1166 bool Entity::has_name() const {
1167 return !name.empty();
1168 }
1169
1170 /**
1171 * \brief Returns whether the name of this entity starts with the specified prefix.
1172 * \param prefix a prefix
1173 * \return true if the name starts with this prefix
1174 */
has_prefix(const std::string & prefix) const1175 bool Entity::has_prefix(const std::string& prefix) const {
1176 return name.substr(0, prefix.size()) == prefix;
1177 }
1178
1179 /**
1180 * \brief Returns the origin point of the entity,
1181 * relative to the top-left corner of its rectangle.
1182 * \return the origin point
1183 */
get_origin() const1184 const Point& Entity::get_origin() const {
1185 return origin;
1186 }
1187
1188 /**
1189 * \brief Sets the origin point of the entity,
1190 * relative to the uppper-left corner of its bounding box.
1191 *
1192 * The bounding box of the entity is shifted so that the result
1193 * of get_xy() does not change.
1194 *
1195 * \param x X coordinate of the origin.
1196 * \param y Y coordinate of the origin.
1197 */
set_origin(int x,int y)1198 void Entity::set_origin(int x, int y) {
1199
1200 bounding_box.add_xy(origin.x - x, origin.y - y);
1201 origin = { x, y };
1202 }
1203
1204 /**
1205 * \brief Sets the origin point of the entity,
1206 * relative to the top-left corner of its rectangle.
1207 * \param origin x and y coordinates of the origin
1208 */
set_origin(const Point & origin)1209 void Entity::set_origin(const Point& origin) {
1210 set_origin(origin.x, origin.y);
1211 }
1212
1213 /**
1214 * \brief Returns the optimization distance of this entity.
1215 *
1216 * Above this distance from the visible area, the engine may decide to
1217 * skip updates.
1218 *
1219 * \return The optimization distance (0 means infinite).
1220 */
get_optimization_distance() const1221 int Entity::get_optimization_distance() const {
1222 return optimization_distance;
1223 }
1224
1225 /**
1226 * \brief Returns the square of the optimization distance of this entity.
1227 * \return Square of the optimization distance (0 means infinite).
1228 */
get_optimization_distance2() const1229 int Entity::get_optimization_distance2() const {
1230 return optimization_distance2;
1231 }
1232
1233 /**
1234 * \brief Sets the optimization distance of this entity.
1235 *
1236 * Above this distance from the visible area, the engine may decide to
1237 * skip updates.
1238 *
1239 * \param distance The optimization distance (0 means infinite).
1240 */
set_optimization_distance(int distance)1241 void Entity::set_optimization_distance(int distance) {
1242 this->optimization_distance = distance;
1243 this->optimization_distance2 = distance * distance;
1244 }
1245
1246 /**
1247 * \brief Returns the user-defined properties of this entity.
1248 * \return The user-defined properties.
1249 */
get_user_properties() const1250 const std::vector<Entity::UserProperty>& Entity::get_user_properties() const {
1251 return user_properties;
1252 }
1253
1254 /**
1255 * \brief Sets the user-defined properties of this entity.
1256 * \param user_properties The user-defined properties to set.
1257 */
set_user_properties(const std::vector<UserProperty> & user_properties)1258 void Entity::set_user_properties(const std::vector<UserProperty>& user_properties) {
1259
1260 this->user_properties = user_properties;
1261 }
1262
1263 /**
1264 * \brief Returns whether the entity has a user-defined property.
1265 * \param key Key of the user-defined property to check.
1266 * \return \c true if such a property exists.
1267 */
has_user_property(const std::string & key) const1268 bool Entity::has_user_property(const std::string& key) const {
1269
1270 for (const UserProperty& user_property : user_properties) {
1271 if (user_property.first == key) {
1272 return true;
1273 }
1274 }
1275
1276 return false;
1277 }
1278
1279 /**
1280 * \brief Returns the value of a user property.
1281 * \param key Key of the property to get.
1282 * \return The corresponding value or an empty string.
1283 */
get_user_property_value(const std::string & key) const1284 const std::string& Entity::get_user_property_value(const std::string& key) const {
1285
1286 for (const UserProperty& user_property : user_properties) {
1287 if (user_property.first == key) {
1288 return user_property.second;
1289 }
1290 }
1291
1292 static const std::string empty_string;
1293 return empty_string;
1294 }
1295
1296 /**
1297 * \brief Sets the value of a user property.
1298 *
1299 * Creates the property if it does not exists yet.
1300 *
1301 * \param key Key of the property to set.
1302 * \param value The value to set.
1303 */
set_user_property_value(const std::string & key,const std::string & value)1304 void Entity::set_user_property_value(const std::string& key, const std::string& value) {
1305
1306 for (UserProperty& user_property : user_properties) {
1307 if (user_property.first == key) {
1308 user_property.second = value;
1309 return;
1310 }
1311 }
1312
1313 // Not found: add a new property.
1314 user_properties.emplace_back(std::make_pair(key, value));
1315 }
1316
1317 /**
1318 * \brief Removes a user property if it exists.
1319 * \param key Key of the property to remove.
1320 */
remove_user_property(const std::string & key)1321 void Entity::remove_user_property(const std::string& key) {
1322
1323 for (auto it = user_properties.begin(); it != user_properties.end(); ++it) {
1324 if (it->first == key) {
1325 user_properties.erase(it);
1326 return;
1327 }
1328 }
1329 }
1330
1331 /**
1332 * \brief Returns whether the entity has at least one sprite.
1333 * \return true if the entity has at least one sprite.
1334 */
has_sprite() const1335 bool Entity::has_sprite() const {
1336
1337 for (const NamedSprite& named_sprite : sprites) {
1338 if (!named_sprite.removed) {
1339 return true;
1340 }
1341 }
1342 return false;
1343 }
1344
1345 /**
1346 * \brief Returns a sprite of this entity.
1347 * \param sprite_name Name of the sprite to get, or an empty string to
1348 * get the default sprite.
1349 * \return The corresponding sprite, or nullptr if there is no such sprite.
1350 */
get_sprite(const std::string & sprite_name) const1351 SpritePtr Entity::get_sprite(const std::string& sprite_name) const {
1352
1353 if (sprites.empty()) {
1354 // This entity has no sprite.
1355 return nullptr;
1356 }
1357
1358 std::string valid_sprite_name;
1359 if (sprite_name.empty()) {
1360 // No sprite name specified: use the default one if any.
1361 if (default_sprite_name.empty()) {
1362 // No default sprite either: return the first one.
1363 for (const NamedSprite& named_sprite : sprites) {
1364 if (!named_sprite.removed) {
1365 return named_sprite.sprite;
1366 }
1367 }
1368 }
1369 else {
1370 valid_sprite_name = default_sprite_name;
1371 }
1372 }
1373 else {
1374 valid_sprite_name = sprite_name;
1375 }
1376
1377 for (const NamedSprite& named_sprite : sprites) {
1378 // Find a sprite with the given name and that was not removed.
1379 if (named_sprite.name == valid_sprite_name &&
1380 !named_sprite.removed) {
1381 return named_sprite.sprite;
1382 }
1383 }
1384 return nullptr;
1385 }
1386
1387 /**
1388 * \brief Returns all sprites of this entity.
1389 * \return The sprites.
1390 */
get_sprites() const1391 std::vector<SpritePtr> Entity::get_sprites() const {
1392
1393 std::vector<SpritePtr> result;
1394 result.reserve(sprites.size());
1395 for (const NamedSprite& named_sprite : sprites) {
1396 if (!named_sprite.removed) {
1397 result.push_back(named_sprite.sprite);
1398 }
1399 }
1400 return result;
1401 }
1402
1403 /**
1404 * \brief Returns all sprites of this entity and their names.
1405 * \return The sprites and their names.
1406 */
get_named_sprites() const1407 std::vector<Entity::NamedSprite> Entity::get_named_sprites() const {
1408 return sprites;
1409 }
1410
1411 /**
1412 * \brief Creates a sprite and adds it to this entity.
1413 * \param animation_set_id Id of the sprite's animation set to use.
1414 * \param sprite_name Name to identify the sprite or an empty string.
1415 * \param order Index where to insert to sprite. \c -1 means last.
1416 * \return The sprite created.
1417 */
create_sprite(const std::string & animation_set_id,const std::string & sprite_name,int order)1418 SpritePtr Entity::create_sprite(
1419 const std::string& animation_set_id,
1420 const std::string& sprite_name,
1421 int order
1422 ) {
1423 if (order == -1) {
1424 order = sprites.size();
1425 }
1426 SpritePtr sprite = std::make_shared<Sprite>(animation_set_id);
1427
1428 NamedSprite named_sprite;
1429 named_sprite.name = sprite_name;
1430 named_sprite.sprite = sprite;
1431 named_sprite.removed = false;
1432 sprites.insert(sprites.begin() + order, named_sprite);
1433 notify_bounding_box_changed();
1434 return sprite;
1435 }
1436
1437 /**
1438 * \brief Returns the index of a sprite in the list of sprites of this entity.
1439 * \param sprite A sprite.
1440 * \return Index of the sprite for this entity, or \c -1 if this entity has
1441 * no such sprite.
1442 */
get_sprite_order(Sprite & sprite)1443 int Entity::get_sprite_order(Sprite& sprite) {
1444
1445 int i = 0;
1446 for (NamedSprite& named_sprite: sprites) {
1447 if (named_sprite.sprite.get() == &sprite) {
1448 if (named_sprite.removed) {
1449 continue;
1450 }
1451 return i;
1452 }
1453 ++i;
1454 }
1455 return -1;
1456 }
1457
1458 /**
1459 * \brief Marks a sprite of this entity to be removed as soon as possible.
1460 * \return \c true in case of success, \c false if this entity has no such
1461 * sprite.
1462 */
remove_sprite(Sprite & sprite)1463 bool Entity::remove_sprite(Sprite& sprite) {
1464
1465 for (NamedSprite& named_sprite: sprites) {
1466 if (named_sprite.sprite.get() == &sprite) {
1467 if (named_sprite.removed) {
1468 continue;
1469 }
1470 named_sprite.removed = true;
1471 return true;
1472 }
1473 }
1474
1475 return false;
1476 }
1477
1478 /**
1479 * \brief Removes all sprites of this entity.
1480 *
1481 * They will be destroyed at next iteration.
1482 */
clear_sprites()1483 void Entity::clear_sprites() {
1484
1485 for (NamedSprite& named_sprite: sprites) {
1486 named_sprite.removed = true;
1487 }
1488 }
1489
1490 /**
1491 * \brief Really removes the sprites that were recently marked to be removed.
1492 */
clear_old_sprites()1493 void Entity::clear_old_sprites() {
1494
1495 for (auto it = sprites.begin();
1496 it != sprites.end();
1497 // No ++it since elements can be removed while traversing
1498 ) {
1499 const NamedSprite& named_sprite = *it;
1500 if (named_sprite.removed) {
1501 it = sprites.erase(it);
1502 }
1503 else {
1504 ++it;
1505 }
1506 }
1507 }
1508
1509 /**
1510 * \brief Changes the order of a sprite of this entity to display it first.
1511 * \return \c true in case of success, \c false if this entity has no such
1512 * sprite.
1513 */
bring_sprite_to_back(Sprite & sprite)1514 bool Entity::bring_sprite_to_back(Sprite& sprite) {
1515
1516 for (NamedSprite& named_sprite: sprites) {
1517 if (named_sprite.removed) {
1518 continue;
1519 }
1520 if (named_sprite.sprite.get() == &sprite) {
1521 NamedSprite copy = named_sprite;
1522 named_sprite.removed = true;
1523 // Bring to back means displaying first.
1524 sprites.insert(sprites.begin(), copy);
1525 return true;
1526 }
1527 }
1528
1529 return false;
1530 }
1531
1532 /**
1533 * \brief Changes the order of a sprite of this entity to display it last.
1534 * \return \c true in case of success, \c false if this entity has no such
1535 * sprite.
1536 */
bring_sprite_to_front(Sprite & sprite)1537 bool Entity::bring_sprite_to_front(Sprite& sprite) {
1538
1539 for (NamedSprite& named_sprite: sprites) {
1540 if (named_sprite.removed) {
1541 continue;
1542 }
1543 if (named_sprite.sprite.get() == &sprite) {
1544 NamedSprite copy = named_sprite;
1545 named_sprite.removed = true;
1546 // Bring to front means displaying last.
1547 sprites.push_back(copy);
1548 return true;
1549 }
1550 }
1551
1552 return false;
1553 }
1554
1555 /**
1556 * \brief Returns the name of the default sprite of this entity.
1557 * \return The default sprite name.
1558 * An empty name means the first one in creation order.
1559 */
get_default_sprite_name() const1560 std::string Entity::get_default_sprite_name() const {
1561 return default_sprite_name;
1562 }
1563
1564 /**
1565 * \brief Sets the default sprite of this entity.
1566 * \param default_sprite_name The default sprite name to set.
1567 * An empty name means the first one in creation order.
1568 */
set_default_sprite_name(const std::string & default_sprite_name)1569 void Entity::set_default_sprite_name(const std::string& default_sprite_name) {
1570
1571 this->default_sprite_name = default_sprite_name;
1572 }
1573
1574 /**
1575 * \brief Notifies this entity that the frame of one of its sprites has just changed.
1576 *
1577 * By default, nothing is done.
1578 *
1579 * \param sprite the sprite
1580 * \param animation the current animation
1581 * \param frame the new frame
1582 */
notify_sprite_frame_changed(Sprite &,const std::string &,int)1583 void Entity::notify_sprite_frame_changed(Sprite& /* sprite */, const std::string& /* animation */, int /* frame */) {
1584 }
1585
1586 /**
1587 * \brief Notifies this entity that the animation of one of its sprites
1588 * has just finished.
1589 *
1590 * By default, nothing is done.
1591 *
1592 * \param sprite the sprite
1593 * \param animation the animation just finished
1594 */
notify_sprite_animation_finished(Sprite &,const std::string &)1595 void Entity::notify_sprite_animation_finished(Sprite& /* sprite */, const std::string& /* animation */) {
1596 }
1597
1598 /**
1599 * \brief Returns whether this entity is currently visible.
1600 * \return true if this entity is currently visible
1601 */
is_visible() const1602 bool Entity::is_visible() const {
1603 return visible;
1604 }
1605
1606 /**
1607 * \brief Sets whether this entity is visible.
1608 * \param visible \c true to make it visible.
1609 */
set_visible(bool visible)1610 void Entity::set_visible(bool visible) {
1611 this->visible = visible;
1612 }
1613
1614 /**
1615 * \brief Returns whether sprites this entity should repeat with tiling.
1616 * \return \c true if sprites are tiled.
1617 */
is_tiled() const1618 bool Entity::is_tiled() const {
1619 return tiled;
1620 }
1621
1622 /**
1623 * \brief Sets whether sprites this entity should repeat with tiling.
1624 * \param tiled \c true to make sprites tiled.
1625 */
set_tiled(bool tiled)1626 void Entity::set_tiled(bool tiled) {
1627 this->tiled = tiled;
1628 }
1629
1630 /**
1631 * \brief Returns whether this entity has to be drawn in y order.
1632 *
1633 * This function returns whether an entity of this type should be drawn above
1634 * the hero and other entities having this property when it is in front of them.
1635 * This means that the displaying order of entities having this
1636 * feature depends on their y position. The entities without this feature
1637 * are drawn in the normal order (i.e. in the order of their creation),
1638 * and before the entities with this feature.
1639 *
1640 * \return \c true if this type of entity should be drawn at the same level
1641 * as the hero.
1642 */
is_drawn_in_y_order() const1643 bool Entity::is_drawn_in_y_order() const {
1644 return drawn_in_y_order;
1645 }
1646
1647 /**
1648 * \brief Sets whether this entity should be drawn in y order.
1649 * \param drawn_in_y_order \c true to draw this entity at the same level
1650 * as the hero.
1651 */
set_drawn_in_y_order(bool drawn_in_y_order)1652 void Entity::set_drawn_in_y_order(bool drawn_in_y_order) {
1653 this->drawn_in_y_order = drawn_in_y_order;
1654 }
1655
1656 /**
1657 * \brief Returns the current movement of the entity.
1658 * \return the entity's movement, or nullptr if there is no movement
1659 */
get_movement()1660 const std::shared_ptr<Movement>& Entity::get_movement() {
1661 return movement;
1662 }
1663
1664 /**
1665 * \brief Returns the current movement of the entity.
1666 * \return the entity's movement, or nullptr if there is no movement
1667 */
get_movement() const1668 std::shared_ptr<const Movement> Entity::get_movement() const {
1669 return movement;
1670 }
1671
1672 /**
1673 * \brief Sets the movement of this entity.
1674 * \param movement the movement to set, or nullptr to set no movement
1675 */
set_movement(const std::shared_ptr<Movement> & movement)1676 void Entity::set_movement(const std::shared_ptr<Movement>& movement) {
1677
1678 clear_movement();
1679 this->movement = movement;
1680
1681 if (movement != nullptr) {
1682 movement->set_lua_notifications_enabled(true);
1683 movement->set_entity(this);
1684
1685 if (movement->is_suspended() != suspended) {
1686 if (!suspended) {
1687 movement->set_suspended(false);
1688 }
1689 else {
1690 movement->set_suspended(is_enabled() && !movement->get_ignore_suspend());
1691 }
1692 }
1693 notify_movement_started();
1694 }
1695 }
1696
1697 /**
1698 * \brief Clears the movement of this entity.
1699 *
1700 * The entity immediately stops moving.
1701 * The movement object will be released at the next cycle,
1702 * thus this function can be called by the movement object itself.
1703 */
clear_movement()1704 void Entity::clear_movement() {
1705
1706 if (movement != nullptr) {
1707 movement->set_entity(nullptr); // Tell the movement to forget me.
1708 movement->set_lua_notifications_enabled(false); // Stop future Lua callbacks.
1709 old_movements.push_back(movement); // Destroy it later.
1710 movement = nullptr;
1711 }
1712 }
1713
1714 /**
1715 * \brief Destroys the old movements of this entity.
1716 */
clear_old_movements()1717 void Entity::clear_old_movements() {
1718
1719 old_movements.clear();
1720 }
1721
1722 /**
1723 * \brief Returns whether Lua movement events are enabled for this entity.
1724 *
1725 * If no, events entity:on_position_changed(), entity:on_obstacle_reached(),
1726 * entity:on_movement_started(), entity:on_movement_changed() and
1727 * entity:on_movement_finished() won't be called.
1728 *
1729 * \return Whether movement events are currently enabled.
1730 */
are_movement_notifications_enabled() const1731 bool Entity::are_movement_notifications_enabled() const {
1732 return main_loop != nullptr &&
1733 movement_notifications_enabled;
1734 }
1735
1736 /**
1737 * \brief Sets whether Lua movement events are enabled for this entity.
1738 *
1739 * If no, events entity:on_position_changed(), entity:on_obstacle_reached(),
1740 * entity:on_movement_started(), entity:on_movement_changed() and
1741 * entity:on_movement_finished() won't be called.
1742 *
1743 * \param notify \c true to enable movement events.
1744 */
set_movement_notifications_enabled(bool notify)1745 void Entity::set_movement_notifications_enabled(bool notify) {
1746 this->movement_notifications_enabled = notify;
1747 }
1748
1749 /**
1750 * \brief Returns whether this entity is following a stream.
1751 * \return \c true if there is an active stream action.
1752 */
has_stream_action() const1753 bool Entity::has_stream_action() const {
1754 return stream_action != nullptr && stream_action->is_active();
1755 }
1756
1757 /**
1758 * \brief Returns the stream action currently applied if any.
1759 * \return The stream action of this entity or nullptr.
1760 */
get_stream_action() const1761 const StreamAction* Entity::get_stream_action() const {
1762 return stream_action.get();
1763 }
1764
1765 /**
1766 * \brief Returns the stream action currently applied if any.
1767 * \return The stream action of this entity or nullptr.
1768 */
get_stream_action()1769 StreamAction* Entity::get_stream_action() {
1770 return stream_action.get();
1771 }
1772
1773 /**
1774 * \brief Makes this entity follow a stream.
1775 * \param stream_action The stream action to start.
1776 */
start_stream_action(std::unique_ptr<StreamAction> stream_action)1777 void Entity::start_stream_action(
1778 std::unique_ptr<StreamAction> stream_action
1779 ) {
1780 stop_stream_action();
1781 this->stream_action = std::move(stream_action);
1782 }
1783
1784 /**
1785 * \brief Stops following a stream if any.
1786 */
stop_stream_action()1787 void Entity::stop_stream_action() {
1788
1789 if (stream_action == nullptr) {
1790 return;
1791 }
1792
1793 old_stream_actions.emplace_back(std::move(stream_action));
1794 stream_action = nullptr;
1795 check_collision_with_detectors();
1796 }
1797
1798 /**
1799 * \brief Destroys the old stream actions of this entity.
1800 */
clear_old_stream_actions()1801 void Entity::clear_old_stream_actions() {
1802
1803 old_stream_actions.clear();
1804 }
1805
1806 /**
1807 * \brief Updates the stream action of this entity if any.
1808 */
update_stream_action()1809 void Entity::update_stream_action() {
1810
1811 if (has_stream_action()) {
1812 get_stream_action()->update();
1813 if (get_stream_action() != nullptr && !get_stream_action()->is_active()) {
1814 stop_stream_action();
1815 }
1816 }
1817 clear_old_stream_actions();
1818 }
1819
1820 /**
1821 * \brief Notifies this entity that it has just failed to change its position
1822 * because of obstacles.
1823 *
1824 * This function is called only when the movement is not suspended.
1825 */
notify_obstacle_reached()1826 void Entity::notify_obstacle_reached() {
1827
1828 if (are_movement_notifications_enabled()) {
1829 get_lua_context()->entity_on_obstacle_reached(*this, *get_movement());
1830 }
1831 }
1832
1833 /**
1834 * \brief This function is called when the entity has just moved.
1835 *
1836 * It checks collisions with the detectors on the map
1837 * and, if this entity defines a ground, updates entities sensible to their
1838 * ground.
1839 *
1840 * TODO only keep notify_bounding_box_changed()
1841 */
notify_position_changed()1842 void Entity::notify_position_changed() {
1843
1844 // Notify the quadtree.
1845 notify_bounding_box_changed();
1846
1847 if (is_detector()) {
1848 // Since this entity is a detector, all entities need to check
1849 // their collisions with it.
1850 get_map().check_collision_from_detector(*this);
1851 }
1852
1853 // Check collisions between this entity and other detectors.
1854 check_collision_with_detectors();
1855
1856 // Update the ground.
1857 if (is_ground_modifier()) {
1858 update_ground_observers();
1859 }
1860 update_ground_below();
1861
1862 // Notify Lua.
1863 if (are_movement_notifications_enabled()) {
1864 get_lua_context()->entity_on_position_changed(*this, get_xy(), get_layer());
1865 }
1866 }
1867
1868 /**
1869 * \brief Returns whether this entity is able to detect other entities.
1870 *
1871 * This is \c true if this entity has at least one collision mode.
1872 *
1873 * \return \c true if this entity can detect other entities.
1874 */
is_detector() const1875 bool Entity::is_detector() const {
1876 return collision_modes != CollisionMode::COLLISION_NONE;
1877 }
1878
1879 /**
1880 * \brief Sets the collision modes detected by this entity.
1881 * \param collision_modes The collision modes to set
1882 * (can be an OR combination of collision modes).
1883 */
set_collision_modes(int collision_modes)1884 void Entity::set_collision_modes(int collision_modes) {
1885
1886 if (collision_modes & CollisionMode::COLLISION_SPRITE) {
1887 enable_pixel_collisions();
1888 }
1889 this->collision_modes = collision_modes;
1890 }
1891
1892 /**
1893 * \brief Adds a collision mode to be detected this entity.
1894 * \param collision_mode The collision mode to add.
1895 */
add_collision_mode(CollisionMode collision_mode)1896 void Entity::add_collision_mode(CollisionMode collision_mode) {
1897
1898 set_collision_modes(this->collision_modes | collision_mode);
1899 }
1900
1901 /**
1902 * \brief Returns whether the entity detects the specified.
1903 * \param collision_mode A collision mode.
1904 * \return \c true if this collision mode is detected by this entity.
1905 */
has_collision_mode(CollisionMode collision_mode)1906 bool Entity::has_collision_mode(CollisionMode collision_mode) {
1907 return (this->collision_modes & collision_mode) != 0;
1908 }
1909
1910 /**
1911 * \brief Enables the pixel-perfect collision checks for all sprites
1912 * of this entity.
1913 */
enable_pixel_collisions()1914 void Entity::enable_pixel_collisions() {
1915
1916 for (const NamedSprite& named_sprite: sprites) {
1917 named_sprite.sprite->enable_pixel_collisions();
1918 }
1919 }
1920
1921 /**
1922 * \brief Returns whether this entity can have collisions with entities even if
1923 * they are not on the same layer.
1924 * \return \c true if this entity can detect collisions with entities
1925 * that are on another layer.
1926 */
has_layer_independent_collisions() const1927 bool Entity::has_layer_independent_collisions() const {
1928 return layer_independent_collisions;
1929 }
1930
1931 /**
1932 * \brief Sets whether this entity can detect collisions with entities even if
1933 * they are not on the same layer.
1934 * \param independent \c true if this entity can detect entities
1935 * that are on another layer.
1936 */
set_layer_independent_collisions(bool independent)1937 void Entity::set_layer_independent_collisions(bool independent) {
1938 this->layer_independent_collisions = independent;
1939 }
1940
1941 /**
1942 * \brief Returns whether the hero can lift this entity.
1943 */
can_be_lifted() const1944 bool Entity::can_be_lifted() const {
1945
1946 return get_weight() >= 0 &&
1947 get_equipment().has_ability(Ability::LIFT, get_weight());
1948 }
1949
1950 /**
1951 * \brief Returns the weight of this entity.
1952 *
1953 * This corresponds to the "lift" ability level required to lift the entity.
1954 * Therefore, a value of 0 allows the hero to lift the entity unconditionally.
1955 * A value of -1 means that the entity cannot be lifted.
1956 *
1957 * \return The weight of the entity or -1.
1958 */
get_weight() const1959 int Entity::get_weight() const {
1960 return weight;
1961 }
1962
1963 /**
1964 * \brief Sets the weight of this entity.
1965 *
1966 * This corresponds to the "lift" ability level required to lift the entity.
1967 * Therefore, a value of 0 allows the hero to lift the entity unconditionally.
1968 * A value of -1 means that the entity cannot be lifted.
1969 *
1970 * \param weight The weight of the entity or -1.
1971 */
set_weight(int weight)1972 void Entity::set_weight(int weight) {
1973
1974 this->weight = weight;
1975 if (weight >= 0) {
1976 add_collision_mode(CollisionMode::COLLISION_FACING);
1977 }
1978 }
1979
1980 /**
1981 * \brief Checks whether an entity collides with this detector.
1982 *
1983 * Only checks non pixel precise collisions.
1984 * Does nothing if this entity is not a detector.
1985 *
1986 * This function is called by the map when an entity has just moved.
1987 * It checks whether the entity collides with this detector.
1988 * Depending on this detector's collision mode(s), the appropriate
1989 * test_collision_* functions are called.
1990 * If there is a collision, the notify_collision() method is called.
1991 *
1992 * \param other The entity to check.
1993 */
check_collision(Entity & other)1994 void Entity::check_collision(Entity& other) {
1995
1996 if (!is_detector()) {
1997 // No collision kind to detect.
1998 return;
1999 }
2000
2001 if (&other == this) {
2002 return;
2003 }
2004
2005 if (get_layer() != other.get_layer() && !has_layer_independent_collisions()) {
2006 // Not the same layer: no collision.
2007 return;
2008 }
2009
2010 // Detect the collision depending on the collision modes.
2011
2012 if (has_collision_mode(CollisionMode::COLLISION_OVERLAPPING) && test_collision_rectangle(other)) {
2013 notify_collision(other, CollisionMode::COLLISION_OVERLAPPING);
2014 }
2015
2016 if (has_collision_mode(CollisionMode::COLLISION_CONTAINING) && test_collision_inside(other)) {
2017 notify_collision(other, CollisionMode::COLLISION_CONTAINING);
2018 }
2019
2020 if (has_collision_mode(CollisionMode::COLLISION_ORIGIN) && test_collision_origin_point(other)) {
2021 notify_collision(other, CollisionMode::COLLISION_ORIGIN);
2022 }
2023
2024 if (has_collision_mode(CollisionMode::COLLISION_FACING) && test_collision_facing_point(other)) {
2025
2026 if (other.get_facing_entity() == nullptr) {
2027 // Make sure only one entity can think "I am the facing entity".
2028 other.set_facing_entity(this);
2029 }
2030 notify_collision(other, CollisionMode::COLLISION_FACING);
2031 }
2032
2033 if (has_collision_mode(CollisionMode::COLLISION_TOUCHING) && test_collision_touching(other)) {
2034 notify_collision(other, CollisionMode::COLLISION_TOUCHING);
2035 }
2036
2037 if (has_collision_mode(CollisionMode::COLLISION_CENTER) && test_collision_center(other)) {
2038 notify_collision(other, CollisionMode::COLLISION_CENTER);
2039 }
2040
2041 if (has_collision_mode(CollisionMode::COLLISION_CUSTOM) && test_collision_custom(other)) {
2042 notify_collision(other, CollisionMode::COLLISION_CUSTOM);
2043 }
2044 }
2045
2046 /**
2047 * \brief Checks whether any sprite of this detector collides
2048 * with a specific sprite of another entity.
2049 *
2050 * If there is a collision, the notify_collision(Entity&, Sprite&, Sprite&) method is called.
2051 *
2052 * \param other The entity to check.
2053 * \param other_sprite The sprite of that entity.
2054 */
check_collision(Entity & other,Sprite & other_sprite)2055 void Entity::check_collision(Entity& other, Sprite& other_sprite) {
2056
2057 if (!has_collision_mode(CollisionMode::COLLISION_SPRITE)) {
2058 return;
2059 }
2060
2061 if (&other == this) {
2062 return;
2063 }
2064
2065 if (get_layer() != other.get_layer() && !has_layer_independent_collisions()) {
2066 // Not the same layer: no collision.
2067 return;
2068 }
2069
2070 if (!other_sprite.is_animation_started()) {
2071 // Animation is not running.
2072 return;
2073 }
2074
2075 if (!other_sprite.are_pixel_collisions_enabled()) {
2076 return;
2077 }
2078
2079 // We check the collision between the specified entity's sprite and
2080 // all sprites of the current entity.
2081 // Make a copy of the sprites list in case it gets reallocated while
2082 // traversing it.
2083 std::vector<SpritePtr> this_sprites = get_sprites();
2084 for (const SpritePtr& this_sprite: this_sprites) {
2085
2086 if (!this_sprite->is_animation_started()) {
2087 continue;
2088 }
2089
2090 if (!this_sprite->are_pixel_collisions_enabled()) {
2091 continue;
2092 }
2093
2094 if (this_sprite->test_collision(other_sprite, get_x(), get_y(), other.get_x(), other.get_y())) {
2095 notify_collision(other, *this_sprite, other_sprite);
2096 }
2097 }
2098 }
2099
2100 /**
2101 * \brief Checks whether a specific sprite of this detector collides
2102 * with any sprite of another entity.
2103 *
2104 * If there is a collision, the notify_collision(Entity&, Sprite&, Sprite&) method is called.
2105 *
2106 * \param other The entity to check.
2107 * \param other_sprite The sprite of that entity.
2108 */
check_collision(Sprite & this_sprite,Entity & other)2109 void Entity::check_collision(Sprite& this_sprite, Entity& other) {
2110
2111 if (!has_collision_mode(CollisionMode::COLLISION_SPRITE)) {
2112 return;
2113 }
2114
2115 if (&other == this) {
2116 return;
2117 }
2118
2119 if (get_layer() != other.get_layer() && !has_layer_independent_collisions()) {
2120 // Not the same layer: no collision.
2121 return;
2122 }
2123
2124 if (!this_sprite.is_animation_started()) {
2125 // Animation is not running.
2126 return;
2127 }
2128
2129 if (!this_sprite.are_pixel_collisions_enabled()) {
2130 return;
2131 }
2132
2133 // We check the collision between the specified detector's sprite and
2134 // all sprites of the other entity.
2135 // Make a copy of the sprites list in case it gets reallocated while
2136 // traversing it.
2137 std::vector<SpritePtr> other_sprites = other.get_sprites();
2138 for (const SpritePtr& other_sprite: other_sprites) {
2139
2140 if (!other_sprite->is_animation_started()) {
2141 continue;
2142 }
2143
2144 if (!other_sprite->are_pixel_collisions_enabled()) {
2145 continue;
2146 }
2147
2148 if (this_sprite.test_collision(*other_sprite, get_x(), get_y(), other.get_x(), other.get_y())) {
2149 notify_collision(other, this_sprite, *other_sprite);
2150 }
2151 }
2152 }
2153
2154 /**
2155 * \brief Returns whether an entity is overlapping this entity with the given
2156 * collision test.
2157 * \param entity The entity.
2158 * \param collision_mode The collision test to perform.
2159 * \param this_sprite Sprite of this entity to test (only for sprite collision mode),
2160 * or nullptr to test all of them.
2161 * \param other_sprite Sprite of the other entity to test (only for sprite collision mode),
2162 * or nullptr to test all of them.
2163 * \return \c true if there is a collision.
2164 */
test_collision(Entity & entity,CollisionMode collision_mode,const SpritePtr & this_sprite,const SpritePtr & other_sprite)2165 bool Entity::test_collision(
2166 Entity& entity,
2167 CollisionMode collision_mode,
2168 const SpritePtr& this_sprite,
2169 const SpritePtr& other_sprite) {
2170
2171 if (get_layer() != entity.get_layer() && !has_layer_independent_collisions()) {
2172 // Not the same layer: no collision.
2173 return false;
2174 }
2175
2176 switch (collision_mode) {
2177
2178 case CollisionMode::COLLISION_NONE:
2179 return false;
2180
2181 case CollisionMode::COLLISION_OVERLAPPING:
2182 return test_collision_rectangle(entity);
2183
2184 case CollisionMode::COLLISION_CONTAINING:
2185 return test_collision_inside(entity);
2186
2187 case CollisionMode::COLLISION_ORIGIN:
2188 return test_collision_origin_point(entity);
2189
2190 case CollisionMode::COLLISION_FACING:
2191 return test_collision_facing_point(entity);
2192
2193 case CollisionMode::COLLISION_TOUCHING:
2194 return test_collision_touching(entity);
2195
2196 case CollisionMode::COLLISION_CENTER:
2197 return test_collision_center(entity);
2198
2199 case CollisionMode::COLLISION_CUSTOM:
2200 return test_collision_custom(entity);
2201
2202 case CollisionMode::COLLISION_SPRITE:
2203 return test_collision_sprites(entity, this_sprite, other_sprite);
2204 }
2205
2206 return false;
2207 }
2208
2209 /**
2210 * \brief Returns whether an entity's rectangle is overlapping this entity's rectangle.
2211 *
2212 * The layer is not checked.
2213 *
2214 * \param entity The entity.
2215 * \return \c true if the entity's rectangle is overlapping this entity's rectangle.
2216 */
test_collision_rectangle(const Entity & entity) const2217 bool Entity::test_collision_rectangle(const Entity& entity) const {
2218
2219 return entity.overlaps(*this);
2220 }
2221
2222 /**
2223 * \brief Returns whether an entity's rectangle is entirely inside this entity's rectangle.
2224 *
2225 * The layer is not checked.
2226 *
2227 * \param entity The entity.
2228 * \return \c true if the entity's rectangle is entirely inside this entity's rectangle.
2229 */
test_collision_inside(const Entity & entity) const2230 bool Entity::test_collision_inside(const Entity& entity) const {
2231
2232 return get_bounding_box().contains(entity.get_bounding_box());
2233 }
2234
2235
2236 /**
2237 * \brief Returns whether the origin point of an entity is overlapping this entity's rectangle.
2238 *
2239 * The layer is not checked.
2240 *
2241 * \param entity The entity.
2242 * \return \c true if the entity's origin point is overlapping the this entity's rectangle
2243 */
test_collision_origin_point(const Entity & entity) const2244 bool Entity::test_collision_origin_point(const Entity& entity) const {
2245
2246 return entity.is_origin_point_in(get_bounding_box());
2247 }
2248
2249 /**
2250 * \brief Returns whether the facing point of an entity is overlapping this entity's rectangle.
2251 *
2252 * The layer is not checked.
2253 *
2254 * \param entity The entity.
2255 * \return \c true if the entity's facing point is overlapping this entity's rectangle
2256 */
test_collision_facing_point(const Entity & entity) const2257 bool Entity::test_collision_facing_point(const Entity& entity) const {
2258
2259 return entity.is_facing_point_in(get_bounding_box());
2260 }
2261
2262 /**
2263 * \brief Returns whether a touching point of an entity
2264 * (in any of the four main directions)
2265 * is overlapping this entity's rectangle.
2266 *
2267 * The layer is not checked.
2268 *
2269 * \param entity The entity.
2270 * \return \c true if a touching point of the entity is overlapping
2271 * this entity's rectangle.
2272 */
test_collision_touching(const Entity & entity) const2273 bool Entity::test_collision_touching(const Entity& entity) const {
2274
2275 const Rectangle& bounding_box = get_bounding_box();
2276 return entity.is_touching_point_in(bounding_box, 0)
2277 || entity.is_touching_point_in(bounding_box, 1)
2278 || entity.is_touching_point_in(bounding_box, 2)
2279 || entity.is_touching_point_in(bounding_box, 3);
2280 }
2281
2282 /**
2283 * \brief Returns whether the center point of an entity is overlapping this entity's rectangle.
2284 *
2285 * The layer is not checked.
2286 *
2287 * \param entity The entity.
2288 * \return \c true if the entity's center is overlapping this entity's rectangle.
2289 */
test_collision_center(const Entity & entity) const2290 bool Entity::test_collision_center(const Entity& entity) const {
2291
2292 return entity.is_center_in(get_bounding_box());
2293 }
2294
2295 /**
2296 * \brief Returns whether a sprite of this entity collides with a sprite of another one.
2297 *
2298 * The layer is not checked.
2299 * The test is pixel-precise.
2300 *
2301 * \param entity The entity.
2302 * \param this_sprite Sprite of this entity to test, or nullptr to test all of them.
2303 * \param other_sprite Sprite of the other entity to test, or nullptr to test all of them.
2304 * \return \c true if sprites of both entities overlap.
2305 */
test_collision_sprites(Entity & entity,const SpritePtr & this_sprite,const SpritePtr & other_sprite)2306 bool Entity::test_collision_sprites(
2307 Entity& entity,
2308 const SpritePtr& this_sprite,
2309 const SpritePtr& other_sprite) {
2310
2311 // Select the sprites to check depending on paramaters.
2312 std::vector<SpritePtr> this_sprites;
2313 if (this_sprite != nullptr) {
2314 this_sprites.push_back(this_sprite);
2315 } else {
2316 for (const NamedSprite& this_named_sprite: this->sprites) {
2317 if (!this_named_sprite.removed) {
2318 this_sprites.push_back(this_named_sprite.sprite);
2319 }
2320 }
2321 }
2322 std::vector<SpritePtr> other_sprites;
2323 if (other_sprite != nullptr) {
2324 other_sprites.push_back(other_sprite);
2325 } else {
2326 for (const NamedSprite& other_named_sprite: entity.sprites) {
2327 if (!other_named_sprite.removed) {
2328 other_sprites.push_back(other_named_sprite.sprite);
2329 }
2330 }
2331 }
2332
2333 // Test the selected sprites.
2334 for (const SpritePtr& this_sprite : this_sprites) {
2335 this_sprite->enable_pixel_collisions();
2336 for (const SpritePtr& other_sprite : other_sprites) {
2337 other_sprite->enable_pixel_collisions();
2338 if (this_sprite->test_collision(*other_sprite, get_x(), get_y(), entity.get_x(), entity.get_y())) {
2339 return true;
2340 }
2341 }
2342 }
2343
2344 return false;
2345 }
2346
2347 /**
2348 * \brief Returns whether an entity collides with this entity with respect to a custom rule.
2349 *
2350 * This method is called by check_collision(Entity*) when this entity's collision
2351 * mode is COLLISION_CUSTOM.
2352 * Redefine it if you want to use this collision mode.
2353 *
2354 * \param entity The entity.
2355 * \return \c true if the entity's collides with this entity with respect to the custom rule
2356 */
test_collision_custom(Entity &)2357 bool Entity::test_collision_custom(Entity& /* entity */) {
2358
2359 return false;
2360 }
2361
2362 /**
2363 * \brief Notifies this entity that it just detected a collision with another entity.
2364 *
2365 * This function is called by check_collision(Entity*)
2366 * when an entity overlaps this detector.
2367 *
2368 * \param entity_overlapping The entity overlapping this detector.
2369 * \param collision_mode The collision mode that detected the collision (useful if
2370 * this detector has several collision modes).
2371 */
notify_collision(Entity &,CollisionMode)2372 void Entity::notify_collision(Entity& /* entity_overlapping */, CollisionMode /* collision_mode */) {
2373
2374 // By default, nothing happens.
2375 // Redefine this method in the subclasses to do the appropriate action.
2376 }
2377
2378 /**
2379 * \brief Notifies this entity that it just detected a pixel-perfect collision with another sprite.
2380 *
2381 * This function is called by check_collision(Entity*, Sprite*) when another entity's
2382 * sprite overlaps a sprite of this detector.
2383 *
2384 * \param other_entity The entity overlapping this detector.
2385 * \param this_sprite The sprite of this detector that is overlapping the other entity's sprite.
2386 * \param other_sprite The sprite of other_entity that is overlapping this detector.
2387 */
notify_collision(Entity &,Sprite &,Sprite &)2388 void Entity::notify_collision(
2389 Entity& /* other_entity */,
2390 Sprite& /* this_sprite */,
2391 Sprite& /* other_sprite */
2392 ) {
2393 // By default, nothing happens.
2394 // Redefine this method in the subclasses to do the appropriate action.
2395 }
2396
2397 /**
2398 * \brief Checks collisions between this entity and the detectors of the map.
2399 *
2400 * Simple collisions are checked, and then pixel-precise collisions if they are
2401 * enabled for some sprites of this entity.
2402 */
check_collision_with_detectors()2403 void Entity::check_collision_with_detectors() {
2404
2405 if (!is_on_map()) {
2406 // The entity is still being initialized.
2407 return;
2408 }
2409
2410 if (!is_enabled()) {
2411 // The entity is disabled.
2412 return;
2413 }
2414
2415 if (is_being_removed()) {
2416 return;
2417 }
2418
2419 // Detect simple collisions.
2420 get_map().check_collision_with_detectors(*this);
2421
2422 // Detect pixel-precise collisions.
2423 std::vector<NamedSprite> sprites = this->sprites;
2424 for (const NamedSprite& named_sprite: sprites) {
2425 if (named_sprite.removed) {
2426 continue;
2427 }
2428 Sprite& sprite = *named_sprite.sprite;
2429 if (sprite.are_pixel_collisions_enabled()) {
2430 get_map().check_collision_with_detectors(*this, sprite);
2431 }
2432 }
2433 }
2434
2435 /**
2436 * \brief Checks pixel-precise collisions between a particular sprite of this
2437 * entity and the detectors of the map.
2438 * \param sprite the sprite to check
2439 */
check_collision_with_detectors(Sprite & sprite)2440 void Entity::check_collision_with_detectors(Sprite& sprite) {
2441
2442 if (!is_enabled()) {
2443 // The entity is disabled.
2444 return;
2445 }
2446
2447 get_map().check_collision_with_detectors(*this, sprite);
2448 }
2449
2450 /**
2451 * \brief This function is called when a movement started on this entity.
2452 */
notify_movement_started()2453 void Entity::notify_movement_started() {
2454
2455 if (are_movement_notifications_enabled()) {
2456 get_lua_context()->entity_on_movement_started(*this, *get_movement());
2457 }
2458 }
2459
2460 /**
2461 * \brief This function is called when the movement of the entity is finished.
2462 */
notify_movement_finished()2463 void Entity::notify_movement_finished() {
2464
2465 if (are_movement_notifications_enabled()) {
2466 get_lua_context()->entity_on_movement_finished(*this);
2467 }
2468 }
2469
2470 /**
2471 * \brief This function can be called by the movement object
2472 * to notify the entity when the movement has just changed
2473 * (e.g. the speed, the angle or the trajectory).
2474 */
notify_movement_changed()2475 void Entity::notify_movement_changed() {
2476
2477 if (are_movement_notifications_enabled() && get_movement()) {
2478 get_lua_context()->entity_on_movement_changed(*this, *get_movement());
2479 }
2480 }
2481
2482 /**
2483 * \brief This function is called when this entity starts being moved by
2484 * another one.
2485 * \param entity The other entity.
2486 */
notify_moving_by(Entity &)2487 void Entity::notify_moving_by(Entity& /* entity */) {
2488 // Do nothing by default.
2489 }
2490
2491 /**
2492 * \brief This function is called when this entity has just finished to get
2493 * moved by another one.
2494 * \param entity The other entity.
2495 */
notify_moved_by(Entity &)2496 void Entity::notify_moved_by(Entity& /* entity */) {
2497 // Do nothing by default.
2498 }
2499
2500 /**
2501 * \brief Converts a direction into the corresponding one-pixel move on x and y.
2502 * \param direction8 a direction (0 to 7)
2503 * \return a point with x and y set to -1, 0 or 1 depending on the direction
2504 */
direction_to_xy_move(int direction8)2505 const Point& Entity::direction_to_xy_move(int direction8) {
2506
2507 static constexpr Point directions_to_xy_moves[] = {
2508 { 1, 0 },
2509 { 1, -1 },
2510 { 0, -1 },
2511 { -1, -1 },
2512 { -1, 0 },
2513 { -1, 1 },
2514 { 0, 1 },
2515 { 1, 1 }
2516 };
2517
2518 return directions_to_xy_moves[direction8];
2519 }
2520
2521 /**
2522 * \brief Enables or disables this entity.
2523 * \param enabled true to enable the entity, false to disable it
2524 */
set_enabled(bool enabled)2525 void Entity::set_enabled(bool enabled) {
2526
2527 if (this->enabled == enabled) {
2528 return;
2529 }
2530
2531 if (enabled) {
2532 // Enable the entity.
2533
2534 this->enabled = true;
2535
2536 if (!is_suspended()) {
2537 // Enabling an entity that is not suspended:
2538 // unsuspend its movement, its sprites and its timers.
2539 if (get_movement() != nullptr) {
2540 get_movement()->set_suspended(false);
2541 }
2542
2543 if (stream_action != nullptr) {
2544 stream_action->set_suspended(false);
2545 }
2546
2547 for (const NamedSprite& named_sprite: sprites) {
2548 if (named_sprite.removed) {
2549 continue;
2550 }
2551 Sprite& sprite = *named_sprite.sprite;
2552 sprite.set_suspended(false);
2553 }
2554
2555 if (is_on_map()) {
2556 get_lua_context()->set_entity_timers_suspended_as_map(*this, false);
2557 }
2558 }
2559 notify_enabled(true);
2560 }
2561 else {
2562 this->enabled = false;
2563
2564 if (!is_suspended()) {
2565 // Disabling an entity that is not suspended:
2566 // suspend its movement, its sprites and its timers.
2567 if (get_movement() != nullptr) {
2568 get_movement()->set_suspended(true);
2569 }
2570
2571 for (const NamedSprite& named_sprite: sprites) {
2572 if (named_sprite.removed) {
2573 continue;
2574 }
2575 Sprite& sprite = *named_sprite.sprite;
2576 sprite.set_suspended(true);
2577 }
2578
2579 if (is_on_map()) {
2580 get_lua_context()->set_entity_timers_suspended_as_map(*this, true);
2581 }
2582 }
2583 notify_enabled(false);
2584 }
2585 }
2586
2587 /**
2588 * \brief Notifies this entity that it was just enabled or disabled.
2589 * \param enabled \c true if the entity is now enabled.
2590 */
notify_enabled(bool enabled)2591 void Entity::notify_enabled(bool enabled) {
2592
2593 if (!is_on_map()) {
2594 return;
2595 }
2596
2597 if (is_ground_modifier()) {
2598 update_ground_observers();
2599 }
2600 update_ground_below();
2601
2602 if (enabled) {
2603 get_lua_context()->entity_on_enabled(*this);
2604 }
2605 else {
2606 get_lua_context()->entity_on_disabled(*this);
2607 }
2608
2609 }
2610
2611 /**
2612 * \brief Returns whether this entity is an obstacle for another one.
2613 *
2614 * This function is called by the default implementation of
2615 * Entity::is_obstacle_for(Entity&, const Rectangle& candidate_position).
2616 *
2617 * \param other Another entity.
2618 * \return \c true if this entity is an obstacle for the other one.
2619 */
is_obstacle_for(Entity &)2620 bool Entity::is_obstacle_for(Entity& /* other */) {
2621
2622 return false;
2623 }
2624
2625 /**
2626 * \brief Returns whether this entity is an obstacle for another one it that
2627 * other entity was at the specified place.
2628 *
2629 * There are two mechanisms to block entities: by another entity or by the
2630 * ground of the map.
2631 *
2632 * This function is about entities blocking other entities.
2633 * If you return \c true, the other entity will be blocked even if there are
2634 * traversable entities on top of yours.
2635 *
2636 * If your entity modifies the ground of the map (see is_ground_modifier()),
2637 * you then rely on the map ground mechanism. In this case, if
2638 * other entities at the same coordinates also modify the map ground and are
2639 * higher than your entity, their ground overrides yours.
2640 *
2641 * To respect this behavior, is_obstacle_for() should return false for
2642 * ground modifiers.
2643 *
2644 * \param other Another entity.
2645 * \param candidate_position Candidate position of this other entity.
2646 * \return \c true if this entity is an obstacle for the other one at that
2647 * position.
2648 */
is_obstacle_for(Entity & other,const Rectangle &)2649 bool Entity::is_obstacle_for(Entity& other, const Rectangle& /* candidate_position */) {
2650
2651 // By default, use a position-independent test.
2652 // Most entities don't need the candidate position of the other one to decide
2653 // if they want to block them.
2654 return is_obstacle_for(other);
2655 }
2656
2657 /**
2658 * \brief Returns whether a kind of ground is an obstacle for this entity.
2659 */
is_ground_obstacle(Ground ground) const2660 bool Entity::is_ground_obstacle(Ground ground) const {
2661
2662 switch (ground) {
2663
2664 case Ground::EMPTY:
2665 return false;
2666
2667 case Ground::TRAVERSABLE:
2668 return is_traversable_obstacle();
2669
2670 case Ground::WALL:
2671 return is_wall_obstacle();
2672
2673 case Ground::LOW_WALL:
2674 return is_low_wall_obstacle();
2675
2676 case Ground::WALL_TOP_RIGHT:
2677 case Ground::WALL_TOP_LEFT:
2678 case Ground::WALL_BOTTOM_LEFT:
2679 case Ground::WALL_BOTTOM_RIGHT:
2680 case Ground::WALL_TOP_RIGHT_WATER:
2681 case Ground::WALL_TOP_LEFT_WATER:
2682 case Ground::WALL_BOTTOM_LEFT_WATER:
2683 case Ground::WALL_BOTTOM_RIGHT_WATER:
2684 return is_wall_obstacle();
2685
2686 case Ground::DEEP_WATER:
2687 return is_deep_water_obstacle();
2688
2689 case Ground::SHALLOW_WATER:
2690 return is_shallow_water_obstacle();
2691
2692 case Ground::GRASS:
2693 return is_grass_obstacle();
2694
2695 case Ground::HOLE:
2696 return is_hole_obstacle();
2697
2698 case Ground::ICE:
2699 return is_ice_obstacle();
2700
2701 case Ground::LADDER:
2702 return is_ladder_obstacle();
2703
2704 case Ground::PRICKLE:
2705 return is_prickle_obstacle();
2706
2707 case Ground::LAVA:
2708 return is_lava_obstacle();
2709
2710 }
2711
2712 return false;
2713 }
2714
2715 /**
2716 * \brief Returns whether traversable ground is currently considered as an
2717 * obstacle by this entity.
2718 *
2719 * This function returns \c false by default.
2720 *
2721 * \return \c true if traversable ground is currently obstacle for this entity.
2722 */
is_traversable_obstacle() const2723 bool Entity::is_traversable_obstacle() const {
2724 return false;
2725 }
2726
2727 /**
2728 * \brief Returns whether walls are currently considered as an
2729 * obstacle by this entity.
2730 *
2731 * This function returns \c true by default.
2732 *
2733 * \return \c true if wall ground is currently obstacle for this entity.
2734 */
is_wall_obstacle() const2735 bool Entity::is_wall_obstacle() const {
2736 return true;
2737 }
2738
2739 /**
2740 * \brief Returns whether a low wall is currently considered as an obstacle
2741 * by this entity.
2742 *
2743 * This function returns \c true by default.
2744 *
2745 * \return \c true if low walls are currently obstacle for this entity.
2746 */
is_low_wall_obstacle() const2747 bool Entity::is_low_wall_obstacle() const {
2748 return true;
2749 }
2750
2751 /**
2752 * \brief Returns whether grass ground is currently considered as an
2753 * obstacle by this entity.
2754 *
2755 * This function returns \c false by default.
2756 *
2757 * \return \c true if grass ground is currently obstacle for this entity.
2758 */
is_grass_obstacle() const2759 bool Entity::is_grass_obstacle() const {
2760 return false;
2761 }
2762
2763 /**
2764 * \brief Returns whether shallow water is currently considered as an obstacle by this entity.
2765 *
2766 * This function returns is_deep_water_obstacle() by default.
2767 *
2768 * \return true if shallow water is currently an obstacle for this entity
2769 */
is_shallow_water_obstacle() const2770 bool Entity::is_shallow_water_obstacle() const {
2771 return is_deep_water_obstacle();
2772 }
2773
2774 /**
2775 * \brief Returns whether deep water is currently considered as an obstacle by this entity.
2776 *
2777 * This function returns true by default.
2778 *
2779 * \return true if deep water is currently an obstacle for this entity
2780 */
is_deep_water_obstacle() const2781 bool Entity::is_deep_water_obstacle() const {
2782 return true;
2783 }
2784
2785 /**
2786 * \brief Returns whether a hole is currently considered as an obstacle by this entity.
2787 *
2788 * This function returns true by default.
2789 *
2790 * \return true if the holes are currently an obstacle for this entity
2791 */
is_hole_obstacle() const2792 bool Entity::is_hole_obstacle() const {
2793 return true;
2794 }
2795
2796 /**
2797 * \brief Returns whether lava is currently considered as an obstacle by this entity.
2798 *
2799 * This function returns true by default.
2800 *
2801 * \return true if lava is currently an obstacle for this entity
2802 */
is_lava_obstacle() const2803 bool Entity::is_lava_obstacle() const {
2804 return true;
2805 }
2806
2807 /**
2808 * \brief Returns whether ice ground is currently considered as an
2809 * obstacle by this entity.
2810 *
2811 * This function returns \c false by default.
2812 *
2813 * \return \c true if ice ground is currently obstacle for this entity.
2814 */
is_ice_obstacle() const2815 bool Entity::is_ice_obstacle() const {
2816 return false;
2817 }
2818
2819 /**
2820 * \brief Returns whether prickles are currently considered as an obstacle by this entity.
2821 *
2822 * This function returns true by default.
2823 *
2824 * \return true if prickles are currently an obstacle for this entity
2825 */
is_prickle_obstacle() const2826 bool Entity::is_prickle_obstacle() const {
2827 return true;
2828 }
2829
2830 /**
2831 * \brief Returns whether a ladder is currently considered as an obstacle by this entity.
2832 *
2833 * This function returns true by default.
2834 *
2835 * \return true if the ladders are currently an obstacle for this entity
2836 */
is_ladder_obstacle() const2837 bool Entity::is_ladder_obstacle() const {
2838 return true;
2839 }
2840
2841 /**
2842 * \brief Returns whether the hero is currently considered as an obstacle by this entity.
2843 *
2844 * This function returns false by default.
2845 *
2846 * \param hero the hero
2847 * \return true if the hero is currently an obstacle for this entity
2848 */
is_hero_obstacle(Hero &)2849 bool Entity::is_hero_obstacle(Hero& /* hero */) {
2850 return false;
2851 }
2852
2853 /**
2854 * \brief Returns whether a block is currently considered as an obstacle by this entity.
2855 *
2856 * This function returns true by default.
2857 *
2858 * \param block a block
2859 * \return true if the block is currently an obstacle for this entity
2860 */
is_block_obstacle(Block &)2861 bool Entity::is_block_obstacle(Block& /* block */) {
2862 return true;
2863 }
2864
2865 /**
2866 * \brief Returns whether a teletransporter is currently considered as an obstacle by this entity.
2867 *
2868 * This function returns true by default.
2869 *
2870 * \param teletransporter a teletransporter
2871 * \return true if the teletransporter is currently an obstacle for this entity
2872 */
is_teletransporter_obstacle(Teletransporter &)2873 bool Entity::is_teletransporter_obstacle(Teletransporter& /* teletransporter */) {
2874 return true;
2875 }
2876
2877 /**
2878 * \brief Returns whether a stream is currently considered as an obstacle by
2879 * this entity.
2880 *
2881 * This function returns true by default.
2882 *
2883 * \param stream A stream.
2884 * \return \c true if the stream is currently an obstacle for this entity.
2885 */
is_stream_obstacle(Stream &)2886 bool Entity::is_stream_obstacle(Stream& /* stream */) {
2887 return true;
2888 }
2889
2890 /**
2891 * \brief Returns whether some stairs are currently considered as an obstacle for this entity.
2892 *
2893 * This function returns true by default.
2894 *
2895 * \param stairs an stairs entity
2896 * \return true if the stairs are currently an obstacle for this entity
2897 */
is_stairs_obstacle(Stairs &)2898 bool Entity::is_stairs_obstacle(Stairs& /* stairs */) {
2899 return true;
2900 }
2901
2902 /**
2903 * \brief Returns whether a sensor is currently considered as an obstacle by this entity.
2904 *
2905 * This function returns false by default.
2906 *
2907 * \param sensor a sensor
2908 * \return true if the sensor is currently an obstacle for this entity
2909 */
is_sensor_obstacle(Sensor &)2910 bool Entity::is_sensor_obstacle(Sensor& /* sensor */) {
2911 return false;
2912 }
2913
2914 /**
2915 * \brief Returns whether a switch is currently considered as an obstacle by this entity.
2916 *
2917 * By default, this function returns true for solid switches and false for other ones.
2918 *
2919 * \param sw a switch
2920 * \return true if the switch is currently an obstacle for this entity
2921 */
is_switch_obstacle(Switch & sw)2922 bool Entity::is_switch_obstacle(Switch& sw) {
2923 return sw.is_solid();
2924 }
2925
2926 /**
2927 * \brief Returns whether a raised crystal block is currently considered as an obstacle by this entity.
2928 *
2929 * This function returns true by default.
2930 *
2931 * \param raised_block a crystal block raised
2932 * \return true if the raised block is currently an obstacle for this entity
2933 */
is_raised_block_obstacle(CrystalBlock &)2934 bool Entity::is_raised_block_obstacle(CrystalBlock& /* raised_block */) {
2935 return true;
2936 }
2937
2938 /**
2939 * \brief Returns whether a crystal is currently considered as an obstacle by this entity.
2940 *
2941 * This function returns true by default.
2942 * It should be redefined only for entities that can activate a crystal: a pot, the boomerang, etc.
2943 *
2944 * \param crystal a crystal
2945 * \return true if the crystal is currently an obstacle for this entity
2946 */
is_crystal_obstacle(Crystal &)2947 bool Entity::is_crystal_obstacle(Crystal& /* crystal */) {
2948 return true;
2949 }
2950
2951 /**
2952 * \brief Returns whether a non-playing character is currently considered as an obstacle by this entity.
2953 *
2954 * By default, this depends on the NPC.
2955 *
2956 * \param npc a non-playing character
2957 * \return true if the NPC is currently an obstacle for this entity
2958 */
is_npc_obstacle(Npc & npc)2959 bool Entity::is_npc_obstacle(Npc& npc) {
2960 return !npc.is_traversable();
2961 }
2962
2963 /**
2964 * \brief Returns whether a door is currently considered as an obstacle
2965 * by this entity.
2966 *
2967 * By default, this function returns \c true unless the door is open.
2968 *
2969 * \param door A door.
2970 * \return \c true if the door is currently an obstacle for this entity.
2971 */
is_door_obstacle(Door & door)2972 bool Entity::is_door_obstacle(Door& door) {
2973 return !door.is_open();
2974 }
2975
2976 /**
2977 * \brief Returns whether an enemy is currently considered as an obstacle by this entity.
2978 *
2979 * This function returns false by default.
2980 *
2981 * \param enemy an enemy
2982 * \return true if the enemy is currently an obstacle for this entity
2983 */
is_enemy_obstacle(Enemy &)2984 bool Entity::is_enemy_obstacle(Enemy& /* enemy */) {
2985 return false;
2986 }
2987
2988 /**
2989 * \brief Returns whether a jumper is currently considered as an obstacle by this entity.
2990 * \param jumper A jumper.
2991 * \param candidate_position Candidate position of the entity to test.
2992 * \return \c true if the jumper is currently an obstacle for this entity at
2993 * this candidate position.
2994 */
is_jumper_obstacle(Jumper &,const Rectangle &)2995 bool Entity::is_jumper_obstacle(Jumper& /* jumper */, const Rectangle& /* candidate_position */) {
2996 return true;
2997 }
2998
2999 /**
3000 * \brief Returns whether a destructible object is currently considered as an obstacle by this entity.
3001 *
3002 * By default, this function returns true.
3003 *
3004 * \param destructible a destructible item
3005 * \return true if the destructible item is currently an obstacle for this entity
3006 */
is_destructible_obstacle(Destructible &)3007 bool Entity::is_destructible_obstacle(Destructible& /* destructible */) {
3008
3009 return true;
3010 }
3011
3012 /**
3013 * \brief Returns whether a separator is currently considered as an obstacle
3014 * by this entity.
3015 *
3016 * By default, this function returns \c true.
3017 *
3018 * \param separator A separator.
3019 * \param candidate_position Candidate position of the entity to test.
3020 * \return \c true if the separator is currently an obstacle for this entity.
3021 */
is_separator_obstacle(Separator &,const Rectangle &)3022 bool Entity::is_separator_obstacle(Separator& /* separator */, const Rectangle& /* candidate_position */) {
3023
3024 return true;
3025 }
3026
3027 /**
3028 * \brief Returns true if this entity does not react to the sword.
3029 *
3030 * If true is returned, nothing will happen when the hero taps this entity with the sword.
3031 *
3032 * \return true if the sword is ignored
3033 */
is_sword_ignored() const3034 bool Entity::is_sword_ignored() const {
3035 return false;
3036 }
3037
3038 /**
3039 * \brief Returns whether the bounding box or a sprite of this entity overlaps
3040 * the visible part of the map
3041 * \return true if the entity is in the visible part of the map
3042 */
overlaps_camera() const3043 bool Entity::overlaps_camera() const {
3044
3045 const CameraPtr& camera = get_map().get_camera();
3046 if (camera == nullptr) {
3047 return false;
3048 }
3049
3050 if (camera->overlaps(bounding_box)) {
3051 return true;
3052 }
3053
3054 for (const NamedSprite& named_sprite: sprites) {
3055 if (named_sprite.removed) {
3056 continue;
3057 }
3058 Sprite& sprite = *named_sprite.sprite;
3059 const Size& sprite_size = sprite.get_size();
3060 const Point& sprite_origin = sprite.get_origin();
3061 const Rectangle sprite_bounding_box(
3062 get_x() - sprite_origin.x,
3063 get_y() - sprite_origin.y,
3064 sprite_size.width,
3065 sprite_size.height
3066 );
3067 if (camera->overlaps(sprite_bounding_box)) {
3068 return true;
3069 }
3070 }
3071
3072 return false;
3073 }
3074
3075 /**
3076 * \brief Returns whether or not this entity's origin point is in
3077 * the specified rectangle.
3078 * \param rectangle the rectangle to check
3079 * \return true if this entity's origin point is in the specified rectangle
3080 */
is_origin_point_in(const Rectangle & rectangle) const3081 bool Entity::is_origin_point_in(const Rectangle& rectangle) const {
3082 return rectangle.contains(get_xy());
3083 }
3084
3085 /**
3086 * \brief Returns whether this entity's facing point is in
3087 * the specified rectangle.
3088 * \param rectangle the rectangle to check
3089 * \return true if this entity's facing point is in the specified rectangle
3090 */
is_facing_point_in(const Rectangle & rectangle) const3091 bool Entity::is_facing_point_in(const Rectangle& rectangle) const {
3092
3093 const Point& facing_point = get_facing_point();
3094 return rectangle.contains(facing_point);
3095 }
3096
3097 /**
3098 * \brief Returns whether a touching point of this entity is in
3099 * the specified rectangle.
3100 * \param rectangle the rectangle to check
3101 * \param direction direction of the touching point to consider (0 to 3)
3102 * \return true if this touching point is in the specified rectangle
3103 */
is_touching_point_in(const Rectangle & rectangle,int direction) const3104 bool Entity::is_touching_point_in(
3105 const Rectangle& rectangle, int direction) const {
3106
3107 const Point& touching_point = get_touching_point(direction);
3108 return rectangle.contains(touching_point);
3109 }
3110
3111 /**
3112 * \brief Returns whether or not this entity's center is in
3113 * the specified rectangle.
3114 * \param rectangle the rectangle to check
3115 * \return true if this entity's center is in the specified rectangle
3116 */
is_center_in(const Rectangle & rectangle) const3117 bool Entity::is_center_in(const Rectangle& rectangle) const {
3118
3119 const Point& center = get_center_point();
3120 return rectangle.contains(center);
3121 }
3122
3123 /**
3124 * \brief Returns the angle of the vector between the origin of this entity
3125 * and a point.
3126 * \param x X coordinate of the point.
3127 * \param y Y coordinate of the point.
3128 * \return The angle of the vector in radians, between 0 and Geometry::TWO_PI.
3129 */
get_angle(int x,int y) const3130 double Entity::get_angle(int x, int y) const {
3131 return Geometry::get_angle(get_x(), get_y(), x, y);
3132 }
3133
3134 /**
3135 * \brief Returns the angle of the vector between the origin of this entity
3136 * and the origin of another entity.
3137 * \param other The other entity.
3138 * \return The angle of the vector in radians, between 0 and Geometry::TWO_PI.
3139 */
get_angle(const Entity & other) const3140 double Entity::get_angle(const Entity& other) const {
3141 return Geometry::get_angle(get_xy(), other.get_xy());
3142 }
3143
3144 /**
3145 * \brief Returns the angle of the vector between the origin of this entity or
3146 * one of its sprite and the origin of another entity or one of its sprites.
3147 * \param other The other entity.
3148 * \param this_sprite Sprite of this entity to use instead of the entity itself
3149 * or nullptr.
3150 * \param other_sprite Sprite of the other entity to use instead of the entity
3151 * itself or nullptr.
3152 * \return The angle of the vector in radians, between 0 and Geometry::TWO_PI.
3153 */
get_angle(const Entity & other,const Sprite * this_sprite,const Sprite * other_sprite) const3154 double Entity::get_angle(
3155 const Entity& other,
3156 const Sprite* this_sprite,
3157 const Sprite* other_sprite
3158 ) const {
3159
3160 // Add the coordinates of sprites as offsets.
3161 Point this_offset;
3162 if (this_sprite != nullptr) {
3163 this_offset += this_sprite->get_xy();
3164 }
3165
3166 Point other_offset;
3167 if (other_sprite != nullptr) {
3168 other_offset += other_sprite->get_xy();
3169 }
3170
3171 return Geometry::get_angle(
3172 get_x() + this_offset.x,
3173 get_y() + this_offset.y,
3174 other.get_x() + other_offset.x,
3175 other.get_y() + other_offset.y
3176 );
3177 }
3178
3179 /**
3180 * \brief Returns the distance between the origin of this entity and a point.
3181 * \param x x coordinate of the point
3182 * \param y y coordinate of the point
3183 * \return the distance between this entity and the point in pixels
3184 */
get_distance(int x,int y) const3185 int Entity::get_distance(int x, int y) const {
3186 return (int) Geometry::get_distance(get_x(), get_y(), x, y);
3187 }
3188
3189 /**
3190 * \brief Returns the distance between the origin of this entity and a point.
3191 * \param point coordinates of the point
3192 * \return the distance between this entity and the point in pixels
3193 */
get_distance(const Point & point) const3194 int Entity::get_distance(const Point& point) const {
3195 return (int) Geometry::get_distance(get_xy(), point);
3196 }
3197
3198 /**
3199 * \brief Returns the distance between the origin of this entity
3200 * and the origin of another entity.
3201 * \param other the other entity
3202 * \return the distance between the two entities in pixels
3203 */
get_distance(const Entity & other) const3204 int Entity::get_distance(const Entity& other) const {
3205 return (int) Geometry::get_distance(get_xy(), other.get_xy());
3206 }
3207
3208 /**
3209 * \brief Returns whether this entity is in the same region as another one.
3210 *
3211 * Regions are defined by the position of separators on the map.
3212 * The region of entities is the one of their center point.
3213 *
3214 * \param other Another entity.
3215 * \return \c true if both entities are in the same region.
3216 */
is_in_same_region(const Entity & other) const3217 bool Entity::is_in_same_region(const Entity& other) const {
3218
3219 return is_in_same_region(other.get_center_point());
3220 }
3221
3222 /**
3223 * \brief Returns whether this entity is in the same region as a point.
3224 *
3225 * Regions are defined by the position of separators on the map.
3226 * The region of this entity is the one of its center point.
3227 *
3228 * \param xy A point.
3229 * \return \c true if this entity and the point are in the same region.
3230 */
is_in_same_region(const Point & xy) const3231 bool Entity::is_in_same_region(const Point& xy) const {
3232
3233 const Point& this_xy = get_center_point();
3234 const Point& other_xy = xy;
3235
3236 const std::set<ConstSeparatorPtr>& separators =
3237 get_entities().get_entities_by_type<Separator>();
3238 for (const ConstSeparatorPtr& separator: separators) {
3239
3240 if (separator->is_vertical()) {
3241 // Vertical separation.
3242 if (this_xy.y < separator->get_top_left_y() ||
3243 this_xy.y >= separator->get_top_left_y() + separator->get_height()) {
3244 // This separator is irrelevant: the entity is not in either side,
3245 // it is too much to the north or to the south.
3246 //
3247 // |
3248 // |
3249 // |
3250 //
3251 // x
3252 //
3253 continue;
3254 }
3255
3256 if (other_xy.y < separator->get_top_left_y() ||
3257 other_xy.y >= separator->get_top_left_y() + separator->get_height()) {
3258 // This separator is irrelevant: the other entity is not in either side.
3259 // it is too much to the north or to the south.
3260 continue;
3261 }
3262
3263 // Both entities are in the zone of influence of this separator.
3264 // See if they are in the same side.
3265 const int separation_x = separator->get_center_point().x;
3266 if (this_xy.x < separation_x &&
3267 separation_x <= other_xy.x) {
3268 // Different side.
3269 return false;
3270 }
3271
3272 if (other_xy.x < separation_x &&
3273 separation_x <= this_xy.x) {
3274 // Different side.
3275 return false;
3276 }
3277 }
3278 else {
3279 // Horizontal separation.
3280 if (this_xy.x < separator->get_top_left_x() ||
3281 this_xy.x >= separator->get_top_left_x() + separator->get_width()) {
3282 continue;
3283 }
3284
3285 if (other_xy.x < separator->get_top_left_x() ||
3286 other_xy.x >= separator->get_top_left_x() + separator->get_width()) {
3287 continue;
3288 }
3289
3290 const int separation_y = separator->get_center_point().y;
3291 if (this_xy.y < separation_y &&
3292 separation_y <= other_xy.y) {
3293 return false;
3294 }
3295
3296 if (other_xy.y < separation_y &&
3297 separation_y <= this_xy.y) {
3298 return false;
3299 }
3300 }
3301 }
3302
3303 return true;
3304 }
3305
3306 /**
3307 * \brief This function is called when the position, movement or state changes.
3308 *
3309 * Subclasses can redefine it to perform some checks.
3310 */
check_position()3311 void Entity::check_position() {
3312 }
3313
3314 /**
3315 * \brief This function is called when a destructible item detects a non-pixel perfect collision with this entity.
3316 * \param destructible the destructible item
3317 * \param collision_mode the collision mode that detected the event
3318 */
notify_collision_with_destructible(Destructible &,CollisionMode)3319 void Entity::notify_collision_with_destructible(Destructible& /* destructible */, CollisionMode /* collision_mode */) {
3320 }
3321
3322 /**
3323 * \brief This function is called when a teletransporter detects a collision with this entity.
3324 * \param teletransporter the teletransporter
3325 * \param collision_mode the collision mode that detected the event
3326 */
notify_collision_with_teletransporter(Teletransporter &,CollisionMode)3327 void Entity::notify_collision_with_teletransporter(Teletransporter& /* teletransporter */, CollisionMode /* collision_mode */) {
3328 }
3329
3330 /**
3331 * \brief This function is called when a stream detects a collision with this
3332 * entity.
3333 * \param stream A stream.
3334 * \param dx Direction of the x move in pixels (0, 1 or -1).
3335 * \param dy Direction of the y move in pixels (0, 1 or -1).
3336 */
notify_collision_with_stream(Stream &,int,int)3337 void Entity::notify_collision_with_stream(
3338 Stream& /* stream */, int /* dx */, int /* dy */) {
3339 }
3340
3341 /**
3342 * \brief This function is called when a stairs entity detects a collision with this entity.
3343 * \param stairs the stairs
3344 * \param collision_mode the collision mode that detected the event
3345 */
notify_collision_with_stairs(Stairs &,CollisionMode)3346 void Entity::notify_collision_with_stairs(Stairs& /* stairs */, CollisionMode /* collision_mode */) {
3347 }
3348
3349 /**
3350 * \brief This function is called when a jumper detects a collision with this entity.
3351 * \param jumper The jumper.
3352 * \param collision_mode The collision mode that detected the event.
3353 */
notify_collision_with_jumper(Jumper &,CollisionMode)3354 void Entity::notify_collision_with_jumper(Jumper& /* jumper */, CollisionMode /* collision_mode */) {
3355 }
3356
3357 /**
3358 * \brief This function is called when a sensor detects a collision with this entity.
3359 * \param sensor a sensor
3360 * \param collision_mode the collision mode that detected the collision
3361 */
notify_collision_with_sensor(Sensor &,CollisionMode)3362 void Entity::notify_collision_with_sensor(Sensor& /* sensor */, CollisionMode /* collision_mode */) {
3363 }
3364
3365 /**
3366 * \brief This function is called when a switch detects a collision with this entity.
3367 * \param sw a switch
3368 * \param collision_mode the collision mode that detected the event
3369 */
notify_collision_with_switch(Switch &,CollisionMode)3370 void Entity::notify_collision_with_switch(Switch& /* sw */,
3371 CollisionMode /* collision_mode */) {
3372 }
3373
3374 /**
3375 * \brief This function is called when the sprite of a switch
3376 * detects a pixel-precise collision with a sprite of this entity.
3377 * \param sw the switch
3378 * \param sprite_overlapping the sprite of the current entity that collides with the switch
3379 */
notify_collision_with_switch(Switch &,Sprite &)3380 void Entity::notify_collision_with_switch(Switch& /* sw */, Sprite& /* sprite_overlapping */) {
3381 }
3382
3383 /**
3384 * \brief This function is called when a crystal detects a collision with this entity.
3385 * \param crystal the crystal
3386 * \param collision_mode the collision mode that detected the event
3387 */
notify_collision_with_crystal(Crystal &,CollisionMode)3388 void Entity::notify_collision_with_crystal(Crystal& /* crystal */,
3389 CollisionMode /* collision_mode */) {
3390 }
3391
3392 /**
3393 * \brief This function is called when the sprite of a crystal
3394 * detects a pixel-precise collision with a sprite of this entity.
3395 * \param crystal the crystal
3396 * \param sprite_overlapping the sprite of the current entity that collides with the crystal
3397 */
notify_collision_with_crystal(Crystal &,Sprite &)3398 void Entity::notify_collision_with_crystal(Crystal& /* crystal */, Sprite& /* sprite_overlapping */) {
3399 }
3400
3401 /**
3402 * \brief This function is called when a chest detects a collision with this entity.
3403 * \param chest the chest
3404 */
notify_collision_with_chest(Chest &)3405 void Entity::notify_collision_with_chest(Chest& /* chest */) {
3406 }
3407
3408 /**
3409 * \brief This function is called when a block detects a collision with this entity.
3410 * \param block the block
3411 */
notify_collision_with_block(Block &)3412 void Entity::notify_collision_with_block(Block& /* block */) {
3413 }
3414
3415 /**
3416 * \brief This function is called when a separator detects a collision with
3417 * this entity.
3418 * \param separator The separator.
3419 * \param collision_mode The collision mode that detected the event.
3420 */
notify_collision_with_separator(Separator &,CollisionMode)3421 void Entity::notify_collision_with_separator(
3422 Separator& /* separator */, CollisionMode /* collision_mode */) {
3423
3424 }
3425
3426 /**
3427 * \brief This function is called when bomb detects a collision with a this entity.
3428 * \param bomb the bomb
3429 * \param collision_mode the collision mode that detected the event
3430 */
notify_collision_with_bomb(Bomb &,CollisionMode)3431 void Entity::notify_collision_with_bomb(Bomb& /* bomb */, CollisionMode /* collision_mode */) {
3432 }
3433
3434 /**
3435 * \brief This function is called when an explosion detects a collision with this entity.
3436 * \param explosion the explosion
3437 * \param collision_mode the collision mode that detected the event
3438 */
notify_collision_with_explosion(Explosion &,CollisionMode)3439 void Entity::notify_collision_with_explosion(Explosion& /* explosion */,
3440 CollisionMode /* collision_mode */) {
3441 }
3442
3443 /**
3444 * \brief This function is called when an explosion's sprite
3445 * detects a pixel-perfect collision with a sprite of this entity.
3446 * \param explosion the explosion
3447 * \param sprite_overlapping the sprite of the current entity that collides with the explosion
3448 */
notify_collision_with_explosion(Explosion &,Sprite &)3449 void Entity::notify_collision_with_explosion(Explosion& /* explosion */, Sprite& /* sprite_overlapping */) {
3450 }
3451
3452 /**
3453 * \brief Notifies this entity that a sprite of fire
3454 * detects a pixel-perfect collision with a sprite of this entity.
3455 * \param fire the fire
3456 * \param sprite_overlapping the sprite of the current entity that collides with the fire
3457 */
notify_collision_with_fire(Fire &,Sprite &)3458 void Entity::notify_collision_with_fire(Fire& /* fire */, Sprite& /* sprite_overlapping */) {
3459 }
3460
3461 /**
3462 * \brief This function is called when an enemy detects a collision with this entity.
3463 * \param enemy The enemy.
3464 * \param collision_mode The collision mode that detected the event.
3465 */
notify_collision_with_enemy(Enemy &,CollisionMode)3466 void Entity::notify_collision_with_enemy(Enemy& /* enemy */, CollisionMode /* collision_mode */) {
3467 }
3468
3469 /**
3470 * \brief This function is called when an enemy's sprite collides with a sprite of this entity.
3471 * \param enemy the enemy
3472 * \param this_sprite this entity's sprite that overlaps the enemy's sprite
3473 * \param enemy_sprite the enemy's sprite that overlaps a sprite of this entity
3474 */
notify_collision_with_enemy(Enemy &,Sprite &,Sprite &)3475 void Entity::notify_collision_with_enemy(Enemy& /* enemy */, Sprite& /* this_sprite */, Sprite& /* enemy_sprite */) {
3476 }
3477
3478 /**
3479 * \brief Notifies this entity that it has just attacked an enemy.
3480 *
3481 * This function is called even if this attack was not successful.
3482 *
3483 * \param attack The attack.
3484 * \param victim The enemy just hurt.
3485 * \param victim_sprite The enemy's sprite that was touched or nullptr.
3486 * \param result How the enemy has reacted to the attack.
3487 * \param killed Whether the attack has just killed the enemy.
3488 */
notify_attacked_enemy(EnemyAttack,Enemy &,Sprite *,const EnemyReaction::Reaction &,bool)3489 void Entity::notify_attacked_enemy(
3490 EnemyAttack /* attack */,
3491 Enemy& /* victim */,
3492 Sprite* /* victim_sprite */,
3493 const EnemyReaction::Reaction& /* result */,
3494 bool /* killed */) {
3495 }
3496
3497 /**
3498 * \brief Notifies this entity that the player is interacting with it by
3499 * pressing the action command.
3500 *
3501 * Only possible if this entity detects collisions of type
3502 * CollisionMode::COLLISION_FACING.
3503 *
3504 * This function is called when the player presses the action command
3505 * while the hero is facing this entity, unless the action command effect
3506 * does not allow the hero to interact with the entity, like while he is
3507 * carrying an object.
3508 *
3509 * By default, the entity is lifted if the player's lift ability allows it.
3510 *
3511 * Redefine your function in the subclasses to make the hero interact with
3512 * this entity differently.
3513 *
3514 * \return \c true if an interaction happened.
3515 */
notify_action_command_pressed()3516 bool Entity::notify_action_command_pressed() {
3517
3518 if (!can_be_lifted()) {
3519 return false;
3520 }
3521
3522 CommandsEffects::ActionKeyEffect effect = get_commands_effects().get_action_key_effect();
3523 if (effect == CommandsEffects::ACTION_KEY_LIFT &&
3524 get_hero().get_facing_entity() == this &&
3525 get_hero().is_facing_point_in(get_bounding_box())) {
3526
3527 std::string sprite_id;
3528 if (has_sprite()) {
3529 sprite_id = get_sprite()->get_animation_set_id();
3530 }
3531 std::shared_ptr<CarriedObject> carried_object = std::make_shared<CarriedObject>(
3532 get_hero(),
3533 *this,
3534 sprite_id,
3535 "stone",
3536 1, // damage_on_enemies
3537 0 // explosion_date
3538 );
3539 get_hero().start_lifting(carried_object);
3540
3541 Sound::play("lift");
3542 remove_from_map();
3543 get_lua_context()->entity_on_lifting(*this, get_hero(), *carried_object);
3544 return true;
3545 }
3546
3547 return false;
3548 }
3549
3550 /**
3551 * \brief Notifies this entity that the player is interacting with it by
3552 * using an equipment item.
3553 *
3554 * Only possible if this entity detects collisions of type
3555 * CollisionMode::COLLISION_FACING.
3556 *
3557 * This function is called when the player uses an equipment item
3558 * while the hero is facing this entity.
3559 *
3560 * By default, nothing happens.
3561 * Redefine your function in the subclasses to make your entity react to an
3562 * equipment item.
3563 *
3564 * \param item The equipment item used.
3565 * \return \c true if an interaction occurred.
3566 */
notify_interaction_with_item(EquipmentItem &)3567 bool Entity::notify_interaction_with_item(EquipmentItem& /* item */) {
3568 return false;
3569 }
3570
3571 /**
3572 * \brief This function is called when the player tries to push or pull this
3573 * entity.
3574 *
3575 * By default, nothing happens.
3576 * Redefine your function in the subclasses to make something happen with the entity.
3577 *
3578 * \return \c true if this entity was pushed or pulled successfully.
3579 */
start_movement_by_hero()3580 bool Entity::start_movement_by_hero() {
3581 return false;
3582 }
3583
3584 /**
3585 * \brief This function is called when the player finishes to push or pull
3586 * this entity.
3587 *
3588 * By default, nothing happens.
3589 * Redefine your function in the subclasses to make something happen with the entity.
3590 */
stop_movement_by_hero()3591 void Entity::stop_movement_by_hero() {
3592 }
3593
3594 /**
3595 * \brief This function is called when the player is tapping his sword against this entity.
3596 * \return The sound to play when tapping this entity with the sword.
3597 */
get_sword_tapping_sound()3598 std::string Entity::get_sword_tapping_sound() {
3599 return "sword_tapping";
3600 }
3601
3602 /**
3603 * \brief Returns whether the movement and the animations of this entity are suspended.
3604 * \return true if the movement and the animations are suspended
3605 */
is_suspended() const3606 bool Entity::is_suspended() const {
3607 return suspended;
3608 }
3609
3610 /**
3611 * \brief Suspends or resumes the movement and the animations of this entity.
3612 * \param suspended true to suspend the movement and the animations, false to resume them
3613 */
set_suspended(bool suspended)3614 void Entity::set_suspended(bool suspended) {
3615
3616 this->suspended = suspended;
3617
3618 // Remember the date if the entity is being suspended.
3619 if (suspended) {
3620 when_suspended = System::now();
3621 }
3622
3623 // Suspend/unsuspend sprite animations.
3624 set_sprites_suspended(suspended);
3625
3626 // Suspend/unsuspend the movement.
3627 if (movement != nullptr) {
3628 if (!movement->get_ignore_suspend()) {
3629 movement->set_suspended(suspended || !is_enabled());
3630 }
3631 }
3632 if (stream_action != nullptr) {
3633 stream_action->set_suspended(suspended || !is_enabled());
3634 }
3635
3636 if (is_on_map()) {
3637 // Suspend/unsuspend timers.
3638 get_lua_context()->set_entity_timers_suspended_as_map(*this, suspended || !is_enabled());
3639
3640 if (!suspended) {
3641 // Collision tests were disabled when the entity was suspended.
3642 get_map().check_collision_from_detector(*this);
3643 check_collision_with_detectors();
3644 }
3645 get_lua_context()->entity_on_suspended(*this, suspended);
3646 }
3647 }
3648
3649 /**
3650 * \brief Returns the date when this entity was suspended.
3651 * \return When this entity was suspended.
3652 */
get_when_suspended() const3653 uint32_t Entity::get_when_suspended() const {
3654 return when_suspended;
3655 }
3656
3657 /**
3658 * \brief Makes this entity's sprites play their animation even when the game is suspended.
3659 * \param ignore_suspend true to keep playing the sprites when the game is suspended
3660 */
set_animation_ignore_suspend(bool ignore_suspend)3661 void Entity::set_animation_ignore_suspend(bool ignore_suspend) {
3662
3663 for (const NamedSprite& named_sprite: sprites) {
3664 if (named_sprite.removed) {
3665 continue;
3666 }
3667 Sprite& sprite = *named_sprite.sprite;
3668 sprite.set_ignore_suspend(ignore_suspend);
3669 }
3670 }
3671
3672 /**
3673 * \brief Suspends or resumes the animations of this entity.
3674 * \param suspended \c true to suspend the animations, false to resume them
3675 */
set_sprites_suspended(bool suspended)3676 void Entity::set_sprites_suspended(bool suspended) {
3677
3678 for (const NamedSprite& named_sprite: sprites) {
3679 if (named_sprite.removed) {
3680 continue;
3681 }
3682 Sprite& sprite = *named_sprite.sprite;
3683 sprite.set_suspended(suspended || !is_enabled());
3684 }
3685 }
3686
3687 /**
3688 * \brief Updates the entity.
3689 *
3690 * This function is called repeatedly by the map.
3691 * By default, it updates the position
3692 * of the entity according to its movement (if any),
3693 * and it updates the sprites frames if there are sprites.
3694 * Redefine it in subclasses for the entities that should be updated
3695 * for other treatments but don't forget to call this method
3696 * to handle the movement and the sprites.
3697 */
update()3698 void Entity::update() {
3699
3700 // Static tiles are optimized and should never be used individually
3701 // once the map is created.
3702 SOLARUS_ASSERT(get_type() != EntityType::TILE,
3703 "Attempt to update a static tile");
3704
3705 if (is_being_removed()) {
3706 return;
3707 }
3708
3709 // Check the facing entity.
3710 if (facing_entity != nullptr && facing_entity->is_being_removed()) {
3711 set_facing_entity(nullptr);
3712 }
3713
3714 update_sprites();
3715
3716 // Update the movement.
3717 if (movement != nullptr) {
3718 movement->update();
3719 }
3720 clear_old_movements();
3721 update_stream_action();
3722
3723 // Update the state if any.
3724 update_state();
3725 }
3726
3727 /**
3728 * \brief Updates all sprites of this entity.
3729 */
update_sprites()3730 void Entity::update_sprites() {
3731
3732 if (sprites.size() == 1) {
3733 // Special case just to avoid a copy of the vector.
3734 if (!sprites[0].removed) {
3735 update_sprite(*sprites[0].sprite);
3736 }
3737 } else {
3738 // Iterate on a copy because the list might change during the iteration.
3739 std::vector<NamedSprite> sprites = this->sprites;
3740 for (const NamedSprite& named_sprite: sprites) {
3741 if (named_sprite.removed) {
3742 continue;
3743 }
3744 update_sprite(*named_sprite.sprite);
3745 }
3746 }
3747 clear_old_sprites();
3748 }
3749
3750 /**
3751 * Updates one sprite of this entity.
3752 * @param named_sprite The sprite to update.
3753 */
update_sprite(Sprite & sprite)3754 void Entity::update_sprite(Sprite& sprite) {
3755
3756 sprite.update();
3757 if (sprite.has_frame_changed()) {
3758 // The frame has just changed.
3759 // Pixel-precise collisions need to be rechecked.
3760 if (sprite.are_pixel_collisions_enabled()) {
3761
3762 if (is_detector()) {
3763 // Since this entity is a detector, all entities need to check
3764 // their pixel-precise collisions with it.
3765 get_map().check_collision_from_detector(*this, sprite);
3766 }
3767
3768 check_collision_with_detectors(sprite);
3769 }
3770
3771 notify_sprite_frame_changed(sprite, sprite.get_current_animation(), sprite.get_current_frame());
3772 if (sprite.is_animation_finished()) {
3773 notify_sprite_animation_finished(sprite, sprite.get_current_animation());
3774 }
3775 }
3776 }
3777
3778 /**
3779 * \brief Returns whether this entity is drawn at its position on the map.
3780 *
3781 * Usually, this function returns true, and when it is the case, draw_on_map()
3782 * is called only for entities located in the camera's rectangle.
3783 *
3784 * However, some entities may want to be drawn in the camera even when their
3785 * position is outside, typically to make an illusion of movement like parallax
3786 * scrolling.
3787 *
3788 * \return true if this entity is drawn where it is located.
3789 */
is_drawn_at_its_position() const3790 bool Entity::is_drawn_at_its_position() const {
3791 return true;
3792 }
3793
3794 /**
3795 * \brief Draws this entity on the map, including the Lua draw events.
3796 */
draw(Camera & camera)3797 void Entity::draw(Camera& camera) {
3798
3799 if (!is_visible()) {
3800 return;
3801 }
3802 if (get_state() != nullptr && !get_state()->is_visible()) {
3803 return;
3804 }
3805
3806 get_lua_context()->entity_on_pre_draw(*this, camera);
3807 if (draw_override.is_empty()) {
3808 built_in_draw(camera);
3809 }
3810 else {
3811 get_lua_context()->do_entity_draw_override_function(draw_override, *this, camera);
3812 }
3813 get_lua_context()->entity_on_post_draw(*this, camera);
3814 }
3815
3816 /**
3817 * \brief Built-in implementation of drawing the entity on the map.
3818 *
3819 * By default, this function draws the entity's sprites.
3820 * Lua scripts can replace this built-in draw with entity:set_draw_override().
3821 *
3822 * \param camera The camera where to draw.
3823 */
built_in_draw(Camera & camera)3824 void Entity::built_in_draw(Camera& camera) {
3825 draw_sprites(camera);
3826 }
3827
3828 /**
3829 * \brief Draws the sprites of this entity.
3830 *
3831 * This function draws the entity's sprites (if any) and if
3832 * at least one of them is in the visible part of the map.
3833 *
3834 * \param camera The camera where to draw.
3835 * \param clipping_area Rectangle of the map where the drawing will be
3836 * restricted. A flat rectangle means no restriction.
3837 */
draw_sprites(Camera &,const Rectangle & clipping_area)3838 void Entity::draw_sprites(Camera& /* camera */, const Rectangle& clipping_area) {
3839
3840 const Point& xy = get_displayed_xy();
3841 const Size& size = get_size();
3842
3843 // Draw the sprites.
3844 for (const NamedSprite& named_sprite: sprites) {
3845 if (named_sprite.removed) {
3846 continue;
3847 }
3848 Sprite& sprite = *named_sprite.sprite;
3849
3850 if (!is_tiled()) {
3851 get_map().draw_visual(sprite, xy, clipping_area);
3852 }
3853 else {
3854 // Repeat the sprite with tiling.
3855 const Size& sprite_size = sprite.get_size();
3856 int x1 = xy.x;
3857 int y1 = xy.y;
3858 int x2 = x1 + size.width;
3859 int y2 = y1 + size.height;
3860
3861 for (int y = y1; y < y2; y += sprite_size.height) {
3862 for (int x = x1; x < x2; x += sprite_size.width) {
3863 get_map().draw_visual(sprite, x, y, clipping_area);
3864 }
3865 }
3866 }
3867 }
3868 }
3869
3870 /**
3871 * \brief Returns the Lua draw function of this entity if any.
3872 * \return The draw override or an empty ref.
3873 */
get_draw_override() const3874 ScopedLuaRef Entity::get_draw_override() const {
3875 return draw_override;
3876 }
3877
3878 /**
3879 * \brief Sets the Lua draw function of this entity.
3880 * \param draw_override The draw override or an empty ref.
3881 */
set_draw_override(const ScopedLuaRef & draw_override)3882 void Entity::set_draw_override(const ScopedLuaRef& draw_override) {
3883 this->draw_override = draw_override;
3884 }
3885
3886 /**
3887 * \brief Returns the current state of this entity.
3888 * \return The state.
3889 */
get_state() const3890 std::shared_ptr<Entity::State> Entity::get_state() const {
3891 return state;
3892 }
3893
3894 /**
3895 * \brief Changes the entity's internal state.
3896 *
3897 * This function stops the old state and starts the new one.
3898 * The old state will also be automatically destroyed, but not right now,
3899 * in order to allow this function to be called by the old state itself safely.
3900 *
3901 * \param state The new state of the entity.
3902 */
set_state(const std::shared_ptr<State> & new_state)3903 void Entity::set_state(const std::shared_ptr<State>& new_state) {
3904
3905 // Stop the previous state.
3906 std::shared_ptr<State> old_state = this->state;
3907 if (old_state != nullptr) {
3908
3909 old_state->stop(new_state.get()); // Should not change the state again.
3910
3911 // Sanity check.
3912 if (old_state != this->state) {
3913 // old_state->stop() called set_state() again in the meantime.
3914 // This is not a normal situation since we only called stop() to allow
3915 // new_state to start.
3916 Debug::error(std::string("Entity state '") + old_state->get_name()
3917 + "' did not stop properly to let state '" + new_state->get_name()
3918 + "' go, it started state '" + this->state->get_name() + "' instead. "
3919 + "State '" + new_state->get_name() + "' will be forced.");
3920
3921 // Let's start the state that was supposed to start in the first place.
3922 // Note that old_state is already in the old_states list.
3923 set_state(new_state);
3924 return;
3925 }
3926 }
3927
3928 // Don't delete the previous state immediately since it may be the caller
3929 // of this function.
3930 this->old_states.emplace_back(this->state);
3931
3932 this->state = new_state;
3933 this->state->start(old_state.get()); // May also change the state again.
3934
3935 if (this->state == new_state) {
3936 // If the state has not already changed again.
3937 check_position();
3938 }
3939 }
3940
3941 /**
3942 * \brief Returns the name of the entity's internal state.
3943 * \return A name describing the current state of the entity.
3944 * Returns an empty string if this entity has no state.
3945 */
get_state_name() const3946 std::string Entity::get_state_name() const {
3947
3948 if (state == nullptr) {
3949 return "";
3950 }
3951 return state->get_name();
3952 }
3953
3954 /**
3955 * \brief Updates the entity's internal state if any.
3956 *
3957 * This function is called repeatedly by the game loop.
3958 */
update_state()3959 void Entity::update_state() {
3960
3961 // Update the current state
3962 if (state != nullptr) {
3963 state->update();
3964 }
3965
3966 // Cleanup old states.
3967 old_states.clear();
3968 }
3969
3970 }
3971