p_switch.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661
  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 "i_system.h"
  23. #include "doomdef.h"
  24. #include "p_local.h"
  25. #include "g_game.h"
  26. #include "s_sound.h"
  27. // Data.
  28. #include "sounds.h"
  29. // State.
  30. #include "doomstat.h"
  31. #include "r_state.h"
  32. //
  33. // CHANGE THE TEXTURE OF A WALL SWITCH TO ITS OPPOSITE
  34. //
  35. const switchlist_t alphSwitchList[] =
  36. {
  37. // Doom shareware episode 1 switches
  38. {"SW1BRCOM", "SW2BRCOM", 1},
  39. {"SW1BRN1", "SW2BRN1", 1},
  40. {"SW1BRN2", "SW2BRN2", 1},
  41. {"SW1BRNGN", "SW2BRNGN", 1},
  42. {"SW1BROWN", "SW2BROWN", 1},
  43. {"SW1COMM", "SW2COMM", 1},
  44. {"SW1COMP", "SW2COMP", 1},
  45. {"SW1DIRT", "SW2DIRT", 1},
  46. {"SW1EXIT", "SW2EXIT", 1},
  47. {"SW1GRAY", "SW2GRAY", 1},
  48. {"SW1GRAY1", "SW2GRAY1", 1},
  49. {"SW1METAL", "SW2METAL", 1},
  50. {"SW1PIPE", "SW2PIPE", 1},
  51. {"SW1SLAD", "SW2SLAD", 1},
  52. {"SW1STARG", "SW2STARG", 1},
  53. {"SW1STON1", "SW2STON1", 1},
  54. {"SW1STON2", "SW2STON2", 1},
  55. {"SW1STONE", "SW2STONE", 1},
  56. {"SW1STRTN", "SW2STRTN", 1},
  57. // Doom registered episodes 2&3 switches
  58. {"SW1BLUE", "SW2BLUE", 2},
  59. {"SW1CMT", "SW2CMT", 2},
  60. {"SW1GARG", "SW2GARG", 2},
  61. {"SW1GSTON", "SW2GSTON", 2},
  62. {"SW1HOT", "SW2HOT", 2},
  63. {"SW1LION", "SW2LION", 2},
  64. {"SW1SATYR", "SW2SATYR", 2},
  65. {"SW1SKIN", "SW2SKIN", 2},
  66. {"SW1VINE", "SW2VINE", 2},
  67. {"SW1WOOD", "SW2WOOD", 2},
  68. // Doom II switches
  69. {"SW1PANEL", "SW2PANEL", 3},
  70. {"SW1ROCK", "SW2ROCK", 3},
  71. {"SW1MET2", "SW2MET2", 3},
  72. {"SW1WDMET", "SW2WDMET", 3},
  73. {"SW1BRIK", "SW2BRIK", 3},
  74. {"SW1MOD1", "SW2MOD1", 3},
  75. {"SW1ZIM", "SW2ZIM", 3},
  76. {"SW1STON6", "SW2STON6", 3},
  77. {"SW1TEK", "SW2TEK", 3},
  78. {"SW1MARB", "SW2MARB", 3},
  79. {"SW1SKULL", "SW2SKULL", 3},
  80. {"\0", "\0", 0}
  81. };
  82. //
  83. // P_InitSwitchList
  84. // Only called at game initialization.
  85. //
  86. void P_InitSwitchList(void)
  87. {
  88. int i;
  89. int index;
  90. int episode;
  91. episode = 1;
  92. if (::g->gamemode == registered || ::g->gamemode == retail)
  93. episode = 2;
  94. else if ( ::g->gamemode == commercial )
  95. episode = 3;
  96. for (index = 0,i = 0;i < MAXSWITCHES;i++)
  97. {
  98. if (!alphSwitchList[i].episode)
  99. {
  100. ::g->numswitches = index/2;
  101. ::g->switchlist[index] = -1;
  102. break;
  103. }
  104. if (alphSwitchList[i].episode <= episode)
  105. {
  106. #if 0 // UNUSED - debug?
  107. int value;
  108. if (R_CheckTextureNumForName(alphSwitchList[i].name1) < 0)
  109. {
  110. I_Error("Can't find switch texture '%s'!",
  111. alphSwitchList[i].name1);
  112. continue;
  113. }
  114. value = R_TextureNumForName(alphSwitchList[i].name1);
  115. #endif
  116. ::g->switchlist[index++] = R_TextureNumForName(alphSwitchList[i].name1);
  117. ::g->switchlist[index++] = R_TextureNumForName(alphSwitchList[i].name2);
  118. }
  119. }
  120. }
  121. //
  122. // Start a button counting down till it turns off.
  123. //
  124. void
  125. P_StartButton
  126. ( line_t* line,
  127. bwhere_e w,
  128. int texture,
  129. int time )
  130. {
  131. int i;
  132. // See if button is already pressed
  133. for (i = 0;i < MAXBUTTONS;i++)
  134. {
  135. if (::g->buttonlist[i].btimer
  136. && ::g->buttonlist[i].line == line)
  137. {
  138. return;
  139. }
  140. }
  141. for (i = 0;i < MAXBUTTONS;i++)
  142. {
  143. if (!::g->buttonlist[i].btimer)
  144. {
  145. ::g->buttonlist[i].line = line;
  146. ::g->buttonlist[i].where = w;
  147. ::g->buttonlist[i].btexture = texture;
  148. ::g->buttonlist[i].btimer = time;
  149. ::g->buttonlist[i].degensoundorg = &line->frontsector->soundorg;
  150. return;
  151. }
  152. }
  153. I_Error("P_StartButton: no button slots left!");
  154. }
  155. //
  156. // Function that changes wall texture.
  157. // Tell it if switch is ok to use again (1=yes, it's a button).
  158. //
  159. void
  160. P_ChangeSwitchTexture
  161. ( line_t* line,
  162. int useAgain )
  163. {
  164. int texTop;
  165. int texMid;
  166. int texBot;
  167. int i;
  168. int sound;
  169. if (!useAgain)
  170. line->special = 0;
  171. texTop = ::g->sides[line->sidenum[0]].toptexture;
  172. texMid = ::g->sides[line->sidenum[0]].midtexture;
  173. texBot = ::g->sides[line->sidenum[0]].bottomtexture;
  174. sound = sfx_swtchn;
  175. // EXIT SWITCH?
  176. if (line->special == 11)
  177. sound = sfx_swtchx;
  178. for (i = 0;i < ::g->numswitches*2;i++)
  179. {
  180. if (::g->switchlist[i] == texTop)
  181. {
  182. S_StartSound(::g->buttonlist->soundorg,sound);
  183. ::g->sides[line->sidenum[0]].toptexture = ::g->switchlist[i^1];
  184. if (useAgain)
  185. P_StartButton(line,top,::g->switchlist[i],BUTTONTIME);
  186. return;
  187. }
  188. else
  189. {
  190. if (::g->switchlist[i] == texMid)
  191. {
  192. S_StartSound(::g->buttonlist->soundorg,sound);
  193. ::g->sides[line->sidenum[0]].midtexture = ::g->switchlist[i^1];
  194. if (useAgain)
  195. P_StartButton(line, middle,::g->switchlist[i],BUTTONTIME);
  196. return;
  197. }
  198. else
  199. {
  200. if (::g->switchlist[i] == texBot)
  201. {
  202. S_StartSound(::g->buttonlist->soundorg,sound);
  203. ::g->sides[line->sidenum[0]].bottomtexture = ::g->switchlist[i^1];
  204. if (useAgain)
  205. P_StartButton(line, bottom,::g->switchlist[i],BUTTONTIME);
  206. return;
  207. }
  208. }
  209. }
  210. }
  211. }
  212. //
  213. // P_UseSpecialLine
  214. // Called when a thing uses a special line.
  215. // Only the front ::g->sides of ::g->lines are usable.
  216. //
  217. qboolean
  218. P_UseSpecialLine
  219. ( mobj_t* thing,
  220. line_t* line,
  221. int side )
  222. {
  223. // Err...
  224. // Use the back ::g->sides of VERY SPECIAL ::g->lines...
  225. if (side)
  226. {
  227. switch(line->special)
  228. {
  229. case 124:
  230. // Sliding door open&close
  231. // UNUSED?
  232. break;
  233. default:
  234. return false;
  235. break;
  236. }
  237. }
  238. // Switches that other things can activate.
  239. if (!thing->player)
  240. {
  241. // never open secret doors
  242. if (line->flags & ML_SECRET)
  243. return false;
  244. switch(line->special)
  245. {
  246. case 1: // MANUAL DOOR RAISE
  247. case 32: // MANUAL BLUE
  248. case 33: // MANUAL RED
  249. case 34: // MANUAL YELLOW
  250. break;
  251. default:
  252. return false;
  253. break;
  254. }
  255. }
  256. // do something
  257. switch (line->special)
  258. {
  259. // MANUALS
  260. case 1: // Vertical Door
  261. case 26: // Blue Door/Locked
  262. case 27: // Yellow Door /Locked
  263. case 28: // Red Door /Locked
  264. case 31: // Manual door open
  265. case 32: // Blue locked door open
  266. case 33: // Red locked door open
  267. case 34: // Yellow locked door open
  268. case 117: // Blazing door raise
  269. case 118: // Blazing door open
  270. EV_VerticalDoor (line, thing);
  271. break;
  272. //UNUSED - Door Slide Open&Close
  273. // case 124:
  274. // EV_SlidingDoor (line, thing);
  275. // break;
  276. // SWITCHES
  277. case 7:
  278. // Build Stairs
  279. if (EV_BuildStairs(line,build8))
  280. P_ChangeSwitchTexture(line,0);
  281. break;
  282. case 9:
  283. // Change Donut
  284. if (EV_DoDonut(line))
  285. P_ChangeSwitchTexture(line,0);
  286. break;
  287. case 11:
  288. // Exit level
  289. // DHM - Nerve :: Not in deathmatch, stay in level until timelimit or fraglimit
  290. if ( !::g->deathmatch && ::g->gameaction != ga_completed ) {
  291. P_ChangeSwitchTexture(line,0);
  292. G_ExitLevel ();
  293. }
  294. break;
  295. case 14:
  296. // Raise Floor 32 and change texture
  297. if (EV_DoPlat(line,raiseAndChange,32))
  298. P_ChangeSwitchTexture(line,0);
  299. break;
  300. case 15:
  301. // Raise Floor 24 and change texture
  302. if (EV_DoPlat(line,raiseAndChange,24))
  303. P_ChangeSwitchTexture(line,0);
  304. break;
  305. case 18:
  306. // Raise Floor to next highest floor
  307. if (EV_DoFloor(line, raiseFloorToNearest))
  308. P_ChangeSwitchTexture(line,0);
  309. break;
  310. case 20:
  311. // Raise Plat next highest floor and change texture
  312. if (EV_DoPlat(line,raiseToNearestAndChange,0))
  313. P_ChangeSwitchTexture(line,0);
  314. break;
  315. case 21:
  316. // PlatDownWaitUpStay
  317. if (EV_DoPlat(line,downWaitUpStay,0))
  318. P_ChangeSwitchTexture(line,0);
  319. break;
  320. case 23:
  321. // Lower Floor to Lowest
  322. if (EV_DoFloor(line,lowerFloorToLowest))
  323. P_ChangeSwitchTexture(line,0);
  324. break;
  325. case 29:
  326. // Raise Door
  327. if (EV_DoDoor(line,normal))
  328. P_ChangeSwitchTexture(line,0);
  329. break;
  330. case 41:
  331. // Lower Ceiling to Floor
  332. if (EV_DoCeiling(line,lowerToFloor))
  333. P_ChangeSwitchTexture(line,0);
  334. break;
  335. case 71:
  336. // Turbo Lower Floor
  337. if (EV_DoFloor(line,turboLower))
  338. P_ChangeSwitchTexture(line,0);
  339. break;
  340. case 49:
  341. // Ceiling Crush And Raise
  342. if (EV_DoCeiling(line,crushAndRaise))
  343. P_ChangeSwitchTexture(line,0);
  344. break;
  345. case 50:
  346. // Close Door
  347. if (EV_DoDoor(line,closed))
  348. P_ChangeSwitchTexture(line,0);
  349. break;
  350. case 51:
  351. // Secret EXIT
  352. if ( !::g->deathmatch && ::g->gameaction != ga_completed ) {
  353. P_ChangeSwitchTexture(line,0);
  354. G_SecretExitLevel ();
  355. }
  356. break;
  357. case 55:
  358. // Raise Floor Crush
  359. if (EV_DoFloor(line,raiseFloorCrush))
  360. P_ChangeSwitchTexture(line,0);
  361. break;
  362. case 101:
  363. // Raise Floor
  364. if (EV_DoFloor(line,raiseFloor))
  365. P_ChangeSwitchTexture(line,0);
  366. break;
  367. case 102:
  368. // Lower Floor to Surrounding floor height
  369. if (EV_DoFloor(line,lowerFloor))
  370. P_ChangeSwitchTexture(line,0);
  371. break;
  372. case 103:
  373. // Open Door
  374. if (EV_DoDoor(line,opened))
  375. P_ChangeSwitchTexture(line,0);
  376. break;
  377. case 111:
  378. // Blazing Door Raise (faster than TURBO!)
  379. if (EV_DoDoor (line,blazeRaise))
  380. P_ChangeSwitchTexture(line,0);
  381. break;
  382. case 112:
  383. // Blazing Door Open (faster than TURBO!)
  384. if (EV_DoDoor (line,blazeOpen))
  385. P_ChangeSwitchTexture(line,0);
  386. break;
  387. case 113:
  388. // Blazing Door Close (faster than TURBO!)
  389. if (EV_DoDoor (line,blazeClose))
  390. P_ChangeSwitchTexture(line,0);
  391. break;
  392. case 122:
  393. // Blazing PlatDownWaitUpStay
  394. if (EV_DoPlat(line,blazeDWUS,0))
  395. P_ChangeSwitchTexture(line,0);
  396. break;
  397. case 127:
  398. // Build Stairs Turbo 16
  399. if (EV_BuildStairs(line,turbo16))
  400. P_ChangeSwitchTexture(line,0);
  401. break;
  402. case 131:
  403. // Raise Floor Turbo
  404. if (EV_DoFloor(line,raiseFloorTurbo))
  405. P_ChangeSwitchTexture(line,0);
  406. break;
  407. case 133:
  408. // BlzOpenDoor BLUE
  409. case 135:
  410. // BlzOpenDoor RED
  411. case 137:
  412. // BlzOpenDoor YELLOW
  413. if (EV_DoLockedDoor (line,blazeOpen,thing))
  414. P_ChangeSwitchTexture(line,0);
  415. break;
  416. case 140:
  417. // Raise Floor 512
  418. if (EV_DoFloor(line,raiseFloor512))
  419. P_ChangeSwitchTexture(line,0);
  420. break;
  421. // BUTTONS
  422. case 42:
  423. // Close Door
  424. if (EV_DoDoor(line,closed))
  425. P_ChangeSwitchTexture(line,1);
  426. break;
  427. case 43:
  428. // Lower Ceiling to Floor
  429. if (EV_DoCeiling(line,lowerToFloor))
  430. P_ChangeSwitchTexture(line,1);
  431. break;
  432. case 45:
  433. // Lower Floor to Surrounding floor height
  434. if (EV_DoFloor(line,lowerFloor))
  435. P_ChangeSwitchTexture(line,1);
  436. break;
  437. case 60:
  438. // Lower Floor to Lowest
  439. if (EV_DoFloor(line,lowerFloorToLowest))
  440. P_ChangeSwitchTexture(line,1);
  441. break;
  442. case 61:
  443. // Open Door
  444. if (EV_DoDoor(line,opened))
  445. P_ChangeSwitchTexture(line,1);
  446. break;
  447. case 62:
  448. // PlatDownWaitUpStay
  449. if (EV_DoPlat(line,downWaitUpStay,1))
  450. P_ChangeSwitchTexture(line,1);
  451. break;
  452. case 63:
  453. // Raise Door
  454. if (EV_DoDoor(line,normal))
  455. P_ChangeSwitchTexture(line,1);
  456. break;
  457. case 64:
  458. // Raise Floor to ceiling
  459. if (EV_DoFloor(line,raiseFloor))
  460. P_ChangeSwitchTexture(line,1);
  461. break;
  462. case 66:
  463. // Raise Floor 24 and change texture
  464. if (EV_DoPlat(line,raiseAndChange,24))
  465. P_ChangeSwitchTexture(line,1);
  466. break;
  467. case 67:
  468. // Raise Floor 32 and change texture
  469. if (EV_DoPlat(line,raiseAndChange,32))
  470. P_ChangeSwitchTexture(line,1);
  471. break;
  472. case 65:
  473. // Raise Floor Crush
  474. if (EV_DoFloor(line,raiseFloorCrush))
  475. P_ChangeSwitchTexture(line,1);
  476. break;
  477. case 68:
  478. // Raise Plat to next highest floor and change texture
  479. if (EV_DoPlat(line,raiseToNearestAndChange,0))
  480. P_ChangeSwitchTexture(line,1);
  481. break;
  482. case 69:
  483. // Raise Floor to next highest floor
  484. if (EV_DoFloor(line, raiseFloorToNearest))
  485. P_ChangeSwitchTexture(line,1);
  486. break;
  487. case 70:
  488. // Turbo Lower Floor
  489. if (EV_DoFloor(line,turboLower))
  490. P_ChangeSwitchTexture(line,1);
  491. break;
  492. case 114:
  493. // Blazing Door Raise (faster than TURBO!)
  494. if (EV_DoDoor (line,blazeRaise))
  495. P_ChangeSwitchTexture(line,1);
  496. break;
  497. case 115:
  498. // Blazing Door Open (faster than TURBO!)
  499. if (EV_DoDoor (line,blazeOpen))
  500. P_ChangeSwitchTexture(line,1);
  501. break;
  502. case 116:
  503. // Blazing Door Close (faster than TURBO!)
  504. if (EV_DoDoor (line,blazeClose))
  505. P_ChangeSwitchTexture(line,1);
  506. break;
  507. case 123:
  508. // Blazing PlatDownWaitUpStay
  509. if (EV_DoPlat(line,blazeDWUS,0))
  510. P_ChangeSwitchTexture(line,1);
  511. break;
  512. case 132:
  513. // Raise Floor Turbo
  514. if (EV_DoFloor(line,raiseFloorTurbo))
  515. P_ChangeSwitchTexture(line,1);
  516. break;
  517. case 99:
  518. // BlzOpenDoor BLUE
  519. case 134:
  520. // BlzOpenDoor RED
  521. case 136:
  522. // BlzOpenDoor YELLOW
  523. if (EV_DoLockedDoor (line,blazeOpen,thing))
  524. P_ChangeSwitchTexture(line,1);
  525. break;
  526. case 138:
  527. // Light Turn On
  528. EV_LightTurnOn(line,255);
  529. P_ChangeSwitchTexture(line,1);
  530. break;
  531. case 139:
  532. // Light Turn Off
  533. EV_LightTurnOn(line,35);
  534. P_ChangeSwitchTexture(line,1);
  535. break;
  536. }
  537. return true;
  538. }