1 // Emacs style mode select -*- C++ -*-
2 //-----------------------------------------------------------------------------
3 //
4 // $Id: p_spec.h 4469 2014-01-03 23:38:29Z dr_sean $
5 //
6 // Copyright (C) 1993-1996 by id Software, Inc.
7 // Copyright (C) 2006-2014 by The Odamex Team.
8 //
9 // This program is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU General Public License
11 // as published by the Free Software Foundation; either version 2
12 // of the License, or (at your option) any later version.
13 //
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
18 //
19 // DESCRIPTION: none
20 // Implements special effects:
21 // Texture animation, height or lighting changes
22 // according to adjacent sectors, respective
23 // utility functions, etc.
24 //
25 //-----------------------------------------------------------------------------
26
27
28 #ifndef __P_SPEC__
29 #define __P_SPEC__
30
31 #include <list>
32 #include "dsectoreffect.h"
33
34 typedef struct movingsector_s
35 {
movingsector_smovingsector_s36 movingsector_s() :
37 sector(NULL), moving_ceiling(false), moving_floor(false)
38 {}
39
40 sector_t *sector;
41 bool moving_ceiling;
42 bool moving_floor;
43 } movingsector_t;
44
45 extern std::list<movingsector_t> movingsectors;
46
47 std::list<movingsector_t>::iterator P_FindMovingSector(sector_t *sector);
48 void P_AddMovingCeiling(sector_t *sector);
49 void P_AddMovingFloor(sector_t *sector);
50 void P_RemoveMovingCeiling(sector_t *sector);
51 void P_RemoveMovingFloor(sector_t *sector);
52 bool P_MovingCeilingCompleted(sector_t *sector);
53 bool P_MovingFloorCompleted(sector_t *sector);
54
55 //jff 2/23/98 identify the special classes that can share sectors
56
57 typedef enum
58 {
59 floor_special,
60 ceiling_special,
61 lighting_special
62 } special_e;
63
64 // killough 3/7/98: Add generalized scroll effects
65
66 class DScroller : public DThinker
67 {
68 DECLARE_SERIAL (DScroller, DThinker)
69 public:
70 enum EScrollType
71 {
72 sc_side,
73 sc_floor,
74 sc_ceiling,
75 sc_carry,
76 sc_carry_ceiling // killough 4/11/98: carry objects hanging on ceilings
77
78 };
79
80 DScroller (EScrollType type, fixed_t dx, fixed_t dy, int control, int affectee, int accel);
81 DScroller (fixed_t dx, fixed_t dy, const line_t *l, int control, int accel);
82
83 void RunThink ();
84
AffectsWall(int wallnum)85 bool AffectsWall (int wallnum) { return m_Type == sc_side && m_Affectee == wallnum; }
GetWallNum()86 int GetWallNum () { return m_Type == sc_side ? m_Affectee : -1; }
SetRate(fixed_t dx,fixed_t dy)87 void SetRate (fixed_t dx, fixed_t dy) { m_dx = dx; m_dy = dy; }
88
89 protected:
90 EScrollType m_Type; // Type of scroll effect
91 fixed_t m_dx, m_dy; // (dx,dy) scroll speeds
92 int m_Affectee; // Number of affected sidedef, sector, tag, or whatever
93 int m_Control; // Control sector (-1 if none) used to control scrolling
94 fixed_t m_LastHeight; // Last known height of control sector
95 fixed_t m_vdx, m_vdy; // Accumulated velocity if accelerative
96 int m_Accel; // Whether it's accelerative
97
98 private:
99 DScroller ();
100 };
101
102 inline FArchive &operator<< (FArchive &arc, DScroller::EScrollType type)
103 {
104 return arc << (BYTE)type;
105 }
106 inline FArchive &operator>> (FArchive &arc, DScroller::EScrollType &out)
107 {
108 BYTE in; arc >> in; out = (DScroller::EScrollType)in; return arc;
109 }
110
111 // phares 3/20/98: added new model of Pushers for push/pull effects
112
113 class DPusher : public DThinker
114 {
115 DECLARE_SERIAL (DPusher, DThinker)
116 public:
117 enum EPusher
118 {
119 p_push,
120 p_pull,
121 p_wind,
122 p_current
123 };
124
125 DPusher ();
126 DPusher (EPusher type, line_t *l, int magnitude, int angle, AActor *source, int affectee);
CheckForSectorMatch(EPusher type,int tag)127 int CheckForSectorMatch (EPusher type, int tag)
128 {
129 if (m_Type == type && sectors[m_Affectee].tag == tag)
130 return m_Affectee;
131 else
132 return -1;
133 }
ChangeValues(int magnitude,int angle)134 void ChangeValues (int magnitude, int angle)
135 {
136 angle_t ang = (angle<<24) >> ANGLETOFINESHIFT;
137 m_Xmag = (magnitude * finecosine[ang]) >> FRACBITS;
138 m_Ymag = (magnitude * finesine[ang]) >> FRACBITS;
139 m_Magnitude = magnitude;
140 }
141
142 virtual void RunThink ();
143
144 protected:
145 EPusher m_Type;
146 AActor::AActorPtr m_Source; // Point source if point pusher
147 int m_Xmag; // X Strength
148 int m_Ymag; // Y Strength
149 int m_Magnitude; // Vector strength for point pusher
150 int m_Radius; // Effective radius for point pusher
151 int m_X; // X of point source if point pusher
152 int m_Y; // Y of point source if point pusher
153 int m_Affectee; // Number of affected sector
154
155 friend BOOL PIT_PushThing (AActor *thing);
156 };
157
158 inline FArchive &operator<< (FArchive &arc, DPusher::EPusher type)
159 {
160 return arc << (BYTE)type;
161 }
162 inline FArchive &operator>> (FArchive &arc, DPusher::EPusher &out)
163 {
164 BYTE in; arc >> in; out = (DPusher::EPusher)in; return arc;
165 }
166
167 BOOL P_CheckKeys (player_t *p, card_t lock, BOOL remote);
168
169 // Define values for map objects
170 #define MO_TELEPORTMAN 14
171
172
173 // [RH] If a deathmatch game, checks to see if noexit is enabled.
174 // If so, it kills the player and returns false. Otherwise,
175 // it returns true, and the player is allowed to live.
176 BOOL CheckIfExitIsGood (AActor *self);
177
178 // at game start
179 void P_InitPicAnims (void);
180
181 // at map load
182 void P_SpawnSpecials (void);
183
184 // every tic
185 void P_UpdateSpecials (void);
186
187 // when needed
188 void P_CrossSpecialLine (int linenum, int side, AActor* thing, bool FromServer = false);
189 void P_ShootSpecialLine (AActor* thing, line_t* line, bool FromServer = false);
190 bool P_UseSpecialLine (AActor* thing, line_t* line, int side, bool FromServer = false);
191 bool P_PushSpecialLine (AActor* thing, line_t* line, int side, bool FromServer = false);
192
193 void P_PlayerInSpecialSector (player_t *player);
194
195 //
196 // getSide()
197 // Will return a side_t*
198 // given the number of the current sector,
199 // the line number, and the side (0/1) that you want.
200 //
getSide(int currentSector,int line,int side)201 inline side_t *getSide (int currentSector, int line, int side)
202 {
203 return &sides[ (sectors[currentSector].lines[line])->sidenum[side] ];
204 }
205
206 //
207 // getSector()
208 // Will return a sector_t*
209 // given the number of the current sector,
210 // the line number and the side (0/1) that you want.
211 //
getSector(int currentSector,int line,int side)212 inline sector_t *getSector (int currentSector, int line, int side)
213 {
214 return sides[ (sectors[currentSector].lines[line])->sidenum[side] ].sector;
215 }
216
217
218 //
219 // twoSided()
220 // Given the sector number and the line number,
221 // it will tell you whether the line is two-sided or not.
222 //
twoSided(int sector,int line)223 inline int twoSided (int sector, int line)
224 {
225 return (sectors[sector].lines[line])->flags & ML_TWOSIDED;
226 }
227
228 //
229 // getNextSector()
230 // Return sector_t * of sector next to current.
231 // NULL if not two-sided line
232 //
getNextSector(line_t * line,sector_t * sec)233 inline sector_t *getNextSector (line_t *line, sector_t *sec)
234 {
235 if (!(line->flags & ML_TWOSIDED))
236 return NULL;
237
238 return (line->frontsector == sec) ? line->backsector : line->frontsector;
239
240 return line->frontsector;
241 }
242
243
244 fixed_t P_FindLowestFloorSurrounding (sector_t *sec);
245 fixed_t P_FindHighestFloorSurrounding (sector_t *sec);
246
247 fixed_t P_FindNextHighestFloor (sector_t *sec);
248 fixed_t P_FindNextLowestFloor (sector_t* sec);
249
250 fixed_t P_FindLowestCeilingSurrounding (sector_t *sec); // jff 2/04/98
251 fixed_t P_FindHighestCeilingSurrounding (sector_t *sec); // jff 2/04/98
252
253 fixed_t P_FindNextLowestCeiling (sector_t *sec); // jff 2/04/98
254 fixed_t P_FindNextHighestCeiling (sector_t *sec); // jff 2/04/98
255
256 fixed_t P_FindShortestTextureAround (int secnum); // jff 2/04/98
257 fixed_t P_FindShortestUpperAround (int secnum); // jff 2/04/98
258
259 sector_t* P_FindModelFloorSector (fixed_t floordestheight, int secnum); //jff 02/04/98
260 sector_t* P_FindModelCeilingSector (fixed_t ceildestheight, int secnum); //jff 02/04/98
261
262 int P_FindSectorFromTag (int tag, int start);
263 int P_FindLineFromID (int id, int start);
264
265 int P_FindMinSurroundingLight (sector_t *sector, int max);
266
267 sector_t *P_NextSpecialSector (sector_t *sec, int type, sector_t *back2); // [RH]
268
269
270
271 //
272 // P_LIGHTS
273 //
274
275 class DLighting : public DSectorEffect
276 {
277 DECLARE_SERIAL (DLighting, DSectorEffect);
278 public:
279 DLighting (sector_t *sector);
280 protected:
281 DLighting ();
282 };
283
284 class DFireFlicker : public DLighting
285 {
286 DECLARE_SERIAL (DFireFlicker, DLighting)
287 public:
288 DFireFlicker (sector_t *sector);
289 DFireFlicker (sector_t *sector, int upper, int lower);
290 void RunThink ();
291 protected:
292 int m_Count;
293 int m_MaxLight;
294 int m_MinLight;
295 private:
296 DFireFlicker ();
297 };
298
299 class DFlicker : public DLighting
300 {
301 DECLARE_SERIAL (DFlicker, DLighting)
302 public:
303 DFlicker (sector_t *sector, int upper, int lower);
304 void RunThink ();
305 protected:
306 int m_Count;
307 int m_MaxLight;
308 int m_MinLight;
309 private:
310 DFlicker ();
311 };
312
313 class DLightFlash : public DLighting
314 {
315 DECLARE_SERIAL (DLightFlash, DLighting)
316 public:
317 DLightFlash (sector_t *sector);
318 DLightFlash (sector_t *sector, int min, int max);
319 void RunThink ();
320 protected:
321 int m_Count;
322 int m_MaxLight;
323 int m_MinLight;
324 int m_MaxTime;
325 int m_MinTime;
326 private:
327 DLightFlash ();
328 };
329
330 class DStrobe : public DLighting
331 {
332 DECLARE_SERIAL (DStrobe, DLighting)
333 public:
334 DStrobe (sector_t *sector, int utics, int ltics, bool inSync);
335 DStrobe (sector_t *sector, int upper, int lower, int utics, int ltics);
336 void RunThink ();
337 protected:
338 int m_Count;
339 int m_MinLight;
340 int m_MaxLight;
341 int m_DarkTime;
342 int m_BrightTime;
343 private:
344 DStrobe ();
345 };
346
347 class DGlow : public DLighting
348 {
349 DECLARE_SERIAL (DGlow, DLighting)
350 public:
351 DGlow (sector_t *sector);
352 void RunThink ();
353 protected:
354 int m_MinLight;
355 int m_MaxLight;
356 int m_Direction;
357 private:
358 DGlow ();
359 };
360
361 // [RH] Glow from Light_Glow and Light_Fade specials
362 class DGlow2 : public DLighting
363 {
364 DECLARE_SERIAL (DGlow2, DLighting)
365 public:
366 DGlow2 (sector_t *sector, int start, int end, int tics, bool oneshot);
367 void RunThink ();
368 protected:
369 int m_Start;
370 int m_End;
371 int m_MaxTics;
372 int m_Tics;
373 bool m_OneShot;
374 private:
375 DGlow2 ();
376 };
377
378 // [RH] Phased light thinker
379 class DPhased : public DLighting
380 {
381 DECLARE_SERIAL (DPhased, DLighting)
382 public:
383 DPhased (sector_t *sector);
384 DPhased (sector_t *sector, int baselevel, int phase);
385 void RunThink ();
386 protected:
387 byte m_BaseLevel;
388 byte m_Phase;
389 private:
390 DPhased ();
391 DPhased (sector_t *sector, int baselevel);
392 int PhaseHelper (sector_t *sector, int index, int light, sector_t *prev);
393 };
394
395 #define GLOWSPEED 8
396 #define STROBEBRIGHT 5
397 #define FASTDARK 15
398 #define SLOWDARK TICRATE
399
400 void EV_StartLightFlickering (int tag, int upper, int lower);
401 void EV_StartLightStrobing (int tag, int upper, int lower, int utics, int ltics);
402 void EV_StartLightStrobing (int tag, int utics, int ltics);
403 void EV_TurnTagLightsOff (int tag);
404 void EV_LightTurnOn (int tag, int bright);
405 void EV_LightChange (int tag, int value);
406 int EV_LightTurnOnPartway(int tag, int level);
407
408 void P_SpawnGlowingLight (sector_t *sector);
409
410 void EV_StartLightGlowing (int tag, int upper, int lower, int tics);
411 void EV_StartLightFading (int tag, int value, int tics);
412
413
414 //
415 // P_SWITCH
416 //
417 typedef struct
418 {
419 char name1[9];
420 char name2[9];
421 short episode;
422
423 } switchlist_t;
424
425
426 // 1 second, in ticks.
427 #define BUTTONTIME TICRATE
428
429 void P_ChangeSwitchTexture (line_t *line, int useAgain);
430
431 void P_InitSwitchList ();
432
433 void P_ProcessSwitchDef ();
434
435 bool P_GetButtonInfo (line_t *line, unsigned &state, unsigned &time);
436 bool P_SetButtonInfo (line_t *line, unsigned state, unsigned time);
437
438
439 //
440 // P_PLATS
441 //
442 class DPlat : public DMovingFloor
443 {
444 DECLARE_SERIAL (DPlat, DMovingFloor);
445 public:
446 enum EPlatState
447 {
448 init = 0,
449 up,
450 down,
451 waiting,
452 in_stasis,
453 midup,
454 middown,
455 finished,
456 destroy,
457 state_size
458 };
459
460 enum EPlatType
461 {
462 platPerpetualRaise,
463 platDownWaitUpStay,
464 platUpWaitDownStay,
465 platDownByValue,
466 platUpByValue,
467 platUpByValueStay,
468 platRaiseAndStay,
469 platToggle,
470 platDownToNearestFloor,
471 platDownToLowestCeiling
472 };
473
474 void RunThink ();
475
SetState(byte state,int count)476 void SetState(byte state, int count) { m_Status = (EPlatState)state; m_Count = count; }
GetState(byte & state,int & count)477 void GetState(byte &state, int &count) { state = (byte)m_Status; count = m_Count; }
478
479 DPlat(sector_t *sector);
480 DPlat(sector_t *sector, DPlat::EPlatType type, fixed_t height, int speed, int delay, fixed_t lip);
481 friend void P_SetPlatDestroy(DPlat *plat);
482
483 void PlayPlatSound ();
484
485 fixed_t m_Speed;
486 fixed_t m_Low;
487 fixed_t m_High;
488 int m_Wait;
489 int m_Count;
490 EPlatState m_Status;
491 EPlatState m_OldStatus;
492 bool m_Crush;
493 int m_Tag;
494 EPlatType m_Type;
495 fixed_t m_Height;
496 fixed_t m_Lip;
497
498 protected:
499
500 void Reactivate ();
501 void Stop ();
502
503 private:
504 DPlat ();
505
506 friend BOOL EV_DoPlat (int tag, line_t *line, EPlatType type,
507 fixed_t height, int speed, int delay, fixed_t lip, int change);
508 friend void EV_StopPlat (int tag);
509 friend void P_ActivateInStasis (int tag);
510 };
511
512 inline FArchive &operator<< (FArchive &arc, DPlat::EPlatType type)
513 {
514 return arc << (BYTE)type;
515 }
516 inline FArchive &operator>> (FArchive &arc, DPlat::EPlatType &out)
517 {
518 BYTE in; arc >> in; out = (DPlat::EPlatType)in; return arc;
519 }
520 inline FArchive &operator<< (FArchive &arc, DPlat::EPlatState state)
521 {
522 return arc << (BYTE)state;
523 }
524 inline FArchive &operator>> (FArchive &arc, DPlat::EPlatState &out)
525 {
526 BYTE in; arc >> in; out = (DPlat::EPlatState)in; return arc;
527 }
528
529 //
530 // [RH]
531 // P_PILLAR
532 //
533
534 class DPillar : public DMover
535 {
536 DECLARE_SERIAL (DPillar, DMover)
537 public:
538 enum EPillarState
539 {
540 init = 0,
541 finished,
542 destroy,
543 state_size
544 };
545
546 enum EPillar
547 {
548 pillarBuild,
549 pillarOpen
550
551 };
552
553 DPillar ();
554
555 DPillar (sector_t *sector, EPillar type, fixed_t speed, fixed_t height,
556 fixed_t height2, bool crush);
557 friend void P_SetPillarDestroy(DPillar *pillar);
558
559 void RunThink ();
560 void PlayPillarSound();
561
562 EPillar m_Type;
563 fixed_t m_FloorSpeed;
564 fixed_t m_CeilingSpeed;
565 fixed_t m_FloorTarget;
566 fixed_t m_CeilingTarget;
567 bool m_Crush;
568
569 EPillarState m_Status;
570
571 };
572
573 inline FArchive &operator<< (FArchive &arc, DPillar::EPillar type)
574 {
575 return arc << (BYTE)type;
576 }
577 inline FArchive &operator>> (FArchive &arc, DPillar::EPillar &out)
578 {
579 BYTE in; arc >> in; out = (DPillar::EPillar)in; return arc;
580 }
581 inline FArchive &operator<< (FArchive &arc, DPillar::EPillarState state)
582 {
583 return arc << (BYTE)state;
584 }
585 inline FArchive &operator>> (FArchive &arc, DPillar::EPillarState &out)
586 {
587 BYTE in; arc >> in; out = (DPillar::EPillarState)in; return arc;
588 }
589
590 BOOL EV_DoPillar (DPillar::EPillar type, int tag, fixed_t speed, fixed_t height,
591 fixed_t height2, bool crush);
592 void P_SpawnDoorCloseIn30 (sector_t *sec);
593 void P_SpawnDoorRaiseIn5Mins (sector_t *sec);
594
595 //
596 // P_DOORS
597 //
598 class DDoor : public DMovingCeiling
599 {
600 DECLARE_SERIAL (DDoor, DMovingCeiling)
601 public:
602 enum EVlDoor
603 {
604 doorClose,
605 doorOpen,
606 doorRaise,
607 doorRaiseIn5Mins,
608 doorCloseWaitOpen
609 };
610
611 enum EDoorState
612 {
613 init = 0,
614 opening,
615 closing,
616 waiting,
617 reopening,
618 finished,
619 destroy,
620 state_size
621 };
622
623 DDoor (sector_t *sector);
624 // DDoor (sector_t *sec, EVlDoor type, fixed_t speed, int delay);
625 DDoor (sector_t *sec, line_t *ln, EVlDoor type, fixed_t speed, int delay);
626
627 friend void P_SetDoorDestroy(DDoor *door);
628
629 void RunThink ();
630 void PlayDoorSound();
631
632 EVlDoor m_Type;
633 fixed_t m_TopHeight;
634 fixed_t m_Speed;
635
636 // tics to wait at the top
637 int m_TopWait;
638 // (keep in case a door going down is reset)
639 // when it reaches 0, start going down
640 int m_TopCountdown;
641
642 EDoorState m_Status;
643
644 line_t *m_Line;
645
646 protected:
647 friend BOOL EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing,
648 int tag, int speed, int delay, card_t lock);
649 friend void P_SpawnDoorCloseIn30 (sector_t *sec);
650 friend void P_SpawnDoorRaiseIn5Mins (sector_t *sec);
651
652 private:
653 DDoor ();
654
655 };
656
657 inline FArchive &operator<< (FArchive &arc, DDoor::EVlDoor type)
658 {
659 return arc << (BYTE)type;
660 }
661 inline FArchive &operator>> (FArchive &arc, DDoor::EVlDoor &out)
662 {
663 BYTE in; arc >> in; out = (DDoor::EVlDoor)in; return arc;
664 }
665 inline FArchive &operator<< (FArchive &arc, DDoor::EDoorState state)
666 {
667 return arc << (BYTE)state;
668 }
669 inline FArchive &operator>> (FArchive &arc, DDoor::EDoorState &out)
670 {
671 BYTE in; arc >> in; out = (DDoor::EDoorState)in; return arc;
672 }
673
674 //
675 // P_CEILNG
676 //
677
678 // [RH] Changed these
679 class DCeiling : public DMovingCeiling
680 {
681 DECLARE_SERIAL (DCeiling, DMovingCeiling)
682 public:
683 enum ECeilingState
684 {
685 init = 0,
686 up,
687 down,
688 waiting,
689 finished,
690 destroy,
691 state_size
692 };
693
694 enum ECeiling
695 {
696 ceilLowerByValue,
697 ceilRaiseByValue,
698 ceilMoveToValue,
699 ceilLowerToHighestFloor,
700 ceilLowerInstant,
701 ceilRaiseInstant,
702 ceilCrushAndRaise,
703 ceilLowerAndCrush,
704 ceilCrushRaiseAndStay,
705 ceilRaiseToNearest,
706 ceilLowerToLowest,
707 ceilLowerToFloor,
708
709 // The following are only used by Generic_Ceiling
710 ceilRaiseToHighest,
711 ceilLowerToHighest,
712 ceilRaiseToLowest,
713 ceilLowerToNearest,
714 ceilRaiseToHighestFloor,
715 ceilRaiseToFloor,
716 ceilRaiseByTexture,
717 ceilLowerByTexture,
718
719 genCeilingChg0,
720 genCeilingChgT,
721 genCeilingChg
722 };
723
724 DCeiling (sector_t *sec);
725 DCeiling (sector_t *sec, fixed_t speed1, fixed_t speed2, int silent);
726 friend void P_SetCeilingDestroy(DCeiling *ceiling);
727
728 void RunThink ();
729 void PlayCeilingSound();
730
731 ECeiling m_Type;
732 fixed_t m_BottomHeight;
733 fixed_t m_TopHeight;
734 fixed_t m_Speed;
735 fixed_t m_Speed1; // [RH] dnspeed of crushers
736 fixed_t m_Speed2; // [RH] upspeed of crushers
737 bool m_Crush;
738 int m_Silent;
739 int m_Direction; // 1 = up, 0 = waiting, -1 = down
740
741 // [RH] Need these for BOOM-ish transferring ceilings
742 int m_Texture;
743 int m_NewSpecial;
744
745 // ID
746 int m_Tag;
747 int m_OldDirection;
748
749 ECeilingState m_Status;
750
751 protected:
752
753
754 private:
755 DCeiling ();
756
757 friend BOOL EV_DoCeiling (DCeiling::ECeiling type, line_t *line,
758 int tag, fixed_t speed, fixed_t speed2, fixed_t height,
759 bool crush, int silent, int change);
760 friend BOOL EV_CeilingCrushStop (int tag);
761 friend void P_ActivateInStasisCeiling (int tag);
762 };
763
764 inline FArchive &operator<< (FArchive &arc, DCeiling::ECeiling type)
765 {
766 return arc << (BYTE)type;
767 }
768 inline FArchive &operator>> (FArchive &arc, DCeiling::ECeiling &type)
769 {
770 BYTE in; arc >> in; type = (DCeiling::ECeiling)in; return arc;
771 }
772 inline FArchive &operator<< (FArchive &arc, DCeiling::ECeilingState state)
773 {
774 return arc << (BYTE)state;
775 }
776 inline FArchive &operator>> (FArchive &arc, DCeiling::ECeilingState &out)
777 {
778 BYTE in; arc >> in; out = (DCeiling::ECeilingState)in; return arc;
779 }
780
781
782 //
783 // P_FLOOR
784 //
785
786 class DFloor : public DMovingFloor
787 {
788 DECLARE_SERIAL (DFloor, DMovingFloor)
789 public:
790 enum EFloorState
791 {
792 init = 0,
793 up,
794 down,
795 waiting,
796 finished,
797 destroy,
798 state_size
799 };
800
801 enum EFloor
802 {
803 floorLowerToLowest,
804 floorLowerToNearest,
805 floorLowerToHighest,
806 floorLowerByValue,
807 floorRaiseByValue,
808 floorRaiseToHighest,
809 floorRaiseToNearest,
810 floorRaiseAndCrush,
811 floorCrushStop,
812 floorLowerInstant,
813 floorRaiseInstant,
814 floorMoveToValue,
815 floorRaiseToLowestCeiling,
816 floorRaiseByTexture,
817
818 floorLowerAndChange,
819 floorRaiseAndChange,
820
821 floorRaiseToLowest,
822 floorRaiseToCeiling,
823 floorLowerToLowestCeiling,
824 floorLowerByTexture,
825 floorLowerToCeiling,
826
827 donutRaise,
828
829 buildStair,
830 waitStair,
831 resetStair,
832
833 // Not to be used as parameters to EV_DoFloor()
834 genFloorChg0,
835 genFloorChgT,
836 genFloorChg
837 };
838
839 // [RH] Changed to use Hexen-ish specials
840 enum EStair
841 {
842 buildUp,
843 buildDown
844 };
845
846 DFloor(sector_t *sec);
847 DFloor(sector_t *sec, DFloor::EFloor floortype, line_t *line, fixed_t speed,
848 fixed_t height, bool crush, int change);
849 friend void P_SetFloorDestroy(DFloor *floor);
850
851 void RunThink ();
852 void PlayFloorSound();
853
854 EFloor m_Type;
855 EFloorState m_Status;
856 bool m_Crush;
857 int m_Direction;
858 short m_NewSpecial;
859 short m_Texture;
860 fixed_t m_FloorDestHeight;
861 fixed_t m_Speed;
862
863 // [RH] New parameters used to reset and delay stairs
864 int m_ResetCount;
865 int m_OrgHeight;
866 int m_Delay;
867 int m_PauseTime;
868 int m_StepTime;
869 int m_PerStepTime;
870
871 fixed_t m_Height;
872 line_t *m_Line;
873 int m_Change;
874
875 protected:
876 friend BOOL EV_BuildStairs (int tag, DFloor::EStair type, line_t *line,
877 fixed_t stairsize, fixed_t speed, int delay, int reset, int igntxt,
878 int usespecials);
879 friend BOOL EV_DoFloor (DFloor::EFloor floortype, line_t *line, int tag,
880 fixed_t speed, fixed_t height, bool crush, int change);
881 friend int EV_DoDonut (int tag, fixed_t pillarspeed, fixed_t slimespeed);
882 private:
883 DFloor ();
884 };
885
886 inline FArchive &operator<< (FArchive &arc, DFloor::EFloor type)
887 {
888 return arc << (BYTE)type;
889 }
890 inline FArchive &operator>> (FArchive &arc, DFloor::EFloor &type)
891 {
892 BYTE in; arc >> in; type = (DFloor::EFloor)in; return arc;
893 }
894 inline FArchive &operator<< (FArchive &arc, DFloor::EFloorState state)
895 {
896 return arc << (BYTE)state;
897 }
898 inline FArchive &operator>> (FArchive &arc, DFloor::EFloorState &out)
899 {
900 BYTE in; arc >> in; out = (DFloor::EFloorState)in; return arc;
901 }
902
903 class DElevator : public DMover
904 {
905 DECLARE_SERIAL (DElevator, DMover)
906 public:
907 enum EElevatorState
908 {
909 init = 0,
910 finished,
911 destroy,
912 state_size
913 };
914
915 enum EElevator
916 {
917 elevateUp,
918 elevateDown,
919 elevateCurrent,
920 // [RH] For FloorAndCeiling_Raise/Lower
921 elevateRaise,
922 elevateLower
923 };
924
925 DElevator (sector_t *sec);
926 friend void P_SetElevatorDestroy(DElevator *elevator);
927
928 void RunThink ();
929 void PlayElevatorSound();
930
931 EElevator m_Type;
932 int m_Direction;
933 fixed_t m_FloorDestHeight;
934 fixed_t m_CeilingDestHeight;
935 fixed_t m_Speed;
936
937 EElevatorState m_Status;
938
939 protected:
940 friend BOOL EV_DoElevator (line_t *line, DElevator::EElevator type, fixed_t speed,
941 fixed_t height, int tag);
942 private:
943 DElevator ();
944 };
945
946 inline FArchive &operator<< (FArchive &arc, DElevator::EElevator type)
947 {
948 return arc << (BYTE)type;
949 }
950 inline FArchive &operator>> (FArchive &arc, DElevator::EElevator &out)
951 {
952 BYTE in; arc >> in; out = (DElevator::EElevator)in; return arc;
953 }
954 inline FArchive &operator<< (FArchive &arc, DElevator::EElevatorState state)
955 {
956 return arc << (BYTE)state;
957 }
958 inline FArchive &operator>> (FArchive &arc, DElevator::EElevatorState &out)
959 {
960 BYTE in; arc >> in; out = (DElevator::EElevatorState)in; return arc;
961 }
962
963 //jff 3/15/98 pure texture/type change for better generalized support
964 enum EChange
965 {
966 trigChangeOnly,
967 numChangeOnly
968 };
969
970 BOOL EV_DoChange (line_t *line, EChange changetype, int tag);
971
972
973
974 //
975 // P_TELEPT
976 //
977 BOOL EV_Teleport (int tid, int tag, int side, AActor *thing);
978 BOOL EV_LineTeleport (line_t *line, int side, AActor *thing);
979 BOOL EV_SilentTeleport (int tid, line_t *line, int side, AActor *thing);
980 BOOL EV_SilentLineTeleport (line_t *line, int side, AActor *thing, int id,
981 BOOL reverse);
982
983 //
984 // [RH] ACS (see also p_acs.h)
985 //
986
987 bool P_StartScript (AActor *who, line_t *where, int script, char *map, int lineSide,
988 int arg0, int arg1, int arg2, int always);
989 void P_SuspendScript (int script, char *map);
990 void P_TerminateScript (int script, char *map);
991 void P_StartOpenScripts (void);
992 void P_DoDeferedScripts (void);
993
994
995 //
996 // [RH] p_quake.c
997 //
998 BOOL P_StartQuake (int tid, int intensity, int duration, int damrad, int tremrad);
999
1000 // [AM] Trigger actor specials.
1001 bool A_TriggerAction(AActor *mo, AActor *triggerer, int activationType);
1002
1003 #endif
1004