home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #2 / amigaacscoverdisc1998-021998.iso / games / doom / source / linuxdoom-1.10 / p_floor.c < prev    next >
C/C++ Source or Header  |  1997-12-22  |  11KB  |  556 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:
  20. //    Floor animation: raising stairs.
  21. //
  22. //-----------------------------------------------------------------------------
  23.  
  24. static const char
  25. rcsid[] = "$Id: p_floor.c,v 1.4 1997/02/03 16:47:54 b1 Exp $";
  26.  
  27.  
  28. #include "z_zone.h"
  29. #include "doomdef.h"
  30. #include "p_local.h"
  31.  
  32. #include "s_sound.h"
  33.  
  34. // State.
  35. #include "doomstat.h"
  36. #include "r_state.h"
  37. // Data.
  38. #include "sounds.h"
  39.  
  40.  
  41. //
  42. // FLOORS
  43. //
  44.  
  45. //
  46. // Move a plane (floor or ceiling) and check for crushing
  47. //
  48. result_e
  49. T_MovePlane
  50. ( sector_t*    sector,
  51.   fixed_t    speed,
  52.   fixed_t    dest,
  53.   boolean    crush,
  54.   int        floorOrCeiling,
  55.   int        direction )
  56. {
  57.     boolean    flag;
  58.     fixed_t    lastpos;
  59.     
  60.     switch(floorOrCeiling)
  61.     {
  62.       case 0:
  63.     // FLOOR
  64.     switch(direction)
  65.     {
  66.       case -1:
  67.         // DOWN
  68.         if (sector->floorheight - speed < dest)
  69.         {
  70.         lastpos = sector->floorheight;
  71.         sector->floorheight = dest;
  72.         flag = P_ChangeSector(sector,crush);
  73.         if (flag == true)
  74.         {
  75.             sector->floorheight =lastpos;
  76.             P_ChangeSector(sector,crush);
  77.             //return crushed;
  78.         }
  79.         return pastdest;
  80.         }
  81.         else
  82.         {
  83.         lastpos = sector->floorheight;
  84.         sector->floorheight -= speed;
  85.         flag = P_ChangeSector(sector,crush);
  86.         if (flag == true)
  87.         {
  88.             sector->floorheight = lastpos;
  89.             P_ChangeSector(sector,crush);
  90.             return crushed;
  91.         }
  92.         }
  93.         break;
  94.                         
  95.       case 1:
  96.         // UP
  97.         if (sector->floorheight + speed > dest)
  98.         {
  99.         lastpos = sector->floorheight;
  100.         sector->floorheight = dest;
  101.         flag = P_ChangeSector(sector,crush);
  102.         if (flag == true)
  103.         {
  104.             sector->floorheight = lastpos;
  105.             P_ChangeSector(sector,crush);
  106.             //return crushed;
  107.         }
  108.         return pastdest;
  109.         }
  110.         else
  111.         {
  112.         // COULD GET CRUSHED
  113.         lastpos = sector->floorheight;
  114.         sector->floorheight += speed;
  115.         flag = P_ChangeSector(sector,crush);
  116.         if (flag == true)
  117.         {
  118.             if (crush == true)
  119.             return crushed;
  120.             sector->floorheight = lastpos;
  121.             P_ChangeSector(sector,crush);
  122.             return crushed;
  123.         }
  124.         }
  125.         break;
  126.     }
  127.     break;
  128.                                     
  129.       case 1:
  130.     // CEILING
  131.     switch(direction)
  132.     {
  133.       case -1:
  134.         // DOWN
  135.         if (sector->ceilingheight - speed < dest)
  136.         {
  137.         lastpos = sector->ceilingheight;
  138.         sector->ceilingheight = dest;
  139.         flag = P_ChangeSector(sector,crush);
  140.  
  141.         if (flag == true)
  142.         {
  143.             sector->ceilingheight = lastpos;
  144.             P_ChangeSector(sector,crush);
  145.             //return crushed;
  146.         }
  147.         return pastdest;
  148.         }
  149.         else
  150.         {
  151.         // COULD GET CRUSHED
  152.         lastpos = sector->ceilingheight;
  153.         sector->ceilingheight -= speed;
  154.         flag = P_ChangeSector(sector,crush);
  155.  
  156.         if (flag == true)
  157.         {
  158.             if (crush == true)
  159.             return crushed;
  160.             sector->ceilingheight = lastpos;
  161.             P_ChangeSector(sector,crush);
  162.             return crushed;
  163.         }
  164.         }
  165.         break;
  166.                         
  167.       case 1:
  168.         // UP
  169.         if (sector->ceilingheight + speed > dest)
  170.         {
  171.         lastpos = sector->ceilingheight;
  172.         sector->ceilingheight = dest;
  173.         flag = P_ChangeSector(sector,crush);
  174.         if (flag == true)
  175.         {
  176.             sector->ceilingheight = lastpos;
  177.             P_ChangeSector(sector,crush);
  178.             //return crushed;
  179.         }
  180.         return pastdest;
  181.         }
  182.         else
  183.         {
  184.         lastpos = sector->ceilingheight;
  185.         sector->ceilingheight += speed;
  186.         flag = P_ChangeSector(sector,crush);
  187. // UNUSED
  188. #if 0
  189.         if (flag == true)
  190.         {
  191.             sector->ceilingheight = lastpos;
  192.             P_ChangeSector(sector,crush);
  193.             return crushed;
  194.         }
  195. #endif
  196.         }
  197.         break;
  198.     }
  199.     break;
  200.         
  201.     }
  202.     return ok;
  203. }
  204.  
  205.  
  206. //
  207. // MOVE A FLOOR TO IT'S DESTINATION (UP OR DOWN)
  208. //
  209. void T_MoveFloor(floormove_t* floor)
  210. {
  211.     result_e    res;
  212.     
  213.     res = T_MovePlane(floor->sector,
  214.               floor->speed,
  215.               floor->floordestheight,
  216.               floor->crush,0,floor->direction);
  217.     
  218.     if (!(leveltime&7))
  219.     S_StartSound((mobj_t *)&floor->sector->soundorg,
  220.              sfx_stnmov);
  221.     
  222.     if (res == pastdest)
  223.     {
  224.     floor->sector->specialdata = NULL;
  225.  
  226.     if (floor->direction == 1)
  227.     {
  228.         switch(floor->type)
  229.         {
  230.           case donutRaise:
  231.         floor->sector->special = floor->newspecial;
  232.         floor->sector->floorpic = floor->texture;
  233.           default:
  234.         break;
  235.         }
  236.     }
  237.     else if (floor->direction == -1)
  238.     {
  239.         switch(floor->type)
  240.         {
  241.           case lowerAndChange:
  242.         floor->sector->special = floor->newspecial;
  243.         floor->sector->floorpic = floor->texture;
  244.           default:
  245.         break;
  246.         }
  247.     }
  248.     P_RemoveThinker(&floor->thinker);
  249.  
  250.     S_StartSound((mobj_t *)&floor->sector->soundorg,
  251.              sfx_pstop);
  252.     }
  253.  
  254. }
  255.  
  256. //
  257. // HANDLE FLOOR TYPES
  258. //
  259. int
  260. EV_DoFloor
  261. ( line_t*    line,
  262.   floor_e    floortype )
  263. {
  264.     int            secnum;
  265.     int            rtn;
  266.     int            i;
  267.     sector_t*        sec;
  268.     floormove_t*    floor;
  269.  
  270.     secnum = -1;
  271.     rtn = 0;
  272.     while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
  273.     {
  274.     sec = §ors[secnum];
  275.         
  276.     // ALREADY MOVING?  IF SO, KEEP GOING...
  277.     if (sec->specialdata)
  278.         continue;
  279.     
  280.     // new floor thinker
  281.     rtn = 1;
  282.     floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0);
  283.     P_AddThinker (&floor->thinker);
  284.     sec->specialdata = floor;
  285.     floor->thinker.function.acp1 = (actionf_p1) T_MoveFloor;
  286.     floor->type = floortype;
  287.     floor->crush = false;
  288.  
  289.     switch(floortype)
  290.     {
  291.       case lowerFloor:
  292.         floor->direction = -1;
  293.         floor->sector = sec;
  294.         floor->speed = FLOORSPEED;
  295.         floor->floordestheight = 
  296.         P_FindHighestFloorSurrounding(sec);
  297.         break;
  298.  
  299.       case lowerFloorToLowest:
  300.         floor->direction = -1;
  301.         floor->sector = sec;
  302.         floor->speed = FLOORSPEED;
  303.         floor->floordestheight = 
  304.         P_FindLowestFloorSurrounding(sec);
  305.         break;
  306.  
  307.       case turboLower:
  308.         floor->direction = -1;
  309.         floor->sector = sec;
  310.         floor->speed = FLOORSPEED * 4;
  311.         floor->floordestheight = 
  312.         P_FindHighestFloorSurrounding(sec);
  313.         if (floor->floordestheight != sec->floorheight)
  314.         floor->floordestheight += 8*FRACUNIT;
  315.         break;
  316.  
  317.       case raiseFloorCrush:
  318.         floor->crush = true;
  319.       case raiseFloor:
  320.         floor->direction = 1;
  321.         floor->sector = sec;
  322.         floor->speed = FLOORSPEED;
  323.         floor->floordestheight = 
  324.         P_FindLowestCeilingSurrounding(sec);
  325.         if (floor->floordestheight > sec->ceilingheight)
  326.         floor->floordestheight = sec->ceilingheight;
  327.         floor->floordestheight -= (8*FRACUNIT)*
  328.         (floortype == raiseFloorCrush);
  329.         break;
  330.  
  331.       case raiseFloorTurbo:
  332.         floor->direction = 1;
  333.         floor->sector = sec;
  334.         floor->speed = FLOORSPEED*4;
  335.         floor->floordestheight = 
  336.         P_FindNextHighestFloor(sec,sec->floorheight);
  337.         break;
  338.  
  339.       case raiseFloorToNearest:
  340.         floor->direction = 1;
  341.         floor->sector = sec;
  342.         floor->speed = FLOORSPEED;
  343.         floor->floordestheight = 
  344.         P_FindNextHighestFloor(sec,sec->floorheight);
  345.         break;
  346.  
  347.       case raiseFloor24:
  348.         floor->direction = 1;
  349.         floor->sector = sec;
  350.         floor->speed = FLOORSPEED;
  351.         floor->floordestheight = floor->sector->floorheight +
  352.         24 * FRACUNIT;
  353.         break;
  354.       case raiseFloor512:
  355.         floor->direction = 1;
  356.         floor->sector = sec;
  357.         floor->speed = FLOORSPEED;
  358.         floor->floordestheight = floor->sector->floorheight +
  359.         512 * FRACUNIT;
  360.         break;
  361.  
  362.       case raiseFloor24AndChange:
  363.         floor->direction = 1;
  364.         floor->sector = sec;
  365.         floor->speed = FLOORSPEED;
  366.         floor->floordestheight = floor->sector->floorheight +
  367.         24 * FRACUNIT;
  368.         sec->floorpic = line->frontsector->floorpic;
  369.         sec->special = line->frontsector->special;
  370.         break;
  371.  
  372.       case raiseToTexture:
  373.       {
  374.           int    minsize = MAXINT;
  375.           side_t*    side;
  376.                 
  377.           floor->direction = 1;
  378.           floor->sector = sec;
  379.           floor->speed = FLOORSPEED;
  380.           for (i = 0; i < sec->linecount; i++)
  381.           {
  382.           if (twoSided (secnum, i) )
  383.           {
  384.               side = getSide(secnum,i,0);
  385.               if (side->bottomtexture >= 0)
  386.               if (textureheight[side->bottomtexture] < 
  387.                   minsize)
  388.                   minsize = 
  389.                   textureheight[side->bottomtexture];
  390.               side = getSide(secnum,i,1);
  391.               if (side->bottomtexture >= 0)
  392.               if (textureheight[side->bottomtexture] < 
  393.                   minsize)
  394.                   minsize = 
  395.                   textureheight[side->bottomtexture];
  396.           }
  397.           }
  398.           floor->floordestheight =
  399.           floor->sector->floorheight + minsize;
  400.       }
  401.       break;
  402.       
  403.       case lowerAndChange:
  404.         floor->direction = -1;
  405.         floor->sector = sec;
  406.         floor->speed = FLOORSPEED;
  407.         floor->floordestheight = 
  408.         P_FindLowestFloorSurrounding(sec);
  409.         floor->texture = sec->floorpic;
  410.  
  411.         for (i = 0; i < sec->linecount; i++)
  412.         {
  413.         if ( twoSided(secnum, i) )
  414.         {
  415.             if (getSide(secnum,i,0)->sector-sectors == secnum)
  416.             {
  417.             sec = getSector(secnum,i,1);
  418.  
  419.             if (sec->floorheight == floor->floordestheight)
  420.             {
  421.                 floor->texture = sec->floorpic;
  422.                 floor->newspecial = sec->special;
  423.                 break;
  424.             }
  425.             }
  426.             else
  427.             {
  428.             sec = getSector(secnum,i,0);
  429.  
  430.             if (sec->floorheight == floor->floordestheight)
  431.             {
  432.                 floor->texture = sec->floorpic;
  433.                 floor->newspecial = sec->special;
  434.                 break;
  435.             }
  436.             }
  437.         }
  438.         }
  439.       default:
  440.         break;
  441.     }
  442.     }
  443.     return rtn;
  444. }
  445.  
  446.  
  447.  
  448.  
  449. //
  450. // BUILD A STAIRCASE!
  451. //
  452. int
  453. EV_BuildStairs
  454. ( line_t*    line,
  455.   stair_e    type )
  456. {
  457.     int            secnum;
  458.     int            height;
  459.     int            i;
  460.     int            newsecnum;
  461.     int            texture;
  462.     int            ok;
  463.     int            rtn;
  464.     
  465.     sector_t*        sec;
  466.     sector_t*        tsec;
  467.  
  468.     floormove_t*    floor;
  469.     
  470.     fixed_t        stairsize;
  471.     fixed_t        speed;
  472.  
  473.     secnum = -1;
  474.     rtn = 0;
  475.     while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
  476.     {
  477.     sec = §ors[secnum];
  478.         
  479.     // ALREADY MOVING?  IF SO, KEEP GOING...
  480.     if (sec->specialdata)
  481.         continue;
  482.     
  483.     // new floor thinker
  484.     rtn = 1;
  485.     floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0);
  486.     P_AddThinker (&floor->thinker);
  487.     sec->specialdata = floor;
  488.     floor->thinker.function.acp1 = (actionf_p1) T_MoveFloor;
  489.     floor->direction = 1;
  490.     floor->sector = sec;
  491.     switch(type)
  492.     {
  493.       case build8:
  494.         speed = FLOORSPEED/4;
  495.         stairsize = 8*FRACUNIT;
  496.         break;
  497.       case turbo16:
  498.         speed = FLOORSPEED*4;
  499.         stairsize = 16*FRACUNIT;
  500.         break;
  501.     }
  502.     floor->speed = speed;
  503.     height = sec->floorheight + stairsize;
  504.     floor->floordestheight = height;
  505.         
  506.     texture = sec->floorpic;
  507.     
  508.     // Find next sector to raise
  509.     // 1.    Find 2-sided line with same sector side[0]
  510.     // 2.    Other side is the next sector to raise
  511.     do
  512.     {
  513.         ok = 0;
  514.         for (i = 0;i < sec->linecount;i++)
  515.         {
  516.         if ( !((sec->lines[i])->flags & ML_TWOSIDED) )
  517.             continue;
  518.                     
  519.         tsec = (sec->lines[i])->frontsector;
  520.         newsecnum = tsec-sectors;
  521.         
  522.         if (secnum != newsecnum)
  523.             continue;
  524.  
  525.         tsec = (sec->lines[i])->backsector;
  526.         newsecnum = tsec - sectors;
  527.  
  528.         if (tsec->floorpic != texture)
  529.             continue;
  530.                     
  531.         height += stairsize;
  532.  
  533.         if (tsec->specialdata)
  534.             continue;
  535.                     
  536.         sec = tsec;
  537.         secnum = newsecnum;
  538.         floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0);
  539.  
  540.         P_AddThinker (&floor->thinker);
  541.  
  542.         sec->specialdata = floor;
  543.         floor->thinker.function.acp1 = (actionf_p1) T_MoveFloor;
  544.         floor->direction = 1;
  545.         floor->sector = sec;
  546.         floor->speed = speed;
  547.         floor->floordestheight = height;
  548.         ok = 1;
  549.         break;
  550.         }
  551.     } while(ok);
  552.     }
  553.     return rtn;
  554. }
  555.  
  556.