p_doors.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  1. /*
  2. ===========================================================================
  3. Doom 3 BFG Edition GPL Source Code
  4. Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
  6. Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #include "Precompiled.h"
  21. #include "globaldata.h"
  22. #include "z_zone.h"
  23. #include "doomdef.h"
  24. #include "p_local.h"
  25. #include "s_sound.h"
  26. // State.
  27. #include "doomstat.h"
  28. #include "r_state.h"
  29. // Data.
  30. #include "dstrings.h"
  31. #include "sounds.h"
  32. extern bool globalNetworking;
  33. //
  34. // VERTICAL DOORS
  35. //
  36. //
  37. // T_VerticalDoor
  38. //
  39. void T_VerticalDoor (vldoor_t* door)
  40. {
  41. result_e res;
  42. switch(door->direction)
  43. {
  44. case 0:
  45. // WAITING
  46. if (!--door->topcountdown)
  47. {
  48. switch(door->type)
  49. {
  50. case blazeRaise:
  51. door->direction = -1; // time to go back down
  52. S_StartSound( &door->sector->soundorg,
  53. sfx_bdcls);
  54. break;
  55. case normal:
  56. door->direction = -1; // time to go back down
  57. S_StartSound( &door->sector->soundorg,
  58. sfx_dorcls);
  59. break;
  60. case close30ThenOpen:
  61. door->direction = 1;
  62. S_StartSound( &door->sector->soundorg,
  63. sfx_doropn);
  64. break;
  65. default:
  66. break;
  67. }
  68. }
  69. break;
  70. case 2:
  71. // INITIAL WAIT
  72. if (!--door->topcountdown)
  73. {
  74. switch(door->type)
  75. {
  76. case raiseIn5Mins:
  77. door->direction = 1;
  78. door->type = normal;
  79. S_StartSound( &door->sector->soundorg,
  80. sfx_doropn);
  81. break;
  82. default:
  83. break;
  84. }
  85. }
  86. break;
  87. case -1:
  88. // DOWN
  89. res = T_MovePlane(door->sector,
  90. door->speed,
  91. door->sector->floorheight,
  92. false,1,door->direction);
  93. if (res == pastdest)
  94. {
  95. switch(door->type)
  96. {
  97. case blazeRaise:
  98. case blazeClose:
  99. door->sector->specialdata = NULL;
  100. P_RemoveThinker (&door->thinker); // unlink and free
  101. S_StartSound( &door->sector->soundorg,
  102. sfx_bdcls);
  103. break;
  104. case normal:
  105. case closed:
  106. door->sector->specialdata = NULL;
  107. P_RemoveThinker (&door->thinker); // unlink and free
  108. break;
  109. case close30ThenOpen:
  110. door->direction = 0;
  111. door->topcountdown = TICRATE*30;
  112. break;
  113. default:
  114. break;
  115. }
  116. }
  117. else if (res == crushed)
  118. {
  119. switch(door->type)
  120. {
  121. case blazeClose:
  122. case closed: // DO NOT GO BACK UP!
  123. break;
  124. default:
  125. door->direction = 1;
  126. S_StartSound( &door->sector->soundorg,
  127. sfx_doropn);
  128. break;
  129. }
  130. }
  131. break;
  132. case 1:
  133. // UP
  134. res = T_MovePlane(door->sector,
  135. door->speed,
  136. door->topheight,
  137. false,1,door->direction);
  138. if (res == pastdest)
  139. {
  140. switch(door->type)
  141. {
  142. case blazeRaise:
  143. case normal:
  144. door->direction = 0; // wait at top
  145. door->topcountdown = door->topwait;
  146. break;
  147. case close30ThenOpen:
  148. case blazeOpen:
  149. case opened:
  150. door->sector->specialdata = NULL;
  151. P_RemoveThinker (&door->thinker); // unlink and free
  152. break;
  153. default:
  154. break;
  155. }
  156. }
  157. break;
  158. }
  159. }
  160. //
  161. // EV_DoLockedDoor
  162. // Move a locked door up/down
  163. //
  164. int
  165. EV_DoLockedDoor
  166. ( line_t* line,
  167. vldoor_e type,
  168. mobj_t* thing )
  169. {
  170. player_t* p;
  171. p = thing->player;
  172. if (!p)
  173. return 0;
  174. switch(line->special)
  175. {
  176. case 99: // Blue Lock
  177. case 133:
  178. if ( !p )
  179. return 0;
  180. if (!p->cards[it_bluecard] && !p->cards[it_blueskull])
  181. {
  182. p->message = PD_BLUEO;
  183. if (p == &::g->players[::g->consoleplayer])
  184. S_StartSound(NULL,sfx_oof);
  185. return 0;
  186. }
  187. break;
  188. case 134: // Red Lock
  189. case 135:
  190. if ( !p )
  191. return 0;
  192. if (!p->cards[it_redcard] && !p->cards[it_redskull])
  193. {
  194. p->message = PD_REDO;
  195. if (p == &::g->players[::g->consoleplayer])
  196. S_StartSound(NULL,sfx_oof);
  197. return 0;
  198. }
  199. break;
  200. case 136: // Yellow Lock
  201. case 137:
  202. if ( !p )
  203. return 0;
  204. if (!p->cards[it_yellowcard] &&
  205. !p->cards[it_yellowskull])
  206. {
  207. p->message = PD_YELLOWO;
  208. if (p == &::g->players[::g->consoleplayer])
  209. S_StartSound(NULL,sfx_oof);
  210. return 0;
  211. }
  212. break;
  213. }
  214. return EV_DoDoor(line,type);
  215. }
  216. int
  217. EV_DoDoor
  218. ( line_t* line,
  219. vldoor_e type )
  220. {
  221. int secnum,rtn;
  222. sector_t* sec;
  223. vldoor_t* door;
  224. secnum = -1;
  225. rtn = 0;
  226. while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
  227. {
  228. sec = &::g->sectors[secnum];
  229. if (sec->specialdata)
  230. continue;
  231. // new door thinker
  232. rtn = 1;
  233. door = (vldoor_t*)DoomLib::Z_Malloc(sizeof(*door), PU_LEVEL, 0);
  234. P_AddThinker (&door->thinker);
  235. sec->specialdata = door;
  236. door->thinker.function.acp1 = (actionf_p1) T_VerticalDoor;
  237. door->sector = sec;
  238. door->type = type;
  239. door->topwait = VDOORWAIT;
  240. door->speed = VDOORSPEED;
  241. switch(type)
  242. {
  243. case blazeClose:
  244. door->topheight = P_FindLowestCeilingSurrounding(sec);
  245. door->topheight -= 4*FRACUNIT;
  246. door->direction = -1;
  247. door->speed = VDOORSPEED * 4;
  248. S_StartSound( &door->sector->soundorg,
  249. sfx_bdcls);
  250. break;
  251. case closed:
  252. door->topheight = P_FindLowestCeilingSurrounding(sec);
  253. door->topheight -= 4*FRACUNIT;
  254. door->direction = -1;
  255. S_StartSound( &door->sector->soundorg,
  256. sfx_dorcls);
  257. break;
  258. case close30ThenOpen:
  259. door->topheight = sec->ceilingheight;
  260. door->direction = -1;
  261. S_StartSound( &door->sector->soundorg,
  262. sfx_dorcls);
  263. break;
  264. case blazeRaise:
  265. case blazeOpen:
  266. door->direction = 1;
  267. door->topheight = P_FindLowestCeilingSurrounding(sec);
  268. door->topheight -= 4*FRACUNIT;
  269. door->speed = VDOORSPEED * 4;
  270. if (door->topheight != sec->ceilingheight)
  271. S_StartSound( &door->sector->soundorg,
  272. sfx_bdopn);
  273. break;
  274. case normal:
  275. case opened:
  276. door->direction = 1;
  277. door->topheight = P_FindLowestCeilingSurrounding(sec);
  278. door->topheight -= 4*FRACUNIT;
  279. if (door->topheight != sec->ceilingheight)
  280. S_StartSound( &door->sector->soundorg,
  281. sfx_doropn);
  282. break;
  283. default:
  284. break;
  285. }
  286. }
  287. return rtn;
  288. }
  289. //
  290. // EV_VerticalDoor : open a door manually, no tag value
  291. //
  292. void
  293. EV_VerticalDoor
  294. ( line_t* line,
  295. mobj_t* thing )
  296. {
  297. player_t* player;
  298. int secnum;
  299. sector_t* sec;
  300. vldoor_t* door;
  301. int side;
  302. side = 0; // only front ::g->sides can be used
  303. // Check for locks
  304. player = thing->player;
  305. switch(line->special)
  306. {
  307. case 26: // Blue Lock
  308. case 32:
  309. if ( !player )
  310. return;
  311. if (!player->cards[it_bluecard] && !player->cards[it_blueskull])
  312. {
  313. player->message = PD_BLUEK;
  314. if (globalNetworking || (player == &::g->players[::g->consoleplayer]))
  315. S_StartSound(player->mo,sfx_oof);
  316. return;
  317. }
  318. break;
  319. case 27: // Yellow Lock
  320. case 34:
  321. if ( !player )
  322. return;
  323. if (!player->cards[it_yellowcard] &&
  324. !player->cards[it_yellowskull])
  325. {
  326. player->message = PD_YELLOWK;
  327. if (globalNetworking || (player == &::g->players[::g->consoleplayer]))
  328. S_StartSound(player->mo,sfx_oof);
  329. return;
  330. }
  331. break;
  332. case 28: // Red Lock
  333. case 33:
  334. if ( !player )
  335. return;
  336. if (!player->cards[it_redcard] && !player->cards[it_redskull])
  337. {
  338. player->message = PD_REDK;
  339. if (globalNetworking || (player == &::g->players[::g->consoleplayer]))
  340. S_StartSound(player->mo,sfx_oof);
  341. return;
  342. }
  343. break;
  344. }
  345. // if the sector has an active thinker, use it
  346. sec = ::g->sides[ line->sidenum[side^1]] .sector;
  347. secnum = sec-::g->sectors;
  348. if (sec->specialdata)
  349. {
  350. door = (vldoor_t*)sec->specialdata;
  351. switch(line->special)
  352. {
  353. case 1: // ONLY FOR "RAISE" DOORS, NOT "OPEN"s
  354. case 26:
  355. case 27:
  356. case 28:
  357. case 117:
  358. if (door->direction == -1)
  359. door->direction = 1; // go back up
  360. else
  361. {
  362. if (!thing->player)
  363. return; // JDC: bad guys never close doors
  364. door->direction = -1; // start going down immediately
  365. }
  366. return;
  367. }
  368. }
  369. // for proper sound
  370. if (globalNetworking || (player == &::g->players[::g->consoleplayer])) {
  371. switch(line->special)
  372. {
  373. case 117: // BLAZING DOOR RAISE
  374. case 118: // BLAZING DOOR OPEN
  375. S_StartSound( &sec->soundorg,sfx_bdopn);
  376. break;
  377. case 1: // NORMAL DOOR SOUND
  378. case 31:
  379. S_StartSound( &sec->soundorg,sfx_doropn);
  380. break;
  381. default: // LOCKED DOOR SOUND
  382. S_StartSound( &sec->soundorg,sfx_doropn);
  383. break;
  384. }
  385. }
  386. // new door thinker
  387. door = (vldoor_t*)DoomLib::Z_Malloc(sizeof(*door), PU_LEVEL, 0);
  388. P_AddThinker (&door->thinker);
  389. sec->specialdata = door;
  390. door->thinker.function.acp1 = (actionf_p1) T_VerticalDoor;
  391. door->sector = sec;
  392. door->direction = 1;
  393. door->speed = VDOORSPEED;
  394. door->topwait = VDOORWAIT;
  395. switch(line->special)
  396. {
  397. case 1:
  398. case 26:
  399. case 27:
  400. case 28:
  401. door->type = normal;
  402. break;
  403. case 31:
  404. case 32:
  405. case 33:
  406. case 34:
  407. door->type = opened;
  408. line->special = 0;
  409. break;
  410. case 117: // blazing door raise
  411. door->type = blazeRaise;
  412. door->speed = VDOORSPEED*4;
  413. break;
  414. case 118: // blazing door open
  415. door->type = blazeOpen;
  416. line->special = 0;
  417. door->speed = VDOORSPEED*4;
  418. break;
  419. }
  420. // find the top and bottom of the movement range
  421. door->topheight = P_FindLowestCeilingSurrounding(sec);
  422. door->topheight -= 4*FRACUNIT;
  423. }
  424. //
  425. // Spawn a door that closes after 30 seconds
  426. //
  427. void P_SpawnDoorCloseIn30 (sector_t* sec)
  428. {
  429. vldoor_t* door;
  430. door = (vldoor_t*)DoomLib::Z_Malloc( sizeof(*door), PU_LEVEL, 0);
  431. P_AddThinker (&door->thinker);
  432. sec->specialdata = door;
  433. sec->special = 0;
  434. door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor;
  435. door->sector = sec;
  436. door->direction = 0;
  437. door->type = normal;
  438. door->speed = VDOORSPEED;
  439. door->topcountdown = 30 * TICRATE;
  440. }
  441. //
  442. // Spawn a door that opens after 5 minutes
  443. //
  444. void
  445. P_SpawnDoorRaiseIn5Mins
  446. ( sector_t* sec,
  447. int secnum )
  448. {
  449. vldoor_t* door;
  450. door = (vldoor_t*)DoomLib::Z_Malloc( sizeof(*door), PU_LEVEL, 0);
  451. P_AddThinker (&door->thinker);
  452. sec->specialdata = door;
  453. sec->special = 0;
  454. door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor;
  455. door->sector = sec;
  456. door->direction = 2;
  457. door->type = raiseIn5Mins;
  458. door->speed = VDOORSPEED;
  459. door->topheight = P_FindLowestCeilingSurrounding(sec);
  460. door->topheight -= 4*FRACUNIT;
  461. door->topwait = VDOORWAIT;
  462. door->topcountdown = 5 * 60 * TICRATE;
  463. }
  464. // UNUSED
  465. // Separate into p_slidoor.c?