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
19 // DESCRIPTION: Door animation code (opening/closing)
21 //-----------------------------------------------------------------------------
24 rcsid[] = "$Id: p_doors.c,v 1.4 1997/02/03 16:47:53 b1 Exp $";
50 void T_VerticalDoor (void *_door, void*)
52 vldoor_t *door = (vldoor_t*)_door;
55 switch(door->direction)
59 if (!--door->topcountdown)
64 door->direction = -1; // time to go back down
65 S_StartSound((mobj_t *)&door->sector->soundorg,
70 door->direction = -1; // time to go back down
71 S_StartSound((mobj_t *)&door->sector->soundorg,
77 S_StartSound((mobj_t *)&door->sector->soundorg,
89 if (!--door->topcountdown)
96 S_StartSound((mobj_t *)&door->sector->soundorg,
108 res = T_MovePlane(door->sector,
110 door->sector->floorheight,
111 false,1,door->direction);
118 door->sector->specialdata = NULL;
119 P_RemoveThinker (&door->thinker); // unlink and free
120 S_StartSound((mobj_t *)&door->sector->soundorg,
126 door->sector->specialdata = NULL;
127 P_RemoveThinker (&door->thinker); // unlink and free
130 case Close30ThenOpen:
132 door->topcountdown = 35*30;
139 else if (res == crushed)
144 case Close: // DO NOT GO BACK UP!
149 S_StartSound((mobj_t *)&door->sector->soundorg,
158 res = T_MovePlane(door->sector,
161 false,1,door->direction);
169 door->direction = 0; // wait at top
170 door->topcountdown = door->topwait;
173 case Close30ThenOpen:
176 door->sector->specialdata = NULL;
177 P_RemoveThinker (&door->thinker); // unlink and free
191 // Move a locked door up/down
207 switch(line->special)
209 case 99: // Blue Lock
213 if (!p->cards[it_bluecard] && !p->cards[it_blueskull])
215 p->message = PD_BLUEO;
216 S_StartSound(NULL,sfx_oof);
221 case 134: // Red Lock
225 if (!p->cards[it_redcard] && !p->cards[it_redskull])
227 p->message = PD_REDO;
228 S_StartSound(NULL,sfx_oof);
233 case 136: // Yellow Lock
237 if (!p->cards[it_yellowcard] &&
238 !p->cards[it_yellowskull])
240 p->message = PD_YELLOWO;
241 S_StartSound(NULL,sfx_oof);
247 return EV_DoDoor(line,type);
263 while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
265 sec = §ors[secnum];
266 if (sec->specialdata)
272 door = Z_Malloc (sizeof(*door), PU_LEVSPEC, 0);
273 P_AddThinker (&door->thinker);
274 sec->specialdata = door;
276 door->thinker.function = T_VerticalDoor;
279 door->topwait = VDOORWAIT;
280 door->speed = VDOORSPEED;
285 door->topheight = P_FindLowestCeilingSurrounding(sec);
286 door->topheight -= 4*FRACUNIT;
287 door->direction = -1;
288 door->speed = VDOORSPEED * 4;
289 S_StartSound((mobj_t *)&door->sector->soundorg,
294 door->topheight = P_FindLowestCeilingSurrounding(sec);
295 door->topheight -= 4*FRACUNIT;
296 door->direction = -1;
297 S_StartSound((mobj_t *)&door->sector->soundorg,
301 case Close30ThenOpen:
302 door->topheight = sec->ceilingheight;
303 door->direction = -1;
304 S_StartSound((mobj_t *)&door->sector->soundorg,
311 door->topheight = P_FindLowestCeilingSurrounding(sec);
312 door->topheight -= 4*FRACUNIT;
313 door->speed = VDOORSPEED * 4;
314 if (door->topheight != sec->ceilingheight)
315 S_StartSound((mobj_t *)&door->sector->soundorg,
322 door->topheight = P_FindLowestCeilingSurrounding(sec);
323 door->topheight -= 4*FRACUNIT;
324 if (door->topheight != sec->ceilingheight)
325 S_StartSound((mobj_t *)&door->sector->soundorg,
339 // EV_VerticalDoor : open a door manually, no tag value
351 side = 0; // only front sides can be used
354 player = thing->player;
356 switch(line->special)
358 case 26: // Blue Lock
363 if (!player->cards[it_bluecard] && !player->cards[it_blueskull])
365 player->message = PD_BLUEK;
366 S_StartSound(NULL,sfx_oof);
371 case 27: // Yellow Lock
376 if (!player->cards[it_yellowcard] &&
377 !player->cards[it_yellowskull])
379 player->message = PD_YELLOWK;
380 S_StartSound(NULL,sfx_oof);
390 if (!player->cards[it_redcard] && !player->cards[it_redskull])
392 player->message = PD_REDK;
393 S_StartSound(NULL,sfx_oof);
399 // if the sector has an active thinker, use it
400 sec = sides[ line->sidenum[side^1]] .sector;
402 if (sec->specialdata)
404 door = sec->specialdata;
405 switch(line->special)
407 case 1: // ONLY FOR "RAISE" DOORS, NOT "OPEN"s
412 if (door->direction == -1)
413 door->direction = 1; // go back up
417 return; // JDC: bad guys never close doors
419 door->direction = -1; // start going down immediately
426 switch(line->special)
428 case 117: // BLAZING DOOR RAISE
429 case 118: // BLAZING DOOR OPEN
430 S_StartSound((mobj_t *)&sec->soundorg,sfx_bdopn);
433 case 1: // NORMAL DOOR SOUND
435 S_StartSound((mobj_t *)&sec->soundorg,sfx_doropn);
438 default: // LOCKED DOOR SOUND
439 S_StartSound((mobj_t *)&sec->soundorg,sfx_doropn);
445 door = Z_Malloc (sizeof(*door), PU_LEVSPEC, 0);
446 P_AddThinker (&door->thinker);
447 sec->specialdata = door;
448 door->thinker.function = T_VerticalDoor;
451 door->speed = VDOORSPEED;
452 door->topwait = VDOORWAIT;
454 switch(line->special)
471 case 117: // blazing door raise
472 door->type = BlazeRaise;
473 door->speed = VDOORSPEED*4;
475 case 118: // blazing door open
476 door->type = BlazeOpen;
478 door->speed = VDOORSPEED*4;
482 // find the top and bottom of the movement range
483 door->topheight = P_FindLowestCeilingSurrounding(sec);
484 door->topheight -= 4*FRACUNIT;
489 // Spawn a door that closes after 30 seconds
491 void P_SpawnDoorCloseIn30 (sector_t* sec)
495 door = Z_Malloc ( sizeof(*door), PU_LEVSPEC, 0);
497 P_AddThinker (&door->thinker);
499 sec->specialdata = door;
502 door->thinker.function = T_VerticalDoor;
506 door->speed = VDOORSPEED;
507 door->topcountdown = 30 * 35;
511 // Spawn a door that opens after 5 minutes
514 P_SpawnDoorRaiseIn5Mins
519 door = Z_Malloc ( sizeof(*door), PU_LEVSPEC, 0);
521 P_AddThinker (&door->thinker);
523 sec->specialdata = door;
526 door->thinker.function = T_VerticalDoor;
529 door->type = RaiseIn5Mins;
530 door->speed = VDOORSPEED;
531 door->topheight = P_FindLowestCeilingSurrounding(sec);
532 door->topheight -= 4*FRACUNIT;
533 door->topwait = VDOORWAIT;
534 door->topcountdown = 5 * 60 * 35;