1 // Emacs style mode select -*- C++ -*-
2 //-----------------------------------------------------------------------------
6 // Copyright (C) 1993-1996 by id Software, Inc.
8 // This source is available for distribution and/or modification
9 // only under the terms of the DOOM Source Code License as
10 // published by id Software. All rights reserved.
12 // The source is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
18 // Revision 1.1 2000/02/29 18:21:04 stegerg
19 // Doom port based on ADoomPPC. Read README.AROS!
22 // DESCRIPTION: Door animation code (opening/closing)
24 //-----------------------------------------------------------------------------
47 // Sliding door frame information
49 slidename_t slideFrameNames
[MAXSLIDEDOORS
] =
51 {"GDOORF1","GDOORF2","GDOORF3","GDOORF4", // front
52 "GDOORB1","GDOORB2","GDOORB3","GDOORB4"}, // back
66 void T_VerticalDoor (vldoor_t
* door
)
70 switch(door
->direction
)
74 if (!--door
->topcountdown
)
79 door
->direction
= -1; // time to go back down
80 S_StartSound((mobj_t
*)&door
->sector
->soundorg
,
85 door
->direction
= -1; // time to go back down
86 S_StartSound((mobj_t
*)&door
->sector
->soundorg
,
92 S_StartSound((mobj_t
*)&door
->sector
->soundorg
,
104 if (!--door
->topcountdown
)
111 S_StartSound((mobj_t
*)&door
->sector
->soundorg
,
123 res
= T_MovePlane(door
->sector
,
125 door
->sector
->floorheight
,
126 false,1,door
->direction
);
133 door
->sector
->specialdata
= NULL
;
134 P_RemoveThinker (&door
->thinker
); // unlink and free
135 S_StartSound((mobj_t
*)&door
->sector
->soundorg
,
141 door
->sector
->specialdata
= NULL
;
142 P_RemoveThinker (&door
->thinker
); // unlink and free
145 case close30ThenOpen
:
147 door
->topcountdown
= 35*30;
154 else if (res
== crushed
)
159 case close
: // DO NOT GO BACK UP!
164 S_StartSound((mobj_t
*)&door
->sector
->soundorg
,
173 res
= T_MovePlane(door
->sector
,
176 false,1,door
->direction
);
184 door
->direction
= 0; // wait at top
185 door
->topcountdown
= door
->topwait
;
188 case close30ThenOpen
:
191 door
->sector
->specialdata
= NULL
;
192 P_RemoveThinker (&door
->thinker
); // unlink and free
206 // Move a locked door up/down
222 switch(line
->special
)
224 case 99: // Blue Lock
228 if (!p
->cards
[it_bluecard
] && !p
->cards
[it_blueskull
])
230 p
->message
= PD_BLUEO
;
231 S_StartSound(NULL
,sfx_oof
);
236 case 134: // Red Lock
240 if (!p
->cards
[it_redcard
] && !p
->cards
[it_redskull
])
242 p
->message
= PD_REDO
;
243 S_StartSound(NULL
,sfx_oof
);
248 case 136: // Yellow Lock
252 if (!p
->cards
[it_yellowcard
] &&
253 !p
->cards
[it_yellowskull
])
255 p
->message
= PD_YELLOWO
;
256 S_StartSound(NULL
,sfx_oof
);
262 return EV_DoDoor(line
,type
);
278 while ((secnum
= P_FindSectorFromLineTag(line
,secnum
)) >= 0)
280 sec
= §ors
[secnum
];
281 if (sec
->specialdata
)
287 door
= Z_Malloc (sizeof(*door
), PU_LEVSPEC
, 0);
288 P_AddThinker (&door
->thinker
);
289 sec
->specialdata
= door
;
291 door
->thinker
.function
.acp1
= (actionf_p1
) T_VerticalDoor
;
294 door
->topwait
= VDOORWAIT
;
295 door
->speed
= VDOORSPEED
;
300 door
->topheight
= P_FindLowestCeilingSurrounding(sec
);
301 door
->topheight
-= 4*FRACUNIT
;
302 door
->direction
= -1;
303 door
->speed
= VDOORSPEED
* 4;
304 S_StartSound((mobj_t
*)&door
->sector
->soundorg
,
309 door
->topheight
= P_FindLowestCeilingSurrounding(sec
);
310 door
->topheight
-= 4*FRACUNIT
;
311 door
->direction
= -1;
312 S_StartSound((mobj_t
*)&door
->sector
->soundorg
,
316 case close30ThenOpen
:
317 door
->topheight
= sec
->ceilingheight
;
318 door
->direction
= -1;
319 S_StartSound((mobj_t
*)&door
->sector
->soundorg
,
326 door
->topheight
= P_FindLowestCeilingSurrounding(sec
);
327 door
->topheight
-= 4*FRACUNIT
;
328 door
->speed
= VDOORSPEED
* 4;
329 if (door
->topheight
!= sec
->ceilingheight
)
330 S_StartSound((mobj_t
*)&door
->sector
->soundorg
,
337 door
->topheight
= P_FindLowestCeilingSurrounding(sec
);
338 door
->topheight
-= 4*FRACUNIT
;
339 if (door
->topheight
!= sec
->ceilingheight
)
340 S_StartSound((mobj_t
*)&door
->sector
->soundorg
,
354 // EV_VerticalDoor : open a door manually, no tag value
367 side
= 0; // only front sides can be used
370 player
= thing
->player
;
372 switch(line
->special
)
374 case 26: // Blue Lock
379 if (!player
->cards
[it_bluecard
] && !player
->cards
[it_blueskull
])
381 player
->message
= PD_BLUEK
;
382 S_StartSound(NULL
,sfx_oof
);
387 case 27: // Yellow Lock
392 if (!player
->cards
[it_yellowcard
] &&
393 !player
->cards
[it_yellowskull
])
395 player
->message
= PD_YELLOWK
;
396 S_StartSound(NULL
,sfx_oof
);
406 if (!player
->cards
[it_redcard
] && !player
->cards
[it_redskull
])
408 player
->message
= PD_REDK
;
409 S_StartSound(NULL
,sfx_oof
);
415 // if the sector has an active thinker, use it
416 sec
= sides
[ line
->sidenum
[side
^1]] .sector
;
417 secnum
= sec
-sectors
;
419 if (sec
->specialdata
)
421 door
= sec
->specialdata
;
422 switch(line
->special
)
424 case 1: // ONLY FOR "RAISE" DOORS, NOT "OPEN"s
429 if (door
->direction
== -1)
430 door
->direction
= 1; // go back up
434 return; // JDC: bad guys never close doors
436 door
->direction
= -1; // start going down immediately
443 switch(line
->special
)
445 case 117: // BLAZING DOOR RAISE
446 case 118: // BLAZING DOOR OPEN
447 S_StartSound((mobj_t
*)&sec
->soundorg
,sfx_bdopn
);
450 case 1: // NORMAL DOOR SOUND
452 S_StartSound((mobj_t
*)&sec
->soundorg
,sfx_doropn
);
455 default: // LOCKED DOOR SOUND
456 S_StartSound((mobj_t
*)&sec
->soundorg
,sfx_doropn
);
462 door
= Z_Malloc (sizeof(*door
), PU_LEVSPEC
, 0);
463 P_AddThinker (&door
->thinker
);
464 sec
->specialdata
= door
;
465 door
->thinker
.function
.acp1
= (actionf_p1
) T_VerticalDoor
;
468 door
->speed
= VDOORSPEED
;
469 door
->topwait
= VDOORWAIT
;
471 switch(line
->special
)
488 case 117: // blazing door raise
489 door
->type
= blazeRaise
;
490 door
->speed
= VDOORSPEED
*4;
492 case 118: // blazing door open
493 door
->type
= blazeOpen
;
495 door
->speed
= VDOORSPEED
*4;
499 // find the top and bottom of the movement range
500 door
->topheight
= P_FindLowestCeilingSurrounding(sec
);
501 door
->topheight
-= 4*FRACUNIT
;
506 // Spawn a door that closes after 30 seconds
508 void P_SpawnDoorCloseIn30 (sector_t
* sec
)
512 door
= Z_Malloc ( sizeof(*door
), PU_LEVSPEC
, 0);
514 P_AddThinker (&door
->thinker
);
516 sec
->specialdata
= door
;
519 door
->thinker
.function
.acp1
= (actionf_p1
)T_VerticalDoor
;
523 door
->speed
= VDOORSPEED
;
524 door
->topcountdown
= 30 * 35;
528 // Spawn a door that opens after 5 minutes
531 P_SpawnDoorRaiseIn5Mins
537 door
= Z_Malloc ( sizeof(*door
), PU_LEVSPEC
, 0);
539 P_AddThinker (&door
->thinker
);
541 sec
->specialdata
= door
;
544 door
->thinker
.function
.acp1
= (actionf_p1
)T_VerticalDoor
;
547 door
->type
= raiseIn5Mins
;
548 door
->speed
= VDOORSPEED
;
549 door
->topheight
= P_FindLowestCeilingSurrounding(sec
);
550 door
->topheight
-= 4*FRACUNIT
;
551 door
->topwait
= VDOORWAIT
;
552 door
->topcountdown
= 5 * 60 * 35;
558 // Separate into p_slidoor.c?
560 #if 0 // ABANDONED TO THE MISTS OF TIME!!!
562 // EV_SlidingDoor : slide a door horizontally
563 // (animate midtexture, then set noblocking line)
567 slideframe_t slideFrames
[MAXSLIDEDOORS
];
569 void P_InitSlidingDoorFrames(void)
578 if ( gamemode
!= commercial
)
581 for (i
= 0;i
< MAXSLIDEDOORS
; i
++)
583 if (!slideFrameNames
[i
].frontFrame1
[0])
586 f1
= R_TextureNumForName(slideFrameNames
[i
].frontFrame1
);
587 f2
= R_TextureNumForName(slideFrameNames
[i
].frontFrame2
);
588 f3
= R_TextureNumForName(slideFrameNames
[i
].frontFrame3
);
589 f4
= R_TextureNumForName(slideFrameNames
[i
].frontFrame4
);
591 slideFrames
[i
].frontFrames
[0] = f1
;
592 slideFrames
[i
].frontFrames
[1] = f2
;
593 slideFrames
[i
].frontFrames
[2] = f3
;
594 slideFrames
[i
].frontFrames
[3] = f4
;
596 f1
= R_TextureNumForName(slideFrameNames
[i
].backFrame1
);
597 f2
= R_TextureNumForName(slideFrameNames
[i
].backFrame2
);
598 f3
= R_TextureNumForName(slideFrameNames
[i
].backFrame3
);
599 f4
= R_TextureNumForName(slideFrameNames
[i
].backFrame4
);
601 slideFrames
[i
].backFrames
[0] = f1
;
602 slideFrames
[i
].backFrames
[1] = f2
;
603 slideFrames
[i
].backFrames
[2] = f3
;
604 slideFrames
[i
].backFrames
[3] = f4
;
610 // Return index into "slideFrames" array
611 // for which door type to use
613 int P_FindSlidingDoorType(line_t
* line
)
618 for (i
= 0;i
< MAXSLIDEDOORS
;i
++)
620 val
= sides
[line
->sidenum
[0]].midtexture
;
621 if (val
== slideFrames
[i
].frontFrames
[0])
628 void T_SlidingDoor (slidedoor_t
* door
)
635 if (++door
->frame
== SNUMFRAMES
)
637 // IF DOOR IS DONE OPENING...
638 sides
[door
->line
->sidenum
[0]].midtexture
= 0;
639 sides
[door
->line
->sidenum
[1]].midtexture
= 0;
640 door
->line
->flags
&= ML_BLOCKING
^0xff;
642 if (door
->type
== sdt_openOnly
)
644 door
->frontsector
->specialdata
= NULL
;
645 P_RemoveThinker (&door
->thinker
);
649 door
->timer
= SDOORWAIT
;
650 door
->status
= sd_waiting
;
654 // IF DOOR NEEDS TO ANIMATE TO NEXT FRAME...
655 door
->timer
= SWAITTICS
;
657 sides
[door
->line
->sidenum
[0]].midtexture
=
658 slideFrames
[door
->whichDoorIndex
].
659 frontFrames
[door
->frame
];
660 sides
[door
->line
->sidenum
[1]].midtexture
=
661 slideFrames
[door
->whichDoorIndex
].
662 backFrames
[door
->frame
];
668 // IF DOOR IS DONE WAITING...
672 if (door
->frontsector
->thinglist
!= NULL
||
673 door
->backsector
->thinglist
!= NULL
)
675 door
->timer
= SDOORWAIT
;
679 //door->frame = SNUMFRAMES-1;
680 door
->status
= sd_closing
;
681 door
->timer
= SWAITTICS
;
688 if (--door
->frame
< 0)
690 // IF DOOR IS DONE CLOSING...
691 door
->line
->flags
|= ML_BLOCKING
;
692 door
->frontsector
->specialdata
= NULL
;
693 P_RemoveThinker (&door
->thinker
);
698 // IF DOOR NEEDS TO ANIMATE TO NEXT FRAME...
699 door
->timer
= SWAITTICS
;
701 sides
[door
->line
->sidenum
[0]].midtexture
=
702 slideFrames
[door
->whichDoorIndex
].
703 frontFrames
[door
->frame
];
704 sides
[door
->line
->sidenum
[1]].midtexture
=
705 slideFrames
[door
->whichDoorIndex
].
706 backFrames
[door
->frame
];
724 if (gamemode
!= commercial
)
727 // Make sure door isn't already being animated
728 sec
= line
->frontsector
;
730 if (sec
->specialdata
)
735 door
= sec
->specialdata
;
736 if (door
->type
== sdt_openAndClose
)
738 if (door
->status
== sd_waiting
)
739 door
->status
= sd_closing
;
745 // Init sliding door vars
748 door
= Z_Malloc (sizeof(*door
), PU_LEVSPEC
, 0);
749 P_AddThinker (&door
->thinker
);
750 sec
->specialdata
= door
;
752 door
->type
= sdt_openAndClose
;
753 door
->status
= sd_opening
;
754 door
->whichDoorIndex
= P_FindSlidingDoorType(line
);
756 if (door
->whichDoorIndex
< 0)
757 I_Error("EV_SlidingDoor: Can't use texture for sliding door!");
759 door
->frontsector
= sec
;
760 door
->backsector
= line
->backsector
;
761 door
->thinker
.function
= T_SlidingDoor
;
762 door
->timer
= SWAITTICS
;