game_object.hpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. // SuperTux
  2. // Copyright (C) 2006 Matthias Braun <matze@braunis.de>
  3. //
  4. // This program 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. // This program 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
  15. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. #ifndef HEADER_SUPERTUX_SUPERTUX_GAME_OBJECT_HPP
  17. #define HEADER_SUPERTUX_SUPERTUX_GAME_OBJECT_HPP
  18. #include "squirrel/exposable_class.hpp"
  19. #include <algorithm>
  20. #include <string>
  21. #include <vector>
  22. #include <optional>
  23. #include <typeindex>
  24. #include "editor/object_settings.hpp"
  25. #include "supertux/game_object_component.hpp"
  26. #include "util/fade_helper.hpp"
  27. #include "util/gettext.hpp"
  28. #include "util/uid.hpp"
  29. class DrawingContext;
  30. class GameObjectComponent;
  31. class GameObjectManager;
  32. class ObjectRemoveListener;
  33. class ReaderMapping;
  34. class Writer;
  35. namespace ssq {
  36. class VM;
  37. } // namespace ssq
  38. struct GameObjectType
  39. {
  40. const std::string id;
  41. const std::string name;
  42. };
  43. typedef std::vector<GameObjectType> GameObjectTypes;
  44. /**
  45. A helper structure to list all the type_indexes of the classes in the
  46. type hierarchy of a given class. This makes it easier to register e.g.
  47. a MrIceblock in lists for MrIceBlock, WalkingBadguy, Badguy, Portable,
  48. MovingSprite, MovingObject, and GameObject.
  49. */
  50. struct GameObjectClasses
  51. {
  52. std::vector<std::type_index> types;
  53. GameObjectClasses& add(const std::type_info& info)
  54. {
  55. types.emplace_back(info);
  56. return *this;
  57. }
  58. };
  59. /**
  60. This class is responsible for:
  61. * Updating and drawing the object. This should happen in the update() and
  62. draw() functions. Both are called once per frame.
  63. * Providing a safe way to remove the object by calling the remove_me
  64. functions.
  65. */
  66. /**
  67. * @scripting
  68. * @summary Base class for all the things that make up Levels' Sectors.${SRG_NEWPARAGRAPH}
  69. Each sector of a level holds a list of active ""GameObject""s, while the
  70. game is played.${SRG_NEWPARAGRAPH}
  71. */
  72. class GameObject : public ExposableClass
  73. {
  74. friend class GameObjectManager;
  75. public:
  76. static void register_class(ssq::VM& vm);
  77. public:
  78. GameObject(const std::string& name = "");
  79. GameObject(const ReaderMapping& reader);
  80. virtual ~GameObject() override;
  81. /** Called after all objects have been added to the Sector and the
  82. Sector is fully constructed. If objects refer to other objects
  83. by name, those connection can be resolved here. */
  84. virtual void finish_construction() {}
  85. inline UID get_uid() const { return m_uid; }
  86. /** This function is called once per frame and allows the object to
  87. update it's state. The dt_sec is the time that has passed since
  88. the last frame in seconds and should be the base for all timed
  89. calculations (don't use SDL_GetTicks directly as this will fail
  90. in pause mode). This function is not called in the Editor. */
  91. virtual void update(float dt_sec) = 0;
  92. /** The GameObject should draw itself onto the provided
  93. DrawingContext if this function is called. */
  94. virtual void draw(DrawingContext& context) = 0;
  95. /** This function saves the object. Editor will use that. */
  96. virtual void save(Writer& writer);
  97. std::string save();
  98. virtual std::string get_class_name() const { return "game-object"; }
  99. virtual std::string get_exposed_class_name() const override { return "GameObject"; }
  100. /**
  101. * @scripting
  102. * @description Returns the display name of the object, translated to the user's locale.
  103. */
  104. virtual std::string get_display_name() const { return _("Unknown object"); }
  105. /** List notable classes in inheritance hierarchy of class. This makes it possible
  106. to efficiently look up all objects deriving from a particular intermediate class */
  107. virtual GameObjectClasses get_class_types() const;
  108. /** Version checking/updating, patch information */
  109. virtual std::vector<std::string> get_patches() const;
  110. virtual void update_version();
  111. /**
  112. * @scripting
  113. * @description Returns the current version of the object.
  114. */
  115. inline int get_version() const { return m_version; }
  116. /**
  117. * @scripting
  118. * @description Returns the latest version of the object.
  119. */
  120. int get_latest_version() const;
  121. /**
  122. * @scripting
  123. * @description Checks whether the object's current version is equal to its latest one.
  124. */
  125. bool is_up_to_date() const;
  126. /** If true only a single object of this type is allowed in a
  127. given GameObjectManager */
  128. virtual bool is_singleton() const { return false; }
  129. /** Does this object have variable size
  130. (secret area trigger, wind, etc.) */
  131. virtual bool has_variable_size() const { return false; }
  132. /** Indicates if the object will be saved. If false, the object will
  133. be skipped on saving and can't be cloned in the editor. */
  134. virtual bool is_saveable() const { return true; }
  135. /** Indicates if the object's state should be tracked.
  136. If false, load_state() and save_state() calls would not do anything. */
  137. virtual bool track_state() const { return true; }
  138. /** Indicates if the object should be added at the beginning of the object list. */
  139. virtual bool has_object_manager_priority() const { return false; }
  140. /** Returns the amount of coins that this object is worth.
  141. This is considered when calculating all coins in a level. */
  142. virtual int get_coins_worth() const { return 0; }
  143. /** Indicates if get_settings() is implemented. If true the editor
  144. will display Tip and ObjectMenu. */
  145. virtual bool has_settings() const { return is_saveable(); }
  146. virtual ObjectSettings get_settings();
  147. /** Get all types of the object, if available. **/
  148. virtual GameObjectTypes get_types() const;
  149. /**
  150. * @scripting
  151. * @description Returns the type index of the object.
  152. */
  153. inline int get_type() const { return m_type; }
  154. virtual void after_editor_set();
  155. /** When level is flipped vertically */
  156. virtual void on_flip(float height) {}
  157. /** schedules this object to be removed at the end of the frame */
  158. virtual void remove_me() { m_scheduled_for_removal = true; }
  159. /** returns true if the object is not scheduled to be removed yet */
  160. inline bool is_valid() const { return !m_scheduled_for_removal; }
  161. /** registers a remove listener which will be called if the object
  162. gets removed/destroyed */
  163. void add_remove_listener(ObjectRemoveListener* listener);
  164. /** unregisters a remove listener, so it will no longer be called if
  165. the object gets removed/destroyed */
  166. void del_remove_listener(ObjectRemoveListener* listener);
  167. inline void set_name(const std::string& name) { m_name = name; }
  168. /**
  169. * @scripting
  170. * @description Returns the name of the object.
  171. */
  172. inline const std::string& get_name() const { return m_name; }
  173. /** stops all looping sounds */
  174. virtual void stop_looping_sounds() {}
  175. /** continues all looping sounds */
  176. virtual void play_looping_sounds() {}
  177. template<typename T>
  178. T* get_component() {
  179. for(auto& component : m_components) {
  180. if (T* result = dynamic_cast<T*>(component.get())) {
  181. return result;
  182. }
  183. }
  184. return nullptr;
  185. }
  186. void add_component(std::unique_ptr<GameObjectComponent> component) {
  187. m_components.emplace_back(std::move(component));
  188. }
  189. void remove_component(GameObjectComponent* component) {
  190. auto it = std::find_if(m_components.begin(), m_components.end(),
  191. [component](const std::unique_ptr<GameObjectComponent>& lhs){
  192. return lhs.get() == component;
  193. });
  194. if (it != m_components.end()) {
  195. m_components.erase(it);
  196. }
  197. }
  198. /** Save/check the current state of the object. */
  199. virtual void save_state();
  200. virtual void check_state();
  201. /** The editor requested the deletion of the object */
  202. virtual void editor_delete() { remove_me(); }
  203. /** The user clicked on the object in the editor and selected it*/
  204. virtual void editor_select() {}
  205. /** The object got deselected */
  206. virtual void editor_deselect() {}
  207. /** Called each frame in the editor, used to keep linked objects
  208. together (e.g. platform on a path) */
  209. virtual void editor_update() {}
  210. inline GameObjectManager* get_parent() const { return m_parent; }
  211. protected:
  212. /** Parse object type. **/
  213. void parse_type(const ReaderMapping& reader);
  214. /** When the type has been changed from the editor. **/
  215. enum TypeChange { INITIAL = -1 }; // "old_type < 0" indicates initial call
  216. virtual void on_type_change(int old_type) {}
  217. /** Conversion between type ID and value. **/
  218. int type_id_to_value(const std::string& id) const;
  219. std::string type_value_to_id(int value) const;
  220. private:
  221. inline void set_uid(const UID& uid) { m_uid = uid; }
  222. private:
  223. /** The parent GameObjectManager. Set by the manager itself. */
  224. GameObjectManager* m_parent;
  225. protected:
  226. /** a name for the gameobject, this is mostly a hint for scripts and
  227. for debugging, don't rely on names being set or being unique */
  228. std::string m_name;
  229. /** Type of the GameObject. Used to provide special functionality,
  230. based on the child object. */
  231. int m_type;
  232. /** Fade Helpers are for easing/fading script functions */
  233. std::vector<std::unique_ptr<FadeHelper>> m_fade_helpers;
  234. /** Track the following creation/deletion of this object for undo.
  235. If track_state() returns false, this object would not be tracked,
  236. regardless of the value of this variable. */
  237. bool m_track_undo;
  238. private:
  239. /** The object's type at the time of the last get_settings() call.
  240. Used to check if the type has changed. **/
  241. int m_previous_type;
  242. /** Indicates the object's version. By default, this is equal to 1.
  243. Useful for retaining retro-compatibility for objects, whilst allowing for
  244. updated behaviour in newer levels.
  245. The version of an object can be updated from the editor. */
  246. int m_version;
  247. /** A unique id for the object to safely refer to it. This will be
  248. set by the GameObjectManager. */
  249. UID m_uid;
  250. /** this flag indicates if the object should be removed at the end of the frame */
  251. bool m_scheduled_for_removal;
  252. /** The object's settings at the time of the last state save.
  253. Used to check for changes that may have occured. */
  254. std::optional<ObjectSettings> m_last_state;
  255. std::vector<std::unique_ptr<GameObjectComponent> > m_components;
  256. std::vector<ObjectRemoveListener*> m_remove_listeners;
  257. private:
  258. GameObject(const GameObject&) = delete;
  259. GameObject& operator=(const GameObject&) = delete;
  260. };
  261. #endif
  262. /* EOF */