1 ///////////////////////////////////////////////////////////////////////////////
2 //            Copyright (C) 2004-2011 by The Allacrost Project
3 //            Copyright (C) 2012-2016 by Bertram (Valyria Tear)
4 //                         All Rights Reserved
5 //
6 // This code is licensed under the GNU GPL version 2. It is free software
7 // and you may modify it and/or redistribute it under the terms of this license.
8 // See https://www.gnu.org/copyleft/gpl.html for details.
9 ///////////////////////////////////////////////////////////////////////////////
10 
11 /** ****************************************************************************
12 *** \file    map_events.h
13 *** \author  Tyler Olsen, roots@allacrost.org
14 *** \author  Yohann Ferreira, yohann ferreira orange fr
15 *** \brief   Header file for map mode events and event processing
16 ***
17 *** Events occur on map mode to alter the state of the map, present a scene to the
18 *** player, or do any other custom task we require. Events may be "chained" together
19 *** so that one event begins as another ends. Many events are scripted, but this
20 *** file contains some C++ implementations of the most common types of events so
21 *** that these do not have to be continually re-implemented in every Lua map file.
22 *** ***************************************************************************/
23 
24 #ifndef __MAP_EVENTS_HEADER__
25 #define __MAP_EVENTS_HEADER__
26 
27 #include "modes/map/map_treasure_supervisor.h"
28 #include "modes/map/map_treasure_content.h"
29 
30 #include "modes/battle/battle_enemy_info.h"
31 #include "modes/shop/shop_utils.h"
32 
33 #include "engine/audio/audio_descriptor.h"
34 
35 #include "script/script.h"
36 
37 namespace vt_map
38 {
39 
40 namespace private_map
41 {
42 
43 class ContextZone;
44 class MapSprite;
45 class SpriteDialogue;
46 class VirtualSprite;
47 
48 /** ****************************************************************************
49 *** \brief A container class representing a link between two map events
50 ***
51 *** Map events may trigger additional events to occur alongside it or following
52 *** it. This class represents a "link" between two events and describes how the
53 *** two events are linked. In an event link there is a parent event and a child
54 *** event. The parent and child events may begin at the same time, or the child
55 *** event may occur after the parent event starts, but the child will never
56 *** preceed the parent's start. This class only stores the event_id of the child,
57 *** and the link object is added as a member onto the parent event's class. When
58 *** the parent event gets processed, all links are examined and the children events
59 *** are prepared appropriately.
60 ***
61 *** We use two pieces of information to determine when to start a child event relevant
62 *** to its parent. The first is a boolean value that indicates whether the child's
63 *** start is relative to the parent's start or the parent's finish. The second is a
64 *** time value that indicates how long to wait (in milliseconds) from the parent's
65 *** start/finish before starting the child event.
66 *** ***************************************************************************/
67 class EventLink
68 {
69 public:
EventLink(const std::string & child_id,bool start,uint32_t time)70     EventLink(const std::string &child_id, bool start, uint32_t time) :
71         child_event_id(child_id), launch_at_start(start), launch_timer(time) {}
72 
~EventLink()73     ~EventLink()
74     {}
75 
76     //! \brief The ID of the child event in this link
77     std::string child_event_id;
78 
79     //! \brief The event will launch relative to the parent event's start if true, or its finish if false
80     bool launch_at_start;
81 
82     //! \brief The amount of milliseconds to wait before launching the event (0 means launch instantly)
83     uint32_t launch_timer;
84 }; // class EventLink
85 
86 
87 /** ****************************************************************************
88 *** \brief An abstract class representing an event that occurs on a map
89 ***
90 *** An event can be virtually anything from playing a sound to moving a sprite
91 *** to beginning a dialogue. Events do not necessarily inform the user (through
92 *** visual or audio means) that an event has occurred. They may be employed to
93 *** change the state of a map without the player's knowledge. This is an abstract
94 *** class because common types of events (such as beginning a dialogue) are implemented
95 *** in C++ code while Lua is used to represent not-so-common types of events.
96 ***
97 *** All events have a unique, non empty, std::string value that serve to
98 *** distinguish the events from one another (an ID string). Events can also contain any
99 *** number of "links" to children events, which are events which launch simultaneously
100 *** with or some time after the parent event. Events are processed via two
101 *** functions. _Start() is called only one when the event begins. _Update() is called
102 *** once for every iteration of the main game loop until this function returns a true
103 *** value, indicating that the event is finished.
104 *** ***************************************************************************/
105 class MapEvent
106 {
107     friend class EventSupervisor;
108 public:
109     //! \param id The ID for the map event (an empty() value is invalid)
110     MapEvent(const std::string& id, EVENT_TYPE type);
111 
~MapEvent()112     virtual ~MapEvent()
113     {}
114 
GetEventID()115     const std::string& GetEventID() const {
116         return _event_id;
117     }
118 
GetEventType()119     EVENT_TYPE GetEventType() const {
120         return _event_type;
121     }
122 
123     /** \brief Declares a child event to be launched immediately at the start of this event
124     *** \param child_event_id The event id of the child event
125     **/
AddEventLinkAtStart(const std::string & child_event_id)126     void AddEventLinkAtStart(const std::string& child_event_id) {
127         _AddEventLink(child_event_id, true, 0);
128     }
129 
130     /** \brief Declares a child event to be launched after the start of this event
131     *** \param child_event_id The event id of the child event
132     *** \param launch_time The number of milliseconds to wait before launching the child event
133     **/
AddEventLinkAtStart(const std::string & child_event_id,uint32_t launch_time)134     void AddEventLinkAtStart(const std::string& child_event_id, uint32_t launch_time) {
135         _AddEventLink(child_event_id, true, launch_time);
136     }
137 
138     /** \brief Declares a child event to be launched immediately at the end of this event
139     *** \param child_event_id The event id of the child event
140     **/
AddEventLinkAtEnd(const std::string & child_event_id)141     void AddEventLinkAtEnd(const std::string& child_event_id) {
142         _AddEventLink(child_event_id, false, 0);
143     }
144 
145     /** \brief Declares a child event to be launched after the end of this event
146     *** \param child_event_id The event id of the child event
147     *** \param launch_time The number of milliseconds to wait before launching the child event
148     **/
AddEventLinkAtEnd(const std::string & child_event_id,uint32_t launch_time)149     void AddEventLinkAtEnd(const std::string& child_event_id, uint32_t launch_time) {
150         _AddEventLink(child_event_id, false, launch_time);
151     }
152 
153 protected:
154     /** \brief Starts the event
155     *** This function is only called once per event execution
156     **/
157     virtual void _Start() = 0;
158 
159     /** \brief Updates the event progress and checks if the event has finished
160     *** \return True if the event is finished
161     *** This function is called as many times as needed until the event has finished. The contents
162     *** of this function may do more than simply check if the event is finished. It may also execute
163     *** code for the event with the goal of eventually brining the event to a finished state.
164     **/
165     virtual bool _Update() = 0;
166 
167     /** \brief Declares a child event to be linked to this event
168     *** \param child_event_id The event id of the child event
169     *** \param launch_at_start The child starts relative to the start of the event if true, its finish if false
170     *** \param launch_time The number of milliseconds to wait before launching the child event
171     **/
_AddEventLink(const std::string & child_event_id,bool launch_at_start,uint32_t launch_time)172     void _AddEventLink(const std::string& child_event_id, bool launch_at_start, uint32_t launch_time) {
173         _event_links.push_back(EventLink(child_event_id, launch_at_start, launch_time));
174     }
175 
176 private:
177     //! \brief A unique ID string for the event. An empty value is invalid
178     std::string _event_id;
179 
180     //! \brief Identifier for the class type of this event
181     EVENT_TYPE _event_type;
182 
183     //! \brief All child events of this class, represented by EventLink objects
184     std::vector<EventLink> _event_links;
185 }; // class MapEvent
186 
187 
188 /** ****************************************************************************
189 *** \brief An event which activates a dialogue on the map
190 ***
191 *** Note that a dialogue may execute script actions, which would somewhat act
192 *** like events but technically are not events. Children events that are implemented
193 *** in Lua can take advantage of options selected by the player in these dialogues
194 *** to determine what events should follow down the event chain
195 ***
196 *** Sometimes you may want a dialogue event to stop the camera from moving, especially
197 *** if it is the first event in an event chain. When this behavior is desired, call the
198 *** StopCameraMovement() method after creating the event object.
199 *** ***************************************************************************/
200 class DialogueEvent : public MapEvent
201 {
202 public:
203     /** \param event_id The ID of this event
204     *** \param dialogue The SpriteDialogue* to execute through this event
205     **/
206     DialogueEvent(const std::string& event_id, SpriteDialogue* dialogue);
207 
~DialogueEvent()208     virtual ~DialogueEvent() override
209     {
210     }
211 
212     //! \brief A C++ wrapper made to create a new object from scripting,
213     //! without letting Lua handling the object life-cycle.
214     //! \note We don't permit luabind to use constructors here as it can't currently
215     //! give the object ownership at construction time.
216     static DialogueEvent* Create(const std::string& event_id, SpriteDialogue* dialogue);
217 
218     //! \brief Toggles whether or not camera movement should be stopped when the dialogue begins
SetStopCameraMovement(bool stop)219     void SetStopCameraMovement(bool stop) {
220         _stop_camera_movement = stop;
221     }
222 
223 protected:
224     //! \brief The ID of the dialogue to invoke
225     std::string _dialogue_id;
226 
227     //! \brief When true, any camera movement will be stopped when the event begins
228     bool _stop_camera_movement;
229 
230     //! \brief Begins the dialogue
231     void _Start() override;
232 
233     //! \brief Returns true when the last line of the dialogue has been read
234     bool _Update() override;
235 }; // class DialogueEvent : public MapEvent
236 
237 
238 /** ****************************************************************************
239 *** \brief An event that creates an instance of ShopMode when started
240 *** ***************************************************************************/
241 class ShopEvent : public MapEvent
242 {
243 public:
ShopEvent(const std::string & event_id,const std::string & shop_id)244     ShopEvent(const std::string& event_id, const std::string& shop_id):
245         MapEvent(event_id, SHOP_EVENT),
246         _shop_id(shop_id),
247         _buy_level(vt_shop::SHOP_PRICE_STANDARD),
248         _sell_level(vt_shop::SHOP_PRICE_STANDARD),
249         _enable_sell_mode(true)
250     {}
251 
~ShopEvent()252     virtual ~ShopEvent() override
253     {
254     }
255 
256     //! \brief A C++ wrapper made to create a new object from scripting,
257     //! without letting Lua handling the object life-cycle.
258     //! \note We don't permit luabind to use constructors here as it can't currently
259     //! give the object ownership at construction time.
260     static ShopEvent* Create(const std::string& event_id, const std::string& shop_id);
261 
262     //! \brief Set the Shop name
SetShopName(const vt_utils::ustring & shop_name)263     void SetShopName(const vt_utils::ustring& shop_name) {
264         _shop_name = shop_name;
265     }
266 
267     //! \brief Set the Shop greetings text
SetGreetingText(const vt_utils::ustring & greeting_text)268     void SetGreetingText(const vt_utils::ustring& greeting_text) {
269         _greeting_text = greeting_text;
270     }
271 
SetSellModeEnabled(bool sell_mode_enabled)272     void SetSellModeEnabled(bool sell_mode_enabled) {
273         _enable_sell_mode = sell_mode_enabled;
274     }
275 
276     /** \brief Adds an object to the list of objects for sale.
277     *** \param object_id The ID of the GlobalObject to make available for purchase.
278     *** \param stock The amount of the object to make available for purchase.
279     *** If set to 0, the number of objects is infinite.
280     *** \note All wares must be added before the _Start() method is called to ensure
281     *** that the wares actually appear in shop mode.
282     **/
AddItem(uint32_t object_id,uint32_t stock)283     void AddItem(uint32_t object_id, uint32_t stock) {
284         _items.insert(std::make_pair(object_id, stock));
285     }
286 
287     /** \brief Adds an object to the list of objects for sale.
288     *** \param object_id The ID of the GlobalObject to make available for purchase.
289     *** \param stock The amount of the object to make available for purchase.
290     *** If set to 0, the number of objects is infinite.
291     *** \note All wares must be added before the _Start() method is called to ensure
292     *** that the wares actually appear in shop mode.
293     **/
AddTrade(uint32_t object_id,uint32_t stock)294     void AddTrade(uint32_t object_id, uint32_t stock) {
295         _trades.insert(std::make_pair(object_id, stock));
296     }
297 
298     //! \brief Set the shop quality levels which will handle pricing variations.
SetPriceLevels(vt_shop::SHOP_PRICE_LEVEL buy_level,vt_shop::SHOP_PRICE_LEVEL sell_level)299     void SetPriceLevels(vt_shop::SHOP_PRICE_LEVEL buy_level,
300                         vt_shop::SHOP_PRICE_LEVEL sell_level) {
301         _buy_level = buy_level;
302         _sell_level = sell_level;
303     }
304 
305     //! \brief Adds potential scripts to trigger at shop event start
AddScript(const std::string & script_file)306     void AddScript(const std::string& script_file) {
307         _shop_scripts.push_back(script_file);
308     }
309 
310 protected:
311     //! \brief The shop unique Id, used to store shop info in save games.
312     std::string _shop_id;
313 
314     //! \brief The GlobalObject IDs and stock count of all items to be sold in the shop
315     std::set<std::pair<uint32_t, uint32_t> > _items;
316 
317     //! \brief The GlobalObject IDs and stock count of all objects to be sold in the shop
318     std::set<std::pair<uint32_t, uint32_t> > _trades;
319 
320     //! \brief The Shop quality levels. The more the level is, the worse it is for the player.
321     vt_shop::SHOP_PRICE_LEVEL _buy_level;
322     vt_shop::SHOP_PRICE_LEVEL _sell_level;
323 
324     //! \brief Optional custom shop name and greeting text.
325     vt_utils::ustring _shop_name;
326     vt_utils::ustring _greeting_text;
327 
328     //! \brief Tells whether the sell mode can be enabled
329     bool _enable_sell_mode;
330 
331     //! \brief Stores potential scripts to trigger at shop event start
332     std::vector<std::string> _shop_scripts;
333 
334     //! \brief Creates an instance of ShopMode and pushes it to the game mode stack
335     void _Start() override;
336 
337     //! \brief Performs no operation (returns true)
_Update()338     bool _Update() override {
339         return true;
340     }
341 };
342 
343 
344 /** ****************************************************************************
345 *** \brief Plays a sound. The event finishes when the sound stops
346 ***
347 *** The suggested usage for initializing an object of this class is the following:
348 *** -# Call the class constructor
349 *** -# Call the GetSound() function to retrieve the SoundDescriptor object
350 *** -# Call SoundDescriptor methods to set the desired properties of the sound (looping, attenuation, etc)
351 ***
352 *** After these steps are performed the event is ready to launch. The default properties
353 *** of the sound are the same as are in the default constructor of the SoundDescriptor
354 *** class. This includes no looping and no distance attenuation. The event will finish when the
355 *** sound finishes playing (when the sound state is AUDIO_STATE_STOPPED). Note that if looping is set
356 *** to infinite, the sound will never enter this state. It is possible to prematurely terminate this
357 *** event by calling the GetSound() method and invoking Stop() on the SoundDescriptor object that is
358 *** returned.
359 ***
360 *** \note The MapMode class has a container of SoundDescriptor objects which should include all of
361 *** the sounds that may be used on a given map. This means that when a SoundEvent is created, the
362 *** sound file data will already be loaded by the audio engine.
363 ***
364 *** \todo Support sounds with a position that employ distance attenuation. Perhaps
365 *** another derived class would be ideal to implement this, since sounds could possibly
366 *** be mobile (attached to sprites).
367 *** ***************************************************************************/
368 class SoundEvent : public MapEvent
369 {
370 public:
371     /** \param event_id The ID of this event
372     *** \param sound_filename The name of the sound file to load
373     **/
374     SoundEvent(const std::string& event_id, const std::string& sound_filename);
375 
~SoundEvent()376     virtual ~SoundEvent() override
377     {
378         _sound.Stop();
379     }
380 
381     //! \brief A C++ wrapper made to create a new object from scripting,
382     //! without letting Lua handling the object life-cycle.
383     //! \note We don't permit luabind to use constructors here as it can't currently
384     //! give the object ownership at construction time.
385     static SoundEvent* Create(const std::string& event_id, const std::string& sound_filename);
386 
387     //! \brief Accessor which allows the properties of the sound to be customized
GetSound()388     vt_audio::SoundDescriptor &GetSound()
389     { return _sound; }
390 
391 protected:
392     //! \brief Begins playback of the sound
_Start()393     void _Start() override
394     { _sound.Play(); }
395 
396     //! \brief Returns true when the sound has finished playing, or finished looping
397     bool _Update() override;
398 
399     //! \brief The sound that this event will play
400     vt_audio::SoundDescriptor _sound;
401 }; // class SoundEvent : public MapEvent
402 
403 
404 /** ****************************************************************************
405 *** \brief Event for switching from one map to another, with fading.
406 ***
407 ***
408 *** ***************************************************************************/
409 class MapTransitionEvent : public MapEvent
410 {
411 public:
412     /** \param event_id The ID of this event
413     *** \param data_filename The name of the map data file to transition to
414     *** \param data_filename The name of the map script file to use
415     *** \param coming_from The transition origin.
416     **/
417     MapTransitionEvent(const std::string& event_id,
418                        const std::string& data_filename,
419                        const std::string& script_filename,
420                        const std::string& coming_from);
421 
~MapTransitionEvent()422     virtual ~MapTransitionEvent() override
423     {
424     }
425 
426     //! \brief A C++ wrapper made to create a new object from scripting,
427     //! without letting Lua handling the object life-cycle.
428     //! \note We don't permit luabind to use constructors here as it can't currently
429     //! give the object ownership at construction time.
430     static MapTransitionEvent* Create(const std::string& event_id,
431                                       const std::string& data_filename,
432                                       const std::string& script_filename,
433                                       const std::string& coming_from);
434 
435 protected:
436     //! \brief Begins the transition process by fading out the screen and music
437     void _Start() override;
438 
439     //! \brief Once the fading process completes, creates the new map mode to transition to
440     bool _Update() override;
441 
442     //! \brief The data and script filenames of the map to transition to
443     std::string _transition_map_data_filename;
444     std::string _transition_map_script_filename;
445 
446     /** \brief a string telling where the map transition is coming from.
447     *** useful when changing from a map to another to set up the camera position.
448     **/
449     std::string _transition_origin;
450 
451     //! \brief tells the update function to trigger the new map.
452     bool _done;
453 }; // class MapTransitionEvent : public MapEvent
454 
455 
456 /** ****************************************************************************
457 *** \brief Instantly starts a battle.
458 ***
459 ***
460 *** ***************************************************************************/
461 class BattleEncounterEvent : public MapEvent
462 {
463 public:
464     /** \param event_id The ID of this event
465     **/
466     explicit BattleEncounterEvent(const std::string& event_id);
467 
~BattleEncounterEvent()468     virtual ~BattleEncounterEvent() override
469     {
470     }
471 
472     //! \brief A C++ wrapper made to create a new object from scripting,
473     //! without letting Lua handling the object life-cycle.
474     //! \note We don't permit luabind to use constructors here as it can't currently
475     //! give the object ownership at construction time.
476     static BattleEncounterEvent* Create(const std::string& event_id);
477 
SetMusic(const std::string & filename)478     void SetMusic(const std::string &filename) {
479         _battle_music = filename;
480     }
481 
SetBackground(const std::string & filename)482     void SetBackground(const std::string &filename) {
483         _battle_background = filename;
484     }
485 
SetBoss(bool is_boss)486     void SetBoss(bool is_boss) {
487         _is_boss = is_boss;
488     }
489 
490     void AddEnemy(uint32_t enemy_id, float position_x, float position_y);
491 
AddEnemy(uint32_t enemy_id)492     void AddEnemy(uint32_t enemy_id) {
493         AddEnemy(enemy_id, 0, 0);
494     }
495 
AddScript(const std::string & filename)496     void AddScript(const std::string &filename) {
497         _battle_scripts.push_back(filename);
498     }
499 
500 protected:
501     //! \brief ID numbers for enemies to generate
502     std::vector<vt_battle::BattleEnemyInfo> _enemies;
503 
504     //! \brief Filename for battle music
505     std::string _battle_music;
506 
507     //! \brief Filename for battle background
508     std::string _battle_background;
509 
510     //! \brief Filenames of the battle scripts
511     std::vector<std::string> _battle_scripts;
512 
513     //! \brief Tells whether the battle is against a boss
514     bool _is_boss;
515 
516     //! \brief Starts the battle
517     void _Start() override;
518 
519     /** \brief Currently does nothing, since the battle transition management
520     *** is done through games modes.
521     **/
_Update()522     bool _Update() override {
523         return true;
524     }
525 }; // class BattleEncounterEvent : public MapEvent
526 
527 /** ****************************************************************************
528 *** \brief An event thats starts an event or another based on a check function.
529 *** ***************************************************************************/
530 class IfEvent : public MapEvent
531 {
532 public:
533     /** \param event_id The ID of this event
534     *** \param check_function the map file's function to call to make the check requested
535     *** \param on_true_event the map to call when the check function returns true
536     *** \param on_false_event the map to call when the check function returns false
537     ***
538     *** \note An empty value for either the true or false event id arguments
539     *** will result in no event in this case
540     **/
541     IfEvent(const std::string& event_id, const std::string& check_function,
542             const std::string& on_true_event, const std::string& on_false_event);
543 
~IfEvent()544     virtual ~IfEvent() override
545     {
546     }
547 
548     //! \brief A C++ wrapper made to create a new object from scripting,
549     //! without letting Lua handling the object life-cycle.
550     //! \note We don't permit luabind to use constructors here as it can't currently
551     //! give the object ownership at construction time.
552     static IfEvent* Create(const std::string& event_id,
553                            const std::string& check_function,
554                            const std::string& on_true_event,
555                            const std::string& on_false_event);
556 
557 protected:
558     //! \brief A pointer to the Lua function that starts the event
559     luabind::object _check_function;
560 
561     std::string _true_event_id;
562     std::string _false_event_id;
563 
564     //! \brief Calls the Lua _start_function, if one was defined
565     void _Start() override;
566 
567     //! \brief Calls the Lua _update_function. If no update function was defined, does nothing and returns true
_Update()568     bool _Update() override
569     { return true; }
570 }; // class IfEvent : public MapEvent
571 
572 /** ****************************************************************************
573 *** \brief An event with its _Start and _Update functions implemented in Lua.
574 ***
575 *** All events that do not fall into the other categories of events will be
576 *** implemented here. This event uses Lua functions to implement the _Start()
577 *** and _Update() functions (all these C++ functions do is call the
578 *** corresponding Lua functions). Note that any type of event can be implemented
579 *** in Lua, including alternative implementations of the other C++ event types.
580 *** You should only use this event type if there is no way to implement your
581 *** event in the other event types provided.
582 *** ***************************************************************************/
583 class ScriptedEvent : public MapEvent
584 {
585 public:
586     /** \param event_id The ID of this event
587     *** \param start_function the map file's function start function name to call
588     *** \param update_function the map file's function update function name to call
589     ***
590     *** \note An empty value for either the start or update arguments will result in no start or
591     *** update function being defined. If no update function is defined, the call to _Update() will always
592     *** return true, meaning that this event will end immediately after it starts.
593     **/
594     ScriptedEvent(const std::string& event_id, const std::string& start_function,
595                   const std::string& update_function);
596 
~ScriptedEvent()597     virtual ~ScriptedEvent() override
598     {
599     }
600 
601     //! \brief A C++ wrapper made to create a new object from scripting,
602     //! without letting Lua handling the object life-cycle.
603     //! \note We don't permit luabind to use constructors here as it can't currently
604     //! give the object ownership at construction time.
605     static ScriptedEvent* Create(const std::string& event_id,
606                                  const std::string& start_function,
607                                  const std::string& update_function);
608 
609 protected:
610     //! \brief A pointer to the Lua function that starts the event
611     luabind::object _start_function;
612 
613     //! \brief A pointer to the Lua function that returns a boolean value if the event is finished
614     luabind::object _update_function;
615 
616     //! \brief Calls the Lua _start_function, if one was defined
617     void _Start() override;
618 
619     //! \brief Calls the Lua _update_function. If no update function was defined, does nothing and returns true
620     bool _Update() override;
621 }; // class ScriptedEvent : public MapEvent
622 
623 
624 /** ****************************************************************************
625 *** \brief An abstract event class that represents an event controlling a sprite
626 ***
627 *** Sprite events are special types of events that control a sprite (of any type)
628 *** on a map. Technically they are more like controllers than events, in that they
629 *** take control of a sprite and direct how its state should change, whether that
630 *** be their direction, movement, and/or display. All sprite events are connected
631 *** to one (and only one) sprite. When the event takes control over the sprite,
632 *** it notifies the sprite object which grabs a pointer to the SpriteEvent.
633 ***
634 *** For a deriving class to be implemented properly, it must do two things.
635 *** # In the _Start method, call SpriteEvent::_Start() before any other code
636 *** # Before returning true in the _Update() method, call _sprite->ReleaseControl(this)
637 ***
638 *** \note It is important to keep in mind that all map sprites have their update
639 *** function called before map events are updated. This can have implications for
640 *** changing some members of the sprite object inside the _Start() and _Update() methods
641 *** as these methods are called <i>after</i> the sprite's own Update() method. Keep
642 *** this property in mind when designing a derived sprite event class.
643 *** ***************************************************************************/
644 class SpriteEvent : public MapEvent
645 {
646 public:
647     /** \param event_id The ID of this event
648     *** \param event_type The type of this event
649     *** \param sprite A pointer to the sprite that this event will control
650     **/
651     SpriteEvent(const std::string& event_id, EVENT_TYPE event_type, VirtualSprite* sprite);
652 
~SpriteEvent()653     virtual ~SpriteEvent() override
654     {
655     }
656 
GetSprite()657     VirtualSprite* GetSprite() const {
658         return _sprite;
659     }
660 
661     //! \brief Frees the sprite from the control_event
662     virtual void Terminate();
663 
664 protected:
665     //! \brief A pointer to the map sprite that the event controls
666     VirtualSprite* _sprite;
667 
668     /** \brief Starts a sprite event.
669     ***
670     *** This method will make sure no other sprite event is operating the current sprite
671     *** and will potentially end the previous event before
672     *** Acquiring control of the sprite.
673     **/
674     virtual void _Start() override;
675 
676     //! \brief Updates the state of the sprite and returns true if the event is finished
677     virtual bool _Update() override = 0;
678 }; // class SpriteEvent : public MapEvent
679 
680 
681 /** ****************************************************************************
682 *** \brief A scripted event which operates on a sprite
683 ***
684 *** This class is a cross between a SpriteEvent and ScriptedEvent class. The class
685 *** itself inherits from SpriteEvent (it does not also inherit from ScriptedEvent).
686 *** The key feature of this class is that it passes a pointer to a VirtualSprite
687 *** object in the argument list when it makes its Lua function calls. The Lua functions
688 *** are then able to take any allowable action on the sprite object. Otherwise, this
689 *** class behaves just like a standard ScriptedEvent class.
690 *** ***************************************************************************/
691 class ScriptedSpriteEvent : public SpriteEvent
692 {
693 public:
694     /** \param event_id The ID of this event
695     *** \param sprite A pointer to the sprite that will be passed to the Lua script functions
696     *** \param start_function the map file's function start function name to call
697     *** \param update_function the map file's function update function name to call
698     ***
699     *** \note A value of zero for either the start or update index arguments will result in no start or
700     *** update function being defined. If no update function is defined, the call to _Update() will always
701     *** return true, meaning that this event will end immediately after it starts.
702     **/
703     ScriptedSpriteEvent(const std::string& event_id, VirtualSprite* sprite,
704                         const std::string& start_function, const std::string& update_function);
705 
~ScriptedSpriteEvent()706     ~ScriptedSpriteEvent()
707     {}
708 
709     //! \brief A C++ wrapper made to create a new object from scripting,
710     //! without letting Lua handling the object life-cycle.
711     //! \note We don't permit luabind to use constructors here as it can't currently
712     //! give the object ownership at construction time.
713     static ScriptedSpriteEvent* Create(const std::string& event_id, VirtualSprite* sprite,
714                                        const std::string& start_function, const std::string& update_function);
715 
716 protected:
717     //! \brief A pointer to the Lua function that starts the event
718     luabind::object _start_function;
719 
720     //! \brief A pointer to the Lua function that returns a boolean value if the event is finished
721     luabind::object _update_function;
722 
723     //! \brief Calls the Lua _start_function, if one was defined
724     void _Start();
725 
726     //! \brief Calls the Lua _update_function. If no update function was defined, does nothing and returns true
727     bool _Update();
728 }; // class ScriptedSpriteEvent : public SpriteEvent
729 
730 
731 /** ****************************************************************************
732 *** \brief A simple event used to set the direction of a sprite
733 ***
734 *** This event finishes immediately after it starts, as all that it performs is
735 *** to set the direction of a sprite in a particular orientation. Normally such
736 *** a minor event would be better suited as a ScriptedEvent with no update function,
737 *** but because a set direction operation is so common, it makes sense to create a
738 *** specific event for it for convenience.
739 ***
740 *** \note The only directions you should set in the class constructor are: NORTH,
741 *** SOUTH, EAST, and WEST. This event is used when a sprite is stationary, so
742 *** the other types of directions (which also infer movement) are unnecessary.
743 *** Using a direction other than these four will result in a warning being printed.
744 *** ***************************************************************************/
745 class ChangeDirectionSpriteEvent : public SpriteEvent
746 {
747 public:
748     /** \param event_id The ID of this event
749     *** \param sprite A pointer to the sprite that this event will effect
750     *** \param direction The direction to face the sprite
751     **/
752     ChangeDirectionSpriteEvent(const std::string& event_id, VirtualSprite* sprite, uint16_t direction);
753 
~ChangeDirectionSpriteEvent()754     ~ChangeDirectionSpriteEvent()
755     {}
756 
757     //! \brief A C++ wrapper made to create a new object from scripting,
758     //! without letting Lua handling the object life-cycle.
759     //! \note We don't permit luabind to use constructors here as it can't currently
760     //! give the object ownership at construction time.
761     static ChangeDirectionSpriteEvent* Create(const std::string& event_id,
762                                               VirtualSprite* sprite,
763                                               uint16_t direction);
764 
765 protected:
766     //! \brief Retains the direction to move the sprite when the event starts
767     uint16_t _direction;
768 
769     //! \brief Immediately changes the sprite's direction
770     void _Start();
771 
772     //! \brief Always returns true immediately, terminating the event
773     bool _Update();
774 }; // class ChangeDirectionSpriteEvent : public SpriteEvent
775 
776 /** ****************************************************************************
777 *** \brief A simple event used to set the direction of a sprite to make it look
778 *** at something or another sprite.
779 ***
780 *** This event finishes immediately after it starts, as all that it performs is
781 *** to set the direction of a sprite in a particular orientation.
782 ***
783 *** \note The only directions you should set in the class constructor are: NORTH,
784 *** SOUTH, EAST, and WEST. This event is used when a sprite is stationary, so
785 *** the other types of directions (which also infer movement) are unnecessary.
786 *** Using a direction other than these four will result in a warning being printed.
787 *** ***************************************************************************/
788 class LookAtSpriteEvent : public SpriteEvent
789 {
790 public:
791     /** \param event_id The ID of this event
792     *** \param sprite A pointer to the sprite that this event will effect
793     *** \param sprite A pointer to the sprite to look at.
794     **/
795     LookAtSpriteEvent(const std::string& event_id, VirtualSprite* sprite, VirtualSprite* other_sprite);
796 
797     /** \param event_id The ID of this event
798     *** \param sprite A pointer to the sprite that this event will effect
799     *** \param x, y map coodinates to look at.
800     **/
801     LookAtSpriteEvent(const std::string& event_id, VirtualSprite* sprite, float x, float y);
802 
~LookAtSpriteEvent()803     ~LookAtSpriteEvent()
804     {}
805 
806     //! \brief A C++ wrapper made to create a new object from scripting,
807     //! without letting Lua handling the object life-cycle.
808     //! \note We don't permit luabind to use constructors here as it can't currently
809     //! give the object ownership at construction time.
810     static LookAtSpriteEvent* Create(const std::string& event_id,
811                                      VirtualSprite* sprite,
812                                      VirtualSprite* other_sprite);
813     static LookAtSpriteEvent* Create(const std::string& event_id,
814                                      VirtualSprite* sprite,
815                                      float x, float y);
816 
817 protected:
818     //! \brief Retains the position to look at when the event starts.
819     vt_common::Position2D _pos;
820 
821     /** \brief Retains the position to look at when the even starts.
822     *** \note The event will take the sprite coord only at _Start() call, since
823     *** the position may have changed between the event declaration (map load time)
824     *** and its start.
825     **/
826     VirtualSprite* _target_sprite;
827 
828     //! \brief Immediately changes the sprite's direction
829     void _Start();
830 
831     //! \brief Always returns true immediately, terminating the event
832     bool _Update();
833 }; // class LookAtSpriteEvent : public SpriteEvent
834 
835 /** ****************************************************************************
836 *** \brief An event which moves a single sprite to a destination
837 ***
838 *** This class allows for both absolute and relative destinations. A relative
839 *** destination
840 ***
841 *** Using event linking, it is very simple to have a single event represent
842 *** a sprite traveling to multiple destinations, or multiple sprites travel to
843 *** multiple destinations.
844 *** ***************************************************************************/
845 class PathMoveSpriteEvent : public SpriteEvent
846 {
847     friend class VirtualSprite;
848 
849 public:
850     /** \param event_id The ID of this event
851     *** \param sprite A pointer to the sprite to move
852     *** \param x_coord The X coordinate to move the sprite to
853     *** \param y_coord The Y coordinate to move the sprite to
854     *** \param run whether the character has to go there by walking or running
855     **/
856     PathMoveSpriteEvent(const std::string& event_id, VirtualSprite* sprite, float x_coord, float y_coord, bool run);
857 
858     /** \param event_id The ID of this event
859     *** \param sprite A pointer to the sprite to move
860     *** \param target_sprite The target sprite to move the sprite to
861     *** \param run whether the character has to go there by walking or running
862     **/
863     PathMoveSpriteEvent(const std::string& event_id, VirtualSprite* sprite, VirtualSprite* target_sprite, bool run);
864 
~PathMoveSpriteEvent()865     ~PathMoveSpriteEvent()
866     {}
867 
868     //! \brief A C++ wrapper made to create a new object from scripting,
869     //! without letting Lua handling the object life-cycle.
870     //! \note We don't permit luabind to use constructors here as it can't currently
871     //! give the object ownership at construction time.
872     static PathMoveSpriteEvent* Create(const std::string& event_id,
873                                        VirtualSprite* sprite,
874                                        float x, float y,
875                                        bool run);
876     static PathMoveSpriteEvent* Create(const std::string& event_id,
877                                        VirtualSprite* sprite,
878                                        VirtualSprite* target_sprite,
879                                        bool run);
880 
881     /** \brief Used to change the destination coordinates after the class object has been constructed
882     *** \param x_coord The X coordinate to move the sprite to
883     *** \param y_coord The Y coordinate to move the sprite to
884     *** or:
885     *** \param target_sprite The target sprite to move the sprite to
886     *** \param run whether the character has to go there by walking or running
887     *** \note Any previous existing paths are cleared when this function is called. If this function is called when
888     *** the event is active, no change will take place.
889     *** This function is especially useful when trying to path move according to another NPC position, wichi may have
890     *** changed between the event declaration (at map load time) and the event actual start.
891     **/
892     void SetDestination(float x_coord, float y_coord, bool run);
893     void SetDestination(VirtualSprite* target_sprite, bool run);
894 
GetPath()895     Path GetPath() const {
896         return _path;
897     }
898 
899     //! \brief Stops and frees the sprite from the control_event
900     void Terminate();
901 
902 protected:
903     //! \brief Stores the destination coordinates for the path movement. These may be either absolute or relative coordinates.
904     vt_common::Position2D _destination;
905 
906     //! \brief The destination target, useful when willing to reach a moving point.
907     VirtualSprite* _target_sprite;
908 
909     //! \brief Used to store the previous coordinates of the sprite during path movement,
910     //! so as to set the proper direction of the sprite as it moves.
911     vt_common::Position2D _last_position;
912 
913     //! \brief Used to store the current node collision position (with offset)
914     vt_common::Position2D _current_node_pos;
915 
916     //! \brief An index to the path vector containing the node that the sprite currently occupies
917     uint32_t _current_node;
918 
919     //! \brief Holds the path needed to traverse from source to destination
920     Path _path;
921 
922     //! \brief Tells whether the sprite should use the walk or run animation
923     bool _run;
924 
925     //! \brief Calculates a path for the sprite to move to the destination
926     void _Start();
927 
928     //! \brief Returns true when the sprite has reached the destination
929     bool _Update();
930 
931     //! \brief Sets the correct direction for the sprite to move to the next node in the path
932     void _SetSpriteDirection();
933 }; // class PathMoveSpriteEvent : public SpriteEvent
934 
935 
936 /** ****************************************************************************
937 *** \brief An event which randomizes movement of a sprite
938 *** ***************************************************************************/
939 class RandomMoveSpriteEvent : public SpriteEvent
940 {
941     friend class VirtualSprite;
942 
943 public:
944     /** \param event_id The ID of this event
945     *** \param sprite A pointer to the sprite to move
946     *** \param move_time The total amount of time that this event should take
947     *** \param direction_time The amount of time to wait before changing the sprite's direction randomly
948     **/
949     RandomMoveSpriteEvent(const std::string &event_id, VirtualSprite* sprite,
950                           uint32_t move_time = 10000, uint32_t direction_time = 2000);
951 
952     ~RandomMoveSpriteEvent();
953 
954     //! \brief A C++ wrapper made to create a new object from scripting,
955     //! without letting Lua handling the object life-cycle.
956     //! \note We don't permit luabind to use constructors here as it can't currently
957     //! give the object ownership at construction time.
958     static RandomMoveSpriteEvent* Create(const std::string& event_id,
959                                          VirtualSprite* sprite,
960                                          uint32_t move_time,
961                                          uint32_t direction_time);
962 
963     //! \brief Stops and frees the sprite from the control_event
964     void Terminate();
965 
966 protected:
967     /** \brief The amount of time (in milliseconds) to perform random movement before ending this action
968     *** Set this member to vt_system::INFINITE_TIME in order to continue the random movement
969     *** forever. The default value of this member will be set to 10 seconds if it is not specified.
970     **/
971     uint32_t _total_movement_time;
972 
973     /** \brief The amount of time (in milliseconds) that the sprite should continue moving in its current direction
974     *** The default value for this timer is 1.5 seconds (1500ms).
975     **/
976     uint32_t _total_direction_time;
977 
978     //! \brief A timer which keeps track of how long the sprite has been in random movement
979     uint32_t _movement_timer;
980 
981     //! \brief A timer which keeps track of how long the sprite has been moving around since the last change in direction.
982     uint32_t _direction_timer;
983 
984     //! \brief Calculates a path for the sprite to move to the destination
985     void _Start();
986 
987     //! \brief Returns true when the sprite has reached the destination
988     bool _Update();
989 }; // class RandomMoveSpriteEvent : public SpriteEvent
990 
991 
992 /** ****************************************************************************
993 *** \brief Displays specific sprite frames for a certain period of time
994 ***
995 *** This event displays a certain animation of a sprite for a specified amount of time.
996 *** Its primary purpose is to allow complete control over how a sprite appears to the
997 *** player and to show the sprite interacting with its surroundings, such as flipping
998 *** through a book taken from a bookshelf. Looping of these animations is also supported.
999 ***
1000 *** \note You <b>must</b> add at least one frame to this object
1001 ***
1002 *** \note These actions can not be used with VirtualSprite objects, since this
1003 *** class explicitly needs animation images to work and virtual sprites have no
1004 *** images.
1005 *** ***************************************************************************/
1006 class AnimateSpriteEvent : public SpriteEvent
1007 {
1008 public:
1009     /** \param event_id The ID of this event
1010     *** \param sprite A pointer to the sprite to move
1011     *** \param animation_name The name of the custom animation to play
1012     *** \param animation_time The custom animation time, 0 if infinite, and -1 is default time used.
1013     **/
1014     AnimateSpriteEvent(const std::string& event_id, VirtualSprite* sprite,
1015                        const std::string& animation_name, int32_t animation_time);
1016 
~AnimateSpriteEvent()1017     ~AnimateSpriteEvent()
1018     {}
1019 
1020     //! \brief A C++ wrapper made to create a new object from scripting,
1021     //! without letting Lua handling the object life-cycle.
1022     //! \note We don't permit luabind to use constructors here as it can't currently
1023     //! give the object ownership at construction time.
1024     static AnimateSpriteEvent* Create(const std::string& event_id,
1025                                       VirtualSprite* sprite,
1026                                       const std::string& animation_name,
1027                                       int32_t animation_time);
1028 
1029     //! \brief Stops the custom animation and frees the sprite from the control_event
1030     void Terminate();
1031 
1032 protected:
1033     //! The custom animation name
1034     std::string _animation_name;
1035 
1036     //! The custom animation time.
1037     int32_t _animation_time;
1038 
1039     //! A reference to the map sprite object
1040     MapSprite* _map_sprite;
1041 
1042     //! \brief Triggers the custom animation for the given time
1043     void _Start();
1044 
1045     //! \brief Returns true when the sprite has finished to display a custom animation.
1046     bool _Update();
1047 }; // class AnimateSpriteEvent : public SpriteEvent
1048 
1049 /** ****************************************************************************
1050 *** \brief An event permitting to trigger a treasure opening dialog with given content.
1051 ***
1052 *** This event does basically the same as opening a treasure chest. @See TreasureObject.
1053 *** ***************************************************************************/
1054 class TreasureEvent : public MapEvent
1055 {
1056 public:
1057     /** \param event_id The ID of this event
1058     **/
1059     explicit TreasureEvent(const std::string& event_id);
1060 
~TreasureEvent()1061     virtual ~TreasureEvent() override
1062     {
1063         delete _treasure;
1064     }
1065 
1066     //! \brief A C++ wrapper made to create a new object from scripting,
1067     //! without letting Lua handling the object life-cycle.
1068     //! \note We don't permit luabind to use constructors here as it can't currently
1069     //! give the object ownership at construction time.
1070     static TreasureEvent* Create(const std::string& event_id);
1071 
GetTreasure()1072     MapTreasureContent* GetTreasure() const {
1073         return _treasure;
1074     }
1075 
1076     //! \brief Sets the number of drunes present in the chest's contents.
SetDrunes(uint32_t amount)1077     void SetDrunes(uint32_t amount) {
1078         _treasure->SetDrunes(amount);
1079     }
1080 
1081     /** \brief Adds an item to the contents of the TreasureEvent
1082     *** \param id The id of the GlobalObject to add
1083     *** \param quantity The number of the object to add (default == 1)
1084     *** \return True if the object was added successfully
1085     **/
1086     bool AddItem(uint32_t id, uint32_t quantity = 1);
1087 
1088     /** \brief Adds an event triggered at start of the treasure event.
1089     *** \param event_id The id of the event to add
1090     **/
1091     bool AddEvent(const std::string& event_id);
1092 
1093 protected:
1094     //! \brief A pointer to the treasure content, used by the TreasureSupervisor.
1095     MapTreasureContent* _treasure;
1096 
1097     //! \brief Events triggered at the start of the treasure event.
1098     std::vector<std::string> _events;
1099 
1100     /** \brief Starts a sprite event.
1101     ***
1102     *** This method will open the treasure dialog with the treasure content set for this event.
1103     **/
1104     void _Start() override;
1105 
1106     //! \brief Returns true once the treasure dialog is closed, and false otherwise.
1107     bool _Update() override;
1108 }; // class TreasureEvent : public MapEvent
1109 
1110 } // namespace private_map
1111 
1112 } // namespace vt_map
1113 
1114 #endif // __MAP_EVENTS_HEADER__
1115