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 * General plane mover and floor mover action routines
29 * Floor motion, pure changer types, raising stairs. donuts, elevators
31 *-----------------------------------------------------------------------------*/
41 #include "rockmacros.h"
43 ///////////////////////////////////////////////////////////////////////
45 // Plane (floor or ceiling), Floor motion and Elevator action routines
47 ///////////////////////////////////////////////////////////////////////
52 // Move a plane (floor or ceiling) and check for crushing. Called
53 // every tick by all actions that move floors or ceilings.
55 // Passed the sector to move a plane in, the speed to move it at,
56 // the dest height it is to achieve, whether it crushes obstacles,
57 // whether it moves a floor or ceiling, and the direction up or down
60 // Returns a result_e:
61 // ok - plane moved normally, has not achieved destination yet
62 // pastdest - plane moved normally and is now at destination height
63 // crushed - plane encountered an obstacle, is holding until removed
75 fixed_t destheight
; //jff 02/04/98 used to keep floors/ceilings
76 // from moving thru each other
78 switch(floorOrCeiling
)
85 // Moving a floor down
86 if (sector
->floorheight
- speed
< dest
)
88 lastpos
= sector
->floorheight
;
89 sector
->floorheight
= dest
;
90 flag
= P_CheckSector(sector
,crush
); //jff 3/19/98 use faster chk
93 sector
->floorheight
=lastpos
;
94 P_CheckSector(sector
,crush
); //jff 3/19/98 use faster chk
100 lastpos
= sector
->floorheight
;
101 sector
->floorheight
-= speed
;
102 flag
= P_CheckSector(sector
,crush
); //jff 3/19/98 use faster chk
103 /* cph - make more compatible with original Doom, by
104 * reintroducing this code. This means floors can't lower
105 * if objects are stuck in the ceiling */
106 if ((flag
== true) && comp
[comp_floors
]) {
107 sector
->floorheight
= lastpos
;
108 P_ChangeSector(sector
,crush
);
116 // jff 02/04/98 keep floor from moving thru ceilings
117 // jff 2/22/98 weaken check to demo_compatibility
118 destheight
= (comp
[comp_floors
] || dest
<sector
->ceilingheight
)?
119 dest
: sector
->ceilingheight
;
120 if (sector
->floorheight
+ speed
> destheight
)
122 lastpos
= sector
->floorheight
;
123 sector
->floorheight
= destheight
;
124 flag
= P_CheckSector(sector
,crush
); //jff 3/19/98 use faster chk
127 sector
->floorheight
= lastpos
;
128 P_CheckSector(sector
,crush
); //jff 3/19/98 use faster chk
134 // crushing is possible
135 lastpos
= sector
->floorheight
;
136 sector
->floorheight
+= speed
;
137 flag
= P_CheckSector(sector
,crush
); //jff 3/19/98 use faster chk
140 /* jff 1/25/98 fix floor crusher */
141 if (comp
[comp_floors
]) {
145 sector
->floorheight
= lastpos
;
146 P_CheckSector(sector
,crush
); //jff 3/19/98 use faster chk
159 // moving a ceiling down
160 // jff 02/04/98 keep ceiling from moving thru floors
161 // jff 2/22/98 weaken check to demo_compatibility
162 destheight
= (comp
[comp_floors
] || dest
>sector
->floorheight
)?
163 dest
: sector
->floorheight
;
164 if (sector
->ceilingheight
- speed
< destheight
)
166 lastpos
= sector
->ceilingheight
;
167 sector
->ceilingheight
= destheight
;
168 flag
= P_CheckSector(sector
,crush
); //jff 3/19/98 use faster chk
172 sector
->ceilingheight
= lastpos
;
173 P_CheckSector(sector
,crush
); //jff 3/19/98 use faster chk
179 // crushing is possible
180 lastpos
= sector
->ceilingheight
;
181 sector
->ceilingheight
-= speed
;
182 flag
= P_CheckSector(sector
,crush
); //jff 3/19/98 use faster chk
188 sector
->ceilingheight
= lastpos
;
189 P_CheckSector(sector
,crush
); //jff 3/19/98 use faster chk
196 // moving a ceiling up
197 if (sector
->ceilingheight
+ speed
> dest
)
199 lastpos
= sector
->ceilingheight
;
200 sector
->ceilingheight
= dest
;
201 flag
= P_CheckSector(sector
,crush
); //jff 3/19/98 use faster chk
204 sector
->ceilingheight
= lastpos
;
205 P_CheckSector(sector
,crush
); //jff 3/19/98 use faster chk
211 lastpos
= sector
->ceilingheight
;
212 sector
->ceilingheight
+= speed
;
213 flag
= P_CheckSector(sector
,crush
); //jff 3/19/98 use faster chk
225 // Move a floor to it's destination (up or down).
226 // Called once per tick for each moving floor.
228 // Passed a floormove_t structure that contains all pertinent info about the
229 // move. See P_SPEC.H for fields.
232 // jff 02/08/98 all cases with labels beginning with gen added to support
233 // generalized line type behaviors.
234 void T_MoveFloor(floormove_t
* floor
)
238 res
= T_MovePlane
// move the floor
242 floor
->floordestheight
,
248 if (!(leveltime
&7)) // make the floormove sound
249 S_StartSound((mobj_t
*)&floor
->sector
->soundorg
, sfx_stnmov
);
251 if (res
== pastdest
) // if destination height is reached
253 if (floor
->direction
== 1) // going up
255 switch(floor
->type
) // handle texture/type changes
258 floor
->sector
->special
= floor
->newspecial
;
259 floor
->sector
->floorpic
= floor
->texture
;
263 floor
->sector
->special
= floor
->newspecial
;
264 //jff add to fix bug in special transfers from changes
265 floor
->sector
->oldspecial
= floor
->oldspecial
;
268 floor
->sector
->floorpic
= floor
->texture
;
274 else if (floor
->direction
== -1) // going down
276 switch(floor
->type
) // handle texture/type changes
279 floor
->sector
->special
= floor
->newspecial
;
280 //jff add to fix bug in special transfers from changes
281 floor
->sector
->oldspecial
= floor
->oldspecial
;
282 floor
->sector
->floorpic
= floor
->texture
;
286 floor
->sector
->special
= floor
->newspecial
;
287 //jff add to fix bug in special transfers from changes
288 floor
->sector
->oldspecial
= floor
->oldspecial
;
291 floor
->sector
->floorpic
= floor
->texture
;
298 floor
->sector
->floordata
= NULL
; //jff 2/22/98
299 P_RemoveThinker(&floor
->thinker
);//remove this floor from list of movers
301 //jff 2/26/98 implement stair retrigger lockout while still building
302 // note this only applies to the retriggerable generalized stairs
304 if (floor
->sector
->stairlock
==-2) // if this sector is stairlocked
306 sector_t
*sec
= floor
->sector
;
307 sec
->stairlock
=-1; // thinker done, promote lock to -1
309 while (sec
->prevsec
!=-1 && sectors
[sec
->prevsec
].stairlock
!=-2)
310 sec
= §ors
[sec
->prevsec
]; // search for a non-done thinker
311 if (sec
->prevsec
==-1) // if all thinkers previous are done
313 sec
= floor
->sector
; // search forward
314 while (sec
->nextsec
!=-1 && sectors
[sec
->nextsec
].stairlock
!=-2)
315 sec
= §ors
[sec
->nextsec
];
316 if (sec
->nextsec
==-1) // if all thinkers ahead are done too
318 while (sec
->prevsec
!=-1) // clear all locks
321 sec
= §ors
[sec
->prevsec
];
328 // make floor stop sound
329 S_StartSound((mobj_t
*)&floor
->sector
->soundorg
, sfx_pstop
);
336 // Move an elevator to it's destination (up or down)
337 // Called once per tick for each moving floor.
339 // Passed an elevator_t structure that contains all pertinent info about the
340 // move. See P_SPEC.H for fields.
343 // jff 02/22/98 added to support parallel floor/ceiling motion
345 void T_MoveElevator(elevator_t
* elevator
)
349 if (elevator
->direction
<0) // moving down
351 res
= T_MovePlane
//jff 4/7/98 reverse order of ceiling/floor
355 elevator
->ceilingdestheight
,
360 if (res
==ok
|| res
==pastdest
) // jff 4/7/98 don't move ceil if blocked
365 elevator
->floordestheight
,
373 res
= T_MovePlane
//jff 4/7/98 reverse order of ceiling/floor
377 elevator
->floordestheight
,
382 if (res
==ok
|| res
==pastdest
) // jff 4/7/98 don't move floor if blocked
387 elevator
->ceilingdestheight
,
394 // make floor move sound
396 S_StartSound((mobj_t
*)&elevator
->sector
->soundorg
, sfx_stnmov
);
398 if (res
== pastdest
) // if destination height acheived
400 elevator
->sector
->floordata
= NULL
; //jff 2/22/98
401 elevator
->sector
->ceilingdata
= NULL
; //jff 2/22/98
402 P_RemoveThinker(&elevator
->thinker
); // remove elevator from actives
404 // make floor stop sound
405 S_StartSound((mobj_t
*)&elevator
->sector
->soundorg
, sfx_pstop
);
409 ///////////////////////////////////////////////////////////////////////
411 // Floor motion linedef handlers
413 ///////////////////////////////////////////////////////////////////////
418 // Handle regular and extended floor types
420 // Passed the line that activated the floor and the type of floor motion
421 // Returns true if a thinker was created.
435 // move all floors with the same tag as the linedef
436 while ((secnum
= P_FindSectorFromLineTag(line
,secnum
)) >= 0)
438 sec
= §ors
[secnum
];
440 // Don't start a second thinker on the same floor
441 if (P_SectorActive(floor_special
,sec
)) //jff 2/23/98
446 floor
= Z_Malloc (sizeof(*floor
), PU_LEVSPEC
, 0);
447 P_AddThinker (&floor
->thinker
);
448 sec
->floordata
= floor
; //jff 2/22/98
449 floor
->thinker
.function
= T_MoveFloor
;
450 floor
->type
= floortype
;
451 floor
->crush
= false;
453 // setup the thinker according to the linedef type
457 floor
->direction
= -1;
459 floor
->speed
= FLOORSPEED
;
460 floor
->floordestheight
= P_FindHighestFloorSurrounding(sec
);
463 //jff 02/03/30 support lowering floor by 24 absolute
465 floor
->direction
= -1;
467 floor
->speed
= FLOORSPEED
;
468 floor
->floordestheight
= floor
->sector
->floorheight
+ 24 * FRACUNIT
;
471 //jff 02/03/30 support lowering floor by 32 absolute (fast)
472 case lowerFloor32Turbo
:
473 floor
->direction
= -1;
475 floor
->speed
= FLOORSPEED
*4;
476 floor
->floordestheight
= floor
->sector
->floorheight
+ 32 * FRACUNIT
;
479 case lowerFloorToLowest
:
480 floor
->direction
= -1;
482 floor
->speed
= FLOORSPEED
;
483 floor
->floordestheight
= P_FindLowestFloorSurrounding(sec
);
486 //jff 02/03/30 support lowering floor to next lowest floor
487 case lowerFloorToNearest
:
488 floor
->direction
= -1;
490 floor
->speed
= FLOORSPEED
;
491 floor
->floordestheight
=
492 P_FindNextLowestFloor(sec
,floor
->sector
->floorheight
);
496 floor
->direction
= -1;
498 floor
->speed
= FLOORSPEED
* 4;
499 floor
->floordestheight
= P_FindHighestFloorSurrounding(sec
);
500 if (floor
->floordestheight
!= sec
->floorheight
)
501 floor
->floordestheight
+= 8*FRACUNIT
;
504 case raiseFloorCrush
:
507 floor
->direction
= 1;
509 floor
->speed
= FLOORSPEED
;
510 floor
->floordestheight
= P_FindLowestCeilingSurrounding(sec
);
511 if (floor
->floordestheight
> sec
->ceilingheight
)
512 floor
->floordestheight
= sec
->ceilingheight
;
513 floor
->floordestheight
-= (8*FRACUNIT
)*(floortype
== raiseFloorCrush
);
516 case raiseFloorTurbo
:
517 floor
->direction
= 1;
519 floor
->speed
= FLOORSPEED
*4;
520 floor
->floordestheight
= P_FindNextHighestFloor(sec
,sec
->floorheight
);
523 case raiseFloorToNearest
:
524 floor
->direction
= 1;
526 floor
->speed
= FLOORSPEED
;
527 floor
->floordestheight
= P_FindNextHighestFloor(sec
,sec
->floorheight
);
531 floor
->direction
= 1;
533 floor
->speed
= FLOORSPEED
;
534 floor
->floordestheight
= floor
->sector
->floorheight
+ 24 * FRACUNIT
;
537 // jff 2/03/30 support straight raise by 32 (fast)
538 case raiseFloor32Turbo
:
539 floor
->direction
= 1;
541 floor
->speed
= FLOORSPEED
*4;
542 floor
->floordestheight
= floor
->sector
->floorheight
+ 32 * FRACUNIT
;
546 floor
->direction
= 1;
548 floor
->speed
= FLOORSPEED
;
549 floor
->floordestheight
= floor
->sector
->floorheight
+ 512 * FRACUNIT
;
552 case raiseFloor24AndChange
:
553 floor
->direction
= 1;
555 floor
->speed
= FLOORSPEED
;
556 floor
->floordestheight
= floor
->sector
->floorheight
+ 24 * FRACUNIT
;
557 sec
->floorpic
= line
->frontsector
->floorpic
;
558 sec
->special
= line
->frontsector
->special
;
559 //jff 3/14/98 transfer both old and new special
560 sec
->oldspecial
= line
->frontsector
->oldspecial
;
565 int minsize
= INT_MAX
;
568 /* jff 3/13/98 no ovf */
569 if (!comp
[comp_model
]) minsize
= 32000<<FRACBITS
;
570 floor
->direction
= 1;
572 floor
->speed
= FLOORSPEED
;
573 for (i
= 0; i
< sec
->linecount
; i
++)
575 if (twoSided (secnum
, i
) )
577 side
= getSide(secnum
,i
,0);
578 // jff 8/14/98 don't scan texture 0, its not real
579 if (side
->bottomtexture
> 0 ||
580 (comp
[comp_model
] && !side
->bottomtexture
))
581 if (textureheight
[side
->bottomtexture
] < minsize
)
582 minsize
= textureheight
[side
->bottomtexture
];
583 side
= getSide(secnum
,i
,1);
584 // jff 8/14/98 don't scan texture 0, its not real
585 if (side
->bottomtexture
> 0 ||
586 (comp
[comp_model
] && !side
->bottomtexture
))
587 if (textureheight
[side
->bottomtexture
] < minsize
)
588 minsize
= textureheight
[side
->bottomtexture
];
591 if (comp
[comp_model
])
592 floor
->floordestheight
= floor
->sector
->floorheight
+ minsize
;
595 floor
->floordestheight
=
596 (floor
->sector
->floorheight
>>FRACBITS
) + (minsize
>>FRACBITS
);
597 if (floor
->floordestheight
>32000)
598 floor
->floordestheight
= 32000; //jff 3/13/98 do not
599 floor
->floordestheight
<<=FRACBITS
; // allow height overflow
605 floor
->direction
= -1;
607 floor
->speed
= FLOORSPEED
;
608 floor
->floordestheight
= P_FindLowestFloorSurrounding(sec
);
609 floor
->texture
= sec
->floorpic
;
611 // jff 1/24/98 make sure floor->newspecial gets initialized
612 // in case no surrounding sector is at floordestheight
613 // --> should not affect compatibility <--
614 floor
->newspecial
= sec
->special
;
615 //jff 3/14/98 transfer both old and new special
616 floor
->oldspecial
= sec
->oldspecial
;
618 //jff 5/23/98 use model subroutine to unify fixes and handling
619 sec
= P_FindModelFloorSector(floor
->floordestheight
,sec
-sectors
);
622 floor
->texture
= sec
->floorpic
;
623 floor
->newspecial
= sec
->special
;
624 //jff 3/14/98 transfer both old and new special
625 floor
->oldspecial
= sec
->oldspecial
;
638 // Handle pure change types. These change floor texture and sector type
639 // by trigger or numeric model without moving the floor.
641 // The linedef causing the change and the type of change is passed
642 // Returns true if any sector changes
644 // jff 3/15/98 added to better support generalized sector types
648 change_e changetype
)
657 // change all sectors with the same tag as the linedef
658 while ((secnum
= P_FindSectorFromLineTag(line
,secnum
)) >= 0)
660 sec
= §ors
[secnum
];
664 // handle trigger or numeric change type
668 sec
->floorpic
= line
->frontsector
->floorpic
;
669 sec
->special
= line
->frontsector
->special
;
670 sec
->oldspecial
= line
->frontsector
->oldspecial
;
673 secm
= P_FindModelFloorSector(sec
->floorheight
,secnum
);
674 if (secm
) // if no model, no change
676 sec
->floorpic
= secm
->floorpic
;
677 sec
->special
= secm
->special
;
678 sec
->oldspecial
= secm
->oldspecial
;
691 * Handles staircase building. A sequence of sectors chosen by algorithm
692 * rise at a speed indicated to a height that increases by the stepsize
695 * Passed the linedef triggering the stairs and the type of stair rise
696 * Returns true if any thinkers are created
698 * cph 2001/09/21 - compatibility nightmares again
699 * There are three different ways this function has, during its history, stepped
700 * through all the stairs to be triggered by the single switch
701 * - original Doom used a linear P_FindSectorFromLineTag, but failed to preserve
702 * the index of the previous sector found, so instead it would restart its
703 * linear search from the last sector of the previous staircase
704 * - MBF/PrBoom with comp_stairs fail to emulate this, because their
705 * P_FindSectorFromLineTag is a chained hash table implementation. Instead they
706 * start following the hash chain from the last sector of the previous
707 * staircase, which will (probably) have the wrong tag, so they miss any further
709 * - Boom fixed the bug, and MBF/PrBoom without comp_stairs work right
711 static inline int P_FindSectorFromLineTagWithLowerBound
712 (line_t
* l
, int start
, int min
)
714 /* Emulate original Doom's linear lower-bounded P_FindSectorFromLineTag
717 start
= P_FindSectorFromLineTag(l
,start
);
718 } while (start
>= 0 && start
<= min
);
726 /* cph 2001/09/22 - cleaned up this function to save my sanity. A separate
727 * outer loop index makes the logic much cleared, and local variables moved
728 * into the inner blocks helps too */
733 // start a stair at each sector tagged the same as the linedef
734 while ((ssec
= P_FindSectorFromLineTagWithLowerBound(line
,ssec
,minssec
)) >= 0)
737 sector_t
* sec
= §ors
[secnum
];
739 // don't start a stair if the first step's floor is already moving
740 if (!P_SectorActive(floor_special
,sec
)) { //jff 2/22/98
747 // create new floor thinker for first step
749 floor
= Z_Malloc (sizeof(*floor
), PU_LEVSPEC
, 0);
750 P_AddThinker (&floor
->thinker
);
751 sec
->floordata
= floor
;
752 floor
->thinker
.function
= T_MoveFloor
;
753 floor
->direction
= 1;
755 floor
->type
= buildStair
; //jff 3/31/98 do not leave uninited
757 // set up the speed and stepsize according to the stairs type
760 default: // killough -- prevent compiler warning
762 speed
= FLOORSPEED
/4;
763 stairsize
= 8*FRACUNIT
;
764 if (!demo_compatibility
)
765 floor
->crush
= false; //jff 2/27/98 fix uninitialized crush field
768 speed
= FLOORSPEED
*4;
769 stairsize
= 16*FRACUNIT
;
770 if (!demo_compatibility
)
771 floor
->crush
= true; //jff 2/27/98 fix uninitialized crush field
774 floor
->speed
= speed
;
775 height
= sec
->floorheight
+ stairsize
;
776 floor
->floordestheight
= height
;
778 texture
= sec
->floorpic
;
780 // Find next sector to raise
781 // 1. Find 2-sided line with same sector side[0] (lowest numbered)
782 // 2. Other side is the next sector to raise
783 // 3. Unless already moving, or different texture, then stop building
789 for (i
= 0;i
< sec
->linecount
;i
++)
791 sector_t
* tsec
= (sec
->lines
[i
])->frontsector
;
793 if ( !((sec
->lines
[i
])->flags
& ML_TWOSIDED
) )
796 newsecnum
= tsec
-sectors
;
798 if (secnum
!= newsecnum
)
801 tsec
= (sec
->lines
[i
])->backsector
;
802 if (!tsec
) continue; //jff 5/7/98 if no backside, continue
803 newsecnum
= tsec
- sectors
;
805 // if sector's floor is different texture, look for another
806 if (tsec
->floorpic
!= texture
)
809 /* jff 6/19/98 prevent double stepsize
810 * killough 10/98: intentionally left this way [MBF comment]
811 * cph 2001/02/06: stair bug fix should be controlled by comp_stairs,
812 * except if we're emulating MBF which perversly reverted the fix
814 if (comp
[comp_stairs
] || (compatibility_level
== mbf_compatibility
))
815 height
+= stairsize
; // jff 6/28/98 change demo compatibility
817 // if sector's floor already moving, look for another
818 if (P_SectorActive(floor_special
,tsec
)) //jff 2/22/98
821 /* cph - see comment above - do this iff we didn't do so above */
822 if (!comp
[comp_stairs
] && (compatibility_level
!= mbf_compatibility
))
828 // create and initialize a thinker for the next step
829 floor
= Z_Malloc (sizeof(*floor
), PU_LEVSPEC
, 0);
830 P_AddThinker (&floor
->thinker
);
832 sec
->floordata
= floor
; //jff 2/22/98
833 floor
->thinker
.function
= T_MoveFloor
;
834 floor
->direction
= 1;
836 floor
->speed
= speed
;
837 floor
->floordestheight
= height
;
838 floor
->type
= buildStair
; //jff 3/31/98 do not leave uninited
839 //jff 2/27/98 fix uninitialized crush field
840 if (!demo_compatibility
)
841 floor
->crush
= type
==build8
? false : true;
845 } while(ok
); // continue until no next step is found
848 /* killough 10/98: compatibility option */
849 if (comp
[comp_stairs
]) {
850 /* cph 2001/09/22 - emulate buggy MBF comp_stairs for demos, with logic
851 * reversed since we now have a separate outer loop index.
852 * DEMOSYNC - what about boom_compatibility_compatibility?
854 if ((compatibility_level
>= mbf_compatibility
) && (compatibility_level
<
855 prboom_3_compatibility
)) ssec
= secnum
; /* Trash outer loop index */
857 /* cph 2001/09/22 - now the correct comp_stairs - Doom used a linear
858 * search from the last secnum, so we set that as a minimum value and do
861 ssec
= -1; minssec
= secnum
;
871 // Handle donut function: lower pillar, raise surrounding pool, both to height,
872 // texture and type of the sector surrounding the pool.
874 // Passed the linedef that triggered the donut
875 // Returns whether a thinker was created
877 int EV_DoDonut(line_t
* line
)
889 // do function on all sectors with same tag as linedef
890 while ((secnum
= P_FindSectorFromLineTag(line
,secnum
)) >= 0)
892 s1
= §ors
[secnum
]; // s1 is pillar's sector
894 // do not start the donut if the pillar is already moving
895 if (P_SectorActive(floor_special
,s1
)) //jff 2/22/98
898 s2
= getNextSector(s1
->lines
[0],s1
); // s2 is pool's sector
899 if (!s2
) continue; // note lowest numbered line around
900 // pillar must be two-sided
902 /* do not start the donut if the pool is already moving
903 * cph - DEMOSYNC - was !compatibility */
904 if (!comp
[comp_floors
] && P_SectorActive(floor_special
,s2
))
905 continue; //jff 5/7/98
907 // find a two sided line around the pool whose other side isn't the pillar
908 for (i
= 0;i
< s2
->linecount
;i
++)
910 //jff 3/29/98 use true two-sidedness, not the flag
911 // killough 4/5/98: changed demo_compatibility to compatibility
912 if (comp
[comp_model
])
914 if (!(s2
->lines
[i
]->flags
& ML_TWOSIDED
) ||
915 (s2
->lines
[i
]->backsector
== s1
))
918 else if (!s2
->lines
[i
]->backsector
|| s2
->lines
[i
]->backsector
== s1
)
921 rtn
= 1; //jff 1/26/98 no donut action - no switch change on return
923 s3
= s2
->lines
[i
]->backsector
; // s3 is model sector for changes
925 // Spawn rising slime
926 floor
= Z_Malloc (sizeof(*floor
), PU_LEVSPEC
, 0);
927 P_AddThinker (&floor
->thinker
);
928 s2
->floordata
= floor
; //jff 2/22/98
929 floor
->thinker
.function
= T_MoveFloor
;
930 floor
->type
= donutRaise
;
931 floor
->crush
= false;
932 floor
->direction
= 1;
934 floor
->speed
= FLOORSPEED
/ 2;
935 floor
->texture
= s3
->floorpic
;
936 floor
->newspecial
= 0;
937 floor
->floordestheight
= s3
->floorheight
;
939 // Spawn lowering donut-hole pillar
940 floor
= Z_Malloc (sizeof(*floor
), PU_LEVSPEC
, 0);
941 P_AddThinker (&floor
->thinker
);
942 s1
->floordata
= floor
; //jff 2/22/98
943 floor
->thinker
.function
= T_MoveFloor
;
944 floor
->type
= lowerFloor
;
945 floor
->crush
= false;
946 floor
->direction
= -1;
948 floor
->speed
= FLOORSPEED
/ 2;
949 floor
->floordestheight
= s3
->floorheight
;
959 // Handle elevator linedef types
961 // Passed the linedef that triggered the elevator and the elevator action
963 // jff 2/22/98 new type to move floor and ceiling in parallel
967 elevator_e elevtype
)
972 elevator_t
* elevator
;
976 // act on all sectors with the same tag as the triggering linedef
977 while ((secnum
= P_FindSectorFromLineTag(line
,secnum
)) >= 0)
979 sec
= §ors
[secnum
];
981 // If either floor or ceiling is already activated, skip it
982 if (sec
->floordata
|| sec
->ceilingdata
) //jff 2/22/98
985 // create and initialize new elevator thinker
987 elevator
= Z_Malloc (sizeof(*elevator
), PU_LEVSPEC
, 0);
988 P_AddThinker (&elevator
->thinker
);
989 sec
->floordata
= elevator
; //jff 2/22/98
990 sec
->ceilingdata
= elevator
; //jff 2/22/98
991 elevator
->thinker
.function
= T_MoveElevator
;
992 elevator
->type
= elevtype
;
994 // set up the fields according to the type of elevator action
997 // elevator down to next floor
999 elevator
->direction
= -1;
1000 elevator
->sector
= sec
;
1001 elevator
->speed
= ELEVATORSPEED
;
1002 elevator
->floordestheight
=
1003 P_FindNextLowestFloor(sec
,sec
->floorheight
);
1004 elevator
->ceilingdestheight
=
1005 elevator
->floordestheight
+ sec
->ceilingheight
- sec
->floorheight
;
1008 // elevator up to next floor
1010 elevator
->direction
= 1;
1011 elevator
->sector
= sec
;
1012 elevator
->speed
= ELEVATORSPEED
;
1013 elevator
->floordestheight
=
1014 P_FindNextHighestFloor(sec
,sec
->floorheight
);
1015 elevator
->ceilingdestheight
=
1016 elevator
->floordestheight
+ sec
->ceilingheight
- sec
->floorheight
;
1019 // elevator to floor height of activating switch's front sector
1020 case elevateCurrent
:
1021 elevator
->sector
= sec
;
1022 elevator
->speed
= ELEVATORSPEED
;
1023 elevator
->floordestheight
= line
->frontsector
->floorheight
;
1024 elevator
->ceilingdestheight
=
1025 elevator
->floordestheight
+ sec
->ceilingheight
- sec
->floorheight
;
1026 elevator
->direction
=
1027 elevator
->floordestheight
>sec
->floorheight
? 1 : -1;