1 // Emacs style mode select -*- C++ -*-
2 //-----------------------------------------------------------------------------
3 //
4 // $Id: p_heretic.c 1451 2019-08-03 07:02:00Z wesleyjohnson $
5 //
6 // Copyright (C) 1993-1996 by Raven Software, Corp.
7 // Portions Copyright (C) 1998-2000 by DooM Legacy Team.
8 //
9 // This program is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU General Public License
11 // as published by the Free Software Foundation; either version 2
12 // of the License, or (at your option) any later version.
13 //
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
18 //
19 //
20 // $Log: p_heretic.c,v $
21 // Revision 1.7 2001/07/16 22:35:41 bpereira
22 // - fixed crash of e3m8 in heretic
23 // - fixed crosshair not drawed bug
24 //
25 // Revision 1.6 2001/05/27 13:42:47 bpereira
26 // Revision 1.5 2001/03/30 17:12:50 bpereira
27 // Revision 1.4 2001/02/24 13:35:20 bpereira
28 // Revision 1.3 2001/02/10 13:20:55 hurdler
29 // update license
30 //
31 //
32 //
33 // DESCRIPTION:
34 // Heretic sound and other specifics.
35 //
36 //-----------------------------------------------------------------------------
37
38 #include "doomincl.h"
39 #include "g_game.h"
40 #include "p_local.h"
41 #include "r_main.h"
42 #include "r_state.h"
43 #include "s_sound.h"
44 #include "m_random.h"
45 #include "dstrings.h"
46
47 //---------------------------------------------------------------------------
48 //
49 // PROC A_ContMobjSound
50 //
51 //---------------------------------------------------------------------------
52
A_ContMobjSound(mobj_t * actor)53 void A_ContMobjSound(mobj_t *actor)
54 {
55 switch(actor->type)
56 {
57 case MT_KNIGHTAXE:
58 S_StartObjSound(actor, sfx_kgtatk);
59 break;
60 case MT_MUMMYFX1:
61 S_StartObjSound(actor, sfx_mumhed);
62 break;
63 default:
64 break;
65 }
66 }
67
68 //----------------------------------------------------------------------------
69 //
70 // FUNC P_FaceMobj
71 //
72 // Returns 1 if 'source' needs to turn clockwise, or 0 if 'source' needs
73 // to turn counter clockwise. 'delta' is set to the amount 'source'
74 // needs to turn.
75 //
76 //----------------------------------------------------------------------------
P_FaceMobj(mobj_t * source,mobj_t * target,angle_t * delta)77 int P_FaceMobj(mobj_t *source, mobj_t *target, angle_t *delta)
78 {
79 angle_t angle1, angle2, diff;
80
81 angle1 = source->angle;
82 angle2 = R_PointToAngle2(source->x, source->y, target->x, target->y);
83 if(angle2 > angle1)
84 {
85 diff = angle2 - angle1;
86 if(diff > ANG180)
87 {
88 *delta = ANGLE_MAX - diff;
89 return 0;
90 }
91 else
92 {
93 *delta = diff;
94 return 1;
95 }
96 }
97 else
98 {
99 diff = angle1 - angle2;
100 if(diff > ANG180)
101 {
102 *delta = ANGLE_MAX - diff;
103 return 1;
104 }
105 else
106 {
107 *delta = diff;
108 return 0;
109 }
110 }
111 }
112
113 //----------------------------------------------------------------------------
114 //
115 // FUNC P_SeekerMissile
116 //
117 // The missile tracer field must be mobj_t *target. Returns true if
118 // target was tracked, false if not.
119 //
120 //----------------------------------------------------------------------------
121
P_SeekerMissile(mobj_t * actor,angle_t thresh,angle_t turnMax)122 boolean P_SeekerMissile(mobj_t *actor, angle_t thresh, angle_t turnMax)
123 {
124 int dir;
125 int dist;
126 angle_t delta;
127 mobj_t *target;
128
129 target = actor->tracer;
130 if(target == NULL)
131 {
132 return false;
133 }
134 if(!(target->flags&MF_SHOOTABLE))
135 { // Target died
136 actor->tracer = 0;
137 return false;
138 }
139 dir = P_FaceMobj(actor, target, &delta);
140 if(delta > thresh)
141 {
142 delta >>= 1;
143 if(delta > turnMax)
144 {
145 delta = turnMax;
146 }
147 }
148 if(dir)
149 { // Turn clockwise
150 actor->angle += delta;
151 }
152 else
153 { // Turn counter clockwise
154 actor->angle -= delta;
155 }
156 int angf = ANGLE_TO_FINE(actor->angle);
157 actor->momx = FixedMul(actor->info->speed, finecosine[angf]);
158 actor->momy = FixedMul(actor->info->speed, finesine[angf]);
159 if(actor->z+actor->height < target->z ||
160 target->z+target->height < actor->z)
161 { // Need to seek vertically
162 dist = P_AproxDistance(target->x-actor->x, target->y-actor->y);
163 dist = dist/actor->info->speed;
164 if(dist < 1)
165 dist = 1;
166 actor->momz = (target->z+(target->height>>1)
167 -(actor->z+(actor->height>>1)))/dist;
168 }
169 return true;
170 }
171
172 //---------------------------------------------------------------------------
173 //
174 // FUNC P_SpawnMissileAngle
175 //
176 // Returns NULL if the missile exploded immediately, otherwise returns
177 // a mobj_t pointer to the missile.
178 //
179 //---------------------------------------------------------------------------
180
P_SpawnMissileAngle(mobj_t * source,mobjtype_t type,angle_t angle,fixed_t momz)181 mobj_t *P_SpawnMissileAngle(mobj_t *source, mobjtype_t type,
182 angle_t angle, fixed_t momz)
183 {
184 fixed_t z;
185 mobj_t *mo;
186
187 switch(type)
188 {
189 case MT_MNTRFX1: // Minotaur swing attack missile
190 z = source->z+40*FRACUNIT;
191 break;
192 case MT_MNTRFX2: // Minotaur floor fire missile
193 z = ONFLOORZ;
194 break;
195 case MT_SRCRFX1: // Sorcerer Demon fireball
196 z = source->z+48*FRACUNIT;
197 break;
198 default:
199 z = source->z+32*FRACUNIT;
200 break;
201 }
202 if(source->flags2&MF2_FEETARECLIPPED)
203 {
204 z -= FOOTCLIPSIZE;
205 }
206 mo = P_SpawnMobj(source->x, source->y, z, type);
207 if(mo->info->seesound)
208 {
209 S_StartObjSound(mo, mo->info->seesound);
210 }
211 mo->target = source; // Originator
212 mo->angle = angle;
213 // This one spot does not pull common expressions well, explicit is smaller.
214 int angf = ANGLE_TO_FINE( angle );
215 fixed_t speed = mo->info->speed;
216 mo->momx = FixedMul(speed, finecosine[angf]);
217 mo->momy = FixedMul(speed, finesine[angf]);
218 mo->momz = momz;
219 return (P_CheckMissileSpawn(mo) ? mo : NULL);
220 }
221
222
223 extern int GetWeaponAmmo[];
224 extern byte cheat_mus_seq[];
225 extern byte cheat_choppers_seq[];
226 extern byte cheat_god_seq[];
227 extern byte cheat_ammo_seq[];
228 extern byte cheat_ammonokey_seq[];
229 extern byte cheat_noclip_seq[];
230 extern byte cheat_commercial_noclip_seq[];
231 extern byte cheat_powerup_seq[7][10];
232 extern byte cheat_clev_seq[];
233 extern byte cheat_mypos_seq[];
234 extern byte cheat_amap_seq[];
235
236
237 // [WDJ] Reversible Heretic/Doom info table installation.
238 typedef struct {
239 uint16_t doomednum;
240 uint16_t doom_mt;
241 uint16_t heretic_mt;
242 } doomednum_install_t;
243
244 // Order is not important. Only needs to include those doomednum that conflict.
245 static const doomednum_install_t doomednum_install_table[] = {
246 { 7, MT_SPIDER, MT_SORCERER1 }, // SORCERER (monster)
247 { 9, MT_SHOTGUY, MT_MINOTAUR }, // MINOTAUR (monster)
248 { 16, MT_CYBORG, MT_AMMACEHEFTY }, // MACE BALL STACK (ammo M mace)
249 { 64, MT_VILE, MT_HKNIGHT }, // KNIGHT (monster undead)
250 { 65, MT_CHAINGUY, MT_KNIGHTGHOST }, // KNIGHT GHOST (monster undead)
251 { 66, MT_UNDEAD, MT_IMP }, // IMP (monster flying)
252 { 68, MT_BABY, MT_MUMMY }, // MUMMY (monster)
253 { 69, MT_KNIGHT, MT_MUMMYGHOST }, // MUMMY GHOST (monster)
254 { 82, MT_SUPERSHOTGUN, MT_HMISC3 }, // QUARTZ FLASK (health)
255 { 83, MT_MEGA, MT_ARTIFLY }, // WINGS (artifact)
256 { 84, MT_WOLFSS, MT_ARTIINVULNERABILITY }, // INVULNERABLE (artifact invul)
257 { 87, MT_BOSSTARGET, MT_HMISC12 }, // VOLCANO SPEWER
258 { 2001, MT_SHOTGUN, MT_HMISC15 }, // CROSSBOW (weapon)
259 { 2002, MT_CHAINGUN, MT_WMACE }, // MACE (weapon)
260 { 2003, MT_ROCKETLAUNCH, MT_WPHOENIXROD }, // PHOENIX ROD (weapon)
261 { 2004, MT_PLASMAGUN, MT_WSKULLROD }, // SKULL ROD, HELLSTAFF (weapon)
262 { 2005, MT_SHAINSAW, MT_HMISC13 }, // GAUNTLETS (weapon)
263 { 2035, MT_BARREL, MT_POD }, // POD (exploding)
264 { 5, MT_MISC4, MT_IMPLEADER }, // IMP LEADER (monster flying)
265 { 13, MT_MISC5, MT_AMMACEWIMPY }, // MACE BALL (ammo S mace)
266 { 6, MT_MISC6, MT_HHEAD }, // HEAD (monster)
267 { 39, MT_MISC7, MT_STALACTITESMALL }, // STALACTITE SMALL
268 { 38, MT_MISC8, MT_STALAGMITELARGE }, // STALAGMITE LARGE
269 { 40, MT_MISC9, MT_STALACTITELARGE }, // STALACTITE LARGE
270 { 17, MT_MISC21, MT_SKULLHANG70 }, // HANGING SKULL 70
271 { 8, MT_MISC24, MT_HMISC1 }, // BAG OF HOLDING (knapsack)
272 { 85, MT_MISC29, MT_ITEMSHIELD1 }, // SILVER SHIELD (armor)
273 { 86, MT_MISC30, MT_ARTITOMEOFPOWER }, // TOME (artifact)
274 { 30, MT_MISC32, MT_ARTIEGG }, // EGG (artifact)
275 { 31, MT_MISC33, MT_ITEMSHIELD2 }, // SHIELD MEGA (armor)
276 { 32, MT_MISC34, MT_ARTISUPERHEAL }, // SUPER HEAL (artifact health)
277 { 33, MT_MISC35, MT_HMISC4 }, // TORCH (artifact torch)
278 { 37, MT_MISC36, MT_STALAGMITESMALL }, // STALAGMITE SMALL
279 { 36, MT_MISC37, MT_ARTITELEPORT }, // (artifact teleport)
280 { 41, MT_MISC38, MT_SOUNDWATERFALL }, // SOUND WATERFALL (ambience sound)
281 { 42, MT_MISC39, MT_SOUNDWIND }, // SOUND WIND (ambience sound)
282 { 43, MT_MISC40, MT_PODGENERATOR }, // POD GENERATOR
283 { 44, MT_MISC41, MT_HBARREL }, // BARREL
284 { 45, MT_MISC42, MT_MUMMYLEADER }, // MUMMY LEADER (monster)
285 { 46, MT_MISC43, MT_MUMMYLEADERGHOST }, // MUMMY LEADER GHOST (monster)
286 { 55, MT_MISC44, MT_AMBLSRHEFTY }, // ENERGY ORB LARGE (ammo M claw)
287 { 56, MT_MISC45, 0xFFFF }, // heretic use it for monster spawn
288 { 47, MT_MISC47, MT_HMISC7 }, // PILLAR BROWN
289 { 48, MT_MISC48, MT_HMISC8 }, // MOSS 1
290 { 34, MT_MISC49, MT_HMISC5 }, // BOMB (exploding timed)
291 { 35, MT_MISC50, MT_HMISC2 }, // MAP (special)
292 { 49, MT_MISC51, MT_HMISC9 }, // MOSS 2
293 { 50, MT_MISC52, MT_HMISC10 }, // WALL TORCH (torch)
294 { 51, MT_MISC53, MT_HMISC11 }, // HANGING CORPSE
295 { 52, MT_MISC54, MT_TELEGLITGEN2 }, // TELEPORT GLITTER GENERATOR 2
296 { 53, MT_MISC55, MT_HMISC14 }, // DRAGON CLAW (weapon)
297 { 22, MT_MISC61, MT_AMPHRDWIMPY }, // FLAME ORB (ammo S phoenix rod)
298 { 15, MT_MISC62, MT_WIZARD }, // WIZARD (monster floating)
299 { 18, MT_MISC63, MT_AMCBOWWIMPY }, // ETHEREAL ARROWS (ammo S crossbow)
300 { 21, MT_MISC64, MT_AMSKRDHEFTY }, // GREATER RUNES (ammo M skull rod)
301 { 23, MT_MISC65, MT_AMPHRDHEFTY }, // FLAME ORB LARGE (ammo M phoenix rod)
302 { 20, MT_MISC66, MT_AMSKRDWIMPY }, // LESSER RUNES (ammo S skull rod)
303 { 19, MT_MISC67, MT_AMCBOWHEFTY }, // ETHEREAL ARROWS QUIVER (ammo M crossbow)
304 { 10, MT_MISC68, MT_AMGWNDWIMPY }, // WAND CRYSTAL (ammo S staff)
305 { 12, MT_MISC69, MT_AMGWNDHEFTY }, // WAND CRYSTAL LARGE (ammo M staff)
306 { 28, MT_MISC70, MT_CHANDELIER }, // CHANDELIER
307 { 24, MT_MISC71, MT_SKULLHANG60 }, // HANGING SKULL 60
308 { 27, MT_MISC72, MT_SERPTORCH }, // SERPENT TORCH (torch)
309 { 29, MT_MISC73, MT_SMALLPILLAR }, // PILLAR SMALL
310 { 25, MT_MISC74, MT_SKULLHANG45 }, // HANGING SKULL 45
311 { 26, MT_MISC75, MT_SKULLHANG35 }, // HANGING SKULL 35
312 { 54, MT_MISC76, MT_AMBLSRWIMPY }, // CLAW ORB (ammo S claw)
313 { 70, MT_MISC77, MT_BEAST }, // BEAST (monster)
314 { 73, MT_MISC78, MT_AKYY }, // GREEN KEY (key)
315 { 74, MT_MISC79, MT_TELEGLITGEN }, // TELEPORT GLITTER GENERATOR 1
316 { 75, MT_MISC80, MT_ARTIINVISIBILITY }, // INVISIBLE (artifact invis)
317 { 76, MT_MISC81, MT_HMISC6 }, // FIRE BRAZIER (torch)
318 { 79, MT_MISC84, MT_BKYY }, // BLUE KEY (key)
319 { 80, MT_MISC85, MT_CKEY }, // YELLOW KEY (key)
320 { 81, MT_MISC86, MT_HMISC0 }, // CRYSTAL VIAL (health)
321 { 0xFFFF, 0xFFFF, 0xFFFF }, // END
322 };
323
324 #if 0
325 void doomednum_check( byte heretic_check )
326 {
327 doomednum_install_t * ii;
328 for( ii = & doomednum_install_table[0]; ii->doomednum < 0xFFFF; ii++ )
329 {
330 uint16_t mt = ( heretic_check )? ii->heretic_mt : ii->doom_mt;
331 if( mt < NUMMOBJTYPES )
332 if( mobjinfo[ mt ].doomednum != ii->doomednum )
333 printf( "MOBJINFO[%i].doomednum=%i, TABLE doomednum=%i, doom_mt=%i, heretic_mt=%i\n", mt, mobjinfo[mt].doomednum, ii->doomednum, ii->doom_mt, ii->heretic_mt );
334 }
335 }
336 #endif
337
doomednum_install(byte set_heretic)338 void doomednum_install( byte set_heretic )
339 {
340 const doomednum_install_t * ii;
341 uint16_t cancel_mt, set_mt;
342 for( ii = & doomednum_install_table[0]; ii->doomednum < 0xFFFF; ii++ )
343 {
344 cancel_mt = ( set_heretic )? ii->doom_mt : ii->heretic_mt;
345 set_mt = ( set_heretic )? ii->heretic_mt : ii->doom_mt;
346 if( cancel_mt < NUMMOBJTYPES )
347 {
348 if( mobjinfo[ cancel_mt ].doomednum == ii->doomednum )
349 mobjinfo[ cancel_mt ].doomednum = -1;
350 }
351 if( set_mt < NUMMOBJTYPES )
352 mobjinfo[ set_mt ].doomednum = ii->doomednum;
353 }
354 }
355
356
357 // [WDJ] Reversible Heretic/Doom Ammo table installation.
358 typedef struct {
359 uint16_t max_val;
360 byte clip_val;
361 } ammo_install_t;
362
363 // Index by ammotype_t
364 static const ammo_install_t heretic_ammo_table[NUMAMMO] = {
365 { 100, 5 }, // am_goldwand, clip used in deathmatch 1 & 3 mul by 5 (P_GiveWeapon)
366 { 50, 2 }, // am_crossbow
367 { 200, 6 }, // am_blaster
368 { 200, 10 }, // am_skullrod
369 { 20, 1 }, // am_phoenixrod
370 { 150, 10 }, // am_mace
371 };
372
373 // Index by ammotype_t
374 static const ammo_install_t doom_ammo_table[NUMAMMO] = {
375 { 200, 10 }, // am_clip
376 { 50, 4 }, // am_shell
377 { 300, 20 }, // am_cell
378 { 50, 1 }, // am_misl
379 { 0, 0 },
380 { 0, 0 },
381 };
382
383 // Index by weapontype_t
384 static const byte heretic_weapon_ammo_table[NUMWEAPONS] = {
385 0, // wp_staff
386 25, // wp_goldwand
387 10, // wp_crossbow
388 30, // wp_blaster
389 50, // wp_skullrod
390 2, // wp_phoenixrod
391 50, // wp_mace
392 0, // wp_gauntlets
393 0, // wp_beak
394 };
395
396 // Index by weapontype_t
397 static const byte doom_weapon_ammo_table[NUMWEAPONS] = {
398 0, // wp_fist
399 20, // wp_pistol
400 8, // wp_shotgun
401 20, // wp_chaingun
402 2, // wp_missle
403 40, // wp_plasma
404 40, // wp_bfg
405 0, // wp_chainsaw
406 8, // wp_supershotgun
407 };
408
409
410 // [WDJ] Reversible Heretic/Doom Sfx table installation.
411 typedef struct {
412 sfxid_t sfxid; // sfxenum_e
413 char * name;
414 byte priority;
415 } sfx_install_t;
416
417 static const sfx_install_t heretic_sfx_table[] = {
418 { sfx_oof, "plroof", 32 },
419 { sfx_swtchn, "switch", 40 },
420 { sfx_swtchx, "switch", 40 },
421 { sfx_telept, "telept", 50 },
422 { sfx_sawup, "gntact", 32 }, // gauntlets
423 { sfx_pistol, "keyup", 64 }, // for the menu
424 { sfx_tink, "chat", 100 },
425 { sfx_itmbk, "respawn", 10 },
426 { 0xFFFF, NULL, 0 }
427 };
428
429 // To undo heretic install.
430 static const sfx_install_t doom_sfx_table[] = {
431 { sfx_oof, "oof\0\0\0", 96 },
432 { sfx_swtchn, "swtchn", 78 },
433 { sfx_swtchx, "swtchx", 78 },
434 { sfx_telept, "telept", 32 },
435 { sfx_sawup, "sawup\0", 64 }, // chainsaw
436 { sfx_pistol, "pistol", 64 }, // pistol
437 { sfx_tink, "tink\0\0", 60 },
438 { sfx_itmbk, "itmbk\0", 100 },
439 { 0xFFFF, NULL, 0 }
440 };
441
442
443 // [WDJ] Reversible Heretic/Doom text table installation.
444 typedef struct {
445 uint16_t textid;
446 char * text;
447 } text_install_t;
448
449 static const text_install_t heretic_text_table[] = {
450 { PD_BLUEK_NUM, "YOU NEED A BLUE KEY TO OPEN THIS DOOR" },
451 { PD_YELLOWK_NUM, "YOU NEED A YELLOW KEY TO OPEN THIS DOOR" },
452 { PD_REDK_NUM, "YOU NEED A GREEN KEY TO OPEN THIS DOOR" },
453 { GOTBLUECARD_NUM, "BLUE KEY" },
454 { GOTYELWCARD_NUM, "YELLOW KEY" },
455 { GOTREDCARD_NUM, "GREEN KEY" },
456 { GOTARMOR_NUM, "SILVER SHIELD" },
457 { GOTMEGA_NUM, "ENCHANTED SHIELD" },
458 { GOTSTIM_NUM, "CRYSTAL VIAL" },
459 { GOTMAP_NUM, "MAP SCROLL" },
460 { 0xFFFF, NULL }
461 };
462
463 static const text_install_t doom_text_table[] = {
464 { PD_BLUEK_NUM, "You need a blue key to open this door" },
465 { PD_YELLOWK_NUM, "You need a yellow key to open this door" },
466 { PD_REDK_NUM, "You need a red key to open this door" },
467 { GOTBLUECARD_NUM, "Picked up a blue keycard." },
468 { GOTYELWCARD_NUM, "Picked up a yellow keycard." },
469 { GOTREDCARD_NUM, "Picked up a red keycard." },
470 { GOTARMOR_NUM, "Picked up the armor." },
471 { GOTMEGA_NUM, "Picked up the MegaArmor!" },
472 { GOTSTIM_NUM, "Picked up a stimpack." },
473 { GOTMAP_NUM, "Computer Area Map" },
474 { 0xFFFF, NULL }
475 };
476
sfx_ammo_text_install(byte set_heretic)477 void sfx_ammo_text_install( byte set_heretic )
478 {
479 const sfx_install_t * st = doom_sfx_table;
480 const ammo_install_t * aat = doom_ammo_table;
481 const byte * wat = doom_weapon_ammo_table;
482 const text_install_t * tt = doom_text_table;
483 int ai;
484
485 // SFX
486 if( set_heretic )
487 {
488 ceilmovesound = sfx_dormov;
489 doorclosesound = sfx_doropn;
490
491 st = heretic_sfx_table;
492 aat = heretic_ammo_table;
493 wat = heretic_weapon_ammo_table;
494 tt = heretic_text_table;
495 }
496 else
497 {
498 ceilmovesound = sfx_stnmov;
499 doorclosesound = sfx_dorcls;
500 }
501
502 // SFX
503 for( ; st->sfxid < NUMSFX; st++ )
504 {
505 S_sfx[st->sfxid].priority = st->priority;
506 if( st->name )
507 S_sfx[st->sfxid].name = st->name;
508 }
509
510
511 // AMMO
512 for( ai = 0; ai < NUMAMMO; ai++ ) // index ammotype_t
513 {
514 maxammo[ ai ] = aat[ai].max_val;
515 clipammo[ ai ] = aat[ai].clip_val;
516 }
517
518 for( ai = 0; ai < NUMWEAPONS; ai++ ) // index weapontype_t
519 {
520 GetWeaponAmmo[ai] = wat[ai];
521 }
522
523 // TEXT
524 for( ; tt->textid < NUMTEXT ; tt++ )
525 {
526 text[tt->textid] = tt->text;
527 }
528 }
529
530
531
Heretic_PatchEngine(void)532 void Heretic_PatchEngine(void)
533 {
534 // we can put such thinks in a dehacked lump, maybe for later
535 mobjinfo[MT_TFOG].spawnstate = S_HTFOG1;
536 sprnames[SPR_BLUD] = "BLOD";
537
538 S_music[mus_inter].name = "MUS_INTR";
539
540 sfx_ammo_text_install( 1 ); // install heretic sfx, ammo
541
542 // conflicting number for doomednum
543 // so disable doom mobjs and enable heretic's one
544 doomednum_install( 1 ); // install heretic doomednum
545 }
546
547 mobj_t LavaInflictor;
548
549 //----------------------------------------------------------------------------
550 //
551 // PROC P_Init_Lava
552 //
553 //----------------------------------------------------------------------------
554
P_Init_Lava(void)555 void P_Init_Lava(void)
556 {
557 memset(&LavaInflictor, 0, sizeof(mobj_t));
558 LavaInflictor.type = MT_PHOENIXFX2;
559 LavaInflictor.flags2 = MF2_FIREDAMAGE|MF2_NODMGTHRUST;
560 }
561
562 //----------------------------------------------------------------------------
563 //
564 // PROC P_HerePlayerInSpecialSector
565 //
566 // Called every tic frame that the player origin is in a special sector.
567 //
568 //----------------------------------------------------------------------------
569
P_HerePlayerInSpecialSector(player_t * player)570 void P_HerePlayerInSpecialSector(player_t *player)
571 {
572 sector_t *sector;
573 static int pushTab[5] = {
574 2048*5,
575 2048*10,
576 2048*25,
577 2048*30,
578 2048*35
579 };
580
581 sector = player->mo->subsector->sector;
582 // Player is not touching the floor
583 if( player->mo->z != sector->floorheight )
584 return;
585
586 switch(sector->special)
587 {
588 case 7: // Damage_Sludge
589 if(!(leveltime&31))
590 {
591 P_DamageMobj(player->mo, NULL, NULL, 4);
592 }
593 break;
594 case 5: // Damage_LavaWimpy
595 if(!(leveltime&15))
596 {
597 P_DamageMobj(player->mo, &LavaInflictor, NULL, 5);
598 P_HitFloor(player->mo);
599 }
600 break;
601 case 16: // Damage_LavaHefty
602 if(!(leveltime&15))
603 {
604 P_DamageMobj(player->mo, &LavaInflictor, NULL, 8);
605 P_HitFloor(player->mo);
606 }
607 break;
608 case 4: // Scroll_EastLavaDamage
609 P_Thrust(player, 0, 2048*28);
610 if(!(leveltime&15))
611 {
612 P_DamageMobj(player->mo, &LavaInflictor, NULL, 5);
613 P_HitFloor(player->mo);
614 }
615 break;
616 case 9: // SecretArea
617 player->secretcount++;
618 sector->special = 0;
619 break;
620 case 11: // Exit_SuperDamage (DOOM E1M8 finale)
621 /*
622 player->cheats &= ~CF_GODMODE;
623 if(!(leveltime&0x1f))
624 {
625 P_DamageMobj(player->mo, NULL, NULL, 20);
626 }
627 if(player->health <= 10)
628 {
629 G_ExitLevel();
630 }
631 */
632 break;
633
634 case 25: case 26: case 27: case 28: case 29: // Scroll_North
635 P_Thrust(player, ANG90, pushTab[sector->special-25]);
636 break;
637 case 20: case 21: case 22: case 23: case 24: // Scroll_East
638 P_Thrust(player, 0, pushTab[sector->special-20]);
639 break;
640 case 30: case 31: case 32: case 33: case 34: // Scroll_South
641 P_Thrust(player, ANG270, pushTab[sector->special-30]);
642 break;
643 case 35: case 36: case 37: case 38: case 39: // Scroll_West
644 P_Thrust(player, ANG180, pushTab[sector->special-35]);
645 break;
646
647 case 40: case 41: case 42: case 43: case 44: case 45:
648 case 46: case 47: case 48: case 49: case 50: case 51:
649 // Wind specials are handled in (P_mobj):P_XYMovement
650 break;
651
652 case 15: // Friction_Low
653 // Only used in (P_mobj):P_XYMovement and (P_user):P_Thrust
654 break;
655
656 default:
657 I_SoftError( "P_PlayerInSpecialSector: "
658 "unknown special %i\n", sector->special);
659 }
660 }
661
662 //---------------------------------------------------------------------------
663 //
664 // FUNC P_GetThingFloorType
665 //
666 //---------------------------------------------------------------------------
P_GetThingFloorType(mobj_t * thing)667 int P_GetThingFloorType(mobj_t *thing)
668 {
669 return thing->subsector->sector->floortype;
670 }
671