p_spec.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425
  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 "Main.h"
  23. #include <stdlib.h>
  24. #include "doomdef.h"
  25. #include "doomstat.h"
  26. #include "i_system.h"
  27. #include "z_zone.h"
  28. #include "m_argv.h"
  29. #include "m_random.h"
  30. #include "w_wad.h"
  31. #include "r_local.h"
  32. #include "p_local.h"
  33. #include "g_game.h"
  34. #include "s_sound.h"
  35. // State.
  36. #include "r_state.h"
  37. // Data.
  38. #include "sounds.h"
  39. #include "../../neo/d3xp/Game_Local.h"
  40. //
  41. // Animating textures and planes
  42. // There is another anim_t used in wi_stuff, unrelated. BLAH!
  43. // we now use anim_t2
  44. //
  45. //
  46. // source animation definition
  47. //
  48. //
  49. // P_InitPicAnims
  50. //
  51. // Floor/ceiling animation sequences,
  52. // defined by first and last frame,
  53. // i.e. the flat (64x64 tile) name to
  54. // be used.
  55. // The full animation sequence is given
  56. // using all the flats between the start
  57. // and end entry, in the order found in
  58. // the WAD file.
  59. //
  60. const animdef_t animdefs[] =
  61. {
  62. {false, "NUKAGE3", "NUKAGE1", 8},
  63. {false, "FWATER4", "FWATER1", 8},
  64. {false, "SWATER4", "SWATER1", 8},
  65. {false, "LAVA4", "LAVA1", 8},
  66. {false, "BLOOD3", "BLOOD1", 8},
  67. // DOOM II flat animations.
  68. {false, "RROCK08", "RROCK05", 8},
  69. {false, "SLIME04", "SLIME01", 8},
  70. {false, "SLIME08", "SLIME05", 8},
  71. {false, "SLIME12", "SLIME09", 8},
  72. {true, "BLODGR4", "BLODGR1", 8},
  73. {true, "SLADRIP3", "SLADRIP1", 8},
  74. {true, "BLODRIP4", "BLODRIP1", 8},
  75. {true, "FIREWALL", "FIREWALA", 8},
  76. {true, "GSTFONT3", "GSTFONT1", 8},
  77. {true, "FIRELAVA", "FIRELAV3", 8},
  78. {true, "FIREMAG3", "FIREMAG1", 8},
  79. {true, "FIREBLU2", "FIREBLU1", 8},
  80. {true, "ROCKRED3", "ROCKRED1", 8},
  81. {true, "BFALL4", "BFALL1", 8},
  82. {true, "SFALL4", "SFALL1", 8},
  83. {true, "WFALL4", "WFALL1", 8},
  84. {true, "DBRAIN4", "DBRAIN1", 8},
  85. {-1}
  86. };
  87. //
  88. // Animating line specials
  89. //
  90. void P_InitPicAnims (void)
  91. {
  92. int i;
  93. // Init animation
  94. ::g->lastanim = ::g->anims;
  95. for (i=0 ; animdefs[i].istexture != (qboolean)-1 ; i++)
  96. {
  97. if (animdefs[i].istexture)
  98. {
  99. // different episode ?
  100. if (R_CheckTextureNumForName(animdefs[i].startname) == -1)
  101. continue;
  102. ::g->lastanim->picnum = R_TextureNumForName (animdefs[i].endname);
  103. ::g->lastanim->basepic = R_TextureNumForName (animdefs[i].startname);
  104. }
  105. else
  106. {
  107. if (W_CheckNumForName(animdefs[i].startname) == -1)
  108. continue;
  109. ::g->lastanim->picnum = R_FlatNumForName (animdefs[i].endname);
  110. ::g->lastanim->basepic = R_FlatNumForName (animdefs[i].startname);
  111. }
  112. ::g->lastanim->istexture = animdefs[i].istexture;
  113. ::g->lastanim->numpics = ::g->lastanim->picnum - ::g->lastanim->basepic + 1;
  114. if (::g->lastanim->numpics < 2)
  115. I_Error ("P_InitPicAnims: bad cycle from %s to %s",
  116. animdefs[i].startname,
  117. animdefs[i].endname);
  118. ::g->lastanim->speed = animdefs[i].speed;
  119. ::g->lastanim++;
  120. }
  121. }
  122. //
  123. // UTILITIES
  124. //
  125. //
  126. // getSide()
  127. // Will return a side_t*
  128. // given the number of the current sector,
  129. // the line number, and the side (0/1) that you want.
  130. //
  131. side_t*
  132. getSide
  133. ( int currentSector,
  134. int line,
  135. int side )
  136. {
  137. return &::g->sides[ (::g->sectors[currentSector].lines[line])->sidenum[side] ];
  138. }
  139. //
  140. // getSector()
  141. // Will return a sector_t*
  142. // given the number of the current sector,
  143. // the line number and the side (0/1) that you want.
  144. //
  145. sector_t*
  146. getSector
  147. ( int currentSector,
  148. int line,
  149. int side )
  150. {
  151. return ::g->sides[ (::g->sectors[currentSector].lines[line])->sidenum[side] ].sector;
  152. }
  153. //
  154. // twoSided()
  155. // Given the sector number and the line number,
  156. // it will tell you whether the line is two-sided or not.
  157. //
  158. int
  159. twoSided
  160. ( int sector,
  161. int line )
  162. {
  163. return (::g->sectors[sector].lines[line])->flags & ML_TWOSIDED;
  164. }
  165. //
  166. // getNextSector()
  167. // Return sector_t * of sector next to current.
  168. // NULL if not two-sided line
  169. //
  170. sector_t*
  171. getNextSector
  172. ( line_t* line,
  173. sector_t* sec )
  174. {
  175. if (!(line->flags & ML_TWOSIDED))
  176. return NULL;
  177. if (line->frontsector == sec)
  178. return line->backsector;
  179. return line->frontsector;
  180. }
  181. //
  182. // P_FindLowestFloorSurrounding()
  183. // FIND LOWEST FLOOR HEIGHT IN SURROUNDING SECTORS
  184. //
  185. fixed_t P_FindLowestFloorSurrounding(sector_t* sec)
  186. {
  187. int i;
  188. line_t* check;
  189. sector_t* other;
  190. fixed_t floor = sec->floorheight;
  191. for (i=0 ;i < sec->linecount ; i++)
  192. {
  193. check = sec->lines[i];
  194. other = getNextSector(check,sec);
  195. if (!other)
  196. continue;
  197. if (other->floorheight < floor)
  198. floor = other->floorheight;
  199. }
  200. return floor;
  201. }
  202. //
  203. // P_FindHighestFloorSurrounding()
  204. // FIND HIGHEST FLOOR HEIGHT IN SURROUNDING SECTORS
  205. //
  206. fixed_t P_FindHighestFloorSurrounding(sector_t *sec)
  207. {
  208. int i;
  209. line_t* check;
  210. sector_t* other;
  211. fixed_t floor = -500*FRACUNIT;
  212. for (i=0 ;i < sec->linecount ; i++)
  213. {
  214. check = sec->lines[i];
  215. other = getNextSector(check,sec);
  216. if (!other)
  217. continue;
  218. if (other->floorheight > floor)
  219. floor = other->floorheight;
  220. }
  221. return floor;
  222. }
  223. //
  224. // P_FindNextHighestFloor
  225. // FIND NEXT HIGHEST FLOOR IN SURROUNDING SECTORS
  226. // Note: this should be doable w/o a fixed array.
  227. // 20 adjoining ::g->sectors max!
  228. fixed_t
  229. P_FindNextHighestFloor
  230. ( sector_t* sec,
  231. int currentheight )
  232. {
  233. int i;
  234. int h;
  235. int min;
  236. line_t* check;
  237. sector_t* other;
  238. fixed_t height = currentheight;
  239. fixed_t heightlist[MAX_ADJOINING_SECTORS];
  240. for (i=0, h=0 ;i < sec->linecount ; i++)
  241. {
  242. check = sec->lines[i];
  243. other = getNextSector(check,sec);
  244. if (!other)
  245. continue;
  246. if (other->floorheight > height)
  247. heightlist[h++] = other->floorheight;
  248. // Check for overflow. Exit.
  249. if ( h >= MAX_ADJOINING_SECTORS )
  250. {
  251. I_PrintfE("Sector with more than 20 adjoining sectors\n" );
  252. break;
  253. }
  254. }
  255. // Find lowest height in list
  256. if (!h)
  257. return currentheight;
  258. min = heightlist[0];
  259. // Range checking?
  260. for (i = 1;i < h;i++)
  261. if (heightlist[i] < min)
  262. min = heightlist[i];
  263. return min;
  264. }
  265. //
  266. // FIND LOWEST CEILING IN THE SURROUNDING SECTORS
  267. //
  268. fixed_t
  269. P_FindLowestCeilingSurrounding(sector_t* sec)
  270. {
  271. int i;
  272. line_t* check;
  273. sector_t* other;
  274. fixed_t height = MAXINT;
  275. for (i=0 ;i < sec->linecount ; i++)
  276. {
  277. check = sec->lines[i];
  278. other = getNextSector(check,sec);
  279. if (!other)
  280. continue;
  281. if (other->ceilingheight < height)
  282. height = other->ceilingheight;
  283. }
  284. return height;
  285. }
  286. //
  287. // FIND HIGHEST CEILING IN THE SURROUNDING SECTORS
  288. //
  289. fixed_t P_FindHighestCeilingSurrounding(sector_t* sec)
  290. {
  291. int i;
  292. line_t* check;
  293. sector_t* other;
  294. fixed_t height = 0;
  295. for (i=0 ;i < sec->linecount ; i++)
  296. {
  297. check = sec->lines[i];
  298. other = getNextSector(check,sec);
  299. if (!other)
  300. continue;
  301. if (other->ceilingheight > height)
  302. height = other->ceilingheight;
  303. }
  304. return height;
  305. }
  306. //
  307. // RETURN NEXT SECTOR # THAT LINE TAG REFERS TO
  308. //
  309. int
  310. P_FindSectorFromLineTag
  311. ( line_t* line,
  312. int start )
  313. {
  314. int i;
  315. for (i = start+1; i < ::g->numsectors; i++)
  316. if (::g->sectors[i].tag == line->tag)
  317. return i;
  318. return -1;
  319. }
  320. //
  321. // Find minimum light from an adjacent sector
  322. //
  323. int
  324. P_FindMinSurroundingLight
  325. ( sector_t* sector,
  326. int max )
  327. {
  328. int i;
  329. int min;
  330. line_t* line;
  331. sector_t* check;
  332. min = max;
  333. for (i=0 ; i < sector->linecount ; i++)
  334. {
  335. line = sector->lines[i];
  336. check = getNextSector(line,sector);
  337. if (!check)
  338. continue;
  339. if (check->lightlevel < min)
  340. min = check->lightlevel;
  341. }
  342. return min;
  343. }
  344. //
  345. // EVENTS
  346. // Events are operations triggered by using, crossing,
  347. // or shooting special ::g->lines, or by timed thinkers.
  348. //
  349. //
  350. // P_CrossSpecialLine - TRIGGER
  351. // Called every time a thing origin is about
  352. // to cross a line with a non 0 special.
  353. //
  354. void
  355. P_CrossSpecialLine
  356. ( int linenum,
  357. int side,
  358. mobj_t* thing )
  359. {
  360. line_t* line;
  361. int ok;
  362. line = &::g->lines[linenum];
  363. // Triggers that other things can activate
  364. if (!thing->player)
  365. {
  366. // Things that should NOT trigger specials...
  367. switch(thing->type)
  368. {
  369. case MT_ROCKET:
  370. case MT_PLASMA:
  371. case MT_BFG:
  372. case MT_TROOPSHOT:
  373. case MT_HEADSHOT:
  374. case MT_BRUISERSHOT:
  375. return;
  376. break;
  377. default: break;
  378. }
  379. ok = 0;
  380. switch(line->special)
  381. {
  382. case 39: // TELEPORT TRIGGER
  383. case 97: // TELEPORT RETRIGGER
  384. case 125: // TELEPORT MONSTERONLY TRIGGER
  385. case 126: // TELEPORT MONSTERONLY RETRIGGER
  386. case 4: // RAISE DOOR
  387. case 10: // PLAT DOWN-WAIT-UP-STAY TRIGGER
  388. case 88: // PLAT DOWN-WAIT-UP-STAY RETRIGGER
  389. ok = 1;
  390. break;
  391. }
  392. if (!ok)
  393. return;
  394. }
  395. // Note: could use some const's here.
  396. switch (line->special)
  397. {
  398. // TRIGGERS.
  399. // All from here to RETRIGGERS.
  400. case 2:
  401. // Open Door
  402. EV_DoDoor(line,opened);
  403. line->special = 0;
  404. break;
  405. case 3:
  406. // Close Door
  407. EV_DoDoor(line,closed);
  408. line->special = 0;
  409. break;
  410. case 4:
  411. // Raise Door
  412. EV_DoDoor(line,normal);
  413. line->special = 0;
  414. break;
  415. case 5:
  416. // Raise Floor
  417. EV_DoFloor(line,raiseFloor);
  418. line->special = 0;
  419. break;
  420. case 6:
  421. // Fast Ceiling Crush & Raise
  422. EV_DoCeiling(line,fastCrushAndRaise);
  423. line->special = 0;
  424. break;
  425. case 8:
  426. // Build Stairs
  427. EV_BuildStairs(line,build8);
  428. line->special = 0;
  429. break;
  430. case 10:
  431. // PlatDownWaitUp
  432. EV_DoPlat(line,downWaitUpStay,0);
  433. line->special = 0;
  434. break;
  435. case 12:
  436. // Light Turn On - brightest near
  437. EV_LightTurnOn(line,0);
  438. line->special = 0;
  439. break;
  440. case 13:
  441. // Light Turn On 255
  442. EV_LightTurnOn(line,255);
  443. line->special = 0;
  444. break;
  445. case 16:
  446. // Close Door 30
  447. EV_DoDoor(line,close30ThenOpen);
  448. line->special = 0;
  449. break;
  450. case 17:
  451. // Start Light Strobing
  452. EV_StartLightStrobing(line);
  453. line->special = 0;
  454. break;
  455. case 19:
  456. // Lower Floor
  457. EV_DoFloor(line,lowerFloor);
  458. line->special = 0;
  459. break;
  460. case 22:
  461. // Raise floor to nearest height and change texture
  462. EV_DoPlat(line,raiseToNearestAndChange,0);
  463. line->special = 0;
  464. break;
  465. case 25:
  466. // Ceiling Crush and Raise
  467. EV_DoCeiling(line,crushAndRaise);
  468. line->special = 0;
  469. break;
  470. case 30:
  471. // Raise floor to shortest texture height
  472. // on either side of ::g->lines.
  473. EV_DoFloor(line,raiseToTexture);
  474. line->special = 0;
  475. break;
  476. case 35:
  477. // Lights Very Dark
  478. EV_LightTurnOn(line,35);
  479. line->special = 0;
  480. break;
  481. case 36:
  482. // Lower Floor (TURBO)
  483. EV_DoFloor(line,turboLower);
  484. line->special = 0;
  485. break;
  486. case 37:
  487. // LowerAndChange
  488. EV_DoFloor(line,lowerAndChange);
  489. line->special = 0;
  490. break;
  491. case 38:
  492. // Lower Floor To Lowest
  493. EV_DoFloor( line, lowerFloorToLowest );
  494. line->special = 0;
  495. break;
  496. case 39:
  497. // TELEPORT!
  498. EV_Teleport( line, side, thing );
  499. line->special = 0;
  500. break;
  501. case 40:
  502. // RaiseCeilingLowerFloor
  503. EV_DoCeiling( line, raiseToHighest );
  504. EV_DoFloor( line, lowerFloorToLowest );
  505. line->special = 0;
  506. break;
  507. case 44:
  508. // Ceiling Crush
  509. EV_DoCeiling( line, lowerAndCrush );
  510. line->special = 0;
  511. break;
  512. case 52:
  513. // EXIT!
  514. // DHM - Nerve :: Don't exit level in death match, timelimit and fraglimit only
  515. if ( !::g->deathmatch && ::g->gameaction != ga_completed ) {
  516. G_ExitLevel();
  517. }
  518. break;
  519. case 53:
  520. // Perpetual Platform Raise
  521. EV_DoPlat(line,perpetualRaise,0);
  522. line->special = 0;
  523. break;
  524. case 54:
  525. // Platform Stop
  526. EV_StopPlat(line);
  527. line->special = 0;
  528. break;
  529. case 56:
  530. // Raise Floor Crush
  531. EV_DoFloor(line,raiseFloorCrush);
  532. line->special = 0;
  533. break;
  534. case 57:
  535. // Ceiling Crush Stop
  536. EV_CeilingCrushStop(line);
  537. line->special = 0;
  538. break;
  539. case 58:
  540. // Raise Floor 24
  541. EV_DoFloor(line,raiseFloor24);
  542. line->special = 0;
  543. break;
  544. case 59:
  545. // Raise Floor 24 And Change
  546. EV_DoFloor(line,raiseFloor24AndChange);
  547. line->special = 0;
  548. break;
  549. case 104:
  550. // Turn lights off in sector(tag)
  551. EV_TurnTagLightsOff(line);
  552. line->special = 0;
  553. break;
  554. case 108:
  555. // Blazing Door Raise (faster than TURBO!)
  556. EV_DoDoor (line,blazeRaise);
  557. line->special = 0;
  558. break;
  559. case 109:
  560. // Blazing Door Open (faster than TURBO!)
  561. EV_DoDoor (line,blazeOpen);
  562. line->special = 0;
  563. break;
  564. case 100:
  565. // Build Stairs Turbo 16
  566. EV_BuildStairs(line,turbo16);
  567. line->special = 0;
  568. break;
  569. case 110:
  570. // Blazing Door Close (faster than TURBO!)
  571. EV_DoDoor (line,blazeClose);
  572. line->special = 0;
  573. break;
  574. case 119:
  575. // Raise floor to nearest surr. floor
  576. EV_DoFloor(line,raiseFloorToNearest);
  577. line->special = 0;
  578. break;
  579. case 121:
  580. // Blazing PlatDownWaitUpStay
  581. EV_DoPlat(line,blazeDWUS,0);
  582. line->special = 0;
  583. break;
  584. case 124:
  585. // Secret EXIT
  586. if ( !::g->deathmatch && ::g->gameaction != ga_completed ) {
  587. G_SecretExitLevel ();
  588. }
  589. break;
  590. case 125:
  591. // TELEPORT MonsterONLY
  592. if (!thing->player)
  593. {
  594. EV_Teleport( line, side, thing );
  595. line->special = 0;
  596. }
  597. break;
  598. case 130:
  599. // Raise Floor Turbo
  600. EV_DoFloor(line,raiseFloorTurbo);
  601. line->special = 0;
  602. break;
  603. case 141:
  604. // Silent Ceiling Crush & Raise
  605. EV_DoCeiling(line,silentCrushAndRaise);
  606. line->special = 0;
  607. break;
  608. // RETRIGGERS. All from here till end.
  609. case 72:
  610. // Ceiling Crush
  611. EV_DoCeiling( line, lowerAndCrush );
  612. break;
  613. case 73:
  614. // Ceiling Crush and Raise
  615. EV_DoCeiling(line,crushAndRaise);
  616. break;
  617. case 74:
  618. // Ceiling Crush Stop
  619. EV_CeilingCrushStop(line);
  620. break;
  621. case 75:
  622. // Close Door
  623. EV_DoDoor(line,closed);
  624. break;
  625. case 76:
  626. // Close Door 30
  627. EV_DoDoor(line,close30ThenOpen);
  628. break;
  629. case 77:
  630. // Fast Ceiling Crush & Raise
  631. EV_DoCeiling(line,fastCrushAndRaise);
  632. break;
  633. case 79:
  634. // Lights Very Dark
  635. EV_LightTurnOn(line,35);
  636. break;
  637. case 80:
  638. // Light Turn On - brightest near
  639. EV_LightTurnOn(line,0);
  640. break;
  641. case 81:
  642. // Light Turn On 255
  643. EV_LightTurnOn(line,255);
  644. break;
  645. case 82:
  646. // Lower Floor To Lowest
  647. EV_DoFloor( line, lowerFloorToLowest );
  648. break;
  649. case 83:
  650. // Lower Floor
  651. EV_DoFloor(line,lowerFloor);
  652. break;
  653. case 84:
  654. // LowerAndChange
  655. EV_DoFloor(line,lowerAndChange);
  656. break;
  657. case 86:
  658. // Open Door
  659. EV_DoDoor(line,opened);
  660. break;
  661. case 87:
  662. // Perpetual Platform Raise
  663. EV_DoPlat(line,perpetualRaise,0);
  664. break;
  665. case 88:
  666. // PlatDownWaitUp
  667. EV_DoPlat(line,downWaitUpStay,0);
  668. break;
  669. case 89:
  670. // Platform Stop
  671. EV_StopPlat(line);
  672. break;
  673. case 90:
  674. // Raise Door
  675. EV_DoDoor(line,normal);
  676. break;
  677. case 91:
  678. // Raise Floor
  679. EV_DoFloor(line,raiseFloor);
  680. break;
  681. case 92:
  682. // Raise Floor 24
  683. EV_DoFloor(line,raiseFloor24);
  684. break;
  685. case 93:
  686. // Raise Floor 24 And Change
  687. EV_DoFloor(line,raiseFloor24AndChange);
  688. break;
  689. case 94:
  690. // Raise Floor Crush
  691. EV_DoFloor(line,raiseFloorCrush);
  692. break;
  693. case 95:
  694. // Raise floor to nearest height
  695. // and change texture.
  696. EV_DoPlat(line,raiseToNearestAndChange,0);
  697. break;
  698. case 96:
  699. // Raise floor to shortest texture height
  700. // on either side of ::g->lines.
  701. EV_DoFloor(line,raiseToTexture);
  702. break;
  703. case 97:
  704. // TELEPORT!
  705. EV_Teleport( line, side, thing );
  706. break;
  707. case 98:
  708. // Lower Floor (TURBO)
  709. EV_DoFloor(line,turboLower);
  710. break;
  711. case 105:
  712. // Blazing Door Raise (faster than TURBO!)
  713. EV_DoDoor (line,blazeRaise);
  714. break;
  715. case 106:
  716. // Blazing Door Open (faster than TURBO!)
  717. EV_DoDoor (line,blazeOpen);
  718. break;
  719. case 107:
  720. // Blazing Door Close (faster than TURBO!)
  721. EV_DoDoor (line,blazeClose);
  722. break;
  723. case 120:
  724. // Blazing PlatDownWaitUpStay.
  725. EV_DoPlat(line,blazeDWUS,0);
  726. break;
  727. case 126:
  728. // TELEPORT MonsterONLY.
  729. if (!thing->player)
  730. EV_Teleport( line, side, thing );
  731. break;
  732. case 128:
  733. // Raise To Nearest Floor
  734. EV_DoFloor(line,raiseFloorToNearest);
  735. break;
  736. case 129:
  737. // Raise Floor Turbo
  738. EV_DoFloor(line,raiseFloorTurbo);
  739. break;
  740. }
  741. }
  742. //
  743. // P_ShootSpecialLine - IMPACT SPECIALS
  744. // Called when a thing shoots a special line.
  745. //
  746. void
  747. P_ShootSpecialLine
  748. ( mobj_t* thing,
  749. line_t* line )
  750. {
  751. int ok;
  752. // Impacts that other things can activate.
  753. if (!thing->player)
  754. {
  755. ok = 0;
  756. switch(line->special)
  757. {
  758. case 46:
  759. // OPEN DOOR IMPACT
  760. ok = 1;
  761. break;
  762. }
  763. if (!ok)
  764. return;
  765. }
  766. switch(line->special)
  767. {
  768. case 24:
  769. // RAISE FLOOR
  770. EV_DoFloor(line,raiseFloor);
  771. P_ChangeSwitchTexture(line,0);
  772. break;
  773. case 46:
  774. // OPEN DOOR
  775. EV_DoDoor(line,opened);
  776. P_ChangeSwitchTexture(line,1);
  777. break;
  778. case 47:
  779. // RAISE FLOOR NEAR AND CHANGE
  780. EV_DoPlat(line,raiseToNearestAndChange,0);
  781. P_ChangeSwitchTexture(line,0);
  782. break;
  783. }
  784. }
  785. //
  786. // P_PlayerInSpecialSector
  787. // Called every tic frame
  788. // that the player origin is in a special sector
  789. //
  790. void P_PlayerInSpecialSector (player_t* player)
  791. {
  792. sector_t* sector;
  793. sector = player->mo->subsector->sector;
  794. // Falling, not all the way down yet?
  795. if (player->mo->z != sector->floorheight)
  796. return;
  797. // Has hitten ground.
  798. switch (sector->special)
  799. {
  800. case 5:
  801. // HELLSLIME DAMAGE
  802. if (!player->powers[pw_ironfeet])
  803. if (!(::g->leveltime&0x1f))
  804. P_DamageMobj (player->mo, NULL, NULL, 10);
  805. break;
  806. case 7:
  807. // NUKAGE DAMAGE
  808. if (!player->powers[pw_ironfeet])
  809. if (!(::g->leveltime&0x1f))
  810. P_DamageMobj (player->mo, NULL, NULL, 5);
  811. break;
  812. case 16:
  813. // SUPER HELLSLIME DAMAGE
  814. case 4:
  815. // STROBE HURT
  816. if (!player->powers[pw_ironfeet]
  817. || (P_Random()<5) )
  818. {
  819. if (!(::g->leveltime&0x1f))
  820. P_DamageMobj (player->mo, NULL, NULL, 20);
  821. }
  822. break;
  823. case 9:
  824. // SECRET SECTOR
  825. player->secretcount++;
  826. sector->special = 0;
  827. if ( !::g->demoplayback && ( ::g->usergame && !::g->netgame ) ) {
  828. // DHM - Nerve :: Let's give achievements in real time in Doom 2
  829. if ( !common->IsMultiplayer() ) {
  830. switch( DoomLib::GetGameSKU() ) {
  831. case GAME_SKU_DOOM1_BFG: {
  832. // Removing trophies for DOOM and DOOM II BFG due to point limit.
  833. //gameLocal->UnlockAchievement( Doom1BFG_Trophies::SCOUT_FIND_ANY_SECRET );
  834. break;
  835. }
  836. case GAME_SKU_DOOM2_BFG: {
  837. //gameLocal->UnlockAchievement( Doom2BFG_Trophies::IMPORTANT_LOOKING_DOOR_FIND_ANY_SECRET );
  838. idAchievementManager::LocalUser_CompleteAchievement(ACHIEVEMENT_DOOM2_IMPORTANT_LOOKING_DOOR_FIND_ANY_SECRET );
  839. break;
  840. }
  841. case GAME_SKU_DCC: {
  842. // Not on PC.
  843. //gameLocal->UnlockAchievement( DOOM_ACHIEVEMENT_FIND_SECRET );
  844. break;
  845. }
  846. default: {
  847. // No unlocks for other SKUs.
  848. break;
  849. }
  850. }
  851. }
  852. }
  853. break;
  854. case 11:
  855. // EXIT SUPER DAMAGE! (for E1M8 finale)
  856. player->cheats &= ~CF_GODMODE;
  857. if (!(::g->leveltime&0x1f))
  858. P_DamageMobj (player->mo, NULL, NULL, 20);
  859. if (player->health <= 10)
  860. G_ExitLevel();
  861. break;
  862. default:
  863. I_Error ("P_PlayerInSpecialSector: "
  864. "unknown special %i",
  865. sector->special);
  866. break;
  867. };
  868. }
  869. //
  870. // P_UpdateSpecials
  871. // Animate planes, scroll walls, etc.
  872. //
  873. int PlayerFrags( int playernum ) {
  874. int frags = 0;
  875. for( int i=0 ; i<MAXPLAYERS ; i++) {
  876. if ( i != playernum ) {
  877. frags += ::g->players[playernum].frags[i];
  878. }
  879. }
  880. frags -= ::g->players[playernum].frags[playernum];
  881. return frags;
  882. }
  883. void P_UpdateSpecials (void)
  884. {
  885. anim_t2* anim;
  886. int pic;
  887. int i;
  888. line_t* line;
  889. // LEVEL TIMER
  890. if (::g->levelTimer == true)
  891. {
  892. ::g->levelTimeCount--;
  893. if (!::g->levelTimeCount)
  894. G_ExitLevel();
  895. }
  896. // DHM - Nerve :: FRAG COUNT
  897. if ( ::g->deathmatch && ::g->levelFragCount > 0 ) {
  898. bool fragCountHit = false;
  899. for ( int i=0; i<MAXPLAYERS; i++ ) {
  900. if ( ::g->playeringame[i] ) {
  901. if ( PlayerFrags(i) >= ::g->levelFragCount ) {
  902. fragCountHit = true;
  903. }
  904. }
  905. }
  906. if ( fragCountHit ) {
  907. G_ExitLevel();
  908. }
  909. }
  910. // ANIMATE FLATS AND TEXTURES GLOBALLY
  911. for (anim = ::g->anims ; anim < ::g->lastanim ; anim++)
  912. {
  913. for (i=anim->basepic ; i<anim->basepic+anim->numpics ; i++)
  914. {
  915. pic = anim->basepic + ( (::g->leveltime/anim->speed + i)%anim->numpics );
  916. if (anim->istexture)
  917. ::g->texturetranslation[i] = pic;
  918. else
  919. ::g->flattranslation[i] = pic;
  920. }
  921. }
  922. // ANIMATE LINE SPECIALS
  923. for (i = 0; i < ::g->numlinespecials; i++)
  924. {
  925. line = ::g->linespeciallist[i];
  926. switch(line->special)
  927. {
  928. case 48:
  929. // EFFECT FIRSTCOL SCROLL +
  930. ::g->sides[line->sidenum[0]].textureoffset += FRACUNIT;
  931. break;
  932. }
  933. }
  934. // DO BUTTONS
  935. for (i = 0; i < MAXBUTTONS; i++)
  936. if (::g->buttonlist[i].btimer)
  937. {
  938. ::g->buttonlist[i].btimer--;
  939. if (!::g->buttonlist[i].btimer)
  940. {
  941. switch(::g->buttonlist[i].where)
  942. {
  943. case top:
  944. ::g->sides[::g->buttonlist[i].line->sidenum[0]].toptexture =
  945. ::g->buttonlist[i].btexture;
  946. break;
  947. case middle:
  948. ::g->sides[::g->buttonlist[i].line->sidenum[0]].midtexture =
  949. ::g->buttonlist[i].btexture;
  950. break;
  951. case bottom:
  952. ::g->sides[::g->buttonlist[i].line->sidenum[0]].bottomtexture =
  953. ::g->buttonlist[i].btexture;
  954. break;
  955. }
  956. S_StartSound((mobj_t *)&::g->buttonlist[i].soundorg,sfx_swtchn);
  957. memset(&::g->buttonlist[i],0,sizeof(button_t));
  958. }
  959. }
  960. }
  961. //
  962. // Special Stuff that can not be categorized
  963. //
  964. int EV_DoDonut(line_t* line)
  965. {
  966. sector_t* s1;
  967. sector_t* s2;
  968. sector_t* s3;
  969. int secnum;
  970. int rtn;
  971. int i;
  972. floormove_t* floor;
  973. secnum = -1;
  974. rtn = 0;
  975. while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
  976. {
  977. s1 = &::g->sectors[secnum];
  978. // ALREADY MOVING? IF SO, KEEP GOING...
  979. if (s1->specialdata)
  980. continue;
  981. rtn = 1;
  982. s2 = getNextSector(s1->lines[0],s1);
  983. for (i = 0;i < s2->linecount;i++)
  984. {
  985. if ((!(s2->lines[i]->flags & ML_TWOSIDED)) ||
  986. (s2->lines[i]->backsector == s1))
  987. continue;
  988. s3 = s2->lines[i]->backsector;
  989. // Spawn rising slime
  990. floor = (floormove_t*)DoomLib::Z_Malloc (sizeof(*floor), PU_LEVEL, 0);
  991. P_AddThinker (&floor->thinker);
  992. s2->specialdata = floor;
  993. floor->thinker.function.acp1 = (actionf_p1) T_MoveFloor;
  994. floor->type = donutRaise;
  995. floor->crush = false;
  996. floor->direction = 1;
  997. floor->sector = s2;
  998. floor->speed = FLOORSPEED / 2;
  999. floor->texture = s3->floorpic;
  1000. floor->newspecial = 0;
  1001. floor->floordestheight = s3->floorheight;
  1002. // Spawn lowering donut-hole
  1003. floor = (floormove_t*)DoomLib::Z_Malloc (sizeof(*floor), PU_LEVEL, 0);
  1004. P_AddThinker (&floor->thinker);
  1005. s1->specialdata = floor;
  1006. floor->thinker.function.acp1 = (actionf_p1) T_MoveFloor;
  1007. floor->type = lowerFloor;
  1008. floor->crush = false;
  1009. floor->direction = -1;
  1010. floor->sector = s1;
  1011. floor->speed = FLOORSPEED / 2;
  1012. floor->floordestheight = s3->floorheight;
  1013. break;
  1014. }
  1015. }
  1016. return rtn;
  1017. }
  1018. //
  1019. // SPECIAL SPAWNING
  1020. //
  1021. //
  1022. // P_SpawnSpecials
  1023. // After the map has been loaded, scan for specials
  1024. // that spawn thinkers
  1025. //
  1026. // Parses command line parameters.
  1027. void P_SpawnSpecials (void)
  1028. {
  1029. sector_t* sector;
  1030. int i;
  1031. int episode;
  1032. episode = 1;
  1033. if (W_CheckNumForName("texture2") >= 0)
  1034. episode = 2;
  1035. // See if -TIMER needs to be used.
  1036. ::g->levelTimer = false;
  1037. i = M_CheckParm("-avg");
  1038. if (i && ::g->deathmatch)
  1039. {
  1040. ::g->levelTimer = true;
  1041. ::g->levelTimeCount = 20 * 60 * TICRATE;
  1042. }
  1043. //i = M_CheckParm("-timer");
  1044. //if (i && ::g->deathmatch)
  1045. #ifdef ID_ENABLE_DOOM_CLASSIC_NETWORKING
  1046. const int timeLimit = session->GetActingGameStateLobbyBase().GetMatchParms().gameTimeLimit;
  1047. #else
  1048. const int timeLimit = 0;
  1049. #endif
  1050. if (timeLimit != 0 && g->deathmatch)
  1051. {
  1052. int time;
  1053. //time = atoi(::g->myargv[i+1]) * 60 * 35;
  1054. time = timeLimit * 60 * TICRATE;
  1055. ::g->levelTimer = true;
  1056. ::g->levelTimeCount = time;
  1057. }
  1058. //i = M_CheckParm("-fraglimit");
  1059. //if (i && ::g->deathmatch)
  1060. #ifdef ID_ENABLE_DOOM_CLASSIC_NETWORKING
  1061. const int fragLimit = gameLocal->GetMatchParms().GetScoreLimit();
  1062. #else
  1063. const int fragLimit = 0;
  1064. #endif
  1065. if (fragLimit != 0 && ::g->deathmatch)
  1066. {
  1067. //::g->levelFragCount = atoi(::g->myargv[i+1]);
  1068. ::g->levelFragCount = fragLimit;
  1069. } else {
  1070. ::g->levelFragCount = 0;
  1071. }
  1072. // Init special SECTORs.
  1073. sector = ::g->sectors;
  1074. for (i=0 ; i < ::g->numsectors ; i++, sector++)
  1075. {
  1076. if (!sector->special)
  1077. continue;
  1078. switch (sector->special)
  1079. {
  1080. case 1:
  1081. // FLICKERING LIGHTS
  1082. P_SpawnLightFlash (sector);
  1083. break;
  1084. case 2:
  1085. // STROBE FAST
  1086. P_SpawnStrobeFlash(sector,FASTDARK,0);
  1087. break;
  1088. case 3:
  1089. // STROBE SLOW
  1090. P_SpawnStrobeFlash(sector,SLOWDARK,0);
  1091. break;
  1092. case 4:
  1093. // STROBE FAST/DEATH SLIME
  1094. P_SpawnStrobeFlash(sector,FASTDARK,0);
  1095. sector->special = 4;
  1096. break;
  1097. case 8:
  1098. // GLOWING LIGHT
  1099. P_SpawnGlowingLight(sector);
  1100. break;
  1101. case 9:
  1102. // SECRET SECTOR
  1103. ::g->totalsecret++;
  1104. break;
  1105. case 10:
  1106. // DOOR CLOSE IN 30 SECONDS
  1107. P_SpawnDoorCloseIn30 (sector);
  1108. break;
  1109. case 12:
  1110. // SYNC STROBE SLOW
  1111. P_SpawnStrobeFlash (sector, SLOWDARK, 1);
  1112. break;
  1113. case 13:
  1114. // SYNC STROBE FAST
  1115. P_SpawnStrobeFlash (sector, FASTDARK, 1);
  1116. break;
  1117. case 14:
  1118. // DOOR RAISE IN 5 MINUTES
  1119. P_SpawnDoorRaiseIn5Mins (sector, i);
  1120. break;
  1121. case 17:
  1122. P_SpawnFireFlicker(sector);
  1123. break;
  1124. }
  1125. }
  1126. // Init line EFFECTs
  1127. ::g->numlinespecials = 0;
  1128. for (i = 0;i < ::g->numlines; i++)
  1129. {
  1130. switch(::g->lines[i].special)
  1131. {
  1132. case 48:
  1133. // EFFECT FIRSTCOL SCROLL+
  1134. ::g->linespeciallist[::g->numlinespecials] = &::g->lines[i];
  1135. ::g->numlinespecials++;
  1136. break;
  1137. }
  1138. }
  1139. // Init other misc stuff
  1140. for (i = 0;i < MAXCEILINGS;i++)
  1141. ::g->activeceilings[i] = NULL;
  1142. for (i = 0;i < MAXPLATS;i++)
  1143. ::g->activeplats[i] = NULL;
  1144. for (i = 0;i < MAXBUTTONS;i++)
  1145. memset(&::g->buttonlist[i],0,sizeof(button_t));
  1146. // UNUSED: no horizonal sliders.
  1147. // P_InitSlidingDoorFrames();
  1148. }