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