1 // SONIC ROBO BLAST 2 2 //----------------------------------------------------------------------------- 3 // Copyright (C) 1993-1996 by id Software, Inc. 4 // Copyright (C) 1998-2000 by DooM Legacy Team. 5 // Copyright (C) 1999-2020 by Sonic Team Junior. 6 // 7 // This program is free software distributed under the 8 // terms of the GNU General Public License, version 2. 9 // See the 'LICENSE' file for more details. 10 //----------------------------------------------------------------------------- 11 /// \file p_spec.h 12 /// \brief Implements special effects: 13 /// Texture animation, height or lighting changes 14 /// according to adjacent sectors, respective 15 /// utility functions, etc. 16 17 #ifndef __P_SPEC__ 18 #define __P_SPEC__ 19 20 extern mobj_t *skyboxmo[2]; // current skybox mobjs: 0 = viewpoint, 1 = centerpoint 21 extern mobj_t *skyboxviewpnts[16]; // array of MT_SKYBOX viewpoint mobjs 22 extern mobj_t *skyboxcenterpnts[16]; // array of MT_SKYBOX centerpoint mobjs 23 24 // GETSECSPECIAL (specialval, section) 25 // 26 // Pulls out the special # from a particular section. 27 // 28 #define GETSECSPECIAL(i,j) ((i >> ((j-1)*4))&15) 29 30 // This must be updated whenever we up the max flat size - quicker to assume rather than figuring out the sqrt of the specific flat's filesize. 31 #define MAXFLATSIZE (2048<<FRACBITS) 32 33 // at game start 34 void P_InitPicAnims(void); 35 36 // at map load (sectors) 37 void P_SetupLevelFlatAnims(void); 38 39 // at map load 40 void P_InitSpecials(void); 41 void P_SpawnSpecials(boolean fromnetsave); 42 43 // every tic 44 void P_UpdateSpecials(void); 45 sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 number); 46 void P_PlayerInSpecialSector(player_t *player); 47 void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *roversector); 48 49 fixed_t P_FindLowestFloorSurrounding(sector_t *sec); 50 fixed_t P_FindHighestFloorSurrounding(sector_t *sec); 51 52 fixed_t P_FindNextHighestFloor(sector_t *sec, fixed_t currentheight); 53 fixed_t P_FindNextLowestFloor(sector_t *sec, fixed_t currentheight); 54 55 fixed_t P_FindLowestCeilingSurrounding(sector_t *sec); 56 fixed_t P_FindHighestCeilingSurrounding(sector_t *sec); 57 58 INT32 P_FindMinSurroundingLight(sector_t *sector, INT32 max); 59 60 void P_SetupSignExit(player_t *player); 61 boolean P_IsFlagAtBase(mobjtype_t flag); 62 63 void P_SwitchWeather(INT32 weathernum); 64 65 boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller); 66 void P_LinedefExecute(INT16 tag, mobj_t *actor, sector_t *caller); 67 void P_RunNightserizeExecutors(mobj_t *actor); 68 void P_RunDeNightserizeExecutors(mobj_t *actor); 69 void P_RunNightsLapExecutors(mobj_t *actor); 70 void P_RunNightsCapsuleTouchExecutors(mobj_t *actor, boolean entering, boolean enoughspheres); 71 72 UINT16 P_GetFFloorID(ffloor_t *fflr); 73 ffloor_t *P_GetFFloorByID(sector_t *sec, UINT16 id); 74 75 // 76 // P_LIGHTS 77 // 78 /** Fire flicker action structure. 79 */ 80 typedef struct 81 { 82 thinker_t thinker; ///< The thinker in use for the effect. 83 sector_t *sector; ///< The sector where action is taking place. 84 INT32 count; 85 INT32 resetcount; 86 INT32 maxlight; ///< The brightest light level to use. 87 INT32 minlight; ///< The darkest light level to use. 88 } fireflicker_t; 89 90 typedef struct 91 { 92 thinker_t thinker; 93 sector_t *sector; 94 INT32 maxlight; 95 INT32 minlight; 96 } lightflash_t; 97 98 /** Laser block thinker. 99 */ 100 typedef struct 101 { 102 thinker_t thinker; ///< Thinker structure for laser. 103 INT16 tag; 104 line_t *sourceline; 105 UINT8 nobosses; 106 } laserthink_t; 107 108 /** Strobe light action structure.. 109 */ 110 typedef struct 111 { 112 thinker_t thinker; ///< The thinker in use for the effect. 113 sector_t *sector; ///< The sector where the action is taking place. 114 INT32 count; 115 INT32 minlight; ///< The minimum light level to use. 116 INT32 maxlight; ///< The maximum light level to use. 117 INT32 darktime; ///< How INT32 to use minlight. 118 INT32 brighttime; ///< How INT32 to use maxlight. 119 } strobe_t; 120 121 typedef struct 122 { 123 thinker_t thinker; 124 sector_t *sector; 125 INT32 minlight; 126 INT32 maxlight; 127 INT32 direction; 128 INT32 speed; 129 } glow_t; 130 131 /** Thinker struct for fading lights. 132 */ 133 typedef struct 134 { 135 thinker_t thinker; ///< Thinker in use for the effect. 136 sector_t *sector; ///< Sector where action is taking place. 137 INT16 sourcelevel; ///< Light level we're fading from. 138 INT16 destlevel; ///< Light level we're fading to. 139 140 fixed_t fixedcurlevel; ///< Fixed point for current light level. 141 fixed_t fixedpertic; ///< Fixed point for increment per tic. 142 // The reason for those two above to be fixed point is to deal with decimal values that would otherwise get trimmed away. 143 INT32 timer; ///< Internal timer. 144 } lightlevel_t; 145 146 #define GLOWSPEED 8 147 #define STROBEBRIGHT 5 148 #define FASTDARK 15 149 #define SLOWDARK 35 150 151 void P_RemoveLighting(sector_t *sector); 152 153 void T_FireFlicker(fireflicker_t *flick); 154 fireflicker_t *P_SpawnAdjustableFireFlicker(sector_t *minsector, sector_t *maxsector, INT32 length); 155 void T_LightningFlash(lightflash_t *flash); 156 void T_StrobeFlash(strobe_t *flash); 157 158 void P_SpawnLightningFlash(sector_t *sector); 159 strobe_t * P_SpawnAdjustableStrobeFlash(sector_t *minsector, sector_t *maxsector, INT32 darktime, INT32 brighttime, boolean inSync); 160 161 void T_Glow(glow_t *g); 162 glow_t *P_SpawnAdjustableGlowingLight(sector_t *minsector, sector_t *maxsector, INT32 length); 163 164 void P_FadeLightBySector(sector_t *sector, INT32 destvalue, INT32 speed, boolean ticbased); 165 void P_FadeLight(INT16 tag, INT32 destvalue, INT32 speed, boolean ticbased, boolean force); 166 void T_LightFade(lightlevel_t *ll); 167 168 typedef enum 169 { 170 floor_special, 171 ceiling_special, 172 lighting_special, 173 } special_e; 174 175 // 176 // P_CEILNG 177 // 178 typedef enum 179 { 180 raiseToHighest, 181 lowerToLowest, 182 raiseToLowest, 183 lowerToLowestFast, 184 185 instantRaise, // instant-move for ceilings 186 187 lowerAndCrush, 188 crushAndRaise, 189 fastCrushAndRaise, 190 crushCeilOnce, 191 crushBothOnce, 192 193 moveCeilingByFrontSector, 194 instantMoveCeilingByFrontSector, 195 196 moveCeilingByFrontTexture, 197 198 bounceCeiling, 199 bounceCeilingCrush, 200 } ceiling_e; 201 202 /** Ceiling movement structure. 203 */ 204 typedef struct 205 { 206 thinker_t thinker; ///< Thinker for the type of movement. 207 ceiling_e type; ///< Type of movement. 208 sector_t *sector; ///< Sector where the action is taking place. 209 fixed_t bottomheight; ///< The lowest height to move to. 210 fixed_t topheight; ///< The highest height to move to. 211 fixed_t speed; ///< Ceiling speed. 212 fixed_t oldspeed; 213 fixed_t delay; 214 fixed_t delaytimer; 215 UINT8 crush; ///< Whether to crush things or not. 216 217 INT32 texture; ///< The number of a flat to use when done. 218 INT32 direction; ///< 1 = up, 0 = waiting, -1 = down. 219 220 // ID 221 INT32 tag; 222 INT32 olddirection; 223 fixed_t origspeed; ///< The original, "real" speed. 224 INT32 sourceline; ///< Index of the source linedef 225 } ceiling_t; 226 227 #define CEILSPEED (FRACUNIT) 228 229 INT32 EV_DoCeiling(line_t *line, ceiling_e type); 230 231 INT32 EV_DoCrush(line_t *line, ceiling_e type); 232 void T_CrushCeiling(ceiling_t *ceiling); 233 234 void T_MoveCeiling(ceiling_t *ceiling); 235 236 // 237 // P_FLOOR 238 // 239 typedef enum 240 { 241 // lower floor to lowest surrounding floor 242 lowerFloorToLowest, 243 244 // raise floor to next highest surrounding floor 245 raiseFloorToNearestFast, 246 247 // move the floor down instantly 248 instantLower, 249 250 moveFloorByFrontSector, 251 instantMoveFloorByFrontSector, 252 253 moveFloorByFrontTexture, 254 255 bounceFloor, 256 bounceFloorCrush, 257 258 crushFloorOnce, 259 } floor_e; 260 261 typedef enum 262 { 263 elevateUp, 264 elevateDown, 265 elevateCurrent, 266 elevateContinuous, 267 elevateBounce, 268 elevateHighest, 269 bridgeFall, 270 } elevator_e; 271 272 typedef struct 273 { 274 thinker_t thinker; 275 floor_e type; 276 UINT8 crush; 277 sector_t *sector; 278 INT32 direction; 279 INT32 texture; 280 fixed_t floordestheight; 281 fixed_t speed; 282 fixed_t origspeed; 283 fixed_t delay; 284 fixed_t delaytimer; 285 } floormove_t; 286 287 typedef struct 288 { 289 thinker_t thinker; 290 elevator_e type; 291 sector_t *sector; 292 sector_t *actionsector; // The sector the rover action is taking place in. 293 INT32 direction; 294 fixed_t floordestheight; 295 fixed_t ceilingdestheight; 296 fixed_t speed; 297 fixed_t origspeed; 298 fixed_t low; 299 fixed_t high; 300 fixed_t distance; 301 fixed_t delay; 302 fixed_t delaytimer; 303 fixed_t floorwasheight; // Height the floor WAS at 304 fixed_t ceilingwasheight; // Height the ceiling WAS at 305 line_t *sourceline; 306 } elevator_t; 307 308 typedef enum 309 { 310 CF_RETURN = 1, // Return after crumbling 311 CF_FLOATBOB = 1<<1, // Float on water 312 CF_REVERSE = 1<<2, // Reverse gravity 313 } crumbleflag_t; 314 315 typedef struct 316 { 317 thinker_t thinker; 318 line_t *sourceline; 319 sector_t *sector; 320 sector_t *actionsector; // The sector the rover action is taking place in. 321 player_t *player; // Player who initiated the thinker (used for airbob) 322 INT32 direction; 323 INT32 origalpha; 324 INT32 timer; 325 fixed_t speed; 326 fixed_t floorwasheight; // Height the floor WAS at 327 fixed_t ceilingwasheight; // Height the ceiling WAS at 328 UINT8 flags; 329 } crumble_t; 330 331 typedef struct 332 { 333 thinker_t thinker; 334 line_t *sourceline; // Source line of the thinker 335 } noenemies_t; 336 337 typedef struct 338 { 339 thinker_t thinker; 340 sector_t *sector; 341 fixed_t speed; 342 INT32 direction; 343 fixed_t floorstartheight; 344 fixed_t ceilingstartheight; 345 fixed_t destheight; 346 } continuousfall_t; 347 348 typedef struct 349 { 350 thinker_t thinker; 351 line_t *sourceline; 352 sector_t *sector; 353 fixed_t speed; 354 fixed_t distance; 355 fixed_t floorwasheight; 356 fixed_t ceilingwasheight; 357 boolean low; 358 } bouncecheese_t; 359 360 typedef struct 361 { 362 thinker_t thinker; 363 sector_t *sector; 364 fixed_t speed; 365 INT32 direction; 366 fixed_t floorstartheight; 367 fixed_t ceilingstartheight; 368 INT16 tag; 369 } mariothink_t; 370 371 typedef struct 372 { 373 thinker_t thinker; 374 line_t *sourceline; 375 sector_t *sector; 376 } mariocheck_t; 377 378 typedef struct 379 { 380 thinker_t thinker; 381 line_t *sourceline; 382 sector_t *sector; 383 fixed_t crushspeed; 384 fixed_t retractspeed; 385 INT32 direction; 386 fixed_t floorstartheight; 387 fixed_t ceilingstartheight; 388 INT32 delay; 389 INT16 tag; 390 UINT16 sound; 391 } thwomp_t; 392 393 typedef struct 394 { 395 thinker_t thinker; 396 line_t *sourceline; 397 sector_t *sector; 398 INT16 tag; 399 } floatthink_t; 400 401 typedef struct 402 { 403 thinker_t thinker; 404 line_t *sourceline; // Source line of the thinker 405 boolean playersInArea[MAXPLAYERS]; 406 boolean playersOnArea[MAXPLAYERS]; 407 boolean triggerOnExit; 408 } eachtime_t; 409 410 typedef enum 411 { 412 RF_REVERSE = 1, //Lower when stood on 413 RF_SPINDASH = 1<<1, //Require spindash to move 414 RF_DYNAMIC = 1<<2, //Dynamically sinking platform 415 } raiseflag_t; 416 417 typedef struct 418 { 419 thinker_t thinker; 420 INT16 tag; 421 sector_t *sector; 422 fixed_t ceilingbottom; 423 fixed_t ceilingtop; 424 fixed_t basespeed; 425 fixed_t extraspeed; //For dynamically sinking platform 426 UINT8 shaketimer; //For dynamically sinking platform 427 UINT8 flags; 428 } raise_t; 429 430 #define ELEVATORSPEED (FRACUNIT*4) 431 #define FLOORSPEED (FRACUNIT) 432 433 typedef enum 434 { 435 ok, 436 crushed, 437 pastdest 438 } result_e; 439 440 result_e T_MovePlane(sector_t *sector, fixed_t speed, fixed_t dest, boolean crush, 441 boolean ceiling, INT32 direction); 442 void EV_DoFloor(line_t *line, floor_e floortype); 443 void EV_DoElevator(line_t *line, elevator_e elevtype, boolean customspeed); 444 void EV_CrumbleChain(sector_t *sec, ffloor_t *rover); 445 void EV_BounceSector(sector_t *sector, fixed_t momz, line_t *sourceline); 446 447 // Some other special 3dfloor types 448 INT32 EV_StartCrumble(sector_t *sector, ffloor_t *rover, 449 boolean floating, player_t *player, fixed_t origalpha, boolean crumblereturn); 450 451 void EV_DoContinuousFall(sector_t *sec, sector_t *backsector, fixed_t spd, boolean backwards); 452 453 void EV_MarioBlock(ffloor_t *rover, sector_t *sector, mobj_t *puncher); 454 455 void T_MoveFloor(floormove_t *movefloor); 456 457 void T_MoveElevator(elevator_t *elevator); 458 void T_ContinuousFalling(continuousfall_t *faller); 459 void T_BounceCheese(bouncecheese_t *bouncer); 460 void T_StartCrumble(crumble_t *crumble); 461 void T_MarioBlock(mariothink_t *block); 462 void T_FloatSector(floatthink_t *floater); 463 void T_MarioBlockChecker(mariocheck_t *block); 464 void T_ThwompSector(thwomp_t *thwomp); 465 void T_NoEnemiesSector(noenemies_t *nobaddies); 466 void T_EachTimeThinker(eachtime_t *eachtime); 467 void T_CameraScanner(elevator_t *elevator); 468 void T_RaiseSector(raise_t *raise); 469 470 typedef struct 471 { 472 thinker_t thinker; // Thinker for linedef executor delay 473 line_t *line; // Pointer to line that is waiting. 474 mobj_t *caller; // Pointer to calling mobj 475 sector_t *sector; // Pointer to triggering sector 476 INT32 timer; // Delay timer 477 } executor_t; 478 479 void T_ExecutorDelay(executor_t *e); 480 481 /** Generalized scroller. 482 */ 483 typedef struct 484 { 485 thinker_t thinker; ///< Thinker structure for scrolling. 486 fixed_t dx, dy; ///< (dx,dy) scroll speeds. 487 INT32 affectee; ///< Number of affected sidedef or sector. 488 INT32 control; ///< Control sector (-1 if none) used to control scrolling. 489 fixed_t last_height; ///< Last known height of control sector. 490 fixed_t vdx, vdy; ///< Accumulated velocity if accelerative. 491 INT32 accel; ///< Whether it's accelerative. 492 INT32 exclusive; ///< If a conveyor, same property as in pusher_t 493 /** Types of generalized scrollers. 494 */ 495 enum 496 { 497 sc_side, ///< Scroll wall texture on a sidedef. 498 sc_floor, ///< Scroll floor. 499 sc_ceiling, ///< Scroll ceiling. 500 sc_carry, ///< Carry objects on floor. 501 sc_carry_ceiling,///< Carry objects on ceiling (for 3Dfloor conveyors). 502 } type; 503 } scroll_t; 504 505 void T_Scroll(scroll_t *s); 506 void T_LaserFlash(laserthink_t *flash); 507 508 /** Friction for ice/sludge effects. 509 */ 510 typedef struct 511 { 512 thinker_t thinker; ///< Thinker structure for friction. 513 INT32 friction; ///< Friction value, 0xe800 = normal. 514 INT32 movefactor; ///< Inertia factor when adding to momentum, FRACUNIT = normal. 515 INT32 affectee; ///< Number of affected sector. 516 INT32 referrer; ///< If roverfriction == true, then this will contain the sector # of the control sector where the effect was applied. 517 UINT8 roverfriction; ///< flag for whether friction originated from a FOF or not 518 } friction_t; 519 520 // Friction defines. 521 #define ORIG_FRICTION (0xE8 << (FRACBITS-8)) ///< Original value. 522 #define ORIG_FRICTION_FACTOR (8 << (FRACBITS-8)) ///< Original value. 523 524 void T_Friction(friction_t *f); 525 526 typedef enum 527 { 528 p_push, ///< Point pusher or puller. 529 p_wind, ///< Wind. 530 p_current, ///< Current. 531 p_upcurrent, ///< Upwards current. 532 p_downcurrent, ///< Downwards current. 533 p_upwind, ///< Upwards wind. 534 p_downwind ///< Downwards wind. 535 } pushertype_e; 536 537 // Model for pushers for push/pull effects 538 typedef struct 539 { 540 thinker_t thinker; ///< Thinker structure for push/pull effect. 541 /** Types of push/pull effects. 542 */ 543 pushertype_e type; ///< Type of push/pull effect. 544 mobj_t *source; ///< Point source if point pusher/puller. 545 INT32 x_mag; ///< X strength. 546 INT32 y_mag; ///< Y strength. 547 INT32 magnitude; ///< Vector strength for point pusher/puller. 548 INT32 radius; ///< Effective radius for point pusher/puller. 549 INT32 x, y, z; ///< Point source if point pusher/puller. 550 INT32 affectee; ///< Number of affected sector. 551 UINT8 roverpusher; ///< flag for whether pusher originated from a FOF or not 552 INT32 referrer; ///< If roverpusher == true, then this will contain the sector # of the control sector where the effect was applied. 553 INT32 exclusive; /// < Once this affect has been applied to a mobj, no other pushers may affect it. 554 INT32 slider; /// < Should the player go into an uncontrollable slide? 555 } pusher_t; 556 557 // Model for disappearing/reappearing FOFs 558 typedef struct 559 { 560 thinker_t thinker; ///< Thinker structure for effect. 561 tic_t appeartime; ///< Tics to be appeared for 562 tic_t disappeartime;///< Tics to be disappeared for 563 tic_t offset; ///< Time to wait until thinker starts 564 tic_t timer; ///< Timer between states 565 INT32 affectee; ///< Number of affected line 566 INT32 sourceline; ///< Number of source line 567 INT32 exists; ///< Exists toggle 568 } disappear_t; 569 570 void T_Disappear(disappear_t *d); 571 572 // Model for fading FOFs 573 typedef struct 574 { 575 thinker_t thinker; ///< Thinker structure for effect. 576 ffloor_t *rover; ///< Target ffloor 577 extracolormap_t *dest_exc; ///< Colormap to fade to 578 UINT32 sectornum; ///< Number of ffloor target sector 579 UINT32 ffloornum; ///< Number of ffloor of target sector 580 INT32 alpha; ///< Internal alpha counter 581 INT16 sourcevalue; ///< Transparency value to fade from 582 INT16 destvalue; ///< Transparency value to fade to 583 INT16 destlightlevel; ///< Light level to fade to 584 INT16 speed; ///< Speed to fade by 585 boolean ticbased; ///< Tic-based logic toggle 586 INT32 timer; ///< Timer for tic-based logic 587 boolean doexists; ///< Handle FF_EXISTS 588 boolean dotranslucent; ///< Handle FF_TRANSLUCENT 589 boolean dolighting; ///< Handle shadows and light blocks 590 boolean docolormap; ///< Handle colormaps 591 boolean docollision; ///< Handle interactive flags 592 boolean doghostfade; ///< No interactive flags during fading 593 boolean exactalpha; ///< Use exact alpha values (opengl) 594 } fade_t; 595 596 void T_Fade(fade_t *d); 597 598 // Model for fading colormaps 599 600 typedef struct 601 { 602 thinker_t thinker; ///< Thinker structure for effect. 603 sector_t *sector; ///< Sector where action is taking place. 604 extracolormap_t *source_exc; 605 extracolormap_t *dest_exc; 606 boolean ticbased; ///< Tic-based timing 607 INT32 duration; ///< Total duration for tic-based logic (OR: speed increment) 608 INT32 timer; ///< Timer for tic-based logic (OR: internal speed counter) 609 } fadecolormap_t; 610 611 void T_FadeColormap(fadecolormap_t *d); 612 613 // Prototype functions for pushers 614 void T_Pusher(pusher_t *p); 615 mobj_t *P_GetPushThing(UINT32 s); 616 617 // Plane displacement 618 typedef struct 619 { 620 thinker_t thinker; ///< Thinker structure for plane displacement effect. 621 INT32 affectee; ///< Number of affected sector. 622 INT32 control; ///< Control sector used to control plane positions. 623 fixed_t last_height; ///< Last known height of control sector. 624 fixed_t speed; ///< Plane movement speed. 625 UINT8 reverse; ///< Move in reverse direction to control sector? 626 /** Types of plane displacement effects. 627 */ 628 enum 629 { 630 pd_floor, ///< Displace floor. 631 pd_ceiling, ///< Displace ceiling. 632 pd_both, ///< Displace both floor AND ceiling. 633 } type; 634 } planedisplace_t; 635 636 void T_PlaneDisplace(planedisplace_t *pd); 637 638 void P_CalcHeight(player_t *player); 639 640 sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo); 641 642 #endif 643