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