1 // Emacs style mode select -*- C++ -*-
2 //-----------------------------------------------------------------------------
3 //
4 // $Id:$
5 //
6 // Copyright (C) 1993-1996 by id Software, Inc.
7 //
8 // This source is available for distribution and/or modification
9 // only under the terms of the DOOM Source Code License as
10 // published by id Software. All rights reserved.
11 //
12 // The source is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
15 // for more details.
16 //
17 // DESCRIPTION: none
18 // Implements special effects:
19 // Texture animation, height or lighting changes
20 // according to adjacent sectors, respective
21 // utility functions, etc.
22 //
23 //-----------------------------------------------------------------------------
24
25 #ifndef __P_SPEC__
26 #define __P_SPEC__
27
28 #include "dsectoreffect.h"
29 #include "doomdata.h"
30 #include "r_state.h"
31
32 class FScanner;
33 struct level_info_t;
34
35 //jff 2/23/98 identify the special classes that can share sectors
36
37 typedef enum
38 {
39 floor_special,
40 ceiling_special,
41 lighting_special,
42 } special_e;
43
44 // killough 3/7/98: Add generalized scroll effects
45
46 class DScroller : public DThinker
47 {
48 DECLARE_CLASS (DScroller, DThinker)
49 HAS_OBJECT_POINTERS
50 public:
51 enum EScrollType
52 {
53 sc_side,
54 sc_floor,
55 sc_ceiling,
56 sc_carry,
57 sc_carry_ceiling, // killough 4/11/98: carry objects hanging on ceilings
58 };
59 enum EScrollPos
60 {
61 scw_top=1,
62 scw_mid=2,
63 scw_bottom=4,
64 scw_all=7,
65 };
66
67 DScroller (EScrollType type, fixed_t dx, fixed_t dy, int control, int affectee, int accel, int scrollpos = scw_all);
68 DScroller (fixed_t dx, fixed_t dy, const line_t *l, int control, int accel, int scrollpos = scw_all);
69 void Destroy();
70
71 void Serialize (FArchive &arc);
72 void Tick ();
73
AffectsWall(int wallnum)74 bool AffectsWall (int wallnum) const { return m_Type == sc_side && m_Affectee == wallnum; }
GetWallNum()75 int GetWallNum () const { return m_Type == sc_side ? m_Affectee : -1; }
SetRate(fixed_t dx,fixed_t dy)76 void SetRate (fixed_t dx, fixed_t dy) { m_dx = dx; m_dy = dy; }
IsType(EScrollType type)77 bool IsType (EScrollType type) const { return type == m_Type; }
GetAffectee()78 int GetAffectee () const { return m_Affectee; }
GetScrollParts()79 int GetScrollParts() const { return m_Parts; }
80
81 protected:
82 EScrollType m_Type; // Type of scroll effect
83 fixed_t m_dx, m_dy; // (dx,dy) scroll speeds
84 int m_Affectee; // Number of affected sidedef, sector, tag, or whatever
85 int m_Control; // Control sector (-1 if none) used to control scrolling
86 fixed_t m_LastHeight; // Last known height of control sector
87 fixed_t m_vdx, m_vdy; // Accumulated velocity if accelerative
88 int m_Accel; // Whether it's accelerative
89 int m_Parts; // Which parts of a sidedef are being scrolled?
90 TObjPtr<DInterpolation> m_Interpolations[3];
91
92 private:
93 DScroller ();
94 };
95
96 // Factor to scale scrolling effect into mobj-carrying properties = 3/32.
97 // (This is so scrolling floors and objects on them can move at same speed.)
98 enum { CARRYFACTOR = (3*FRACUNIT >> 5) };
99
100 // phares 3/20/98: added new model of Pushers for push/pull effects
101
102 class DPusher : public DThinker
103 {
104 DECLARE_CLASS (DPusher, DThinker)
105 HAS_OBJECT_POINTERS
106 public:
107 enum EPusher
108 {
109 p_push,
110 p_pull,
111 p_wind,
112 p_current
113 };
114
115 DPusher ();
116 DPusher (EPusher type, line_t *l, int magnitude, int angle, AActor *source, int affectee);
117 void Serialize (FArchive &arc);
118 int CheckForSectorMatch (EPusher type, int tag);
ChangeValues(int magnitude,int angle)119 void ChangeValues (int magnitude, int angle)
120 {
121 angle_t ang = ((angle_t)(angle<<24)) >> ANGLETOFINESHIFT;
122 m_Xmag = (magnitude * finecosine[ang]) >> FRACBITS;
123 m_Ymag = (magnitude * finesine[ang]) >> FRACBITS;
124 m_Magnitude = magnitude;
125 }
126
127 void Tick ();
128
129 protected:
130 EPusher m_Type;
131 TObjPtr<AActor> m_Source;// Point source if point pusher
132 int m_Xmag; // X Strength
133 int m_Ymag; // Y Strength
134 int m_Magnitude; // Vector strength for point pusher
135 int m_Radius; // Effective radius for point pusher
136 int m_X; // X of point source if point pusher
137 int m_Y; // Y of point source if point pusher
138 int m_Affectee; // Number of affected sector
139
140 friend bool PIT_PushThing (AActor *thing);
141 };
142
143 bool PIT_PushThing (AActor *thing);
144
145 // Define values for map objects
146 #define MO_TELEPORTMAN 14
147
148 // Flags for P_SectorDamage
149 #define DAMAGE_PLAYERS 1
150 #define DAMAGE_NONPLAYERS 2
151 #define DAMAGE_IN_AIR 4
152 #define DAMAGE_SUBCLASSES_PROTECT 8
153
154
155 // [RH] If a deathmatch game, checks to see if noexit is enabled.
156 // If so, it kills the player and returns false. Otherwise,
157 // it returns true, and the player is allowed to live.
158 bool CheckIfExitIsGood (AActor *self, level_info_t *info);
159
160 // at map load
161 void P_InitSectorSpecial(sector_t *sector, int special, bool nothinkers);
162 void P_SpawnSpecials (void);
163
164 // every tic
165 void P_UpdateSpecials (void);
166
167 // when needed
168 bool P_ActivateLine (line_t *ld, AActor *mo, int side, int activationType);
169 bool P_TestActivateLine (line_t *ld, AActor *mo, int side, int activationType);
170 bool P_PredictLine (line_t *ld, AActor *mo, int side, int activationType);
171
172 void P_PlayerInSpecialSector (player_t *player, sector_t * sector=NULL);
173 void P_PlayerOnSpecialFlat (player_t *player, int floorType);
174 void P_SectorDamage(int tag, int amount, FName type, const PClass *protectClass, int flags);
175 void P_SetSectorFriction (int tag, int amount, bool alterFlag);
176
FrictionToMoveFactor(fixed_t friction)177 inline fixed_t FrictionToMoveFactor(fixed_t friction)
178 {
179 fixed_t movefactor;
180
181 // [RH] Twiddled these values so that velocity on ice (with
182 // friction 0xf900) is the same as in Heretic/Hexen.
183 if (friction >= ORIG_FRICTION) // ice
184 // movefactor = ((0x10092 - friction)*(0x70))/0x158;
185 movefactor = ((0x10092 - friction) * 1024) / 4352 + 568;
186 else
187 movefactor = ((friction - 0xDB34)*(0xA))/0x80;
188
189 // killough 8/28/98: prevent odd situations
190 if (movefactor < 32)
191 movefactor = 32;
192
193 return movefactor;
194 }
195
196 void P_GiveSecret(AActor *actor, bool printmessage, bool playsound, int sectornum);
197
198 //
199 // getSide()
200 // Will return a side_t*
201 // given the number of the current sector,
202 // the line number, and the side (0/1) that you want.
203 //
getSide(int currentSector,int line,int side)204 inline side_t *getSide (int currentSector, int line, int side)
205 {
206 return (sectors[currentSector].lines[line])->sidedef[side];
207 }
208
209 //
210 // getSector()
211 // Will return a sector_t*
212 // given the number of the current sector,
213 // the line number and the side (0/1) that you want.
214 //
getSector(int currentSector,int line,int side)215 inline sector_t *getSector (int currentSector, int line, int side)
216 {
217 return (sectors[currentSector].lines[line])->sidedef[side]->sector;
218 }
219
220
221 //
222 // twoSided()
223 // Given the sector number and the line number,
224 // it will tell you whether the line is two-sided or not.
225 //
twoSided(int sector,int line)226 inline int twoSided (int sector, int line)
227 {
228 return (sectors[sector].lines[line])->flags & ML_TWOSIDED;
229 }
230
231 //
232 // getNextSector()
233 // Return sector_t * of sector next to current.
234 // NULL if not two-sided line
235 //
getNextSector(line_t * line,const sector_t * sec)236 inline sector_t *getNextSector (line_t *line, const sector_t *sec)
237 {
238 if (!(line->flags & ML_TWOSIDED))
239 return NULL;
240
241 return line->frontsector == sec ?
242 (line->backsector != sec ? line->backsector : NULL) :
243 line->frontsector;
244 }
245
246
247 #include "p_tags.h"
248
249 //
250 // P_LIGHTS
251 //
252
253 class DLighting : public DSectorEffect
254 {
255 DECLARE_CLASS (DLighting, DSectorEffect)
256 public:
257 DLighting (sector_t *sector);
258 protected:
259 DLighting ();
260 };
261
262 class DFireFlicker : public DLighting
263 {
264 DECLARE_CLASS (DFireFlicker, DLighting)
265 public:
266 DFireFlicker (sector_t *sector);
267 DFireFlicker (sector_t *sector, int upper, int lower);
268 void Serialize (FArchive &arc);
269 void Tick ();
270 protected:
271 int m_Count;
272 int m_MaxLight;
273 int m_MinLight;
274 private:
275 DFireFlicker ();
276 };
277
278 class DFlicker : public DLighting
279 {
280 DECLARE_CLASS (DFlicker, DLighting)
281 public:
282 DFlicker (sector_t *sector, int upper, int lower);
283 void Serialize (FArchive &arc);
284 void Tick ();
285 protected:
286 int m_Count;
287 int m_MaxLight;
288 int m_MinLight;
289 private:
290 DFlicker ();
291 };
292
293 class DLightFlash : public DLighting
294 {
295 DECLARE_CLASS (DLightFlash, DLighting)
296 public:
297 DLightFlash (sector_t *sector);
298 DLightFlash (sector_t *sector, int min, int max);
299 void Serialize (FArchive &arc);
300 void Tick ();
301 protected:
302 int m_Count;
303 int m_MaxLight;
304 int m_MinLight;
305 int m_MaxTime;
306 int m_MinTime;
307 private:
308 DLightFlash ();
309 };
310
311 class DStrobe : public DLighting
312 {
313 DECLARE_CLASS (DStrobe, DLighting)
314 public:
315 DStrobe (sector_t *sector, int utics, int ltics, bool inSync);
316 DStrobe (sector_t *sector, int upper, int lower, int utics, int ltics);
317 void Serialize (FArchive &arc);
318 void Tick ();
319 protected:
320 int m_Count;
321 int m_MinLight;
322 int m_MaxLight;
323 int m_DarkTime;
324 int m_BrightTime;
325 private:
326 DStrobe ();
327 };
328
329 class DGlow : public DLighting
330 {
331 DECLARE_CLASS (DGlow, DLighting)
332 public:
333 DGlow (sector_t *sector);
334 void Serialize (FArchive &arc);
335 void Tick ();
336 protected:
337 int m_MinLight;
338 int m_MaxLight;
339 int m_Direction;
340 private:
341 DGlow ();
342 };
343
344 // [RH] Glow from Light_Glow and Light_Fade specials
345 class DGlow2 : public DLighting
346 {
347 DECLARE_CLASS (DGlow2, DLighting)
348 public:
349 DGlow2 (sector_t *sector, int start, int end, int tics, bool oneshot);
350 void Serialize (FArchive &arc);
351 void Tick ();
352 protected:
353 int m_Start;
354 int m_End;
355 int m_MaxTics;
356 int m_Tics;
357 bool m_OneShot;
358 private:
359 DGlow2 ();
360 };
361
362 // [RH] Phased light thinker
363 class DPhased : public DLighting
364 {
365 DECLARE_CLASS (DPhased, DLighting)
366 public:
367 DPhased (sector_t *sector);
368 DPhased (sector_t *sector, int baselevel, int phase);
369 void Serialize (FArchive &arc);
370 void Tick ();
371 protected:
372 BYTE m_BaseLevel;
373 BYTE m_Phase;
374 private:
375 DPhased ();
376 DPhased (sector_t *sector, int baselevel);
377 int PhaseHelper (sector_t *sector, int index, int light, sector_t *prev);
378 };
379
380 #define GLOWSPEED 8
381 #define STROBEBRIGHT 5
382 #define FASTDARK 15
383 #define SLOWDARK TICRATE
384
385 void EV_StartLightFlickering (int tag, int upper, int lower);
386 void EV_StartLightStrobing (int tag, int upper, int lower, int utics, int ltics);
387 void EV_StartLightStrobing (int tag, int utics, int ltics);
388 void EV_TurnTagLightsOff (int tag);
389 void EV_LightTurnOn (int tag, int bright);
390 void EV_LightTurnOnPartway (int tag, fixed_t frac); // killough 10/98
391 void EV_LightChange (int tag, int value);
392 void EV_StopLightEffect (int tag);
393
394 void P_SpawnGlowingLight (sector_t *sector);
395
396 void EV_StartLightGlowing (int tag, int upper, int lower, int tics);
397 void EV_StartLightFading (int tag, int value, int tics);
398
399
400 //
401 // P_SWITCH
402 //
403
404 #define BUTTONTIME TICRATE // 1 second, in ticks.
405
406 bool P_ChangeSwitchTexture (side_t *side, int useAgain, BYTE special, bool *quest=NULL);
407 bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno);
408
409 //
410 // P_PLATS
411 //
412 class DPlat : public DMovingFloor
413 {
414 DECLARE_CLASS (DPlat, DMovingFloor)
415 public:
416 enum EPlatState
417 {
418 up,
419 down,
420 waiting,
421 in_stasis
422 };
423
424 enum EPlatType
425 {
426 platPerpetualRaise,
427 platDownWaitUpStay,
428 platDownWaitUpStayStone,
429 platUpWaitDownStay,
430 platUpNearestWaitDownStay,
431 platDownByValue,
432 platUpByValue,
433 platUpByValueStay,
434 platRaiseAndStay,
435 platToggle,
436 platDownToNearestFloor,
437 platDownToLowestCeiling,
438 platRaiseAndStayLockout,
439 };
440
441 void Serialize (FArchive &arc);
442 void Tick ();
443
IsLift()444 bool IsLift() const { return m_Type == platDownWaitUpStay || m_Type == platDownWaitUpStayStone; }
445
446 protected:
447 DPlat (sector_t *sector);
448
449 fixed_t m_Speed;
450 fixed_t m_Low;
451 fixed_t m_High;
452 int m_Wait;
453 int m_Count;
454 EPlatState m_Status;
455 EPlatState m_OldStatus;
456 int m_Crush;
457 int m_Tag;
458 EPlatType m_Type;
459
460 void PlayPlatSound (const char *sound);
461 void Reactivate ();
462 void Stop ();
463
464 private:
465 DPlat ();
466
467 friend bool EV_DoPlat (int tag, line_t *line, EPlatType type,
468 int height, int speed, int delay, int lip, int change);
469 friend void EV_StopPlat (int tag);
470 friend void P_ActivateInStasis (int tag);
471 };
472
473 bool EV_DoPlat (int tag, line_t *line, DPlat::EPlatType type,
474 int height, int speed, int delay, int lip, int change);
475 void EV_StopPlat (int tag);
476 void P_ActivateInStasis (int tag);
477
478 //
479 // [RH]
480 // P_PILLAR
481 //
482
483 class DPillar : public DMover
484 {
485 DECLARE_CLASS (DPillar, DMover)
486 HAS_OBJECT_POINTERS
487 public:
488 enum EPillar
489 {
490 pillarBuild,
491 pillarOpen
492
493 };
494
495 DPillar (sector_t *sector, EPillar type, fixed_t speed, fixed_t height,
496 fixed_t height2, int crush, bool hexencrush);
497
498 void Serialize (FArchive &arc);
499 void Tick ();
500 void Destroy();
501
502 protected:
503 EPillar m_Type;
504 fixed_t m_FloorSpeed;
505 fixed_t m_CeilingSpeed;
506 fixed_t m_FloorTarget;
507 fixed_t m_CeilingTarget;
508 int m_Crush;
509 bool m_Hexencrush;
510 TObjPtr<DInterpolation> m_Interp_Ceiling;
511 TObjPtr<DInterpolation> m_Interp_Floor;
512
513 private:
514 DPillar ();
515 };
516
517 bool EV_DoPillar (DPillar::EPillar type, line_t *line, int tag,
518 fixed_t speed, fixed_t height, fixed_t height2, int crush, bool hexencrush);
519
520 //
521 // P_DOORS
522 //
523 class DDoor : public DMovingCeiling
524 {
525 DECLARE_CLASS (DDoor, DMovingCeiling)
526 public:
527 enum EVlDoor
528 {
529 doorClose,
530 doorOpen,
531 doorRaise,
532 doorRaiseIn5Mins,
533 doorCloseWaitOpen,
534 };
535
536 DDoor (sector_t *sector);
537 DDoor (sector_t *sec, EVlDoor type, fixed_t speed, int delay, int lightTag);
538
539 void Serialize (FArchive &arc);
540 void Tick ();
541 protected:
542 EVlDoor m_Type;
543 fixed_t m_TopDist;
544 fixed_t m_BotDist, m_OldFloorDist;
545 vertex_t *m_BotSpot;
546 fixed_t m_Speed;
547
548 // 1 = up, 0 = waiting at top, -1 = down
549 int m_Direction;
550
551 // tics to wait at the top
552 int m_TopWait;
553 // (keep in case a door going down is reset)
554 // when it reaches 0, start going down
555 int m_TopCountdown;
556
557 int m_LightTag;
558
559 void DoorSound (bool raise, class DSeqNode *curseq=NULL) const;
560
561 friend bool EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing,
562 int tag, int speed, int delay, int lock,
563 int lightTag, bool boomgen);
564 friend void P_SpawnDoorCloseIn30 (sector_t *sec);
565 friend void P_SpawnDoorRaiseIn5Mins (sector_t *sec);
566 private:
567 DDoor ();
568
569 };
570
571 bool EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing,
572 int tag, int speed, int delay, int lock,
573 int lightTag, bool boomgen = false);
574 void P_SpawnDoorCloseIn30 (sector_t *sec);
575 void P_SpawnDoorRaiseIn5Mins (sector_t *sec);
576
577 class DAnimatedDoor : public DMovingCeiling
578 {
579 DECLARE_CLASS (DAnimatedDoor, DMovingCeiling)
580 public:
581 DAnimatedDoor (sector_t *sector);
582 DAnimatedDoor (sector_t *sec, line_t *line, int speed, int delay, FDoorAnimation *anim);
583
584 void Serialize (FArchive &arc);
585 void Tick ();
586
587 bool StartClosing ();
588 protected:
589 line_t *m_Line1, *m_Line2;
590 int m_Frame;
591 FDoorAnimation *m_DoorAnim;
592 int m_Timer;
593 fixed_t m_BotDist;
594 int m_Status;
595 enum
596 {
597 Opening,
598 Waiting,
599 Closing,
600 Dead
601 };
602 int m_Speed;
603 int m_Delay;
604 bool m_SetBlocking1, m_SetBlocking2;
605
606 friend bool EV_SlidingDoor (line_t *line, AActor *thing, int tag, int speed, int delay);
607 private:
608 DAnimatedDoor ();
609 };
610
611 bool EV_SlidingDoor (line_t *line, AActor *thing, int tag, int speed, int delay);
612
613 //
614 // P_CEILNG
615 //
616
617 // [RH] Changed these
618 class DCeiling : public DMovingCeiling
619 {
620 DECLARE_CLASS (DCeiling, DMovingCeiling)
621 public:
622 enum ECeiling
623 {
624 ceilLowerByValue,
625 ceilRaiseByValue,
626 ceilMoveToValue,
627 ceilLowerToHighestFloor,
628 ceilLowerInstant,
629 ceilRaiseInstant,
630 ceilCrushAndRaise,
631 ceilLowerAndCrush,
632 ceilLowerAndCrushDist,
633 ceilCrushRaiseAndStay,
634 ceilRaiseToNearest,
635 ceilLowerToLowest,
636 ceilLowerToFloor,
637
638 // The following are only used by Generic_Ceiling
639 ceilRaiseToHighest,
640 ceilLowerToHighest,
641 ceilRaiseToLowest,
642 ceilLowerToNearest,
643 ceilRaiseToHighestFloor,
644 ceilRaiseToFloor,
645 ceilRaiseByTexture,
646 ceilLowerByTexture,
647
648 genCeilingChg0,
649 genCeilingChgT,
650 genCeilingChg
651 };
652
653 DCeiling (sector_t *sec);
654 DCeiling (sector_t *sec, fixed_t speed1, fixed_t speed2, int silent);
655
656 void Serialize (FArchive &arc);
657 void Tick ();
658
659 static DCeiling *Create(sector_t *sec, DCeiling::ECeiling type, line_t *line, int tag,
660 fixed_t speed, fixed_t speed2, fixed_t height,
661 int crush, int silent, int change, bool hexencrush);
662
663 protected:
664 ECeiling m_Type;
665 fixed_t m_BottomHeight;
666 fixed_t m_TopHeight;
667 fixed_t m_Speed;
668 fixed_t m_Speed1; // [RH] dnspeed of crushers
669 fixed_t m_Speed2; // [RH] upspeed of crushers
670 int m_Crush;
671 bool m_Hexencrush;
672 int m_Silent;
673 int m_Direction; // 1 = up, 0 = waiting, -1 = down
674
675 // [RH] Need these for BOOM-ish transferring ceilings
676 FTextureID m_Texture;
677 secspecial_t m_NewSpecial;
678
679 // ID
680 int m_Tag;
681 int m_OldDirection;
682
683 void PlayCeilingSound ();
684
685 private:
686 DCeiling ();
687
688 friend bool EV_CeilingCrushStop (int tag);
689 friend void P_ActivateInStasisCeiling (int tag);
690 };
691
692 bool EV_DoCeiling (DCeiling::ECeiling type, line_t *line,
693 int tag, fixed_t speed, fixed_t speed2, fixed_t height,
694 int crush, int silent, int change, bool hexencrush);
695 bool EV_CeilingCrushStop (int tag);
696 void P_ActivateInStasisCeiling (int tag);
697
698
699
700 //
701 // P_FLOOR
702 //
703
704 class DFloor : public DMovingFloor
705 {
706 DECLARE_CLASS (DFloor, DMovingFloor)
707 public:
708 enum EFloor
709 {
710 floorLowerToLowest,
711 floorLowerToNearest,
712 floorLowerToHighest,
713 floorLowerByValue,
714 floorRaiseByValue,
715 floorRaiseToHighest,
716 floorRaiseToNearest,
717 floorRaiseAndCrush,
718 floorRaiseAndCrushDoom,
719 floorCrushStop,
720 floorLowerInstant,
721 floorRaiseInstant,
722 floorMoveToValue,
723 floorRaiseToLowestCeiling,
724 floorRaiseByTexture,
725
726 floorLowerAndChange,
727 floorRaiseAndChange,
728
729 floorRaiseToLowest,
730 floorRaiseToCeiling,
731 floorLowerToLowestCeiling,
732 floorLowerByTexture,
733 floorLowerToCeiling,
734
735 donutRaise,
736
737 buildStair,
738 waitStair,
739 resetStair,
740
741 // Not to be used as parameters to EV_DoFloor()
742 genFloorChg0,
743 genFloorChgT,
744 genFloorChg
745 };
746
747 // [RH] Changed to use Hexen-ish specials
748 enum EStair
749 {
750 buildUp,
751 buildDown
752 };
753
754 DFloor (sector_t *sec);
755
756 void Serialize (FArchive &arc);
757 void Tick ();
758
759 protected:
760 EFloor m_Type;
761 int m_Crush;
762 bool m_Hexencrush;
763 int m_Direction;
764 secspecial_t m_NewSpecial;
765 FTextureID m_Texture;
766 fixed_t m_FloorDestDist;
767 fixed_t m_Speed;
768
769 // [RH] New parameters used to reset and delay stairs
770 int m_ResetCount;
771 int m_OrgDist;
772 int m_Delay;
773 int m_PauseTime;
774 int m_StepTime;
775 int m_PerStepTime;
776
777 void StartFloorSound ();
778 void SetFloorChangeType (sector_t *sec, int change);
779
780 friend bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line,
781 fixed_t stairsize, fixed_t speed, int delay, int reset, int igntxt,
782 int usespecials);
783 friend bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag,
784 fixed_t speed, fixed_t height, int crush, int change, bool hexencrush, bool hereticlower);
785 friend bool EV_FloorCrushStop (int tag);
786 friend bool EV_DoDonut (int tag, line_t *line, fixed_t pillarspeed, fixed_t slimespeed);
787 private:
788 DFloor ();
789 };
790
791 bool EV_BuildStairs (int tag, DFloor::EStair type, line_t *line,
792 fixed_t stairsize, fixed_t speed, int delay, int reset, int igntxt,
793 int usespecials);
794 bool EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag,
795 fixed_t speed, fixed_t height, int crush, int change, bool hexencrush, bool hereticlower=false);
796 bool EV_FloorCrushStop (int tag);
797 bool EV_DoDonut (int tag, line_t *line, fixed_t pillarspeed, fixed_t slimespeed);
798
799 class DElevator : public DMover
800 {
801 DECLARE_CLASS (DElevator, DMover)
802 HAS_OBJECT_POINTERS
803 public:
804 enum EElevator
805 {
806 elevateUp,
807 elevateDown,
808 elevateCurrent,
809 // [RH] For FloorAndCeiling_Raise/Lower
810 elevateRaise,
811 elevateLower
812 };
813
814 DElevator (sector_t *sec);
815
816 void Destroy();
817 void Serialize (FArchive &arc);
818 void Tick ();
819
820 protected:
821 EElevator m_Type;
822 int m_Direction;
823 fixed_t m_FloorDestDist;
824 fixed_t m_CeilingDestDist;
825 fixed_t m_Speed;
826 TObjPtr<DInterpolation> m_Interp_Ceiling;
827 TObjPtr<DInterpolation> m_Interp_Floor;
828
829 void StartFloorSound ();
830
831 friend bool EV_DoElevator (line_t *line, DElevator::EElevator type, fixed_t speed,
832 fixed_t height, int tag);
833 private:
834 DElevator ();
835 };
836
837 bool EV_DoElevator (line_t *line, DElevator::EElevator type, fixed_t speed,
838 fixed_t height, int tag);
839
840 class DWaggleBase : public DMover
841 {
842 DECLARE_CLASS (DWaggleBase, DMover)
843 HAS_OBJECT_POINTERS
844 public:
845 DWaggleBase (sector_t *sec);
846
847 void Serialize (FArchive &arc);
848
849 protected:
850 fixed_t m_OriginalDist;
851 fixed_t m_Accumulator;
852 fixed_t m_AccDelta;
853 fixed_t m_TargetScale;
854 fixed_t m_Scale;
855 fixed_t m_ScaleDelta;
856 int m_Ticker;
857 int m_State;
858 TObjPtr<DInterpolation> m_Interpolation;
859
860 friend bool EV_StartWaggle (int tag, line_t *line, int height, int speed,
861 int offset, int timer, bool ceiling);
862
863 void DoWaggle (bool ceiling);
864 void Destroy();
865 DWaggleBase ();
866 };
867
868 bool EV_StartWaggle (int tag, line_t *line, int height, int speed,
869 int offset, int timer, bool ceiling);
870
871 class DFloorWaggle : public DWaggleBase
872 {
873 DECLARE_CLASS (DFloorWaggle, DWaggleBase)
874 public:
875 DFloorWaggle (sector_t *sec);
876 void Tick ();
877 private:
878 DFloorWaggle ();
879 };
880
881 class DCeilingWaggle : public DWaggleBase
882 {
883 DECLARE_CLASS (DCeilingWaggle, DWaggleBase)
884 public:
885 DCeilingWaggle (sector_t *sec);
886 void Tick ();
887 private:
888 DCeilingWaggle ();
889 };
890
891 //jff 3/15/98 pure texture/type change for better generalized support
892 enum EChange
893 {
894 trigChangeOnly,
895 numChangeOnly,
896 };
897
898 bool EV_DoChange (line_t *line, EChange changetype, int tag);
899
900
901
902 //
903 // P_TELEPT
904 //
905 enum
906 {
907 TELF_DESTFOG = 1,
908 TELF_SOURCEFOG = 2,
909 TELF_KEEPORIENTATION = 4,
910 TELF_KEEPVELOCITY = 8,
911 TELF_KEEPHEIGHT = 16,
912 };
913
914 void P_SpawnTeleportFog(AActor *mobj, fixed_t x, fixed_t y, fixed_t z, bool beforeTele = true, bool setTarget = false); //Spawns teleport fog. Pass the actor to pluck TeleFogFromType and TeleFogToType. 'from' determines if this is the fog to spawn at the old position (true) or new (false).
915 inline void P_SpawnTeleportFog(AActor *mobj, const fixedvec3 &pos, bool beforeTele = true, bool setTarget = false)
916 {
917 P_SpawnTeleportFog(mobj, pos.x, pos.y, pos.z, beforeTele, setTarget);
918 }
919 bool P_Teleport (AActor *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, int flags); // bool useFog, bool sourceFog, bool keepOrientation, bool haltVelocity = true, bool keepHeight = false
920 bool EV_Teleport (int tid, int tag, line_t *line, int side, AActor *thing, int flags);
921 bool EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id, INTBOOL reverse);
922 bool EV_TeleportOther (int other_tid, int dest_tid, bool fog);
923 bool EV_TeleportGroup (int group_tid, AActor *victim, int source_tid, int dest_tid, bool moveSource, bool fog);
924 bool EV_TeleportSector (int tag, int source_tid, int dest_tid, bool fog, int group_tid);
925
926
927 //
928 // [RH] ACS (see also p_acs.h)
929 //
930
931 #define ACS_BACKSIDE 1
932 #define ACS_ALWAYS 2
933 #define ACS_WANTRESULT 4
934 #define ACS_NET 8
935
936 int P_StartScript (AActor *who, line_t *where, int script, const char *map, const int *args, int argcount, int flags);
937 void P_SuspendScript (int script, const char *map);
938 void P_TerminateScript (int script, const char *map);
939 void P_DoDeferedScripts (void);
940
941 //
942 // [RH] p_quake.c
943 //
944 bool P_StartQuakeXYZ(AActor *activator, int tid, int intensityX, int intensityY, int intensityZ, int duration, int damrad, int tremrad, FSoundID quakesfx, int flags, double waveSpeedX, double waveSpeedY, double waveSpeedZ);
945 bool P_StartQuake(AActor *activator, int tid, int intensity, int duration, int damrad, int tremrad, FSoundID quakesfx);
946
947 #endif
948