P_FLOOR.C 10 KB

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