home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #2 / amigaacscoverdisc1998-021998.iso / games / doom / source / linuxdoom-1.10 / p_doors.c < prev    next >
C/C++ Source or Header  |  1997-12-22  |  15KB  |  765 lines

  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.
  11. //
  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.
  16. //
  17. // $Log:$
  18. //
  19. // DESCRIPTION: Door animation code (opening/closing)
  20. //
  21. //-----------------------------------------------------------------------------
  22.  
  23. static const char
  24. rcsid[] = "$Id: p_doors.c,v 1.4 1997/02/03 16:47:53 b1 Exp $";
  25.  
  26.  
  27. #include "z_zone.h"
  28. #include "doomdef.h"
  29. #include "p_local.h"
  30.  
  31. #include "s_sound.h"
  32.  
  33.  
  34. // State.
  35. #include "doomstat.h"
  36. #include "r_state.h"
  37.  
  38. // Data.
  39. #include "dstrings.h"
  40. #include "sounds.h"
  41.  
  42. #if 0
  43. //
  44. // Sliding door frame information
  45. //
  46. slidename_t    slideFrameNames[MAXSLIDEDOORS] =
  47. {
  48.     {"GDOORF1","GDOORF2","GDOORF3","GDOORF4",    // front
  49.      "GDOORB1","GDOORB2","GDOORB3","GDOORB4"},    // back
  50.      
  51.     {"\0","\0","\0","\0"}
  52. };
  53. #endif
  54.  
  55.  
  56. //
  57. // VERTICAL DOORS
  58. //
  59.  
  60. //
  61. // T_VerticalDoor
  62. //
  63. void T_VerticalDoor (vldoor_t* door)
  64. {
  65.     result_e    res;
  66.     
  67.     switch(door->direction)
  68.     {
  69.       case 0:
  70.     // WAITING
  71.     if (!--door->topcountdown)
  72.     {
  73.         switch(door->type)
  74.         {
  75.           case blazeRaise:
  76.         door->direction = -1; // time to go back down
  77.         S_StartSound((mobj_t *)&door->sector->soundorg,
  78.                  sfx_bdcls);
  79.         break;
  80.         
  81.           case normal:
  82.         door->direction = -1; // time to go back down
  83.         S_StartSound((mobj_t *)&door->sector->soundorg,
  84.                  sfx_dorcls);
  85.         break;
  86.         
  87.           case close30ThenOpen:
  88.         door->direction = 1;
  89.         S_StartSound((mobj_t *)&door->sector->soundorg,
  90.                  sfx_doropn);
  91.         break;
  92.         
  93.           default:
  94.         break;
  95.         }
  96.     }
  97.     break;
  98.     
  99.       case 2:
  100.     //  INITIAL WAIT
  101.     if (!--door->topcountdown)
  102.     {
  103.         switch(door->type)
  104.         {
  105.           case raiseIn5Mins:
  106.         door->direction = 1;
  107.         door->type = normal;
  108.         S_StartSound((mobj_t *)&door->sector->soundorg,
  109.                  sfx_doropn);
  110.         break;
  111.         
  112.           default:
  113.         break;
  114.         }
  115.     }
  116.     break;
  117.     
  118.       case -1:
  119.     // DOWN
  120.     res = T_MovePlane(door->sector,
  121.               door->speed,
  122.               door->sector->floorheight,
  123.               false,1,door->direction);
  124.     if (res == pastdest)
  125.     {
  126.         switch(door->type)
  127.         {
  128.           case blazeRaise:
  129.           case blazeClose:
  130.         door->sector->specialdata = NULL;
  131.         P_RemoveThinker (&door->thinker);  // unlink and free
  132.         S_StartSound((mobj_t *)&door->sector->soundorg,
  133.                  sfx_bdcls);
  134.         break;
  135.         
  136.           case normal:
  137.           case close:
  138.         door->sector->specialdata = NULL;
  139.         P_RemoveThinker (&door->thinker);  // unlink and free
  140.         break;
  141.         
  142.           case close30ThenOpen:
  143.         door->direction = 0;
  144.         door->topcountdown = 35*30;
  145.         break;
  146.         
  147.           default:
  148.         break;
  149.         }
  150.     }
  151.     else if (res == crushed)
  152.     {
  153.         switch(door->type)
  154.         {
  155.           case blazeClose:
  156.           case close:        // DO NOT GO BACK UP!
  157.         break;
  158.         
  159.           default:
  160.         door->direction = 1;
  161.         S_StartSound((mobj_t *)&door->sector->soundorg,
  162.                  sfx_doropn);
  163.         break;
  164.         }
  165.     }
  166.     break;
  167.     
  168.       case 1:
  169.     // UP
  170.     res = T_MovePlane(door->sector,
  171.               door->speed,
  172.               door->topheight,
  173.               false,1,door->direction);
  174.     
  175.     if (res == pastdest)
  176.     {
  177.         switch(door->type)
  178.         {
  179.           case blazeRaise:
  180.           case normal:
  181.         door->direction = 0; // wait at top
  182.         door->topcountdown = door->topwait;
  183.         break;
  184.         
  185.           case close30ThenOpen:
  186.           case blazeOpen:
  187.           case open:
  188.         door->sector->specialdata = NULL;
  189.         P_RemoveThinker (&door->thinker);  // unlink and free
  190.         break;
  191.         
  192.           default:
  193.         break;
  194.         }
  195.     }
  196.     break;
  197.     }
  198. }
  199.  
  200.  
  201. //
  202. // EV_DoLockedDoor
  203. // Move a locked door up/down
  204. //
  205.  
  206. int
  207. EV_DoLockedDoor
  208. ( line_t*    line,
  209.   vldoor_e    type,
  210.   mobj_t*    thing )
  211. {
  212.     player_t*    p;
  213.     
  214.     p = thing->player;
  215.     
  216.     if (!p)
  217.     return 0;
  218.         
  219.     switch(line->special)
  220.     {
  221.       case 99:    // Blue Lock
  222.       case 133:
  223.     if ( !p )
  224.         return 0;
  225.     if (!p->cards[it_bluecard] && !p->cards[it_blueskull])
  226.     {
  227.         p->message = PD_BLUEO;
  228.         S_StartSound(NULL,sfx_oof);
  229.         return 0;
  230.     }
  231.     break;
  232.     
  233.       case 134: // Red Lock
  234.       case 135:
  235.     if ( !p )
  236.         return 0;
  237.     if (!p->cards[it_redcard] && !p->cards[it_redskull])
  238.     {
  239.         p->message = PD_REDO;
  240.         S_StartSound(NULL,sfx_oof);
  241.         return 0;
  242.     }
  243.     break;
  244.     
  245.       case 136:    // Yellow Lock
  246.       case 137:
  247.     if ( !p )
  248.         return 0;
  249.     if (!p->cards[it_yellowcard] &&
  250.         !p->cards[it_yellowskull])
  251.     {
  252.         p->message = PD_YELLOWO;
  253.         S_StartSound(NULL,sfx_oof);
  254.         return 0;
  255.     }
  256.     break;    
  257.     }
  258.  
  259.     return EV_DoDoor(line,type);
  260. }
  261.  
  262.  
  263. int
  264. EV_DoDoor
  265. ( line_t*    line,
  266.   vldoor_e    type )
  267. {
  268.     int        secnum,rtn;
  269.     sector_t*    sec;
  270.     vldoor_t*    door;
  271.     
  272.     secnum = -1;
  273.     rtn = 0;
  274.     
  275.     while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
  276.     {
  277.     sec = §ors[secnum];
  278.     if (sec->specialdata)
  279.         continue;
  280.         
  281.     
  282.     // new door thinker
  283.     rtn = 1;
  284.     door = Z_Malloc (sizeof(*door), PU_LEVSPEC, 0);
  285.     P_AddThinker (&door->thinker);
  286.     sec->specialdata = door;
  287.  
  288.     door->thinker.function.acp1 = (actionf_p1) T_VerticalDoor;
  289.     door->sector = sec;
  290.     door->type = type;
  291.     door->topwait = VDOORWAIT;
  292.     door->speed = VDOORSPEED;
  293.         
  294.     switch(type)
  295.     {
  296.       case blazeClose:
  297.         door->topheight = P_FindLowestCeilingSurrounding(sec);
  298.         door->topheight -= 4*FRACUNIT;
  299.         door->direction = -1;
  300.         door->speed = VDOORSPEED * 4;
  301.         S_StartSound((mobj_t *)&door->sector->soundorg,
  302.              sfx_bdcls);
  303.         break;
  304.         
  305.       case close:
  306.         door->topheight = P_FindLowestCeilingSurrounding(sec);
  307.         door->topheight -= 4*FRACUNIT;
  308.         door->direction = -1;
  309.         S_StartSound((mobj_t *)&door->sector->soundorg,
  310.              sfx_dorcls);
  311.         break;
  312.         
  313.       case close30ThenOpen:
  314.         door->topheight = sec->ceilingheight;
  315.         door->direction = -1;
  316.         S_StartSound((mobj_t *)&door->sector->soundorg,
  317.              sfx_dorcls);
  318.         break;
  319.         
  320.       case blazeRaise:
  321.       case blazeOpen:
  322.         door->direction = 1;
  323.         door->topheight = P_FindLowestCeilingSurrounding(sec);
  324.         door->topheight -= 4*FRACUNIT;
  325.         door->speed = VDOORSPEED * 4;
  326.         if (door->topheight != sec->ceilingheight)
  327.         S_StartSound((mobj_t *)&door->sector->soundorg,
  328.                  sfx_bdopn);
  329.         break;
  330.         
  331.       case normal:
  332.       case open:
  333.         door->direction = 1;
  334.         door->topheight = P_FindLowestCeilingSurrounding(sec);
  335.         door->topheight -= 4*FRACUNIT;
  336.         if (door->topheight != sec->ceilingheight)
  337.         S_StartSound((mobj_t *)&door->sector->soundorg,
  338.                  sfx_doropn);
  339.         break;
  340.         
  341.       default:
  342.         break;
  343.     }
  344.         
  345.     }
  346.     return rtn;
  347. }
  348.  
  349.  
  350. //
  351. // EV_VerticalDoor : open a door manually, no tag value
  352. //
  353. void
  354. EV_VerticalDoor
  355. ( line_t*    line,
  356.   mobj_t*    thing )
  357. {
  358.     player_t*    player;
  359.     int        secnum;
  360.     sector_t*    sec;
  361.     vldoor_t*    door;
  362.     int        side;
  363.     
  364.     side = 0;    // only front sides can be used
  365.  
  366.     //    Check for locks
  367.     player = thing->player;
  368.         
  369.     switch(line->special)
  370.     {
  371.       case 26: // Blue Lock
  372.       case 32:
  373.     if ( !player )
  374.         return;
  375.     
  376.     if (!player->cards[it_bluecard] && !player->cards[it_blueskull])
  377.     {
  378.         player->message = PD_BLUEK;
  379.         S_StartSound(NULL,sfx_oof);
  380.         return;
  381.     }
  382.     break;
  383.     
  384.       case 27: // Yellow Lock
  385.       case 34:
  386.     if ( !player )
  387.         return;
  388.     
  389.     if (!player->cards[it_yellowcard] &&
  390.         !player->cards[it_yellowskull])
  391.     {
  392.         player->message = PD_YELLOWK;
  393.         S_StartSound(NULL,sfx_oof);
  394.         return;
  395.     }
  396.     break;
  397.     
  398.       case 28: // Red Lock
  399.       case 33:
  400.     if ( !player )
  401.         return;
  402.     
  403.     if (!player->cards[it_redcard] && !player->cards[it_redskull])
  404.     {
  405.         player->message = PD_REDK;
  406.         S_StartSound(NULL,sfx_oof);
  407.         return;
  408.     }
  409.     break;
  410.     }
  411.     
  412.     // if the sector has an active thinker, use it
  413.     sec = sides[ line->sidenum[side^1]] .sector;
  414.     secnum = sec-sectors;
  415.  
  416.     if (sec->specialdata)
  417.     {
  418.     door = sec->specialdata;
  419.     switch(line->special)
  420.     {
  421.       case    1: // ONLY FOR "RAISE" DOORS, NOT "OPEN"s
  422.       case    26:
  423.       case    27:
  424.       case    28:
  425.       case    117:
  426.         if (door->direction == -1)
  427.         door->direction = 1;    // go back up
  428.         else
  429.         {
  430.         if (!thing->player)
  431.             return;        // JDC: bad guys never close doors
  432.         
  433.         door->direction = -1;    // start going down immediately
  434.         }
  435.         return;
  436.     }
  437.     }
  438.     
  439.     // for proper sound
  440.     switch(line->special)
  441.     {
  442.       case 117:    // BLAZING DOOR RAISE
  443.       case 118:    // BLAZING DOOR OPEN
  444.     S_StartSound((mobj_t *)&sec->soundorg,sfx_bdopn);
  445.     break;
  446.     
  447.       case 1:    // NORMAL DOOR SOUND
  448.       case 31:
  449.     S_StartSound((mobj_t *)&sec->soundorg,sfx_doropn);
  450.     break;
  451.     
  452.       default:    // LOCKED DOOR SOUND
  453.     S_StartSound((mobj_t *)&sec->soundorg,sfx_doropn);
  454.     break;
  455.     }
  456.     
  457.     
  458.     // new door thinker
  459.     door = Z_Malloc (sizeof(*door), PU_LEVSPEC, 0);
  460.     P_AddThinker (&door->thinker);
  461.     sec->specialdata = door;
  462.     door->thinker.function.acp1 = (actionf_p1) T_VerticalDoor;
  463.     door->sector = sec;
  464.     door->direction = 1;
  465.     door->speed = VDOORSPEED;
  466.     door->topwait = VDOORWAIT;
  467.  
  468.     switch(line->special)
  469.     {
  470.       case 1:
  471.       case 26:
  472.       case 27:
  473.       case 28:
  474.     door->type = normal;
  475.     break;
  476.     
  477.       case 31:
  478.       case 32:
  479.       case 33:
  480.       case 34:
  481.     door->type = open;
  482.     line->special = 0;
  483.     break;
  484.     
  485.       case 117:    // blazing door raise
  486.     door->type = blazeRaise;
  487.     door->speed = VDOORSPEED*4;
  488.     break;
  489.       case 118:    // blazing door open
  490.     door->type = blazeOpen;
  491.     line->special = 0;
  492.     door->speed = VDOORSPEED*4;
  493.     break;
  494.     }
  495.     
  496.     // find the top and bottom of the movement range
  497.     door->topheight = P_FindLowestCeilingSurrounding(sec);
  498.     door->topheight -= 4*FRACUNIT;
  499. }
  500.  
  501.  
  502. //
  503. // Spawn a door that closes after 30 seconds
  504. //
  505. void P_SpawnDoorCloseIn30 (sector_t* sec)
  506. {
  507.     vldoor_t*    door;
  508.     
  509.     door = Z_Malloc ( sizeof(*door), PU_LEVSPEC, 0);
  510.  
  511.     P_AddThinker (&door->thinker);
  512.  
  513.     sec->specialdata = door;
  514.     sec->special = 0;
  515.  
  516.     door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor;
  517.     door->sector = sec;
  518.     door->direction = 0;
  519.     door->type = normal;
  520.     door->speed = VDOORSPEED;
  521.     door->topcountdown = 30 * 35;
  522. }
  523.  
  524. //
  525. // Spawn a door that opens after 5 minutes
  526. //
  527. void
  528. P_SpawnDoorRaiseIn5Mins
  529. ( sector_t*    sec,
  530.   int        secnum )
  531. {
  532.     vldoor_t*    door;
  533.     
  534.     door = Z_Malloc ( sizeof(*door), PU_LEVSPEC, 0);
  535.     
  536.     P_AddThinker (&door->thinker);
  537.  
  538.     sec->specialdata = door;
  539.     sec->special = 0;
  540.  
  541.     door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor;
  542.     door->sector = sec;
  543.     door->direction = 2;
  544.     door->type = raiseIn5Mins;
  545.     door->speed = VDOORSPEED;
  546.     door->topheight = P_FindLowestCeilingSurrounding(sec);
  547.     door->topheight -= 4*FRACUNIT;
  548.     door->topwait = VDOORWAIT;
  549.     door->topcountdown = 5 * 60 * 35;
  550. }
  551.  
  552.  
  553.  
  554. // UNUSED
  555. // Separate into p_slidoor.c?
  556.  
  557. #if 0        // ABANDONED TO THE MISTS OF TIME!!!
  558. //
  559. // EV_SlidingDoor : slide a door horizontally
  560. // (animate midtexture, then set noblocking line)
  561. //
  562.  
  563.  
  564. slideframe_t slideFrames[MAXSLIDEDOORS];
  565.  
  566. void P_InitSlidingDoorFrames(void)
  567. {
  568.     int        i;
  569.     int        f1;
  570.     int        f2;
  571.     int        f3;
  572.     int        f4;
  573.     
  574.     // DOOM II ONLY...
  575.     if ( gamemode != commercial)
  576.     return;
  577.     
  578.     for (i = 0;i < MAXSLIDEDOORS; i++)
  579.     {
  580.     if (!slideFrameNames[i].frontFrame1[0])
  581.         break;
  582.             
  583.     f1 = R_TextureNumForName(slideFrameNames[i].frontFrame1);
  584.     f2 = R_TextureNumForName(slideFrameNames[i].frontFrame2);
  585.     f3 = R_TextureNumForName(slideFrameNames[i].frontFrame3);
  586.     f4 = R_TextureNumForName(slideFrameNames[i].frontFrame4);
  587.  
  588.     slideFrames[i].frontFrames[0] = f1;
  589.     slideFrames[i].frontFrames[1] = f2;
  590.     slideFrames[i].frontFrames[2] = f3;
  591.     slideFrames[i].frontFrames[3] = f4;
  592.         
  593.     f1 = R_TextureNumForName(slideFrameNames[i].backFrame1);
  594.     f2 = R_TextureNumForName(slideFrameNames[i].backFrame2);
  595.     f3 = R_TextureNumForName(slideFrameNames[i].backFrame3);
  596.     f4 = R_TextureNumForName(slideFrameNames[i].backFrame4);
  597.  
  598.     slideFrames[i].backFrames[0] = f1;
  599.     slideFrames[i].backFrames[1] = f2;
  600.     slideFrames[i].backFrames[2] = f3;
  601.     slideFrames[i].backFrames[3] = f4;
  602.     }
  603. }
  604.  
  605.  
  606. //
  607. // Return index into "slideFrames" array
  608. // for which door type to use
  609. //
  610. int P_FindSlidingDoorType(line_t*    line)
  611. {
  612.     int        i;
  613.     int        val;
  614.     
  615.     for (i = 0;i < MAXSLIDEDOORS;i++)
  616.     {
  617.     val = sides[line->sidenum[0]].midtexture;
  618.     if (val == slideFrames[i].frontFrames[0])
  619.         return i;
  620.     }
  621.     
  622.     return -1;
  623. }
  624.  
  625. void T_SlidingDoor (slidedoor_t*    door)
  626. {
  627.     switch(door->status)
  628.     {
  629.       case sd_opening:
  630.     if (!door->timer--)
  631.     {
  632.         if (++door->frame == SNUMFRAMES)
  633.         {
  634.         // IF DOOR IS DONE OPENING...
  635.         sides[door->line->sidenum[0]].midtexture = 0;
  636.         sides[door->line->sidenum[1]].midtexture = 0;
  637.         door->line->flags &= ML_BLOCKING^0xff;
  638.                     
  639.         if (door->type == sdt_openOnly)
  640.         {
  641.             door->frontsector->specialdata = NULL;
  642.             P_RemoveThinker (&door->thinker);
  643.             break;
  644.         }
  645.                     
  646.         door->timer = SDOORWAIT;
  647.         door->status = sd_waiting;
  648.         }
  649.         else
  650.         {
  651.         // IF DOOR NEEDS TO ANIMATE TO NEXT FRAME...
  652.         door->timer = SWAITTICS;
  653.                     
  654.         sides[door->line->sidenum[0]].midtexture =
  655.             slideFrames[door->whichDoorIndex].
  656.             frontFrames[door->frame];
  657.         sides[door->line->sidenum[1]].midtexture =
  658.             slideFrames[door->whichDoorIndex].
  659.             backFrames[door->frame];
  660.         }
  661.     }
  662.     break;
  663.             
  664.       case sd_waiting:
  665.     // IF DOOR IS DONE WAITING...
  666.     if (!door->timer--)
  667.     {
  668.         // CAN DOOR CLOSE?
  669.         if (door->frontsector->thinglist != NULL ||
  670.         door->backsector->thinglist != NULL)
  671.         {
  672.         door->timer = SDOORWAIT;
  673.         break;
  674.         }
  675.  
  676.         //door->frame = SNUMFRAMES-1;
  677.         door->status = sd_closing;
  678.         door->timer = SWAITTICS;
  679.     }
  680.     break;
  681.             
  682.       case sd_closing:
  683.     if (!door->timer--)
  684.     {
  685.         if (--door->frame < 0)
  686.         {
  687.         // IF DOOR IS DONE CLOSING...
  688.         door->line->flags |= ML_BLOCKING;
  689.         door->frontsector->specialdata = NULL;
  690.         P_RemoveThinker (&door->thinker);
  691.         break;
  692.         }
  693.         else
  694.         {
  695.         // IF DOOR NEEDS TO ANIMATE TO NEXT FRAME...
  696.         door->timer = SWAITTICS;
  697.                     
  698.         sides[door->line->sidenum[0]].midtexture =
  699.             slideFrames[door->whichDoorIndex].
  700.             frontFrames[door->frame];
  701.         sides[door->line->sidenum[1]].midtexture =
  702.             slideFrames[door->whichDoorIndex].
  703.             backFrames[door->frame];
  704.         }
  705.     }
  706.     break;
  707.     }
  708. }
  709.  
  710.  
  711.  
  712. void
  713. EV_SlidingDoor
  714. ( line_t*    line,
  715.   mobj_t*    thing )
  716. {
  717.     sector_t*        sec;
  718.     slidedoor_t*    door;
  719.     
  720.     // DOOM II ONLY...
  721.     if (gamemode != commercial)
  722.     return;
  723.     
  724.     // Make sure door isn't already being animated
  725.     sec = line->frontsector;
  726.     door = NULL;
  727.     if (sec->specialdata)
  728.     {
  729.     if (!thing->player)
  730.         return;
  731.             
  732.     door = sec->specialdata;
  733.     if (door->type == sdt_openAndClose)
  734.     {
  735.         if (door->status == sd_waiting)
  736.         door->status = sd_closing;
  737.     }
  738.     else
  739.         return;
  740.     }
  741.     
  742.     // Init sliding door vars
  743.     if (!door)
  744.     {
  745.     door = Z_Malloc (sizeof(*door), PU_LEVSPEC, 0);
  746.     P_AddThinker (&door->thinker);
  747.     sec->specialdata = door;
  748.         
  749.     door->type = sdt_openAndClose;
  750.     door->status = sd_opening;
  751.     door->whichDoorIndex = P_FindSlidingDoorType(line);
  752.  
  753.     if (door->whichDoorIndex < 0)
  754.         I_Error("EV_SlidingDoor: Can't use texture for sliding door!");
  755.             
  756.     door->frontsector = sec;
  757.     door->backsector = line->backsector;
  758.     door->thinker.function = T_SlidingDoor;
  759.     door->timer = SWAITTICS;
  760.     door->frame = 0;
  761.     door->line = line;
  762.     }
  763. }
  764. #endif
  765.