1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef NUVIE_CORE_EFFECT_H 24 #define NUVIE_CORE_EFFECT_H 25 26 27 #include "ultima/nuvie/misc/call_back.h" 28 #include "ultima/nuvie/core/map.h" 29 #include "ultima/nuvie/core/obj_manager.h" 30 #include "ultima/nuvie/core/anim_manager.h" 31 32 namespace Ultima { 33 namespace Nuvie { 34 35 //class Actor; 36 class EffectManager; 37 class Game; 38 class MapWindow; 39 class NuvieAnim; 40 class Screen; 41 class TimedAdvance; 42 class TimedCallback; 43 class ObjManager; 44 45 // Effects add themselves to EffectManager and most start immediately. 46 47 /* Effects: * = unwritten or untested 48 * Quake - earthquake from cyclops or volcanos 49 * Hit - hit actor anim + sfx 50 * Explosive - explosion caused by powder keg, volcanos, or cannonball hit 51 * ThrowObject - any thrown object or tile 52 * Cannonball (FIX: change to UseCodeThrow) 53 * Missile - throw object to ground or actor; optionally cause damage 54 * *Boomerang - spin Missile and return to sender 55 * Drop - throw obj from inventory to ground 56 * Sleep - pause game & advance time quickly 57 * Fade - fade the mapwindow in or out 58 * GameFadeIn - blocks user-input until Fade is complete 59 * *Palette - do something with the color palette 60 * Vanish - fade from an image of the mapwindow to the real mapwindow 61 * *FadeObject - might not need this since Vanish can be used 62 * U6WhitePotion - will probably make PaletteEffect to do this 63 */ 64 65 66 /* Control animation and sounds in the game world. 67 */ 68 class Effect : public CallBack { 69 protected: 70 Game *game; 71 EffectManager *effect_manager; 72 bool defunct; 73 74 uint32 retain_count; 75 76 public: 77 Effect(); 78 ~Effect() override; 79 retain()80 void retain() { 81 retain_count++; 82 } release()83 void release() { 84 if (retain_count > 0) retain_count--; 85 } is_retained()86 bool is_retained() { 87 return retain_count == 0 ? false : true; 88 } 89 delete_self()90 void delete_self() { 91 defunct = true; 92 } 93 void add_anim(NuvieAnim *anim); 94 is_defunct()95 bool is_defunct() { 96 return (defunct); 97 } callback(uint16,CallBack *,void *)98 uint16 callback(uint16, CallBack *, void *) override { 99 return (0); 100 } 101 }; 102 103 #define CANNON_SPEED 320 104 /* Toss a cannon ball from one actor to another, or from an object towards 105 * a numbered direction. 106 */ 107 class CannonballEffect : public Effect { 108 UseCode *usecode; 109 NuvieAnim *anim; 110 // *sfx; 111 Obj *obj; 112 MapCoord target_loc; // where cannonball will hit 113 114 void start_anim(); 115 116 public: 117 CannonballEffect(Obj *src_obj, sint8 direction = -1); 118 // CannonballEffect(Actor *src_actor, Actor *target_actor); from a ship 119 120 uint16 callback(uint16 msg, CallBack *caller, void *data) override; 121 }; 122 123 class ProjectileEffect : public Effect { 124 protected: 125 uint16 tile_num; 126 127 MapCoord start_loc; // where explosion will start 128 vector<MapCoord> targets; 129 uint8 anim_speed; 130 bool trail; 131 uint16 initial_tile_rotation; 132 uint16 rotation_amount; 133 uint8 src_tile_y_offset; 134 uint16 finished_tiles; 135 136 vector<MapEntity> hit_entities; 137 138 virtual void start_anim(); 139 140 public: ProjectileEffect()141 ProjectileEffect() { 142 tile_num = 0; 143 anim_speed = 0; 144 trail = false; 145 initial_tile_rotation = 0; 146 rotation_amount = 0; 147 src_tile_y_offset = 0; 148 finished_tiles = 0; 149 } 150 ProjectileEffect(uint16 tileNum, MapCoord start, MapCoord target, uint8 speed, bool trailFlag, uint16 initialTileRotation, uint16 rotationAmount, uint8 src_y_offset); 151 ProjectileEffect(uint16 tileNum, MapCoord start, vector<MapCoord> t, uint8 speed, bool trailFlag, uint16 initialTileRotation); 152 153 void init(uint16 tileNum, MapCoord start, vector<MapCoord> t, uint8 speed, bool trailFlag, uint16 initialTileRotation, uint16 rotationAmount, uint8 src_y_offset); 154 155 uint16 callback(uint16 msg, CallBack *caller, void *data) override; 156 get_hit_entities()157 vector<MapEntity> *get_hit_entities() { 158 return &hit_entities; 159 } 160 }; 161 162 class ExpEffect : public ProjectileEffect { 163 UseCode *usecode; 164 NuvieAnim *anim; 165 166 Obj *obj; 167 uint16 exp_tile_num; 168 169 protected: 170 void start_anim() override; 171 public: 172 ExpEffect(uint16 tileNum, MapCoord location); 173 174 }; 175 176 /* Use to add an effect with timed activity. Self-contained timer must be 177 * stopped/started with the included methods. 178 */ 179 class TimedEffect : public Effect { 180 protected: 181 TimedCallback *timer; 182 public: TimedEffect()183 TimedEffect() { 184 timer = NULL; 185 } TimedEffect(uint32 delay)186 TimedEffect(uint32 delay) { 187 timer = NULL; 188 start_timer(delay); 189 } ~TimedEffect()190 ~TimedEffect() override { 191 stop_timer(); 192 } 193 194 void start_timer(uint32 delay); 195 void stop_timer(); 196 delete_self()197 void delete_self() { 198 stop_timer(); 199 Effect::delete_self(); 200 } 201 callback(uint16 msg,CallBack * caller,void * data)202 uint16 callback(uint16 msg, CallBack *caller, void *data) override { 203 if (msg == MESG_TIMED) delete_self(); //= 0; 204 return (0); 205 } 206 }; 207 208 209 /* Shake the visible play area around. 210 */ 211 class QuakeEffect : public TimedEffect { 212 MapWindow *map_window; 213 static QuakeEffect *current_quake; // do nothing if already active 214 sint32 sx, sy; // last map_window movement amount 215 MapCoord orig; // map_window location at start 216 Actor *orig_actor; // center map_window on actor 217 uint32 stop_time; 218 uint8 strength; // magnitude 219 220 public: 221 QuakeEffect(uint8 magnitude, uint32 duration, Actor *keep_on = NULL); 222 ~QuakeEffect() override; 223 uint16 callback(uint16 msg, CallBack *caller, void *data) override; 224 225 void init_directions(); 226 void recenter_map(); 227 void stop_quake(); 228 }; 229 230 231 /* Hit target actor. 232 */ 233 class HitEffect : public Effect { 234 public: 235 HitEffect(Actor *target, uint32 duration = 300); 236 HitEffect(MapCoord location); 237 uint16 callback(uint16 msg, CallBack *caller, void *data) override; 238 }; 239 240 /* Print text to MapWindow for a given duration 241 */ 242 class TextEffect : public Effect { 243 244 public: 245 TextEffect(Std::string text); 246 TextEffect(Std::string text, MapCoord location); 247 uint16 callback(uint16 msg, CallBack *caller, void *data) override; 248 }; 249 250 251 /* Create explosion animation and sounds from the source location out to 252 * specified radius. Hit actors and objects for `dmg'. 253 */ 254 class ExplosiveEffect : public Effect { 255 protected: 256 NuvieAnim *anim; 257 // *sfx; 258 MapCoord start_at; 259 uint32 radius; 260 uint16 hit_damage; // hp taken off actors hit by explosion 261 262 void start_anim(); 263 264 public: 265 ExplosiveEffect(uint16 x, uint16 y, uint32 size, uint16 dmg = 0); 266 uint16 callback(uint16 msg, CallBack *caller, void *data) override; 267 268 // children can override delete_self()269 virtual void delete_self() { 270 Effect::delete_self(); 271 } hit_object(Obj * obj)272 virtual bool hit_object(Obj *obj) { 273 return (false); // explosion hit something 274 } 275 // true return=end effect 276 }; 277 278 279 /* Explosion that sends usecode event to an object on completion. 280 */ 281 class UseCodeExplosiveEffect : public ExplosiveEffect { 282 Obj *obj; // explosion came from this object (can be NULL) 283 Obj *original_obj; // don't hit this object (chain-reaction avoidance hack) 284 285 public: 286 UseCodeExplosiveEffect(Obj *src_obj, uint16 x, uint16 y, uint32 size, uint16 dmg = 0, Obj *dont_hit_me = NULL) ExplosiveEffect(x,y,size,dmg)287 : ExplosiveEffect(x, y, size, dmg), obj(src_obj), original_obj(dont_hit_me) { 288 } 289 void delete_self() override; 290 bool hit_object(Obj *hit_obj) override; // explosion hit something 291 292 293 294 }; 295 296 297 /* Toss object tile from one location to another with a TossAnim, and play a 298 * sound effect. The ThrowObjectEffect is constructed with uninitialized 299 * parameters and isn't started until start_anim() is called. 300 */ 301 class ThrowObjectEffect : public Effect { 302 protected: 303 ObjManager *obj_manager; 304 NuvieAnim *anim; // TossAnim 305 // *sfx; 306 MapCoord start_at, stop_at; // start_at -> stop_at 307 Obj *throw_obj; // object being thrown 308 Tile *throw_tile; // graphic to use (default is object's tile) 309 uint16 throw_speed; // used in animation 310 uint16 degrees; // rotation of tile 311 uint8 stop_flags; // TossAnim blocking flags 312 313 public: 314 ThrowObjectEffect(); ~ThrowObjectEffect()315 ~ThrowObjectEffect() override { } 316 317 void hit_target(); // stops effect 318 void start_anim(); 319 320 uint16 callback(uint16 msg, CallBack *caller, void *data) override = 0; 321 }; 322 323 324 /* Drop an object from an actor's inventory. Object is removed from the actor 325 * after starting the effect, and added to the map when the effect is complete. 326 * Effect speed is gametype-defined. 327 */ 328 class DropEffect : public ThrowObjectEffect { 329 Actor *drop_from_actor; 330 public: 331 DropEffect(Obj *obj, uint16 qty, Actor *actor, MapCoord *drop_loc); 332 333 void hit_target(); 334 335 void get_obj(Obj *obj, uint16 qty); 336 uint16 callback(uint16 msg, CallBack *caller, void *data) override; 337 }; 338 339 #define MISSILE_DEFAULT_SPEED 200 340 #define MISSILE_HIT_TARGET TOSS_TO_BLOCKING 341 #define MISSILE_HIT_OBJECTS (TOSS_TO_BLOCKING|TOSS_TO_OBJECT) 342 #define MISSILE_HIT_ACTORS (TOSS_TO_BLOCKING|TOSS_TO_ACTOR) 343 #define MISSILE_HIT_ALL (TOSS_TO_BLOCKING|TOSS_TO_OBJECT|TOSS_TO_ACTOR) 344 345 /* Throw a missile towards a target location. If the target is an actor or 346 * object, it will be hit for the requested damage. If the target is an empty 347 * map location, the object will be added to the map. The missile always stops 348 * if hitting a blocking tile. 349 * 350 * Decide in the attack logic, before constructing this, whether or not it was 351 * successful, and use the appropriate constructor. You can set the effect to 352 * hit any actors or objects in the way if the attack missed. 353 */ 354 class MissileEffect : public ThrowObjectEffect { 355 ActorManager *actor_manager; 356 357 uint16 hit_damage; // hp taken off actor/object hit by missile 358 Actor *hit_actor; 359 Obj *hit_obj; 360 361 public: 362 MissileEffect(uint16 tile_num, uint16 obj_n, const MapCoord &source, 363 const MapCoord &target, uint8 dmg, uint8 intercept = MISSILE_HIT_TARGET, uint16 speed = MISSILE_DEFAULT_SPEED); 364 365 void init(uint16 tile_num, uint16 obj_n, const MapCoord &source, 366 const MapCoord &target, uint32 dmg, uint8 intercept, uint32 speed); 367 void hit_target(); 368 void hit_blocking(); 369 uint16 callback(uint16 msg, CallBack *caller, void *data) override; 370 }; 371 372 #if 0 373 /* Throw an object and bring it back. 374 */ 375 class BoomerangEffect : public ThrowObjectEffect { 376 // I might even add an arc from the center line for a cool effect. 377 }; 378 379 380 /* Cycle or modify the game palette in some way. 381 */ 382 class PaletteEffect : public TimedEffect { 383 // palette effects are created from child classes (new BlackPotionEffect();) 384 // ...and these can include SFX like any other effect 385 // but PaletteEffect is not abstract (new PaletteEffect(timing & color params...);) 386 }; 387 388 389 #endif 390 391 392 /* For sleeping at inns. Fade-out, advance time, and fade-in. 393 */ 394 class SleepEffect : public Effect { 395 TimedAdvance *timer; // timed event 396 uint8 stop_hour, stop_minute; // sleep until this time 397 Std::string stop_time; 398 public: 399 SleepEffect(Std::string until); 400 SleepEffect(uint8 to_hour); 401 ~SleepEffect() override; 402 403 uint16 callback(uint16 msg, CallBack *caller, void *data) override; 404 void delete_self(); 405 }; 406 407 408 typedef enum { FADE_PIXELATED, FADE_CIRCLE, FADE_PIXELATED_ONTOP } FadeType; 409 typedef enum { FADE_IN, FADE_OUT } FadeDirection; 410 411 #define FADE_EFFECT_MAX_ITERATIONS 20 412 413 /* Manipulate the MapWindow for two types of fades. One is a stippled-like fade 414 * that draws pixels to random locations on the screen until completely flooded 415 * with a set color. The other changes the ambient light until fully black. 416 */ 417 class FadeEffect : public TimedEffect { 418 protected: 419 static FadeEffect *current_fade; // do nothing if already active 420 421 MapWindow *map_window; 422 Screen *screen; // for PIXELATED, the overlay is blitted to the screen... 423 Common::Rect *viewport; // ...at the MapWindow coordinates set here 424 Graphics::ManagedSurface *overlay; // this is what gets blitted 425 426 FadeType fade_type; // PIXELATED[_ONTOP] or CIRCLE 427 FadeDirection fade_dir; // IN (removing color) or OUT (adding color) 428 uint32 fade_speed; // meaning of this depends on fade_type 429 uint8 pixelated_color; // color from palette that is being faded to/from 430 Graphics::ManagedSurface *fade_from; // image being faded from or to (or NULL if coloring) 431 uint16 fade_x, fade_y; // start fade from this point (to fade_from size) 432 433 uint32 evtime, prev_evtime; // time of last message to callback() 434 uint32 pixel_count, colored_total; // number of pixels total/colored 435 uint16 fade_iterations; // number of times we've updated the fade effect 436 437 public: 438 FadeEffect(FadeType fade, FadeDirection dir, uint32 color = 0, uint32 speed = 0); 439 FadeEffect(FadeType fade, FadeDirection dir, Graphics::ManagedSurface *capture, uint32 speed = 0); 440 FadeEffect(FadeType fade, FadeDirection dir, Graphics::ManagedSurface *capture, uint16 x, uint16 y, uint32 speed = 0); 441 ~FadeEffect() override; 442 uint16 callback(uint16 msg, CallBack *caller, void *data) override; 443 444 bool pixelated_fade_out(); 445 bool pixelated_fade_in(); 446 bool circle_fade_out(); 447 bool circle_fade_in(); 448 449 void delete_self(); 450 451 protected: 452 void init(FadeType fade, FadeDirection dir, uint32 color, Graphics::ManagedSurface *capture, uint16 x, uint16 y, uint32 speed); 453 void init_pixelated_fade(); 454 void init_circle_fade(); 455 456 inline bool find_free_pixel(uint32 &rnum, uint32 pixel_count); 457 uint32 pixels_to_check(); 458 bool pixelated_fade_core(uint32 pixels_to_check, sint16 fade_to); 459 // inline uint32 get_random_pixel(uint16 center_thresh = 0); 460 }; 461 462 463 /* Front-end to FadeEffect that fades in, and resumes game. 464 */ 465 class GameFadeInEffect : public FadeEffect { 466 public: 467 GameFadeInEffect(uint32 color); 468 ~GameFadeInEffect() override; 469 uint16 callback(uint16 msg, CallBack *caller, void *data) override; 470 }; 471 472 473 /* Captures an image of the MapWindow without an object, then places the object 474 * on the map and fades to the new image. (or the opposite if FADE_OUT is used) 475 */ 476 class FadeObjectEffect : public Effect { 477 ObjManager *obj_manager; 478 Obj *fade_obj; 479 FadeDirection fade_dir; 480 public: 481 FadeObjectEffect(Obj *obj, FadeDirection dir); 482 ~FadeObjectEffect() override; 483 uint16 callback(uint16 msg, CallBack *caller, void *data) override; 484 }; 485 486 487 /* Do a blocking fade-to (FADE_OUT) from a captured image of the game area, to 488 * the active game area. (transparent) This is used for vanish or morph effects. 489 */ 490 #define VANISH_WAIT true 491 #define VANISH_NOWAIT false 492 class VanishEffect : public Effect { 493 bool input_blocked; 494 public: 495 VanishEffect(bool pause_user = VANISH_NOWAIT); 496 ~VanishEffect() override; 497 uint16 callback(uint16 msg, CallBack *caller, void *data) override; 498 }; 499 500 class TileFadeEffect : public TimedEffect { 501 TileAnim *anim; 502 Tile *to_tile; 503 Tile *anim_tile; 504 Actor *actor; 505 uint8 color_from, color_to; 506 bool inc_reverse; 507 uint16 spd; 508 509 uint16 num_anim_running; 510 public: 511 TileFadeEffect(MapCoord loc, Tile *from, Tile *to, FadeType type, uint16 speed); 512 //TileFadeEffect(MapCoord loc, Tile *from, uint8 color_from, uint8 color_to, bool reverse, uint16 speed); 513 TileFadeEffect(Actor *a, uint16 speed); 514 ~TileFadeEffect() override; 515 uint16 callback(uint16 msg, CallBack *caller, void *data) override; 516 517 protected: 518 void add_actor_anim(); 519 void add_fade_anim(MapCoord loc, Tile *tile); 520 void add_tile_anim(MapCoord loc, Tile *tile); 521 void add_obj_anim(Obj *obj); 522 }; 523 524 class TileBlackFadeEffect : public TimedEffect { 525 Actor *actor; 526 Obj *obj; 527 uint8 color; 528 bool reverse; 529 uint16 fade_speed; 530 531 uint16 num_anim_running; 532 public: 533 TileBlackFadeEffect(Actor *a, uint8 fade_color, uint16 speed); 534 TileBlackFadeEffect(Obj *o, uint8 fade_color, uint16 speed); 535 ~TileBlackFadeEffect() override; 536 uint16 callback(uint16 msg, CallBack *caller, void *data) override; 537 protected: 538 void init(uint8 fade_color, uint16 speed); 539 void add_actor_anim(); 540 void add_obj_anim(Obj *o); 541 void add_tile_anim(MapCoord loc, Tile *tile); 542 }; 543 544 /* Briefly modify the mapwindow colors, disable map-blacking and player 545 * movement for a few seconds, then enable both. 546 */ 547 class XorEffect : public TimedEffect { 548 MapWindow *map_window; 549 uint32 length; 550 Graphics::ManagedSurface *capture; // this is what gets blitted 551 552 void xor_capture(uint8 mod); 553 void init_effect(); 554 555 public: 556 /* eff_ms=length of visual effect */ 557 XorEffect(uint32 eff_ms); ~XorEffect()558 ~XorEffect() override { } 559 560 /* Called by the timer between each effect stage. */ 561 uint16 callback(uint16 msg, CallBack *caller, void *data) override; 562 }; 563 564 /* Briefly modify the mapwindow colors, disable map-blacking and player 565 * movement for a few seconds, then enable both. 566 */ 567 class U6WhitePotionEffect : public TimedEffect { 568 MapWindow *map_window; 569 uint8 state; // 0=start, 1=eff1, 2=eff2, 3=x-ray, 4=complete 570 uint32 start_length, eff1_length, eff2_length, xray_length; 571 Graphics::ManagedSurface *capture; // this is what gets blitted 572 Obj *potion; // allows effect to call usecode and delete object 573 574 void xor_capture(uint8 mod); 575 void init_effect(); 576 577 public: 578 /* eff_ms=length of visual effect; delay_ms=length of x-ray effect */ 579 U6WhitePotionEffect(uint32 eff_ms, uint32 delay_ms, Obj *callback_obj = NULL); ~U6WhitePotionEffect()580 ~U6WhitePotionEffect() override { } 581 582 /* Called by the timer between each effect stage. */ 583 uint16 callback(uint16 msg, CallBack *caller, void *data) override; 584 }; 585 586 587 class XRayEffect : public TimedEffect { 588 uint32 xray_length; 589 void init_effect(); 590 591 public: 592 /* eff_ms=length of x-ray effect */ 593 XRayEffect(uint32 eff_ms); ~XRayEffect()594 ~XRayEffect() override { } 595 596 uint16 callback(uint16 msg, CallBack *caller, void *data) override; 597 }; 598 599 /* Pause the game, create an effect, and wait for user input to continue. */ 600 class PauseEffect: public Effect { 601 public: 602 /* Called by the Effect handler when input is available. */ 603 uint16 callback(uint16 msg, CallBack *caller, void *data) override; delete_self()604 virtual void delete_self() { 605 Effect::delete_self(); 606 } 607 PauseEffect(); ~PauseEffect()608 ~PauseEffect() override { } 609 }; 610 611 /* Gather text from scroll input then continue. */ 612 class TextInputEffect: public Effect { 613 Std::string input; 614 public: 615 /* Called by the Effect handler when input is available. */ 616 uint16 callback(uint16 msg, CallBack *caller, void *data) override; 617 TextInputEffect(const char *allowed_chars, bool can_escape); ~TextInputEffect()618 ~TextInputEffect() override { } get_input()619 Std::string get_input() { 620 return input; 621 } 622 }; 623 624 class WizardEyeEffect: public Effect { 625 public: 626 /* Called by the Effect handler when input is available. */ 627 uint16 callback(uint16 msg, CallBack *caller, void *data) override; delete_self()628 virtual void delete_self() { 629 Effect::delete_self(); 630 } 631 WizardEyeEffect(MapCoord location, uint16 duration); ~WizardEyeEffect()632 ~WizardEyeEffect() override { } 633 }; 634 635 /* colors for PeerEffect */ 636 const uint8 peer_tilemap[4] = { 637 0x0A, // GROUND/PASSABLE 638 0x09, // WATER 639 0x07, // WALLS/BLOCKED 640 0x0C // DANGER/DAMAGING 641 }; 642 643 #define PEER_TILEW 4 644 const uint8 peer_tile[PEER_TILEW * PEER_TILEW] = { 645 0, 1, 0, 1, 646 1, 0, 1, 0, 647 0, 1, 0, 1, 648 1, 0, 1, 0 649 }; 650 651 /* Display an overview of the current area in the MapWindow. Any new actions 652 * cancel the effect and return to the prompt. 653 * (area is 48x48 tiles around the player, regardless of MapWindow size) 654 */ 655 class PeerEffect : public PauseEffect { 656 MapWindow *map_window; 657 Graphics::ManagedSurface *overlay; // this is what gets blitted 658 Obj *gem; // allows effect to call usecode and delete object 659 MapCoord area; // area to display (top-left corner) 660 uint8 tile_trans; // peer_tile transparency mask (0 or 1) 661 uint16 map_pitch; 662 663 inline void blit_tile(uint16 x, uint16 y, uint8 c); 664 inline void blit_actor(Actor *actor); 665 inline uint8 get_tilemap_type(uint16 wx, uint16 wy, uint8 wz); 666 void fill_buffer(uint8 *mapbuffer, uint16 x, uint16 y); 667 void peer(); 668 669 public: 670 PeerEffect(uint16 x, uint16 y, uint8 z, Obj *callback_obj = 0); ~PeerEffect()671 ~PeerEffect() override { } 672 void init_effect(); 673 void delete_self() override; 674 }; 675 676 class WingStrikeEffect : public Effect { 677 protected: 678 679 Actor *actor; 680 681 public: 682 WingStrikeEffect(Actor *target_actor); 683 684 uint16 callback(uint16 msg, CallBack *caller, void *data) override; 685 }; 686 687 class HailStormEffect : public Effect { 688 protected: 689 690 public: 691 HailStormEffect(MapCoord target); 692 693 uint16 callback(uint16 msg, CallBack *caller, void *data) override; 694 }; 695 696 #define EFFECT_PROCESS_GUI_INPUT true 697 698 /* Run an effect asynchronously and keep updating the world until the effect completes. */ 699 class AsyncEffect : public Effect { 700 protected: 701 Effect *effect; 702 bool effect_complete; 703 704 public: 705 AsyncEffect(Effect *e); 706 ~AsyncEffect() override; 707 void run(bool process_gui_input = false); 708 uint16 callback(uint16 msg, CallBack *caller, void *data) override; 709 }; 710 711 } // End of namespace Nuvie 712 } // End of namespace Ultima 713 714 #endif 715