1 /* Emacs style mode select -*- C++ -*-
2 *-----------------------------------------------------------------------------
5 * PrBoom a Doom port merged with LxDoom and LSDLDoom
6 * based on BOOM, a modified and improved DOOM engine
7 * Copyright (C) 1999 by
8 * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
9 * Copyright (C) 1999-2000 by
10 * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
28 * Generalized linedef type handlers
29 * Floors, Ceilings, Doors, Locked Doors, Lifts, Stairs, Crushers
31 *-----------------------------------------------------------------------------*/
33 #include "doomstat.h" //jff 6/19/98 for demo_compatibility
41 //////////////////////////////////////////////////////////
43 // Generalized Linedef Type handlers
45 //////////////////////////////////////////////////////////
50 // Handle generalized floor types
52 // Passed the line activating the generalized floor function
53 // Returns true if a thinker is created
55 // jff 02/04/98 Added this routine (and file) to handle generalized
56 // floor movers using bit fields in the line special type.
66 unsigned value
= (unsigned)line
->special
- GenFloorBase
;
68 // parse the bit fields in the line's special type
70 int Crsh
= (value
& FloorCrush
) >> FloorCrushShift
;
71 int ChgT
= (value
& FloorChange
) >> FloorChangeShift
;
72 int Targ
= (value
& FloorTarget
) >> FloorTargetShift
;
73 int Dirn
= (value
& FloorDirection
) >> FloorDirectionShift
;
74 int ChgM
= (value
& FloorModel
) >> FloorModelShift
;
75 int Sped
= (value
& FloorSpeed
) >> FloorSpeedShift
;
76 int Trig
= (value
& TriggerType
) >> TriggerTypeShift
;
80 // check if a manual trigger, if so do just the sector on the backside
82 if (Trig
==PushOnce
|| Trig
==PushMany
)
84 if (!(sec
= line
->backsector
))
92 // if not manual do all sectors tagged the same as the line
93 while ((secnum
= P_FindSectorFromLineTag(line
,secnum
)) >= 0)
95 sec
= §ors
[secnum
];
98 // Do not start another function if floor already moving
99 if (P_SectorActive(floor_special
,sec
))
109 floor
= Z_Malloc (sizeof(*floor
), PU_LEVSPEC
, 0);
110 P_AddThinker (&floor
->thinker
);
111 sec
->floordata
= floor
;
112 floor
->thinker
.function
= T_MoveFloor
;
114 floor
->direction
= Dirn
? 1 : -1;
116 floor
->texture
= sec
->floorpic
;
117 floor
->newspecial
= sec
->special
;
118 //jff 3/14/98 transfer old special field too
119 floor
->oldspecial
= sec
->oldspecial
;
120 floor
->type
= genFloor
;
122 // set the speed of motion
126 floor
->speed
= FLOORSPEED
;
129 floor
->speed
= FLOORSPEED
*2;
132 floor
->speed
= FLOORSPEED
*4;
135 floor
->speed
= FLOORSPEED
*8;
141 // set the destination height
145 floor
->floordestheight
= P_FindHighestFloorSurrounding(sec
);
148 floor
->floordestheight
= P_FindLowestFloorSurrounding(sec
);
151 floor
->floordestheight
= Dirn
?
152 P_FindNextHighestFloor(sec
,sec
->floorheight
) :
153 P_FindNextLowestFloor(sec
,sec
->floorheight
);
156 floor
->floordestheight
= P_FindLowestCeilingSurrounding(sec
);
159 floor
->floordestheight
= sec
->ceilingheight
;
162 floor
->floordestheight
= (floor
->sector
->floorheight
>>FRACBITS
) +
163 floor
->direction
* (P_FindShortestTextureAround(secnum
)>>FRACBITS
);
164 if (floor
->floordestheight
>32000) //jff 3/13/98 prevent overflow
165 floor
->floordestheight
=32000; // wraparound in floor height
166 if (floor
->floordestheight
<-32000)
167 floor
->floordestheight
=-32000;
168 floor
->floordestheight
<<=FRACBITS
;
171 floor
->floordestheight
= floor
->sector
->floorheight
+
172 floor
->direction
* 24*FRACUNIT
;
175 floor
->floordestheight
= floor
->sector
->floorheight
+
176 floor
->direction
* 32*FRACUNIT
;
182 // set texture/type change properties
183 if (ChgT
) // if a texture change is indicated
185 if (ChgM
) // if a numeric model change
189 //jff 5/23/98 find model with ceiling at target height if target
191 sec
= (Targ
==FtoLnC
|| Targ
==FtoC
)?
192 P_FindModelCeilingSector(floor
->floordestheight
,secnum
) :
193 P_FindModelFloorSector(floor
->floordestheight
,secnum
);
196 floor
->texture
= sec
->floorpic
;
199 case FChgZero
: // zero type
200 floor
->newspecial
= 0;
201 //jff 3/14/98 change old field too
202 floor
->oldspecial
= 0;
203 floor
->type
= genFloorChg0
;
205 case FChgTyp
: // copy type
206 floor
->newspecial
= sec
->special
;
207 //jff 3/14/98 change old field too
208 floor
->oldspecial
= sec
->oldspecial
;
209 floor
->type
= genFloorChgT
;
211 case FChgTxt
: // leave type be
212 floor
->type
= genFloorChg
;
219 else // else if a trigger model change
221 floor
->texture
= line
->frontsector
->floorpic
;
224 case FChgZero
: // zero type
225 floor
->newspecial
= 0;
226 //jff 3/14/98 change old field too
227 floor
->oldspecial
= 0;
228 floor
->type
= genFloorChg0
;
230 case FChgTyp
: // copy type
231 floor
->newspecial
= line
->frontsector
->special
;
232 //jff 3/14/98 change old field too
233 floor
->oldspecial
= line
->frontsector
->oldspecial
;
234 floor
->type
= genFloorChgT
;
236 case FChgTxt
: // leave type be
237 floor
->type
= genFloorChg
;
243 if (manual
) return rtn
;
252 // Handle generalized ceiling types
254 // Passed the linedef activating the ceiling function
255 // Returns true if a thinker created
257 // jff 02/04/98 Added this routine (and file) to handle generalized
258 // floor movers using bit fields in the line special type.
269 unsigned value
= (unsigned)line
->special
- GenCeilingBase
;
271 // parse the bit fields in the line's special type
273 int Crsh
= (value
& CeilingCrush
) >> CeilingCrushShift
;
274 int ChgT
= (value
& CeilingChange
) >> CeilingChangeShift
;
275 int Targ
= (value
& CeilingTarget
) >> CeilingTargetShift
;
276 int Dirn
= (value
& CeilingDirection
) >> CeilingDirectionShift
;
277 int ChgM
= (value
& CeilingModel
) >> CeilingModelShift
;
278 int Sped
= (value
& CeilingSpeed
) >> CeilingSpeedShift
;
279 int Trig
= (value
& TriggerType
) >> TriggerTypeShift
;
283 // check if a manual trigger, if so do just the sector on the backside
285 if (Trig
==PushOnce
|| Trig
==PushMany
)
287 if (!(sec
= line
->backsector
))
289 secnum
= sec
-sectors
;
295 // if not manual do all sectors tagged the same as the line
296 while ((secnum
= P_FindSectorFromLineTag(line
,secnum
)) >= 0)
298 sec
= §ors
[secnum
];
301 // Do not start another function if ceiling already moving
302 if (P_SectorActive(ceiling_special
,sec
)) //jff 2/22/98
310 // new ceiling thinker
312 ceiling
= Z_Malloc (sizeof(*ceiling
), PU_LEVSPEC
, 0);
313 P_AddThinker (&ceiling
->thinker
);
314 sec
->ceilingdata
= ceiling
; //jff 2/22/98
315 ceiling
->thinker
.function
= T_MoveCeiling
;
316 ceiling
->crush
= Crsh
;
317 ceiling
->direction
= Dirn
? 1 : -1;
318 ceiling
->sector
= sec
;
319 ceiling
->texture
= sec
->ceilingpic
;
320 ceiling
->newspecial
= sec
->special
;
321 //jff 3/14/98 change old field too
322 ceiling
->oldspecial
= sec
->oldspecial
;
323 ceiling
->tag
= sec
->tag
;
324 ceiling
->type
= genCeiling
;
326 // set speed of motion
330 ceiling
->speed
= CEILSPEED
;
333 ceiling
->speed
= CEILSPEED
*2;
336 ceiling
->speed
= CEILSPEED
*4;
339 ceiling
->speed
= CEILSPEED
*8;
345 // set destination target height
346 targheight
= sec
->ceilingheight
;
350 targheight
= P_FindHighestCeilingSurrounding(sec
);
353 targheight
= P_FindLowestCeilingSurrounding(sec
);
357 P_FindNextHighestCeiling(sec
,sec
->ceilingheight
) :
358 P_FindNextLowestCeiling(sec
,sec
->ceilingheight
);
361 targheight
= P_FindHighestFloorSurrounding(sec
);
364 targheight
= sec
->floorheight
;
367 targheight
= (ceiling
->sector
->ceilingheight
>>FRACBITS
) +
368 ceiling
->direction
* (P_FindShortestUpperAround(secnum
)>>FRACBITS
);
369 if (targheight
>32000) //jff 3/13/98 prevent overflow
370 targheight
=32000; // wraparound in ceiling height
371 if (targheight
<-32000)
373 targheight
<<=FRACBITS
;
376 targheight
= ceiling
->sector
->ceilingheight
+
377 ceiling
->direction
* 24*FRACUNIT
;
380 targheight
= ceiling
->sector
->ceilingheight
+
381 ceiling
->direction
* 32*FRACUNIT
;
386 if (Dirn
) ceiling
->topheight
= targheight
;
387 else ceiling
->bottomheight
= targheight
;
389 // set texture/type change properties
390 if (ChgT
) // if a texture change is indicated
392 if (ChgM
) // if a numeric model change
396 //jff 5/23/98 find model with floor at target height if target
398 sec
= (Targ
==CtoHnF
|| Targ
==CtoF
)?
399 P_FindModelFloorSector(targheight
,secnum
) :
400 P_FindModelCeilingSector(targheight
,secnum
);
403 ceiling
->texture
= sec
->ceilingpic
;
406 case CChgZero
: // type is zeroed
407 ceiling
->newspecial
= 0;
408 //jff 3/14/98 change old field too
409 ceiling
->oldspecial
= 0;
410 ceiling
->type
= genCeilingChg0
;
412 case CChgTyp
: // type is copied
413 ceiling
->newspecial
= sec
->special
;
414 //jff 3/14/98 change old field too
415 ceiling
->oldspecial
= sec
->oldspecial
;
416 ceiling
->type
= genCeilingChgT
;
418 case CChgTxt
: // type is left alone
419 ceiling
->type
= genCeilingChg
;
426 else // else if a trigger model change
428 ceiling
->texture
= line
->frontsector
->ceilingpic
;
431 case CChgZero
: // type is zeroed
432 ceiling
->newspecial
= 0;
433 //jff 3/14/98 change old field too
434 ceiling
->oldspecial
= 0;
435 ceiling
->type
= genCeilingChg0
;
437 case CChgTyp
: // type is copied
438 ceiling
->newspecial
= line
->frontsector
->special
;
439 //jff 3/14/98 change old field too
440 ceiling
->oldspecial
= line
->frontsector
->oldspecial
;
441 ceiling
->type
= genCeilingChgT
;
443 case CChgTxt
: // type is left alone
444 ceiling
->type
= genCeilingChg
;
451 P_AddActiveCeiling(ceiling
); // add this ceiling to the active list
452 if (manual
) return rtn
;
460 // Handle generalized lift types
462 // Passed the linedef activating the lift
463 // Returns true if a thinker is created
473 unsigned value
= (unsigned)line
->special
- GenLiftBase
;
475 // parse the bit fields in the line's special type
477 int Targ
= (value
& LiftTarget
) >> LiftTargetShift
;
478 int Dely
= (value
& LiftDelay
) >> LiftDelayShift
;
479 int Sped
= (value
& LiftSpeed
) >> LiftSpeedShift
;
480 int Trig
= (value
& TriggerType
) >> TriggerTypeShift
;
485 // Activate all <type> plats that are in_stasis
488 P_ActivateInStasis(line
->tag
);
490 // check if a manual trigger, if so do just the sector on the backside
492 if (Trig
==PushOnce
|| Trig
==PushMany
)
494 if (!(sec
= line
->backsector
))
496 secnum
= sec
-sectors
;
501 // if not manual do all sectors tagged the same as the line
502 while ((secnum
= P_FindSectorFromLineTag(line
,secnum
)) >= 0)
504 sec
= §ors
[secnum
];
507 // Do not start another function if floor already moving
508 if (P_SectorActive(floor_special
,sec
))
516 // Setup the plat thinker
518 plat
= Z_Malloc( sizeof(*plat
), PU_LEVSPEC
, 0);
519 P_AddThinker(&plat
->thinker
);
522 plat
->sector
->floordata
= plat
;
523 plat
->thinker
.function
= T_PlatRaise
;
525 plat
->tag
= line
->tag
;
527 plat
->type
= genLift
;
528 plat
->high
= sec
->floorheight
;
531 // setup the target destination height
535 plat
->low
= P_FindLowestFloorSurrounding(sec
);
536 if (plat
->low
> sec
->floorheight
)
537 plat
->low
= sec
->floorheight
;
540 plat
->low
= P_FindNextLowestFloor(sec
,sec
->floorheight
);
543 plat
->low
= P_FindLowestCeilingSurrounding(sec
);
544 if (plat
->low
> sec
->floorheight
)
545 plat
->low
= sec
->floorheight
;
548 plat
->type
= genPerpetual
;
549 plat
->low
= P_FindLowestFloorSurrounding(sec
);
550 if (plat
->low
> sec
->floorheight
)
551 plat
->low
= sec
->floorheight
;
552 plat
->high
= P_FindHighestFloorSurrounding(sec
);
553 if (plat
->high
< sec
->floorheight
)
554 plat
->high
= sec
->floorheight
;
555 plat
->status
= P_Random(pr_genlift
)&1;
561 // setup the speed of motion
565 plat
->speed
= PLATSPEED
* 2;
568 plat
->speed
= PLATSPEED
* 4;
571 plat
->speed
= PLATSPEED
* 8;
574 plat
->speed
= PLATSPEED
* 16;
580 // setup the delay time before the floor returns
587 plat
->wait
= PLATWAIT
*35;
597 S_StartSound((mobj_t
*)&sec
->soundorg
,sfx_pstart
);
598 P_AddActivePlat(plat
); // add this plat to the list of active plats
609 // Handle generalized stair building
611 // Passed the linedef activating the stairs
612 // Returns true if a thinker is created
618 int osecnum
; //jff 3/4/98 preserve loop index
635 unsigned value
= (unsigned)line
->special
- GenStairsBase
;
637 // parse the bit fields in the line's special type
639 int Igno
= (value
& StairIgnore
) >> StairIgnoreShift
;
640 int Dirn
= (value
& StairDirection
) >> StairDirectionShift
;
641 int Step
= (value
& StairStep
) >> StairStepShift
;
642 int Sped
= (value
& StairSpeed
) >> StairSpeedShift
;
643 int Trig
= (value
& TriggerType
) >> TriggerTypeShift
;
647 // check if a manual trigger, if so do just the sector on the backside
649 if (Trig
==PushOnce
|| Trig
==PushMany
)
651 if (!(sec
= line
->backsector
))
653 secnum
= sec
-sectors
;
659 // if not manual do all sectors tagged the same as the line
660 while ((secnum
= P_FindSectorFromLineTag(line
,secnum
)) >= 0)
662 sec
= §ors
[secnum
];
665 //Do not start another function if floor already moving
666 //jff 2/26/98 add special lockout condition to wait for entire
667 //staircase to build before retriggering
668 if (P_SectorActive(floor_special
,sec
) || sec
->stairlock
)
678 floor
= Z_Malloc (sizeof(*floor
), PU_LEVSPEC
, 0);
679 P_AddThinker (&floor
->thinker
);
680 sec
->floordata
= floor
;
681 floor
->thinker
.function
= T_MoveFloor
;
682 floor
->direction
= Dirn
? 1 : -1;
685 // setup speed of stair building
690 floor
->speed
= FLOORSPEED
/4;
693 floor
->speed
= FLOORSPEED
/2;
696 floor
->speed
= FLOORSPEED
*2;
699 floor
->speed
= FLOORSPEED
*4;
703 // setup stepsize for stairs
708 stairsize
= 4*FRACUNIT
;
711 stairsize
= 8*FRACUNIT
;
714 stairsize
= 16*FRACUNIT
;
717 stairsize
= 24*FRACUNIT
;
721 speed
= floor
->speed
;
722 height
= sec
->floorheight
+ floor
->direction
* stairsize
;
723 floor
->floordestheight
= height
;
724 texture
= sec
->floorpic
;
725 floor
->crush
= false;
726 floor
->type
= genBuildStair
; // jff 3/31/98 do not leave uninited
728 sec
->stairlock
= -2; // jff 2/26/98 set up lock on current sector
732 osecnum
= secnum
; //jff 3/4/98 preserve loop index
733 // Find next sector to raise
734 // 1. Find 2-sided line with same sector side[0]
735 // 2. Other side is the next sector to raise
739 for (i
= 0;i
< sec
->linecount
;i
++)
741 if ( !((sec
->lines
[i
])->backsector
) )
744 tsec
= (sec
->lines
[i
])->frontsector
;
745 newsecnum
= tsec
-sectors
;
747 if (secnum
!= newsecnum
)
750 tsec
= (sec
->lines
[i
])->backsector
;
751 newsecnum
= tsec
- sectors
;
753 if (!Igno
&& tsec
->floorpic
!= texture
)
756 /* jff 6/19/98 prevent double stepsize */
757 if (compatibility_level
< boom_202_compatibility
)
758 height
+= floor
->direction
* stairsize
;
760 //jff 2/26/98 special lockout condition for retriggering
761 if (P_SectorActive(floor_special
,tsec
) || tsec
->stairlock
)
764 /* jff 6/19/98 increase height AFTER continue */
765 if (compatibility_level
>= boom_202_compatibility
)
766 height
+= floor
->direction
* stairsize
;
769 // link the stair chain in both directions
770 // lock the stair sector until building complete
771 sec
->nextsec
= newsecnum
; // link step to next
772 tsec
->prevsec
= secnum
; // link next back
773 tsec
->nextsec
= -1; // set next forward link as end
774 tsec
->stairlock
= -2; // lock the step
778 floor
= Z_Malloc (sizeof(*floor
), PU_LEVSPEC
, 0);
780 P_AddThinker (&floor
->thinker
);
782 sec
->floordata
= floor
;
783 floor
->thinker
.function
= T_MoveFloor
;
784 floor
->direction
= Dirn
? 1 : -1;
786 floor
->speed
= speed
;
787 floor
->floordestheight
= height
;
788 floor
->crush
= false;
789 floor
->type
= genBuildStair
; // jff 3/31/98 do not leave uninited
797 secnum
= osecnum
; //jff 3/4/98 restore old loop index
799 // retriggerable generalized stairs build up or down alternately
801 line
->special
^= StairDirection
; // alternate dir on succ activations
808 // Handle generalized crusher types
810 // Passed the linedef activating the crusher
811 // Returns true if a thinker created
821 unsigned value
= (unsigned)line
->special
- GenCrusherBase
;
823 // parse the bit fields in the line's special type
825 int Slnt
= (value
& CrusherSilent
) >> CrusherSilentShift
;
826 int Sped
= (value
& CrusherSpeed
) >> CrusherSpeedShift
;
827 int Trig
= (value
& TriggerType
) >> TriggerTypeShift
;
829 //jff 2/22/98 Reactivate in-stasis ceilings...for certain types.
830 //jff 4/5/98 return if activated
831 rtn
= P_ActivateInStasisCeiling(line
);
833 // check if a manual trigger, if so do just the sector on the backside
835 if (Trig
==PushOnce
|| Trig
==PushMany
)
837 if (!(sec
= line
->backsector
))
839 secnum
= sec
-sectors
;
845 // if not manual do all sectors tagged the same as the line
846 while ((secnum
= P_FindSectorFromLineTag(line
,secnum
)) >= 0)
848 sec
= §ors
[secnum
];
851 // Do not start another function if ceiling already moving
852 if (P_SectorActive(ceiling_special
,sec
)) //jff 2/22/98
860 // new ceiling thinker
862 ceiling
= Z_Malloc (sizeof(*ceiling
), PU_LEVSPEC
, 0);
863 P_AddThinker (&ceiling
->thinker
);
864 sec
->ceilingdata
= ceiling
; //jff 2/22/98
865 ceiling
->thinker
.function
= T_MoveCeiling
;
866 ceiling
->crush
= true;
867 ceiling
->direction
= -1;
868 ceiling
->sector
= sec
;
869 ceiling
->texture
= sec
->ceilingpic
;
870 ceiling
->newspecial
= sec
->special
;
871 ceiling
->tag
= sec
->tag
;
872 ceiling
->type
= Slnt
? genSilentCrusher
: genCrusher
;
873 ceiling
->topheight
= sec
->ceilingheight
;
874 ceiling
->bottomheight
= sec
->floorheight
+ (8*FRACUNIT
);
876 // setup ceiling motion speed
880 ceiling
->speed
= CEILSPEED
;
883 ceiling
->speed
= CEILSPEED
*2;
886 ceiling
->speed
= CEILSPEED
*4;
889 ceiling
->speed
= CEILSPEED
*8;
894 ceiling
->oldspeed
=ceiling
->speed
;
896 P_AddActiveCeiling(ceiling
); // add to list of active ceilings
897 if (manual
) return rtn
;
903 // EV_DoGenLockedDoor()
905 // Handle generalized locked door types
907 // Passed the linedef activating the generalized locked door
908 // Returns true if a thinker created
910 int EV_DoGenLockedDoor
917 unsigned value
= (unsigned)line
->special
- GenLockedBase
;
919 // parse the bit fields in the line's special type
921 int Kind
= (value
& LockedKind
) >> LockedKindShift
;
922 int Sped
= (value
& LockedSpeed
) >> LockedSpeedShift
;
923 int Trig
= (value
& TriggerType
) >> TriggerTypeShift
;
927 // check if a manual trigger, if so do just the sector on the backside
929 if (Trig
==PushOnce
|| Trig
==PushMany
)
931 if (!(sec
= line
->backsector
))
933 secnum
= sec
-sectors
;
941 // if not manual do all sectors tagged the same as the line
942 while ((secnum
= P_FindSectorFromLineTag(line
,secnum
)) >= 0)
944 sec
= §ors
[secnum
];
946 // Do not start another function if ceiling already moving
947 if (P_SectorActive(ceiling_special
,sec
)) //jff 2/22/98
957 door
= Z_Malloc (sizeof(*door
), PU_LEVSPEC
, 0);
958 P_AddThinker (&door
->thinker
);
959 sec
->ceilingdata
= door
; //jff 2/22/98
961 door
->thinker
.function
= T_VerticalDoor
;
963 door
->topwait
= VDOORWAIT
;
965 door
->topheight
= P_FindLowestCeilingSurrounding(sec
);
966 door
->topheight
-= 4*FRACUNIT
;
969 /* killough 10/98: implement gradual lighting */
970 door
->lighttag
= !comp
[comp_doorlight
] &&
971 (line
->special
&6) == 6 &&
972 line
->special
> GenLockedBase
? line
->tag
: 0;
974 // setup speed of door motion
979 door
->type
= Kind
? genOpen
: genRaise
;
980 door
->speed
= VDOORSPEED
;
983 door
->type
= Kind
? genOpen
: genRaise
;
984 door
->speed
= VDOORSPEED
*2;
987 door
->type
= Kind
? genBlazeOpen
: genBlazeRaise
;
988 door
->speed
= VDOORSPEED
*4;
991 door
->type
= Kind
? genBlazeOpen
: genBlazeRaise
;
992 door
->speed
= VDOORSPEED
*8;
997 // killough 4/15/98: fix generalized door opening sounds
998 // (previously they always had the blazing door close sound)
1000 S_StartSound((mobj_t
*)&door
->sector
->soundorg
, // killough 4/15/98
1001 door
->speed
>= VDOORSPEED
*4 ? sfx_bdopn
: sfx_doropn
);
1012 // Handle generalized door types
1014 // Passed the linedef activating the generalized door
1015 // Returns true if a thinker created
1024 unsigned value
= (unsigned)line
->special
- GenDoorBase
;
1026 // parse the bit fields in the line's special type
1028 int Dely
= (value
& DoorDelay
) >> DoorDelayShift
;
1029 int Kind
= (value
& DoorKind
) >> DoorKindShift
;
1030 int Sped
= (value
& DoorSpeed
) >> DoorSpeedShift
;
1031 int Trig
= (value
& TriggerType
) >> TriggerTypeShift
;
1035 // check if a manual trigger, if so do just the sector on the backside
1037 if (Trig
==PushOnce
|| Trig
==PushMany
)
1039 if (!(sec
= line
->backsector
))
1041 secnum
= sec
-sectors
;
1050 // if not manual do all sectors tagged the same as the line
1051 while ((secnum
= P_FindSectorFromLineTag(line
,secnum
)) >= 0)
1053 sec
= §ors
[secnum
];
1055 // Do not start another function if ceiling already moving
1056 if (P_SectorActive(ceiling_special
,sec
)) //jff 2/22/98
1066 door
= Z_Malloc (sizeof(*door
), PU_LEVSPEC
, 0);
1067 P_AddThinker (&door
->thinker
);
1068 sec
->ceilingdata
= door
; //jff 2/22/98
1070 door
->thinker
.function
= T_VerticalDoor
;
1072 // setup delay for door remaining open/closed
1080 door
->topwait
= VDOORWAIT
;
1083 door
->topwait
= 2*VDOORWAIT
;
1086 door
->topwait
= 7*VDOORWAIT
;
1090 // setup speed of door motion
1095 door
->speed
= VDOORSPEED
;
1098 door
->speed
= VDOORSPEED
*2;
1101 door
->speed
= VDOORSPEED
*4;
1104 door
->speed
= VDOORSPEED
*8;
1107 door
->line
= line
; // jff 1/31/98 remember line that triggered us
1109 /* killough 10/98: implement gradual lighting */
1110 door
->lighttag
= !comp
[comp_doorlight
] &&
1111 (line
->special
&6) == 6 &&
1112 line
->special
> GenLockedBase
? line
->tag
: 0;
1114 // set kind of door, whether it opens then close, opens, closes etc.
1115 // assign target heights accordingly
1119 door
->direction
= 1;
1120 door
->topheight
= P_FindLowestCeilingSurrounding(sec
);
1121 door
->topheight
-= 4*FRACUNIT
;
1122 if (door
->topheight
!= sec
->ceilingheight
)
1123 S_StartSound((mobj_t
*)&door
->sector
->soundorg
,Sped
>=SpeedFast
|| comp
[comp_sound
] ? sfx_bdopn
: sfx_doropn
);
1124 door
->type
= Sped
>=SpeedFast
? genBlazeRaise
: genRaise
;
1127 door
->direction
= 1;
1128 door
->topheight
= P_FindLowestCeilingSurrounding(sec
);
1129 door
->topheight
-= 4*FRACUNIT
;
1130 if (door
->topheight
!= sec
->ceilingheight
)
1131 S_StartSound((mobj_t
*)&door
->sector
->soundorg
,Sped
>=SpeedFast
|| comp
[comp_sound
] ? sfx_bdopn
: sfx_doropn
);
1132 door
->type
= Sped
>=SpeedFast
? genBlazeOpen
: genOpen
;
1135 door
->topheight
= sec
->ceilingheight
;
1136 door
->direction
= -1;
1137 S_StartSound((mobj_t
*)&door
->sector
->soundorg
,Sped
>=SpeedFast
&& !comp
[comp_sound
] ? sfx_bdcls
: sfx_dorcls
);
1138 door
->type
= Sped
>=SpeedFast
? genBlazeCdO
: genCdO
;
1141 door
->topheight
= P_FindLowestCeilingSurrounding(sec
);
1142 door
->topheight
-= 4*FRACUNIT
;
1143 door
->direction
= -1;
1144 S_StartSound((mobj_t
*)&door
->sector
->soundorg
,Sped
>=SpeedFast
&& !comp
[comp_sound
] ? sfx_bdcls
: sfx_dorcls
);
1145 door
->type
= Sped
>=SpeedFast
? genBlazeClose
: genClose
;