set the include directory
[AROS-Contrib.git] / Games / Doom / p_doors.c
blob03c7eda815b65afcf826fce56088c4ec09ac8c5d
1 // Emacs style mode select -*- C++ -*-
2 //-----------------------------------------------------------------------------
3 //
4 // $Id$
5 //
6 // Copyright (C) 1993-1996 by id Software, Inc.
7 //
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
15 // for more details.
17 // $Log$
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 //-----------------------------------------------------------------------------
26 static const char
27 rcsid[] = "$Id$";
30 #include "z_zone.h"
31 #include "doomdef.h"
32 #include "p_local.h"
34 #include "s_sound.h"
37 // State.
38 #include "doomstat.h"
39 #include "r_state.h"
41 // Data.
42 #include "dstrings.h"
43 #include "sounds.h"
45 #if 0
47 // Sliding door frame information
49 slidename_t slideFrameNames[MAXSLIDEDOORS] =
51 {"GDOORF1","GDOORF2","GDOORF3","GDOORF4", // front
52 "GDOORB1","GDOORB2","GDOORB3","GDOORB4"}, // back
54 {"\0","\0","\0","\0"}
56 #endif
60 // VERTICAL DOORS
64 // T_VerticalDoor
66 void T_VerticalDoor (vldoor_t* door)
68 result_e res;
70 switch(door->direction)
72 case 0:
73 // WAITING
74 if (!--door->topcountdown)
76 switch(door->type)
78 case blazeRaise:
79 door->direction = -1; // time to go back down
80 S_StartSound((mobj_t *)&door->sector->soundorg,
81 sfx_bdcls);
82 break;
84 case normal:
85 door->direction = -1; // time to go back down
86 S_StartSound((mobj_t *)&door->sector->soundorg,
87 sfx_dorcls);
88 break;
90 case close30ThenOpen:
91 door->direction = 1;
92 S_StartSound((mobj_t *)&door->sector->soundorg,
93 sfx_doropn);
94 break;
96 default:
97 break;
100 break;
102 case 2:
103 // INITIAL WAIT
104 if (!--door->topcountdown)
106 switch(door->type)
108 case raiseIn5Mins:
109 door->direction = 1;
110 door->type = normal;
111 S_StartSound((mobj_t *)&door->sector->soundorg,
112 sfx_doropn);
113 break;
115 default:
116 break;
119 break;
121 case -1:
122 // DOWN
123 res = T_MovePlane(door->sector,
124 door->speed,
125 door->sector->floorheight,
126 false,1,door->direction);
127 if (res == pastdest)
129 switch(door->type)
131 case blazeRaise:
132 case blazeClose:
133 door->sector->specialdata = NULL;
134 P_RemoveThinker (&door->thinker); // unlink and free
135 S_StartSound((mobj_t *)&door->sector->soundorg,
136 sfx_bdcls);
137 break;
139 case normal:
140 case close:
141 door->sector->specialdata = NULL;
142 P_RemoveThinker (&door->thinker); // unlink and free
143 break;
145 case close30ThenOpen:
146 door->direction = 0;
147 door->topcountdown = 35*30;
148 break;
150 default:
151 break;
154 else if (res == crushed)
156 switch(door->type)
158 case blazeClose:
159 case close: // DO NOT GO BACK UP!
160 break;
162 default:
163 door->direction = 1;
164 S_StartSound((mobj_t *)&door->sector->soundorg,
165 sfx_doropn);
166 break;
169 break;
171 case 1:
172 // UP
173 res = T_MovePlane(door->sector,
174 door->speed,
175 door->topheight,
176 false,1,door->direction);
178 if (res == pastdest)
180 switch(door->type)
182 case blazeRaise:
183 case normal:
184 door->direction = 0; // wait at top
185 door->topcountdown = door->topwait;
186 break;
188 case close30ThenOpen:
189 case blazeOpen:
190 case open:
191 door->sector->specialdata = NULL;
192 P_RemoveThinker (&door->thinker); // unlink and free
193 break;
195 default:
196 break;
199 break;
205 // EV_DoLockedDoor
206 // Move a locked door up/down
210 EV_DoLockedDoor
211 ( line_t* line,
212 vldoor_e type,
213 mobj_t* thing )
215 player_t* p;
217 p = thing->player;
219 if (!p)
220 return 0;
222 switch(line->special)
224 case 99: // Blue Lock
225 case 133:
226 if ( !p )
227 return 0;
228 if (!p->cards[it_bluecard] && !p->cards[it_blueskull])
230 p->message = PD_BLUEO;
231 S_StartSound(NULL,sfx_oof);
232 return 0;
234 break;
236 case 134: // Red Lock
237 case 135:
238 if ( !p )
239 return 0;
240 if (!p->cards[it_redcard] && !p->cards[it_redskull])
242 p->message = PD_REDO;
243 S_StartSound(NULL,sfx_oof);
244 return 0;
246 break;
248 case 136: // Yellow Lock
249 case 137:
250 if ( !p )
251 return 0;
252 if (!p->cards[it_yellowcard] &&
253 !p->cards[it_yellowskull])
255 p->message = PD_YELLOWO;
256 S_StartSound(NULL,sfx_oof);
257 return 0;
259 break;
262 return EV_DoDoor(line,type);
267 EV_DoDoor
268 ( line_t* line,
269 vldoor_e type )
271 int secnum,rtn;
272 sector_t* sec;
273 vldoor_t* door;
275 secnum = -1;
276 rtn = 0;
278 while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
280 sec = &sectors[secnum];
281 if (sec->specialdata)
282 continue;
285 // new door thinker
286 rtn = 1;
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;
292 door->sector = sec;
293 door->type = type;
294 door->topwait = VDOORWAIT;
295 door->speed = VDOORSPEED;
297 switch(type)
299 case blazeClose:
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,
305 sfx_bdcls);
306 break;
308 case close:
309 door->topheight = P_FindLowestCeilingSurrounding(sec);
310 door->topheight -= 4*FRACUNIT;
311 door->direction = -1;
312 S_StartSound((mobj_t *)&door->sector->soundorg,
313 sfx_dorcls);
314 break;
316 case close30ThenOpen:
317 door->topheight = sec->ceilingheight;
318 door->direction = -1;
319 S_StartSound((mobj_t *)&door->sector->soundorg,
320 sfx_dorcls);
321 break;
323 case blazeRaise:
324 case blazeOpen:
325 door->direction = 1;
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,
331 sfx_bdopn);
332 break;
334 case normal:
335 case open:
336 door->direction = 1;
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,
341 sfx_doropn);
342 break;
344 default:
345 break;
349 return rtn;
354 // EV_VerticalDoor : open a door manually, no tag value
356 void
357 EV_VerticalDoor
358 ( line_t* line,
359 mobj_t* thing )
361 player_t* player;
362 int secnum;
363 sector_t* sec;
364 vldoor_t* door;
365 int side;
367 side = 0; // only front sides can be used
369 // Check for locks
370 player = thing->player;
372 switch(line->special)
374 case 26: // Blue Lock
375 case 32:
376 if ( !player )
377 return;
379 if (!player->cards[it_bluecard] && !player->cards[it_blueskull])
381 player->message = PD_BLUEK;
382 S_StartSound(NULL,sfx_oof);
383 return;
385 break;
387 case 27: // Yellow Lock
388 case 34:
389 if ( !player )
390 return;
392 if (!player->cards[it_yellowcard] &&
393 !player->cards[it_yellowskull])
395 player->message = PD_YELLOWK;
396 S_StartSound(NULL,sfx_oof);
397 return;
399 break;
401 case 28: // Red Lock
402 case 33:
403 if ( !player )
404 return;
406 if (!player->cards[it_redcard] && !player->cards[it_redskull])
408 player->message = PD_REDK;
409 S_StartSound(NULL,sfx_oof);
410 return;
412 break;
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
425 case 26:
426 case 27:
427 case 28:
428 case 117:
429 if (door->direction == -1)
430 door->direction = 1; // go back up
431 else
433 if (!thing->player)
434 return; // JDC: bad guys never close doors
436 door->direction = -1; // start going down immediately
438 return;
442 // for proper sound
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);
448 break;
450 case 1: // NORMAL DOOR SOUND
451 case 31:
452 S_StartSound((mobj_t *)&sec->soundorg,sfx_doropn);
453 break;
455 default: // LOCKED DOOR SOUND
456 S_StartSound((mobj_t *)&sec->soundorg,sfx_doropn);
457 break;
461 // new door thinker
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;
466 door->sector = sec;
467 door->direction = 1;
468 door->speed = VDOORSPEED;
469 door->topwait = VDOORWAIT;
471 switch(line->special)
473 case 1:
474 case 26:
475 case 27:
476 case 28:
477 door->type = normal;
478 break;
480 case 31:
481 case 32:
482 case 33:
483 case 34:
484 door->type = open;
485 line->special = 0;
486 break;
488 case 117: // blazing door raise
489 door->type = blazeRaise;
490 door->speed = VDOORSPEED*4;
491 break;
492 case 118: // blazing door open
493 door->type = blazeOpen;
494 line->special = 0;
495 door->speed = VDOORSPEED*4;
496 break;
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)
510 vldoor_t* door;
512 door = Z_Malloc ( sizeof(*door), PU_LEVSPEC, 0);
514 P_AddThinker (&door->thinker);
516 sec->specialdata = door;
517 sec->special = 0;
519 door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor;
520 door->sector = sec;
521 door->direction = 0;
522 door->type = normal;
523 door->speed = VDOORSPEED;
524 door->topcountdown = 30 * 35;
528 // Spawn a door that opens after 5 minutes
530 void
531 P_SpawnDoorRaiseIn5Mins
532 ( sector_t* sec,
533 int secnum )
535 vldoor_t* door;
537 door = Z_Malloc ( sizeof(*door), PU_LEVSPEC, 0);
539 P_AddThinker (&door->thinker);
541 sec->specialdata = door;
542 sec->special = 0;
544 door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor;
545 door->sector = sec;
546 door->direction = 2;
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;
557 // UNUSED
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)
571 int i;
572 int f1;
573 int f2;
574 int f3;
575 int f4;
577 // DOOM II ONLY...
578 if ( gamemode != commercial)
579 return;
581 for (i = 0;i < MAXSLIDEDOORS; i++)
583 if (!slideFrameNames[i].frontFrame1[0])
584 break;
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)
615 int i;
616 int val;
618 for (i = 0;i < MAXSLIDEDOORS;i++)
620 val = sides[line->sidenum[0]].midtexture;
621 if (val == slideFrames[i].frontFrames[0])
622 return i;
625 return -1;
628 void T_SlidingDoor (slidedoor_t* door)
630 switch(door->status)
632 case sd_opening:
633 if (!door->timer--)
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);
646 break;
649 door->timer = SDOORWAIT;
650 door->status = sd_waiting;
652 else
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];
665 break;
667 case sd_waiting:
668 // IF DOOR IS DONE WAITING...
669 if (!door->timer--)
671 // CAN DOOR CLOSE?
672 if (door->frontsector->thinglist != NULL ||
673 door->backsector->thinglist != NULL)
675 door->timer = SDOORWAIT;
676 break;
679 //door->frame = SNUMFRAMES-1;
680 door->status = sd_closing;
681 door->timer = SWAITTICS;
683 break;
685 case sd_closing:
686 if (!door->timer--)
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);
694 break;
696 else
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];
709 break;
715 void
716 EV_SlidingDoor
717 ( line_t* line,
718 mobj_t* thing )
720 sector_t* sec;
721 slidedoor_t* door;
723 // DOOM II ONLY...
724 if (gamemode != commercial)
725 return;
727 // Make sure door isn't already being animated
728 sec = line->frontsector;
729 door = NULL;
730 if (sec->specialdata)
732 if (!thing->player)
733 return;
735 door = sec->specialdata;
736 if (door->type == sdt_openAndClose)
738 if (door->status == sd_waiting)
739 door->status = sd_closing;
741 else
742 return;
745 // Init sliding door vars
746 if (!door)
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;
763 door->frame = 0;
764 door->line = line;
767 #endif