P_SPEC.C 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254
  1. // P_Spec.c
  2. #include "DoomDef.h"
  3. #include "P_local.h"
  4. #include "soundst.h"
  5. // Macros
  6. #define MAX_AMBIENT_SFX 8 // Per level
  7. // Types
  8. typedef enum
  9. {
  10. afxcmd_play, // (sound)
  11. afxcmd_playabsvol, // (sound, volume)
  12. afxcmd_playrelvol, // (sound, volume)
  13. afxcmd_delay, // (ticks)
  14. afxcmd_delayrand, // (andbits)
  15. afxcmd_end // ()
  16. } afxcmd_t;
  17. // Data
  18. int *LevelAmbientSfx[MAX_AMBIENT_SFX];
  19. int *AmbSfxPtr;
  20. int AmbSfxCount;
  21. int AmbSfxTics;
  22. int AmbSfxVolume;
  23. int AmbSndSeqInit[] =
  24. { // Startup
  25. afxcmd_end
  26. };
  27. int AmbSndSeq1[] =
  28. { // Scream
  29. afxcmd_play, sfx_amb1,
  30. afxcmd_end
  31. };
  32. int AmbSndSeq2[] =
  33. { // Squish
  34. afxcmd_play, sfx_amb2,
  35. afxcmd_end
  36. };
  37. int AmbSndSeq3[] =
  38. { // Drops
  39. afxcmd_play, sfx_amb3,
  40. afxcmd_delay, 16,
  41. afxcmd_delayrand, 31,
  42. afxcmd_play, sfx_amb7,
  43. afxcmd_delay, 16,
  44. afxcmd_delayrand, 31,
  45. afxcmd_play, sfx_amb3,
  46. afxcmd_delay, 16,
  47. afxcmd_delayrand, 31,
  48. afxcmd_play, sfx_amb7,
  49. afxcmd_delay, 16,
  50. afxcmd_delayrand, 31,
  51. afxcmd_play, sfx_amb3,
  52. afxcmd_delay, 16,
  53. afxcmd_delayrand, 31,
  54. afxcmd_play, sfx_amb7,
  55. afxcmd_delay, 16,
  56. afxcmd_delayrand, 31,
  57. afxcmd_end
  58. };
  59. int AmbSndSeq4[] =
  60. { // SlowFootSteps
  61. afxcmd_play, sfx_amb4,
  62. afxcmd_delay, 15,
  63. afxcmd_playrelvol, sfx_amb11, -3,
  64. afxcmd_delay, 15,
  65. afxcmd_playrelvol, sfx_amb4, -3,
  66. afxcmd_delay, 15,
  67. afxcmd_playrelvol, sfx_amb11, -3,
  68. afxcmd_delay, 15,
  69. afxcmd_playrelvol, sfx_amb4, -3,
  70. afxcmd_delay, 15,
  71. afxcmd_playrelvol, sfx_amb11, -3,
  72. afxcmd_delay, 15,
  73. afxcmd_playrelvol, sfx_amb4, -3,
  74. afxcmd_delay, 15,
  75. afxcmd_playrelvol, sfx_amb11, -3,
  76. afxcmd_end
  77. };
  78. int AmbSndSeq5[] =
  79. { // Heartbeat
  80. afxcmd_play, sfx_amb5,
  81. afxcmd_delay, 35,
  82. afxcmd_play, sfx_amb5,
  83. afxcmd_delay, 35,
  84. afxcmd_play, sfx_amb5,
  85. afxcmd_delay, 35,
  86. afxcmd_play, sfx_amb5,
  87. afxcmd_end
  88. };
  89. int AmbSndSeq6[] =
  90. { // Bells
  91. afxcmd_play, sfx_amb6,
  92. afxcmd_delay, 17,
  93. afxcmd_playrelvol, sfx_amb6, -8,
  94. afxcmd_delay, 17,
  95. afxcmd_playrelvol, sfx_amb6, -8,
  96. afxcmd_delay, 17,
  97. afxcmd_playrelvol, sfx_amb6, -8,
  98. afxcmd_end
  99. };
  100. int AmbSndSeq7[] =
  101. { // Growl
  102. afxcmd_play, sfx_bstsit,
  103. afxcmd_end
  104. };
  105. int AmbSndSeq8[] =
  106. { // Magic
  107. afxcmd_play, sfx_amb8,
  108. afxcmd_end
  109. };
  110. int AmbSndSeq9[] =
  111. { // Laughter
  112. afxcmd_play, sfx_amb9,
  113. afxcmd_delay, 16,
  114. afxcmd_playrelvol, sfx_amb9, -4,
  115. afxcmd_delay, 16,
  116. afxcmd_playrelvol, sfx_amb9, -4,
  117. afxcmd_delay, 16,
  118. afxcmd_playrelvol, sfx_amb10, -4,
  119. afxcmd_delay, 16,
  120. afxcmd_playrelvol, sfx_amb10, -4,
  121. afxcmd_delay, 16,
  122. afxcmd_playrelvol, sfx_amb10, -4,
  123. afxcmd_end
  124. };
  125. int AmbSndSeq10[] =
  126. { // FastFootsteps
  127. afxcmd_play, sfx_amb4,
  128. afxcmd_delay, 8,
  129. afxcmd_playrelvol, sfx_amb11, -3,
  130. afxcmd_delay, 8,
  131. afxcmd_playrelvol, sfx_amb4, -3,
  132. afxcmd_delay, 8,
  133. afxcmd_playrelvol, sfx_amb11, -3,
  134. afxcmd_delay, 8,
  135. afxcmd_playrelvol, sfx_amb4, -3,
  136. afxcmd_delay, 8,
  137. afxcmd_playrelvol, sfx_amb11, -3,
  138. afxcmd_delay, 8,
  139. afxcmd_playrelvol, sfx_amb4, -3,
  140. afxcmd_delay, 8,
  141. afxcmd_playrelvol, sfx_amb11, -3,
  142. afxcmd_end
  143. };
  144. int *AmbientSfx[] =
  145. {
  146. AmbSndSeq1, // Scream
  147. AmbSndSeq2, // Squish
  148. AmbSndSeq3, // Drops
  149. AmbSndSeq4, // SlowFootsteps
  150. AmbSndSeq5, // Heartbeat
  151. AmbSndSeq6, // Bells
  152. AmbSndSeq7, // Growl
  153. AmbSndSeq8, // Magic
  154. AmbSndSeq9, // Laughter
  155. AmbSndSeq10 // FastFootsteps
  156. };
  157. animdef_t animdefs[] =
  158. {
  159. // false = flat
  160. // true = texture
  161. {false, "FLTWAWA3", "FLTWAWA1", 8}, // Water
  162. {false, "FLTSLUD3", "FLTSLUD1", 8}, // Sludge
  163. {false, "FLTTELE4", "FLTTELE1", 6}, // Teleport
  164. {false, "FLTFLWW3", "FLTFLWW1", 9}, // River - West
  165. {false, "FLTLAVA4", "FLTLAVA1", 8}, // Lava
  166. {false, "FLATHUH4", "FLATHUH1", 8}, // Super Lava
  167. {true, "LAVAFL3", "LAVAFL1", 6}, // Texture: Lavaflow
  168. {true, "WATRWAL3", "WATRWAL1", 4}, // Texture: Waterfall
  169. {-1}
  170. };
  171. anim_t anims[MAXANIMS];
  172. anim_t *lastanim;
  173. int *TerrainTypes;
  174. struct
  175. {
  176. char *name;
  177. int type;
  178. } TerrainTypeDefs[] =
  179. {
  180. { "FLTWAWA1", FLOOR_WATER },
  181. { "FLTFLWW1", FLOOR_WATER },
  182. { "FLTLAVA1", FLOOR_LAVA },
  183. { "FLATHUH1", FLOOR_LAVA },
  184. { "FLTSLUD1", FLOOR_SLUDGE },
  185. { "END", -1 }
  186. };
  187. mobj_t LavaInflictor;
  188. //----------------------------------------------------------------------------
  189. //
  190. // PROC P_InitLava
  191. //
  192. //----------------------------------------------------------------------------
  193. void P_InitLava(void)
  194. {
  195. memset(&LavaInflictor, 0, sizeof(mobj_t));
  196. LavaInflictor.type = MT_PHOENIXFX2;
  197. LavaInflictor.flags2 = MF2_FIREDAMAGE|MF2_NODMGTHRUST;
  198. }
  199. //----------------------------------------------------------------------------
  200. //
  201. // PROC P_InitTerrainTypes
  202. //
  203. //----------------------------------------------------------------------------
  204. void P_InitTerrainTypes(void)
  205. {
  206. int i;
  207. int lump;
  208. int size;
  209. size = (numflats+1)*sizeof(int);
  210. TerrainTypes = Z_Malloc(size, PU_STATIC, 0);
  211. memset(TerrainTypes, 0, size);
  212. for(i = 0; TerrainTypeDefs[i].type != -1; i++)
  213. {
  214. lump = W_CheckNumForName(TerrainTypeDefs[i].name);
  215. if(lump != -1)
  216. {
  217. TerrainTypes[lump-firstflat] = TerrainTypeDefs[i].type;
  218. }
  219. }
  220. }
  221. //----------------------------------------------------------------------------
  222. //
  223. // PROC P_InitPicAnims
  224. //
  225. //----------------------------------------------------------------------------
  226. void P_InitPicAnims(void)
  227. {
  228. int i;
  229. lastanim = anims;
  230. for(i = 0; animdefs[i].istexture != -1; i++)
  231. {
  232. if(animdefs[i].istexture)
  233. { // Texture animation
  234. if(R_CheckTextureNumForName(animdefs[i].startname) == -1)
  235. { // Texture doesn't exist
  236. continue;
  237. }
  238. lastanim->picnum = R_TextureNumForName(animdefs[i].endname);
  239. lastanim->basepic = R_TextureNumForName(animdefs[i].startname);
  240. }
  241. else
  242. { // Flat animation
  243. if(W_CheckNumForName(animdefs[i].startname) == -1)
  244. { // Flat doesn't exist
  245. continue;
  246. }
  247. lastanim->picnum = R_FlatNumForName(animdefs[i].endname);
  248. lastanim->basepic = R_FlatNumForName(animdefs[i].startname);
  249. }
  250. lastanim->istexture = animdefs[i].istexture;
  251. lastanim->numpics = lastanim->picnum-lastanim->basepic+1;
  252. if(lastanim->numpics < 2)
  253. {
  254. I_Error("P_InitPicAnims: bad cycle from %s to %s",
  255. animdefs[i].startname, animdefs[i].endname);
  256. }
  257. lastanim->speed = animdefs[i].speed;
  258. lastanim++;
  259. }
  260. }
  261. /*
  262. ==============================================================================
  263. UTILITIES
  264. ==============================================================================
  265. */
  266. //
  267. // Will return a side_t* given the number of the current sector,
  268. // the line number, and the side (0/1) that you want.
  269. //
  270. side_t *getSide(int currentSector,int line, int side)
  271. {
  272. return &sides[ (sectors[currentSector].lines[line])->sidenum[side] ];
  273. }
  274. //
  275. // Will return a sector_t* given the number of the current sector,
  276. // the line number and the side (0/1) that you want.
  277. //
  278. sector_t *getSector(int currentSector,int line,int side)
  279. {
  280. return sides[ (sectors[currentSector].lines[line])->sidenum[side] ].sector;
  281. }
  282. //
  283. // Given the sector number and the line number, will tell you whether
  284. // the line is two-sided or not.
  285. //
  286. int twoSided(int sector,int line)
  287. {
  288. return (sectors[sector].lines[line])->flags & ML_TWOSIDED;
  289. }
  290. //==================================================================
  291. //
  292. // Return sector_t * of sector next to current. NULL if not two-sided line
  293. //
  294. //==================================================================
  295. sector_t *getNextSector(line_t *line,sector_t *sec)
  296. {
  297. if (!(line->flags & ML_TWOSIDED))
  298. return NULL;
  299. if (line->frontsector == sec)
  300. return line->backsector;
  301. return line->frontsector;
  302. }
  303. //==================================================================
  304. //
  305. // FIND LOWEST FLOOR HEIGHT IN SURROUNDING SECTORS
  306. //
  307. //==================================================================
  308. fixed_t P_FindLowestFloorSurrounding(sector_t *sec)
  309. {
  310. int i;
  311. line_t *check;
  312. sector_t *other;
  313. fixed_t floor = sec->floorheight;
  314. for (i=0 ;i < sec->linecount ; i++)
  315. {
  316. check = sec->lines[i];
  317. other = getNextSector(check,sec);
  318. if (!other)
  319. continue;
  320. if (other->floorheight < floor)
  321. floor = other->floorheight;
  322. }
  323. return floor;
  324. }
  325. //==================================================================
  326. //
  327. // FIND HIGHEST FLOOR HEIGHT IN SURROUNDING SECTORS
  328. //
  329. //==================================================================
  330. fixed_t P_FindHighestFloorSurrounding(sector_t *sec)
  331. {
  332. int i;
  333. line_t *check;
  334. sector_t *other;
  335. fixed_t floor = -500*FRACUNIT;
  336. for (i=0 ;i < sec->linecount ; i++)
  337. {
  338. check = sec->lines[i];
  339. other = getNextSector(check,sec);
  340. if (!other)
  341. continue;
  342. if (other->floorheight > floor)
  343. floor = other->floorheight;
  344. }
  345. return floor;
  346. }
  347. //==================================================================
  348. //
  349. // FIND NEXT HIGHEST FLOOR IN SURROUNDING SECTORS
  350. //
  351. //==================================================================
  352. fixed_t P_FindNextHighestFloor(sector_t *sec,int currentheight)
  353. {
  354. int i;
  355. int h;
  356. int min;
  357. line_t *check;
  358. sector_t *other;
  359. fixed_t height = currentheight;
  360. fixed_t heightlist[20]; // 20 adjoining sectors max!
  361. for (i =0,h = 0 ;i < sec->linecount ; i++)
  362. {
  363. check = sec->lines[i];
  364. other = getNextSector(check,sec);
  365. if (!other)
  366. continue;
  367. if (other->floorheight > height)
  368. heightlist[h++] = other->floorheight;
  369. }
  370. //
  371. // Find lowest height in list
  372. //
  373. min = heightlist[0];
  374. for (i = 1;i < h;i++)
  375. if (heightlist[i] < min)
  376. min = heightlist[i];
  377. return min;
  378. }
  379. //==================================================================
  380. //
  381. // FIND LOWEST CEILING IN THE SURROUNDING SECTORS
  382. //
  383. //==================================================================
  384. fixed_t P_FindLowestCeilingSurrounding(sector_t *sec)
  385. {
  386. int i;
  387. line_t *check;
  388. sector_t *other;
  389. fixed_t height = MAXINT;
  390. for (i=0 ;i < sec->linecount ; i++)
  391. {
  392. check = sec->lines[i];
  393. other = getNextSector(check,sec);
  394. if (!other)
  395. continue;
  396. if (other->ceilingheight < height)
  397. height = other->ceilingheight;
  398. }
  399. return height;
  400. }
  401. //==================================================================
  402. //
  403. // FIND HIGHEST CEILING IN THE SURROUNDING SECTORS
  404. //
  405. //==================================================================
  406. fixed_t P_FindHighestCeilingSurrounding(sector_t *sec)
  407. {
  408. int i;
  409. line_t *check;
  410. sector_t *other;
  411. fixed_t height = 0;
  412. for (i=0 ;i < sec->linecount ; i++)
  413. {
  414. check = sec->lines[i];
  415. other = getNextSector(check,sec);
  416. if (!other)
  417. continue;
  418. if (other->ceilingheight > height)
  419. height = other->ceilingheight;
  420. }
  421. return height;
  422. }
  423. //==================================================================
  424. //
  425. // RETURN NEXT SECTOR # THAT LINE TAG REFERS TO
  426. //
  427. //==================================================================
  428. int P_FindSectorFromLineTag(line_t *line,int start)
  429. {
  430. int i;
  431. for (i=start+1;i<numsectors;i++)
  432. if (sectors[i].tag == line->tag)
  433. return i;
  434. return -1;
  435. }
  436. //==================================================================
  437. //
  438. // Find minimum light from an adjacent sector
  439. //
  440. //==================================================================
  441. int P_FindMinSurroundingLight(sector_t *sector,int max)
  442. {
  443. int i;
  444. int min;
  445. line_t *line;
  446. sector_t *check;
  447. min = max;
  448. for (i=0 ; i < sector->linecount ; i++)
  449. {
  450. line = sector->lines[i];
  451. check = getNextSector(line,sector);
  452. if (!check)
  453. continue;
  454. if (check->lightlevel < min)
  455. min = check->lightlevel;
  456. }
  457. return min;
  458. }
  459. /*
  460. ==============================================================================
  461. EVENTS
  462. Events are operations triggered by using, crossing, or shooting special lines, or by timed thinkers
  463. ==============================================================================
  464. */
  465. /*
  466. ===============================================================================
  467. =
  468. = P_CrossSpecialLine - TRIGGER
  469. =
  470. = Called every time a thing origin is about to cross
  471. = a line with a non 0 special
  472. =
  473. ===============================================================================
  474. */
  475. void P_CrossSpecialLine(int linenum, int side, mobj_t *thing)
  476. {
  477. line_t *line;
  478. line = &lines[linenum];
  479. if(!thing->player)
  480. { // Check if trigger allowed by non-player mobj
  481. switch(line->special)
  482. {
  483. case 39: // Trigger_TELEPORT
  484. case 97: // Retrigger_TELEPORT
  485. case 4: // Trigger_Raise_Door
  486. //case 10: // PLAT DOWN-WAIT-UP-STAY TRIGGER
  487. //case 88: // PLAT DOWN-WAIT-UP-STAY RETRIGGER
  488. break;
  489. default:
  490. return;
  491. break;
  492. }
  493. }
  494. switch(line->special)
  495. {
  496. //====================================================
  497. // TRIGGERS
  498. //====================================================
  499. case 2: // Open Door
  500. EV_DoDoor(line,open,VDOORSPEED);
  501. line->special = 0;
  502. break;
  503. case 3: // Close Door
  504. EV_DoDoor(line,close,VDOORSPEED);
  505. line->special = 0;
  506. break;
  507. case 4: // Raise Door
  508. EV_DoDoor(line,normal,VDOORSPEED);
  509. line->special = 0;
  510. break;
  511. case 5: // Raise Floor
  512. EV_DoFloor(line,raiseFloor);
  513. line->special = 0;
  514. break;
  515. case 6: // Fast Ceiling Crush & Raise
  516. EV_DoCeiling(line,fastCrushAndRaise);
  517. line->special = 0;
  518. break;
  519. case 8: // Trigger_Build_Stairs (8 pixel steps)
  520. EV_BuildStairs(line, 8*FRACUNIT);
  521. line->special = 0;
  522. break;
  523. case 106: // Trigger_Build_Stairs_16 (16 pixel steps)
  524. EV_BuildStairs(line, 16*FRACUNIT);
  525. line->special = 0;
  526. break;
  527. case 10: // PlatDownWaitUp
  528. EV_DoPlat(line,downWaitUpStay,0);
  529. line->special = 0;
  530. break;
  531. case 12: // Light Turn On - brightest near
  532. EV_LightTurnOn(line,0);
  533. line->special = 0;
  534. break;
  535. case 13: // Light Turn On 255
  536. EV_LightTurnOn(line,255);
  537. line->special = 0;
  538. break;
  539. case 16: // Close Door 30
  540. EV_DoDoor(line,close30ThenOpen,VDOORSPEED);
  541. line->special = 0;
  542. break;
  543. case 17: // Start Light Strobing
  544. EV_StartLightStrobing(line);
  545. line->special = 0;
  546. break;
  547. case 19: // Lower Floor
  548. EV_DoFloor(line,lowerFloor);
  549. line->special = 0;
  550. break;
  551. case 22: // Raise floor to nearest height and change texture
  552. EV_DoPlat(line,raiseToNearestAndChange,0);
  553. line->special = 0;
  554. break;
  555. case 25: // Ceiling Crush and Raise
  556. EV_DoCeiling(line,crushAndRaise);
  557. line->special = 0;
  558. break;
  559. case 30: // Raise floor to shortest texture height
  560. // on either side of lines
  561. EV_DoFloor(line,raiseToTexture);
  562. line->special = 0;
  563. break;
  564. case 35: // Lights Very Dark
  565. EV_LightTurnOn(line,35);
  566. line->special = 0;
  567. break;
  568. case 36: // Lower Floor (TURBO)
  569. EV_DoFloor(line,turboLower);
  570. line->special = 0;
  571. break;
  572. case 37: // LowerAndChange
  573. EV_DoFloor(line,lowerAndChange);
  574. line->special = 0;
  575. break;
  576. case 38: // Lower Floor To Lowest
  577. EV_DoFloor( line, lowerFloorToLowest );
  578. line->special = 0;
  579. break;
  580. case 39: // TELEPORT!
  581. EV_Teleport( line, side, thing );
  582. line->special = 0;
  583. break;
  584. case 40: // RaiseCeilingLowerFloor
  585. EV_DoCeiling( line, raiseToHighest );
  586. EV_DoFloor( line, lowerFloorToLowest );
  587. line->special = 0;
  588. break;
  589. case 44: // Ceiling Crush
  590. EV_DoCeiling( line, lowerAndCrush );
  591. line->special = 0;
  592. break;
  593. case 52: // EXIT!
  594. G_ExitLevel ();
  595. line->special = 0;
  596. break;
  597. case 53: // Perpetual Platform Raise
  598. EV_DoPlat(line,perpetualRaise,0);
  599. line->special = 0;
  600. break;
  601. case 54: // Platform Stop
  602. EV_StopPlat(line);
  603. line->special = 0;
  604. break;
  605. case 56: // Raise Floor Crush
  606. EV_DoFloor(line,raiseFloorCrush);
  607. line->special = 0;
  608. break;
  609. case 57: // Ceiling Crush Stop
  610. EV_CeilingCrushStop(line);
  611. line->special = 0;
  612. break;
  613. case 58: // Raise Floor 24
  614. EV_DoFloor(line,raiseFloor24);
  615. line->special = 0;
  616. break;
  617. case 59: // Raise Floor 24 And Change
  618. EV_DoFloor(line,raiseFloor24AndChange);
  619. line->special = 0;
  620. break;
  621. case 104: // Turn lights off in sector(tag)
  622. EV_TurnTagLightsOff(line);
  623. line->special = 0;
  624. break;
  625. case 105: // Trigger_SecretExit
  626. G_SecretExitLevel();
  627. line->special = 0;
  628. break;
  629. //====================================================
  630. // RE-DOABLE TRIGGERS
  631. //====================================================
  632. case 72: // Ceiling Crush
  633. EV_DoCeiling( line, lowerAndCrush );
  634. break;
  635. case 73: // Ceiling Crush and Raise
  636. EV_DoCeiling(line,crushAndRaise);
  637. break;
  638. case 74: // Ceiling Crush Stop
  639. EV_CeilingCrushStop(line);
  640. break;
  641. case 75: // Close Door
  642. EV_DoDoor(line,close,VDOORSPEED);
  643. break;
  644. case 76: // Close Door 30
  645. EV_DoDoor(line,close30ThenOpen,VDOORSPEED);
  646. break;
  647. case 77: // Fast Ceiling Crush & Raise
  648. EV_DoCeiling(line,fastCrushAndRaise);
  649. break;
  650. case 79: // Lights Very Dark
  651. EV_LightTurnOn(line,35);
  652. break;
  653. case 80: // Light Turn On - brightest near
  654. EV_LightTurnOn(line,0);
  655. break;
  656. case 81: // Light Turn On 255
  657. EV_LightTurnOn(line,255);
  658. break;
  659. case 82: // Lower Floor To Lowest
  660. EV_DoFloor( line, lowerFloorToLowest );
  661. break;
  662. case 83: // Lower Floor
  663. EV_DoFloor(line,lowerFloor);
  664. break;
  665. case 84: // LowerAndChange
  666. EV_DoFloor(line,lowerAndChange);
  667. break;
  668. case 86: // Open Door
  669. EV_DoDoor(line,open,VDOORSPEED);
  670. break;
  671. case 87: // Perpetual Platform Raise
  672. EV_DoPlat(line,perpetualRaise,0);
  673. break;
  674. case 88: // PlatDownWaitUp
  675. EV_DoPlat(line,downWaitUpStay,0);
  676. break;
  677. case 89: // Platform Stop
  678. EV_StopPlat(line);
  679. break;
  680. case 90: // Raise Door
  681. EV_DoDoor(line,normal,VDOORSPEED);
  682. break;
  683. case 100: // Retrigger_Raise_Door_Turbo
  684. EV_DoDoor(line, normal, VDOORSPEED*3);
  685. break;
  686. case 91: // Raise Floor
  687. EV_DoFloor(line,raiseFloor);
  688. break;
  689. case 92: // Raise Floor 24
  690. EV_DoFloor(line,raiseFloor24);
  691. break;
  692. case 93: // Raise Floor 24 And Change
  693. EV_DoFloor(line,raiseFloor24AndChange);
  694. break;
  695. case 94: // Raise Floor Crush
  696. EV_DoFloor(line,raiseFloorCrush);
  697. break;
  698. case 95: // Raise floor to nearest height and change texture
  699. EV_DoPlat(line,raiseToNearestAndChange,0);
  700. break;
  701. case 96: // Raise floor to shortest texture height
  702. // on either side of lines
  703. EV_DoFloor(line,raiseToTexture);
  704. break;
  705. case 97: // TELEPORT!
  706. EV_Teleport( line, side, thing );
  707. break;
  708. case 98: // Lower Floor (TURBO)
  709. EV_DoFloor(line,turboLower);
  710. break;
  711. }
  712. }
  713. //----------------------------------------------------------------------------
  714. //
  715. // PROC P_ShootSpecialLine
  716. //
  717. // Called when a thing shoots a special line.
  718. //
  719. //----------------------------------------------------------------------------
  720. void P_ShootSpecialLine(mobj_t *thing, line_t *line)
  721. {
  722. if(!thing->player)
  723. { // Check if trigger allowed by non-player mobj
  724. switch(line->special)
  725. {
  726. case 46: // Impact_OpenDoor
  727. break;
  728. default:
  729. return;
  730. break;
  731. }
  732. }
  733. switch(line->special)
  734. {
  735. case 24: // Impact_RaiseFloor
  736. EV_DoFloor(line, raiseFloor);
  737. P_ChangeSwitchTexture(line, 0);
  738. break;
  739. case 46: // Impact_OpenDoor
  740. EV_DoDoor(line, open, VDOORSPEED);
  741. P_ChangeSwitchTexture(line, 1);
  742. break;
  743. case 47: // Impact_RaiseFloorNear&Change
  744. EV_DoPlat(line, raiseToNearestAndChange, 0);
  745. P_ChangeSwitchTexture(line, 0);
  746. break;
  747. }
  748. }
  749. //----------------------------------------------------------------------------
  750. //
  751. // PROC P_PlayerInSpecialSector
  752. //
  753. // Called every tic frame that the player origin is in a special sector.
  754. //
  755. //----------------------------------------------------------------------------
  756. void P_PlayerInSpecialSector(player_t *player)
  757. {
  758. sector_t *sector;
  759. static int pushTab[5] = {
  760. 2048*5,
  761. 2048*10,
  762. 2048*25,
  763. 2048*30,
  764. 2048*35
  765. };
  766. sector = player->mo->subsector->sector;
  767. if(player->mo->z != sector->floorheight)
  768. { // Player is not touching the floor
  769. return;
  770. }
  771. switch(sector->special)
  772. {
  773. case 7: // Damage_Sludge
  774. if(!(leveltime&31))
  775. {
  776. P_DamageMobj(player->mo, NULL, NULL, 4);
  777. }
  778. break;
  779. case 5: // Damage_LavaWimpy
  780. if(!(leveltime&15))
  781. {
  782. P_DamageMobj(player->mo, &LavaInflictor, NULL, 5);
  783. P_HitFloor(player->mo);
  784. }
  785. break;
  786. case 16: // Damage_LavaHefty
  787. if(!(leveltime&15))
  788. {
  789. P_DamageMobj(player->mo, &LavaInflictor, NULL, 8);
  790. P_HitFloor(player->mo);
  791. }
  792. break;
  793. case 4: // Scroll_EastLavaDamage
  794. P_Thrust(player, 0, 2048*28);
  795. if(!(leveltime&15))
  796. {
  797. P_DamageMobj(player->mo, &LavaInflictor, NULL, 5);
  798. P_HitFloor(player->mo);
  799. }
  800. break;
  801. case 9: // SecretArea
  802. player->secretcount++;
  803. sector->special = 0;
  804. break;
  805. case 11: // Exit_SuperDamage (DOOM E1M8 finale)
  806. /*
  807. player->cheats &= ~CF_GODMODE;
  808. if(!(leveltime&0x1f))
  809. {
  810. P_DamageMobj(player->mo, NULL, NULL, 20);
  811. }
  812. if(player->health <= 10)
  813. {
  814. G_ExitLevel();
  815. }
  816. */
  817. break;
  818. case 25: case 26: case 27: case 28: case 29: // Scroll_North
  819. P_Thrust(player, ANG90, pushTab[sector->special-25]);
  820. break;
  821. case 20: case 21: case 22: case 23: case 24: // Scroll_East
  822. P_Thrust(player, 0, pushTab[sector->special-20]);
  823. break;
  824. case 30: case 31: case 32: case 33: case 34: // Scroll_South
  825. P_Thrust(player, ANG270, pushTab[sector->special-30]);
  826. break;
  827. case 35: case 36: case 37: case 38: case 39: // Scroll_West
  828. P_Thrust(player, ANG180, pushTab[sector->special-35]);
  829. break;
  830. case 40: case 41: case 42: case 43: case 44: case 45:
  831. case 46: case 47: case 48: case 49: case 50: case 51:
  832. // Wind specials are handled in (P_mobj):P_XYMovement
  833. break;
  834. case 15: // Friction_Low
  835. // Only used in (P_mobj):P_XYMovement and (P_user):P_Thrust
  836. break;
  837. default:
  838. I_Error("P_PlayerInSpecialSector: "
  839. "unknown special %i", sector->special);
  840. }
  841. }
  842. //----------------------------------------------------------------------------
  843. //
  844. // PROC P_UpdateSpecials
  845. //
  846. // Animate planes, scroll walls, etc.
  847. //
  848. //----------------------------------------------------------------------------
  849. void P_UpdateSpecials(void)
  850. {
  851. int i;
  852. int pic;
  853. anim_t *anim;
  854. line_t *line;
  855. // Animate flats and textures
  856. for(anim = anims; anim < lastanim; anim++)
  857. {
  858. for(i = anim->basepic; i < anim->basepic+anim->numpics; i++)
  859. {
  860. pic = anim->basepic+((leveltime/anim->speed+i)%anim->numpics);
  861. if(anim->istexture)
  862. {
  863. texturetranslation[i] = pic;
  864. }
  865. else
  866. {
  867. flattranslation[i] = pic;
  868. }
  869. }
  870. }
  871. // Update scrolling texture offsets
  872. for(i = 0; i < numlinespecials; i++)
  873. {
  874. line = linespeciallist[i];
  875. switch(line->special)
  876. {
  877. case 48: // Effect_Scroll_Left
  878. sides[line->sidenum[0]].textureoffset += FRACUNIT;
  879. break;
  880. case 99: // Effect_Scroll_Right
  881. sides[line->sidenum[0]].textureoffset -= FRACUNIT;
  882. break;
  883. }
  884. }
  885. // Handle buttons
  886. for(i = 0; i < MAXBUTTONS; i++)
  887. {
  888. if(buttonlist[i].btimer)
  889. {
  890. buttonlist[i].btimer--;
  891. if(!buttonlist[i].btimer)
  892. {
  893. switch(buttonlist[i].where)
  894. {
  895. case top:
  896. sides[buttonlist[i].line->sidenum[0]].toptexture =
  897. buttonlist[i].btexture;
  898. break;
  899. case middle:
  900. sides[buttonlist[i].line->sidenum[0]].midtexture =
  901. buttonlist[i].btexture;
  902. break;
  903. case bottom:
  904. sides[buttonlist[i].line->sidenum[0]].bottomtexture =
  905. buttonlist[i].btexture;
  906. break;
  907. }
  908. S_StartSound((mobj_t *)&buttonlist[i].soundorg, sfx_switch);
  909. memset(&buttonlist[i], 0, sizeof(button_t));
  910. }
  911. }
  912. }
  913. }
  914. //============================================================
  915. //
  916. // Special Stuff that can't be categorized
  917. //
  918. //============================================================
  919. int EV_DoDonut(line_t *line)
  920. {
  921. sector_t *s1;
  922. sector_t *s2;
  923. sector_t *s3;
  924. int secnum;
  925. int rtn;
  926. int i;
  927. floormove_t *floor;
  928. secnum = -1;
  929. rtn = 0;
  930. while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
  931. {
  932. s1 = &sectors[secnum];
  933. // ALREADY MOVING? IF SO, KEEP GOING...
  934. if (s1->specialdata)
  935. continue;
  936. rtn = 1;
  937. s2 = getNextSector(s1->lines[0],s1);
  938. for (i = 0;i < s2->linecount;i++)
  939. {
  940. if ((!s2->lines[i]->flags & ML_TWOSIDED) ||
  941. (s2->lines[i]->backsector == s1))
  942. continue;
  943. s3 = s2->lines[i]->backsector;
  944. //
  945. // Spawn rising slime
  946. //
  947. floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0);
  948. P_AddThinker (&floor->thinker);
  949. s2->specialdata = floor;
  950. floor->thinker.function = T_MoveFloor;
  951. floor->type = donutRaise;
  952. floor->crush = false;
  953. floor->direction = 1;
  954. floor->sector = s2;
  955. floor->speed = FLOORSPEED / 2;
  956. floor->texture = s3->floorpic;
  957. floor->newspecial = 0;
  958. floor->floordestheight = s3->floorheight;
  959. //
  960. // Spawn lowering donut-hole
  961. //
  962. floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0);
  963. P_AddThinker (&floor->thinker);
  964. s1->specialdata = floor;
  965. floor->thinker.function = T_MoveFloor;
  966. floor->type = lowerFloor;
  967. floor->crush = false;
  968. floor->direction = -1;
  969. floor->sector = s1;
  970. floor->speed = FLOORSPEED / 2;
  971. floor->floordestheight = s3->floorheight;
  972. break;
  973. }
  974. }
  975. return rtn;
  976. }
  977. /*
  978. ==============================================================================
  979. SPECIAL SPAWNING
  980. ==============================================================================
  981. */
  982. /*
  983. ================================================================================
  984. = P_SpawnSpecials
  985. =
  986. = After the map has been loaded, scan for specials that
  987. = spawn thinkers
  988. =
  989. ===============================================================================
  990. */
  991. short numlinespecials;
  992. line_t *linespeciallist[MAXLINEANIMS];
  993. void P_SpawnSpecials (void)
  994. {
  995. sector_t *sector;
  996. int i;
  997. int episode;
  998. episode = 1;
  999. if (W_CheckNumForName("texture2") >= 0)
  1000. episode = 2;
  1001. //
  1002. // Init special SECTORs
  1003. //
  1004. sector = sectors;
  1005. for (i=0 ; i<numsectors ; i++, sector++)
  1006. {
  1007. if (!sector->special)
  1008. continue;
  1009. switch (sector->special)
  1010. {
  1011. case 1: // FLICKERING LIGHTS
  1012. P_SpawnLightFlash (sector);
  1013. break;
  1014. case 2: // STROBE FAST
  1015. P_SpawnStrobeFlash(sector,FASTDARK,0);
  1016. break;
  1017. case 3: // STROBE SLOW
  1018. P_SpawnStrobeFlash(sector,SLOWDARK,0);
  1019. break;
  1020. case 4: // STROBE FAST/DEATH SLIME
  1021. P_SpawnStrobeFlash(sector,FASTDARK,0);
  1022. sector->special = 4;
  1023. break;
  1024. case 8: // GLOWING LIGHT
  1025. P_SpawnGlowingLight(sector);
  1026. break;
  1027. case 9: // SECRET SECTOR
  1028. totalsecret++;
  1029. break;
  1030. case 10: // DOOR CLOSE IN 30 SECONDS
  1031. P_SpawnDoorCloseIn30 (sector);
  1032. break;
  1033. case 12: // SYNC STROBE SLOW
  1034. P_SpawnStrobeFlash (sector, SLOWDARK, 1);
  1035. break;
  1036. case 13: // SYNC STROBE FAST
  1037. P_SpawnStrobeFlash (sector, FASTDARK, 1);
  1038. break;
  1039. case 14: // DOOR RAISE IN 5 MINUTES
  1040. P_SpawnDoorRaiseIn5Mins (sector, i);
  1041. break;
  1042. }
  1043. }
  1044. //
  1045. // Init line EFFECTs
  1046. //
  1047. numlinespecials = 0;
  1048. for (i = 0;i < numlines; i++)
  1049. switch(lines[i].special)
  1050. {
  1051. case 48: // Effect_Scroll_Left
  1052. case 99: // Effect_Scroll_Right
  1053. linespeciallist[numlinespecials] = &lines[i];
  1054. numlinespecials++;
  1055. break;
  1056. }
  1057. //
  1058. // Init other misc stuff
  1059. //
  1060. for (i = 0;i < MAXCEILINGS;i++)
  1061. activeceilings[i] = NULL;
  1062. for (i = 0;i < MAXPLATS;i++)
  1063. activeplats[i] = NULL;
  1064. for (i = 0;i < MAXBUTTONS;i++)
  1065. memset(&buttonlist[i],0,sizeof(button_t));
  1066. }
  1067. //----------------------------------------------------------------------------
  1068. //
  1069. // PROC P_InitAmbientSound
  1070. //
  1071. //----------------------------------------------------------------------------
  1072. void P_InitAmbientSound(void)
  1073. {
  1074. AmbSfxCount = 0;
  1075. AmbSfxVolume = 0;
  1076. AmbSfxTics = 10*TICSPERSEC;
  1077. AmbSfxPtr = AmbSndSeqInit;
  1078. }
  1079. //----------------------------------------------------------------------------
  1080. //
  1081. // PROC P_AddAmbientSfx
  1082. //
  1083. // Called by (P_mobj):P_SpawnMapThing during (P_setup):P_SetupLevel.
  1084. //
  1085. //----------------------------------------------------------------------------
  1086. void P_AddAmbientSfx(int sequence)
  1087. {
  1088. if(AmbSfxCount == MAX_AMBIENT_SFX)
  1089. {
  1090. I_Error("Too many ambient sound sequences");
  1091. }
  1092. LevelAmbientSfx[AmbSfxCount++] = AmbientSfx[sequence];
  1093. }
  1094. //----------------------------------------------------------------------------
  1095. //
  1096. // PROC P_AmbientSound
  1097. //
  1098. // Called every tic by (P_tick):P_Ticker.
  1099. //
  1100. //----------------------------------------------------------------------------
  1101. void P_AmbientSound(void)
  1102. {
  1103. afxcmd_t cmd;
  1104. int sound;
  1105. boolean done;
  1106. if(!AmbSfxCount)
  1107. { // No ambient sound sequences on current level
  1108. return;
  1109. }
  1110. if(--AmbSfxTics)
  1111. {
  1112. return;
  1113. }
  1114. done = false;
  1115. do
  1116. {
  1117. cmd = *AmbSfxPtr++;
  1118. switch(cmd)
  1119. {
  1120. case afxcmd_play:
  1121. AmbSfxVolume = P_Random()>>2;
  1122. S_StartSoundAtVolume(NULL, *AmbSfxPtr++, AmbSfxVolume);
  1123. break;
  1124. case afxcmd_playabsvol:
  1125. sound = *AmbSfxPtr++;
  1126. AmbSfxVolume = *AmbSfxPtr++;
  1127. S_StartSoundAtVolume(NULL, sound, AmbSfxVolume);
  1128. break;
  1129. case afxcmd_playrelvol:
  1130. sound = *AmbSfxPtr++;
  1131. AmbSfxVolume += *AmbSfxPtr++;
  1132. if(AmbSfxVolume < 0)
  1133. {
  1134. AmbSfxVolume = 0;
  1135. }
  1136. else if(AmbSfxVolume > 127)
  1137. {
  1138. AmbSfxVolume = 127;
  1139. }
  1140. S_StartSoundAtVolume(NULL, sound, AmbSfxVolume);
  1141. break;
  1142. case afxcmd_delay:
  1143. AmbSfxTics = *AmbSfxPtr++;
  1144. done = true;
  1145. break;
  1146. case afxcmd_delayrand:
  1147. AmbSfxTics = P_Random()&(*AmbSfxPtr++);
  1148. done = true;
  1149. break;
  1150. case afxcmd_end:
  1151. AmbSfxTics = 6*TICSPERSEC+P_Random();
  1152. AmbSfxPtr = LevelAmbientSfx[P_Random()%AmbSfxCount];
  1153. done = true;
  1154. break;
  1155. default:
  1156. I_Error("P_AmbientSound: Unknown afxcmd %d", cmd);
  1157. break;
  1158. }
  1159. } while(done == false);
  1160. }