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 #ifndef SOLARUS_ENTITY_H
18 #define SOLARUS_ENTITY_H
19
20 #include "solarus/core/Rectangle.h"
21 #include "solarus/core/GameCommand.h"
22 #include "solarus/core/Common.h"
23 #include "solarus/entities/EntityType.h"
24 #include "solarus/entities/Ground.h"
25 #include "solarus/entities/CollisionMode.h"
26 #include "solarus/entities/EnemyAttack.h"
27 #include "solarus/entities/EnemyReaction.h"
28 #include "solarus/graphics/SpritePtr.h"
29 #include "solarus/lua/ExportableToLua.h"
30 #include <list>
31 #include <memory>
32 #include <set>
33 #include <string>
34 #include <vector>
35
36 struct lua_State;
37
38 namespace Solarus {
39
40 class Block;
41 class Bomb;
42 class Camera;
43 class Chest;
44 class CommandsEffects;
45 class Crystal;
46 class CrystalBlock;
47 class Destination;
48 class Destructible;
49 class Door;
50 class Enemy;
51 class Equipment;
52 class EquipmentItem;
53 class Explosion;
54 class Fire;
55 class Game;
56 class GameCommands;
57 class Hero;
58 class Jumper;
59 class LuaContext;
60 class Map;
61 class MainLoop;
62 class Entities;
63 class Movement;
64 class Npc;
65 class Savegame;
66 class Separator;
67 class Sensor;
68 class Sprite;
69 class Stairs;
70 class Stream;
71 class StreamAction;
72 class Switch;
73 class Teletransporter;
74
75 /**
76 * \brief Abstract class for all objects placed on a map.
77 *
78 * Example of entities include tiles, enemies, the hero,
79 * non-playing characters, doors, chests, etc.
80 * Each entity has:
81 * - a bounding box that represents its position on the map (a rectangle),
82 * - a layer on the map,
83 * - an origin point, relative to the rectangle's top-left corner.
84 * Some entities can also have a name, a movement and some sprites.
85 */
86 class SOLARUS_API Entity: public ExportableToLua {
87
88 public:
89
90 using UserProperty = std::pair<std::string, std::string>;
91
92 struct NamedSprite {
93 std::string name;
94 SpritePtr sprite;
95 bool removed = false;
96 };
97
98 // Destruction.
99 virtual ~Entity();
100 void remove_from_map();
101 virtual void notify_being_removed();
102 bool is_being_removed() const;
103
104 /**
105 * \brief Returns the type of entity.
106 * \return The type of entity.
107 */
108 virtual EntityType get_type() const = 0;
109 virtual const std::string& get_lua_type_name() const override;
110 bool is_hero() const;
111 virtual bool is_ground_observer() const;
112 Point get_ground_point() const;
113 bool is_ground_modifier() const;
114 virtual Ground get_modified_ground() const;
115 virtual bool can_be_drawn() const;
116 virtual bool is_drawn_at_its_position() const;
117
118 virtual void notify_command_pressed(GameCommand command);
119 virtual void notify_command_released(GameCommand command);
120
121 // Adding to a map.
122 bool is_initialized() const;
123 bool is_on_map() const;
124 void set_map(Map& map);
125 Map& get_map() const;
126 virtual void notify_creating();
127 virtual void notify_created();
128 virtual void notify_map_starting(Map& map, const std::shared_ptr<Destination>& destination);
129 virtual void notify_map_started(Map& map, const std::shared_ptr<Destination>& destination);
130 virtual void notify_map_opening_transition_finishing(Map& map, const std::shared_ptr<Destination>& destination);
131 virtual void notify_map_opening_transition_finished(Map& map, const std::shared_ptr<Destination>& destination);
132 virtual void notify_map_finished();
133 virtual void notify_tileset_changed();
134 Game& get_game();
135 const Game& get_game() const;
136
137 // Position in the map.
138 int get_layer() const;
139 void set_layer(int layer);
140 Ground get_ground_below() const;
141
142 int get_x() const;
143 int get_y() const;
144 void set_x(int x);
145 void set_y(int y);
146 Point get_xy() const;
147 void set_xy(const Point& xy);
148 void set_xy(int x, int y);
149 Point get_displayed_xy() const;
150
151 int get_width() const;
152 int get_height() const;
153 Size get_size() const;
154 void set_size(int width, int height);
155 void set_size(const Size& size);
156 virtual void notify_size_changed();
157 const Rectangle& get_bounding_box() const;
158 void set_bounding_box(const Rectangle& bounding_box);
159 Rectangle get_extended_bounding_box(int margin) const;
160 virtual Rectangle get_max_bounding_box() const;
161 void notify_bounding_box_changed();
162 const Point& get_origin() const;
163 void set_origin(int x, int y);
164 void set_origin(const Point& origin);
165 int get_top_left_x() const;
166 int get_top_left_y() const;
167 Point get_top_left_xy() const;
168 void set_top_left_x(int x);
169 void set_top_left_y(int y);
170 void set_top_left_xy(int x, int y);
171 void set_top_left_xy(const Point& xy);
172
173 virtual Point get_facing_point() const;
174 Point get_touching_point(int direction) const;
175 Point get_center_point() const;
176
177 bool is_aligned_to_grid() const;
178 bool is_aligned_to_grid_x() const;
179 bool is_aligned_to_grid_y() const;
180 void set_aligned_to_grid();
181 void set_aligned_to_grid_x();
182 void set_aligned_to_grid_y();
183
184 int get_optimization_distance() const;
185 int get_optimization_distance2() const;
186 void set_optimization_distance(int distance);
187
188 int get_z() const;
189 void set_z(int z);
190
191 bool is_enabled() const;
192 void set_enabled(bool enable);
193 virtual void notify_enabled(bool enabled);
194
195 // Properties.
196 const std::string& get_name() const;
197 void set_name(const std::string& name);
198 bool has_name() const;
199 bool has_prefix(const std::string& prefix) const;
200 int get_direction() const;
201 void set_direction(int direction);
202 virtual void notify_direction_changed();
203
204 const std::vector<UserProperty>& get_user_properties() const;
205 void set_user_properties(const std::vector<UserProperty>& user_properties);
206 bool has_user_property(const std::string& key) const;
207 const std::string& get_user_property_value(const std::string& key) const;
208 void set_user_property_value(const std::string& key, const std::string& value);
209 void remove_user_property(const std::string& key);
210
211 // Sprites.
212 bool has_sprite() const;
213 SpritePtr get_sprite(const std::string& sprite_name = "") const;
214 std::vector<SpritePtr> get_sprites() const;
215 std::vector<NamedSprite> get_named_sprites() const;
216 SpritePtr create_sprite(
217 const std::string& animation_set_id,
218 const std::string& sprite_name = "",
219 int order = -1
220 );
221 int get_sprite_order(Sprite& sprite);
222 bool remove_sprite(Sprite& sprite);
223 void clear_sprites();
224 bool bring_sprite_to_back(Sprite& sprite);
225 bool bring_sprite_to_front(Sprite& sprite);
226 std::string get_default_sprite_name() const;
227 void set_default_sprite_name(const std::string& default_sprite_name);
228 virtual void notify_sprite_frame_changed(Sprite& sprite, const std::string& animation, int frame);
229 virtual void notify_sprite_animation_finished(Sprite& sprite, const std::string& animation);
230 bool is_visible() const;
231 void set_visible(bool visible);
232 bool is_tiled() const;
233 void set_tiled(bool tiled);
234 bool is_drawn_in_y_order() const;
235 void set_drawn_in_y_order(bool drawn_in_y_order);
236 void set_animation_ignore_suspend(bool ignore_suspend);
237 void set_sprites_suspended(bool suspended);
238 void update_sprites();
239 void update_sprite(Sprite& sprite);
240 ScopedLuaRef get_draw_override() const;
241 void set_draw_override(const ScopedLuaRef& draw_override);
242
243 // Movement.
244 const std::shared_ptr<Movement>& get_movement();
245 std::shared_ptr<const Movement> get_movement() const;
246 void set_movement(const std::shared_ptr<Movement>& movement);
247 void clear_movement();
248 bool are_movement_notifications_enabled() const;
249 void set_movement_notifications_enabled(bool notify);
250 bool has_stream_action() const;
251 const StreamAction* get_stream_action() const;
252 StreamAction* get_stream_action();
253 void start_stream_action(std::unique_ptr<StreamAction> stream_action);
254 void stop_stream_action();
255
256 virtual void notify_position_changed();
257 virtual void notify_layer_changed();
258 virtual void notify_ground_below_changed();
259 virtual void notify_obstacle_reached();
260 virtual void notify_movement_started();
261 virtual void notify_movement_finished();
262 virtual void notify_movement_changed();
263 virtual void notify_moving_by(Entity& entity);
264 virtual void notify_moved_by(Entity& entity);
265
266 Entity* get_facing_entity();
267 const Entity* get_facing_entity() const;
268 void set_facing_entity(Entity* facing_entity);
269 virtual void notify_facing_entity_changed(Entity* facing_entity);
270 static const Point& direction_to_xy_move(int direction8);
271
272 // Geometry.
273 bool overlaps(const Rectangle& rectangle) const;
274 bool overlaps(const Point& point) const;
275 bool overlaps(int x, int y) const;
276 bool overlaps(const Entity& other) const;
277 bool overlaps_camera() const;
278 bool is_origin_point_in(const Rectangle& rectangle) const;
279 bool is_facing_point_in(const Rectangle& rectangle) const;
280 bool is_touching_point_in(const Rectangle& rectangle, int direction) const;
281 bool is_center_in(const Rectangle& rectangle) const;
282
283 double get_angle(int x, int y) const;
284 double get_angle(const Entity& other) const;
285 double get_angle(
286 const Entity& other,
287 const Sprite* this_sprite,
288 const Sprite* other_sprite) const;
289 int get_distance(int x, int y) const;
290 int get_distance(const Point& point) const;
291 int get_distance(const Entity& other) const;
292 bool is_in_same_region(const Entity& other) const;
293 bool is_in_same_region(const Point& xy) const;
294
295 // Collisions.
296 bool is_detector() const;
297 void set_collision_modes(int collision_modes);
298 void add_collision_mode(CollisionMode collision_mode);
299 bool has_collision_mode(CollisionMode collision_mode);
300 void enable_pixel_collisions();
301
302 bool has_layer_independent_collisions() const;
303 void set_layer_independent_collisions(bool independent);
304
305 // Detecting other entities.
306 void check_collision(Entity& other);
307 void check_collision(Entity& other, Sprite& other_sprite);
308 void check_collision(Sprite& this_sprite, Entity& other);
309 bool test_collision(
310 Entity& entity,
311 CollisionMode collision_mode,
312 const SpritePtr& this_sprite,
313 const SpritePtr& other_sprite);
314 bool test_collision_rectangle(const Entity& entity) const;
315 bool test_collision_inside(const Entity& entity) const;
316 bool test_collision_origin_point(const Entity& entity) const;
317 bool test_collision_facing_point(const Entity& entity) const;
318 bool test_collision_touching(const Entity& entity) const;
319 bool test_collision_center(const Entity& entity) const;
320 bool test_collision_sprites(
321 Entity& entity,
322 const SpritePtr& this_sprite,
323 const SpritePtr& other_sprite);
324 virtual bool test_collision_custom(Entity& entity);
325
326 // Being detected by other entities.
327 void check_collision_with_detectors();
328 void check_collision_with_detectors(Sprite& sprite);
329
330 virtual void check_position();
331 virtual void notify_collision_with_destructible(Destructible& destructible, CollisionMode collision_mode);
332 virtual void notify_collision_with_teletransporter(Teletransporter& teletransporter, CollisionMode collision_mode);
333 virtual void notify_collision_with_stream(Stream& stream, int dx, int dy);
334 virtual void notify_collision_with_stairs(Stairs& stairs, CollisionMode collision_mode);
335 virtual void notify_collision_with_jumper(Jumper& jumper, CollisionMode collision_mode);
336 virtual void notify_collision_with_sensor(Sensor& sensor, CollisionMode collision_mode);
337 virtual void notify_collision_with_switch(Switch& sw, CollisionMode collision_mode);
338 virtual void notify_collision_with_switch(Switch& sw, Sprite& sprite_overlapping);
339 virtual void notify_collision_with_crystal(Crystal& crystal, CollisionMode collision_mode);
340 virtual void notify_collision_with_crystal(Crystal& crystal, Sprite& sprite_overlapping);
341 virtual void notify_collision_with_chest(Chest& chest);
342 virtual void notify_collision_with_block(Block& block);
343 virtual void notify_collision_with_separator(Separator& separator, CollisionMode collision_mode);
344 virtual void notify_collision_with_bomb(Bomb& bomb, CollisionMode collision_mode);
345 virtual void notify_collision_with_explosion(Explosion& explosion, CollisionMode collision_mode);
346 virtual void notify_collision_with_explosion(Explosion& explosion, Sprite& sprite_overlapping);
347 virtual void notify_collision_with_fire(Fire& fire, Sprite& sprite_overlapping);
348 virtual void notify_collision_with_enemy(Enemy& enemy, CollisionMode collision_mode);
349 virtual void notify_collision_with_enemy(Enemy& enemy, Sprite& this_sprite, Sprite& enemy_sprite);
350 virtual void notify_attacked_enemy(
351 EnemyAttack attack,
352 Enemy& victim,
353 Sprite* victim_sprite,
354 const EnemyReaction::Reaction& result,
355 bool killed);
356
357 // Interactions.
358 bool can_be_lifted() const;
359 int get_weight() const;
360 void set_weight(int weight);
361 virtual bool notify_action_command_pressed();
362 virtual bool notify_interaction_with_item(EquipmentItem& item);
363 virtual bool start_movement_by_hero();
364 virtual void stop_movement_by_hero();
365 virtual std::string get_sword_tapping_sound();
366
367 // Obstacles.
368 virtual bool is_obstacle_for(Entity& other);
369 virtual bool is_obstacle_for(Entity& other, const Rectangle& candidate_position);
370 bool is_ground_obstacle(Ground ground) const;
371 virtual bool is_hero_obstacle(Hero& hero);
372 virtual bool is_block_obstacle(Block& block);
373 virtual bool is_teletransporter_obstacle(Teletransporter& teletransporter);
374 virtual bool is_stream_obstacle(Stream& stream);
375 virtual bool is_stairs_obstacle(Stairs& stairs);
376 virtual bool is_sensor_obstacle(Sensor& sensor);
377 virtual bool is_switch_obstacle(Switch& sw);
378 virtual bool is_raised_block_obstacle(CrystalBlock& raised_block);
379 virtual bool is_crystal_obstacle(Crystal& crystal);
380 virtual bool is_npc_obstacle(Npc& npc);
381 virtual bool is_door_obstacle(Door& door);
382 virtual bool is_enemy_obstacle(Enemy& enemy);
383 virtual bool is_jumper_obstacle(Jumper& jumper, const Rectangle& candidate_position);
384 virtual bool is_destructible_obstacle(Destructible& destructible);
385 virtual bool is_separator_obstacle(Separator& separator, const Rectangle& candidate_position);
386 virtual bool is_sword_ignored() const;
387
388 // Game loop.
389 bool is_suspended() const;
390 virtual void set_suspended(bool suspended);
391 virtual void update();
392 void draw(Camera& camera);
393 virtual void built_in_draw(Camera& camera);
394 void draw_sprites(Camera& camera, const Rectangle& clipping_area = Rectangle());
395
396 // Easy access to various game objects.
397 Entities& get_entities();
398 const Entities& get_entities() const;
399 Equipment& get_equipment();
400 const Equipment& get_equipment() const;
401 CommandsEffects& get_commands_effects();
402 GameCommands& get_commands();
403 Savegame& get_savegame();
404 const Savegame& get_savegame() const;
405 Hero& get_hero();
406
407 /**
408 * \name State.
409 *
410 * These functions provide information about the entity's internal state
411 * and allow to start actions which may modify this state.
412 * Actions can be triggered by equipment items, entities or scripts.
413 */
414 class State; /**< base class for all states */
415
416 std::shared_ptr<State> get_state() const;
417 void set_state(const std::shared_ptr<State>& state);
418
419 std::string get_state_name() const;
420 void update_state();
421
422 protected:
423
424 // Creation.
425 Entity(
426 const std::string& name,
427 int direction,
428 int layer,
429 const Point& xy,
430 const Size& size
431 );
432
433 // No copy constructor or assignment operator.
434 Entity(const Entity& other) = delete;
435 Entity& operator=(const Entity& other) = delete;
436
437 uint32_t get_when_suspended() const;
438
439 // Ground.
440 void update_ground_observers();
441 void update_ground_below();
442
443 // Collisions.
444 virtual void notify_collision(
445 Entity& entity_overlapping, CollisionMode collision_mode);
446 virtual void notify_collision(
447 Entity& other_entity, Sprite& this_sprite, Sprite& other_sprite);
448 void update_stream_action();
449
450 // Obstacles.
451 virtual bool is_traversable_obstacle() const;
452 virtual bool is_wall_obstacle() const;
453 virtual bool is_low_wall_obstacle() const;
454 virtual bool is_grass_obstacle() const;
455 virtual bool is_shallow_water_obstacle() const;
456 virtual bool is_deep_water_obstacle() const;
457 virtual bool is_ice_obstacle() const;
458 virtual bool is_hole_obstacle() const;
459 virtual bool is_lava_obstacle() const;
460 virtual bool is_prickle_obstacle() const;
461 virtual bool is_ladder_obstacle() const;
462
463 private:
464
465 void finish_initialization();
466 void clear_old_movements();
467 void clear_old_stream_actions();
468 void clear_old_sprites();
469
470 MainLoop* main_loop; /**< The Solarus main loop. */
471 Map* map; /**< The map where this entity is, or nullptr. */
472
473 int layer; /**< Layer of the entity on the map.
474 * The layer is constant for the tiles and can change for the hero and the dynamic entities. */
475
476 int z; /**< Z order of this entity on its layer.
477 * This value is abitrary, it can be negative and the sequence can have holes. */
478
479 Rectangle bounding_box; /**< This rectangle represents the position of the entity of the map and is
480 * used for the collision tests. It corresponds to the bounding box of the entity.
481 * It can be different from the sprite's rectangle of the entity.
482 * For example, the hero's bounding box is a 16*16 rectangle, but its sprite may be
483 * a 24*32 rectangle. */
484
485 Ground ground_below; /**< Kind of ground under this entity: grass, shallow water, etc.
486 * Only used by entities sensible to their ground. */
487
488 Point origin; /**< Coordinates of the origin point of the entity,
489 * relative to the top-left corner of its rectangle.
490 * Remember that when you call get_x() and get_y(), you get the coordinates
491 * of the origin point on the map, not the coordinates of the rectangle's
492 * top-left corner.
493 * This is useful because the top-left corner of the entity's bounding box does
494 * not represent the actual entity's coordinates and does not match necessarily
495 * the sprite's rectangle. */
496
497 std::string name; /**< Name of the entity or an empty string.
498 * The name uniquely identifies the entity in the map. */
499
500 int direction; /**< Direction of the entity, not used for all kinds of entities */
501 std::vector<UserProperty> user_properties; /**< List of user-defined properties. */
502
503 std::vector<NamedSprite>
504 sprites; /**< Sprites representing the entity. */
505 std::string default_sprite_name; /**< Name of the sprite to get in get_sprite() without parameter. */
506 bool visible; /**< Whether this entity's sprites are currently displayed. */
507 bool tiled; /**< Whether sprites should be repeated with tiling. */
508 bool drawn_in_y_order; /**< Whether this entity is drawn in Y order or in Z order. */
509 ScopedLuaRef draw_override; /**< Lua function that draws this entity, if any. */
510 std::shared_ptr<Movement> movement; /**< Movement of the entity.
511 * nullptr indicates that the entity has no movement. */
512 std::vector<std::shared_ptr<Movement>>
513 old_movements; /**< Old movements to destroy as soon as possible. */
514 bool movement_notifications_enabled; /**< Whether entity:on_position_changed() and friends should be called. */
515 Entity* facing_entity; /**< The detector in front of this entity if any. */
516 int collision_modes; /**< Collision modes detected by entity
517 * (can be an OR combination of CollisionMode values). */
518 bool layer_independent_collisions; /**< Whether this entity detects collisions on all layers. */
519
520 int weight; /**< Weight of this entity (level of "lift" ability required).
521 * -1 means an entity that cannot be lifted. */
522 std::unique_ptr<StreamAction>
523 stream_action; /**< The stream effect currently applied if any. */
524 std::vector<std::unique_ptr<StreamAction>>
525 old_stream_actions; /**< Old stream actions to destroy as soon as possible. */
526
527 // state
528 std::shared_ptr<State> state; /**< The current internal state */
529 std::vector<std::shared_ptr<State>>
530 old_states; /**< Previous state objects to delete as soon as possible. */
531
532 bool initialized; /**< Whether all initializations were done. */
533 bool being_removed; /**< indicates that the entity is not valid anymore because it is about to be removed */
534 bool enabled; /**< indicates that the entity is enabled
535 * (if not, it will not be displayed and collisions will not be notified) */
536
537 bool suspended; /**< indicates that the animation and movement of this entity are suspended */
538 uint32_t when_suspended; /**< indicates when this entity was suspended */
539
540 int optimization_distance; /**< Above this distance from the visible area,
541 * the engine may skip updates (0 means infinite). */
542 int optimization_distance2; /**< Square of optimization_distance. */
543 static constexpr int
544 default_optimization_distance = 0; /**< Default value. */
545
546 };
547
548 /**
549 * \brief Returns the layer of the entity on the map.
550 * \return The layer of the entity on the map.
551 */
get_layer()552 inline int Entity::get_layer() const {
553 return layer;
554 }
555
556 /**
557 * \brief Returns the Z order of this entity on its layer.
558 *
559 * This is an arbitrary value that can be used to compare the order of
560 * entities. It can be negative. The sequence can have holes.
561 *
562 * \return The Z order.
563 */
get_z()564 inline int Entity::get_z() const {
565 return z;
566 }
567
568 /**
569 * \brief Sets the Z order of this entity on its layer.
570 * \param z The Z order.
571 */
set_z(int z)572 inline void Entity::set_z(int z) {
573 this->z = z;
574 }
575
576 /**
577 * \brief Returns whether this entity is enabled.
578 * \return true if this entity is enabled
579 */
is_enabled()580 inline bool Entity::is_enabled() const {
581 return enabled;
582 }
583
584 /**
585 * \brief Returns true if this entity is about to be deleted.
586 *
587 * When this function returns true, the entity is not
588 * considered to be on the map anymore.
589 *
590 * \return true if this entity is about to be deleted
591 */
is_being_removed()592 inline bool Entity::is_being_removed() const {
593 return being_removed;
594 }
595
596 /**
597 * \brief Returns whether or not this entity's bounding box overlaps a specified rectangle.
598 * \param rectangle the rectangle to check
599 * \return true if this entity's bounding box overlaps the specified rectangle
600 */
overlaps(const Rectangle & rectangle)601 inline bool Entity::overlaps(const Rectangle& rectangle) const {
602 return bounding_box.overlaps(rectangle);
603 }
604
605 /**
606 * \brief Returns whether or not a point overlaps this entity's bounding box.
607 * \param point point to check
608 * \return true if the point is in this entity's bounding box
609 */
overlaps(const Point & point)610 inline bool Entity::overlaps(const Point& point) const {
611 return bounding_box.contains(point);
612 }
613
614 /**
615 * \brief Returns whether or not a point overlaps this entity's bounding box.
616 * \param x x coordinate of the point to check
617 * \param y y coordinate of the point to check
618 * \return true if the point is in this entity's bounding box
619 */
overlaps(int x,int y)620 inline bool Entity::overlaps(int x, int y) const {
621 return bounding_box.contains(x, y);
622 }
623
624 /**
625 * \brief Returns whether or not this entity's bounding box overlaps
626 * another entity's bounding box.
627 * \param other another entity
628 * \return true if this entity's bounding box overlaps the other entity's bounding box
629 */
overlaps(const Entity & other)630 inline bool Entity::overlaps(const Entity& other) const {
631 return overlaps(other.get_bounding_box());
632 }
633
634 }
635
636 #endif
637
638