Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  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 = &sectors[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 = &sectors[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.