p_floor.c
上传用户:xuyinpeng
上传日期:2021-05-12
资源大小:455k
文件大小:12k
源码类别:

射击游戏

开发平台:

Visual C++

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