]> icculus.org git repositories - theoddone33/hhexen.git/blob - base/p_things.c
Add alt-enter fullscreen toggle
[theoddone33/hhexen.git] / base / p_things.c
1
2 //**************************************************************************
3 //**
4 //** p_things.c : Heretic 2 : Raven Software, Corp.
5 //**
6 //** $RCSfile$
7 //** $Revision$
8 //** $Date$
9 //** $Author$
10 //**
11 //**************************************************************************
12
13 // HEADER FILES ------------------------------------------------------------
14
15 #include "h2def.h"
16 #include "p_local.h"
17 #include "soundst.h"
18
19 // MACROS ------------------------------------------------------------------
20
21 // TYPES -------------------------------------------------------------------
22
23 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
24
25 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
26
27 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
28
29 static boolean ActivateThing(mobj_t *mobj);
30 static boolean DeactivateThing(mobj_t *mobj);
31
32 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
33
34 // PUBLIC DATA DEFINITIONS -------------------------------------------------
35
36 mobjtype_t TranslateThingType[] =
37 {
38         MT_MAPSPOT,                             // T_NONE
39         MT_CENTAUR,                             // T_CENTAUR
40         MT_CENTAURLEADER,               // T_CENTAURLEADER
41         MT_DEMON,                               // T_DEMON
42         MT_ETTIN,                               // T_ETTIN
43         MT_FIREDEMON,                   // T_FIREGARGOYLE
44         MT_SERPENT,                             // T_WATERLURKER
45         MT_SERPENTLEADER,               // T_WATERLURKERLEADER
46         MT_WRAITH,                              // T_WRAITH
47         MT_WRAITHB,                             // T_WRAITHBURIED
48         MT_FIREBALL1,                   // T_FIREBALL1
49         MT_MANA1,                               // T_MANA1
50         MT_MANA2,                               // T_MANA2
51         MT_SPEEDBOOTS,                  // T_ITEMBOOTS
52         MT_ARTIEGG,                             // T_ITEMEGG
53         MT_ARTIFLY,                             // T_ITEMFLIGHT
54         MT_SUMMONMAULATOR,              // T_ITEMSUMMON
55         MT_TELEPORTOTHER,               // T_ITEMTPORTOTHER
56         MT_ARTITELEPORT,                // T_ITEMTELEPORT
57         MT_BISHOP,                              // T_BISHOP
58         MT_ICEGUY,                              // T_ICEGOLEM
59         MT_BRIDGE,                              // T_BRIDGE
60         MT_BOOSTARMOR,                  // T_DRAGONSKINBRACERS
61         MT_HEALINGBOTTLE,               // T_ITEMHEALTHPOTION
62         MT_HEALTHFLASK,                 // T_ITEMHEALTHFLASK
63         MT_ARTISUPERHEAL,               // T_ITEMHEALTHFULL
64         MT_BOOSTMANA,                   // T_ITEMBOOSTMANA
65         MT_FW_AXE,                              // T_FIGHTERAXE
66         MT_FW_HAMMER,                   // T_FIGHTERHAMMER
67         MT_FW_SWORD1,                   // T_FIGHTERSWORD1
68         MT_FW_SWORD2,                   // T_FIGHTERSWORD2
69         MT_FW_SWORD3,                   // T_FIGHTERSWORD3
70         MT_CW_SERPSTAFF,                // T_CLERICSTAFF
71         MT_CW_HOLY1,                    // T_CLERICHOLY1
72         MT_CW_HOLY2,                    // T_CLERICHOLY2
73         MT_CW_HOLY3,                    // T_CLERICHOLY3
74         MT_MW_CONE,                             // T_MAGESHARDS
75         MT_MW_STAFF1,                   // T_MAGESTAFF1
76         MT_MW_STAFF2,                   // T_MAGESTAFF2
77         MT_MW_STAFF3,                   // T_MAGESTAFF3
78         MT_EGGFX,                               // T_MORPHBLAST
79         MT_ROCK1,                               // T_ROCK1
80         MT_ROCK2,                               // T_ROCK2
81         MT_ROCK3,                               // T_ROCK3
82         MT_DIRT1,                               // T_DIRT1
83         MT_DIRT2,                               // T_DIRT2
84         MT_DIRT3,                               // T_DIRT3
85         MT_DIRT4,                               // T_DIRT4
86         MT_DIRT5,                               // T_DIRT5
87         MT_DIRT6,                               // T_DIRT6
88         MT_ARROW,                               // T_ARROW
89         MT_DART,                                // T_DART
90         MT_POISONDART,                  // T_POISONDART
91         MT_RIPPERBALL,                  // T_RIPPERBALL
92         MT_SGSHARD1,                    // T_STAINEDGLASS1
93         MT_SGSHARD2,                    // T_STAINEDGLASS2
94         MT_SGSHARD3,                    // T_STAINEDGLASS3
95         MT_SGSHARD4,                    // T_STAINEDGLASS4
96         MT_SGSHARD5,                    // T_STAINEDGLASS5
97         MT_SGSHARD6,                    // T_STAINEDGLASS6
98         MT_SGSHARD7,                    // T_STAINEDGLASS7
99         MT_SGSHARD8,                    // T_STAINEDGLASS8
100         MT_SGSHARD9,                    // T_STAINEDGLASS9
101         MT_SGSHARD0,                    // T_STAINEDGLASS0
102         MT_PROJECTILE_BLADE,    // T_BLADE
103         MT_ICESHARD,                    // T_ICESHARD
104         MT_FLAME_SMALL,                 // T_FLAME_SMALL
105         MT_FLAME_LARGE,                 // T_FLAME_LARGE
106         MT_ARMOR_1,                             // T_MESHARMOR
107         MT_ARMOR_2,                             // T_FALCONSHIELD
108         MT_ARMOR_3,                             // T_PLATINUMHELM
109         MT_ARMOR_4,                             // T_AMULETOFWARDING
110         MT_ARTIPOISONBAG,               // T_ITEMFLECHETTE
111         MT_ARTITORCH,                   // T_ITEMTORCH
112         MT_BLASTRADIUS,                 // T_ITEMREPULSION
113         MT_MANA3,                               // T_MANA3
114         MT_ARTIPUZZSKULL,               // T_PUZZSKULL
115         MT_ARTIPUZZGEMBIG,              // T_PUZZGEMBIG
116         MT_ARTIPUZZGEMRED,              // T_PUZZGEMRED
117         MT_ARTIPUZZGEMGREEN1,   // T_PUZZGEMGREEN1
118         MT_ARTIPUZZGEMGREEN2,   // T_PUZZGEMGREEN2
119         MT_ARTIPUZZGEMBLUE1,    // T_PUZZGEMBLUE1
120         MT_ARTIPUZZGEMBLUE2,    // T_PUZZGEMBLUE2
121         MT_ARTIPUZZBOOK1,               // T_PUZZBOOK1
122         MT_ARTIPUZZBOOK2,               // T_PUZZBOOK2
123         MT_KEY1,                                // T_METALKEY
124         MT_KEY2,                                // T_SMALLMETALKEY
125         MT_KEY3,                                // T_AXEKEY
126         MT_KEY4,                                // T_FIREKEY
127         MT_KEY5,                                // T_GREENKEY
128         MT_KEY6,                                // T_MACEKEY
129         MT_KEY7,                                // T_SILVERKEY
130         MT_KEY8,                                // T_RUSTYKEY
131         MT_KEY9,                                // T_HORNKEY
132         MT_KEYA,                                // T_SERPENTKEY
133         MT_WATER_DRIP,                  // T_WATERDRIP
134         MT_FLAME_SMALL_TEMP,    // T_TEMPSMALLFLAME
135         MT_FLAME_SMALL,                 // T_PERMSMALLFLAME
136         MT_FLAME_LARGE_TEMP,    // T_TEMPLARGEFLAME
137         MT_FLAME_LARGE,                 // T_PERMLARGEFLAME
138         MT_DEMON_MASH,                  // T_DEMON_MASH
139         MT_DEMON2_MASH,                 // T_DEMON2_MASH
140         MT_ETTIN_MASH,                  // T_ETTIN_MASH
141         MT_CENTAUR_MASH,                // T_CENTAUR_MASH
142         MT_THRUSTFLOOR_UP,              // T_THRUSTSPIKEUP
143         MT_THRUSTFLOOR_DOWN,    // T_THRUSTSPIKEDOWN
144         MT_WRAITHFX4,                   // T_FLESH_DRIP1
145         MT_WRAITHFX5,                   // T_FLESH_DRIP2
146         MT_WRAITHFX2                    // T_SPARK_DRIP
147 };
148
149 // PRIVATE DATA DEFINITIONS ------------------------------------------------
150
151 // CODE --------------------------------------------------------------------
152
153 //==========================================================================
154 //
155 // EV_ThingProjectile
156 //
157 //==========================================================================
158
159 boolean EV_ThingProjectile(byte *args, boolean gravity)
160 {
161         int tid;
162         angle_t angle;
163         int fineAngle;
164         fixed_t speed;
165         fixed_t vspeed;
166         mobjtype_t moType;
167         mobj_t *mobj;
168         mobj_t *newMobj;
169         int searcher;
170         boolean success;
171
172         success = false;
173         searcher = -1;
174         tid = args[0];
175         moType = TranslateThingType[args[1]];
176         if(nomonsters && (mobjinfo[moType].flags&MF_COUNTKILL))
177         { // Don't spawn monsters if -nomonsters
178                 return false;
179         }
180         angle = (int)args[2]<<24;
181         fineAngle = angle>>ANGLETOFINESHIFT;
182         speed = (int)args[3]<<13;
183         vspeed = (int)args[4]<<13;
184         while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL)
185         {
186                 newMobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, moType);
187                 if(newMobj->info->seesound)
188                 {
189                         S_StartSound(newMobj, newMobj->info->seesound);
190                 }
191                 newMobj->target = mobj; // Originator
192                 newMobj->angle = angle;
193                 newMobj->momx = FixedMul(speed, finecosine[fineAngle]);
194                 newMobj->momy = FixedMul(speed, finesine[fineAngle]);
195                 newMobj->momz = vspeed;
196                 newMobj->flags2 |= MF2_DROPPED; // Don't respawn
197                 if(gravity == true)
198                 {
199                         newMobj->flags &= ~MF_NOGRAVITY;
200                         newMobj->flags2 |= MF2_LOGRAV;
201                 }
202                 if(P_CheckMissileSpawn(newMobj) == true)
203                 {
204                         success = true;
205                 }
206         }
207         return success;
208 }
209
210 //==========================================================================
211 //
212 // EV_ThingSpawn
213 //
214 //==========================================================================
215
216 boolean EV_ThingSpawn(byte *args, boolean fog)
217 {
218         int tid;
219         angle_t angle;
220         mobj_t *mobj;
221         mobj_t *newMobj;
222         mobj_t *fogMobj;
223         mobjtype_t moType;
224         int searcher;
225         boolean success;
226         fixed_t z;
227
228         success = false;
229         searcher = -1;
230         tid = args[0];
231         moType = TranslateThingType[args[1]];
232         if(nomonsters && (mobjinfo[moType].flags&MF_COUNTKILL))
233         { // Don't spawn monsters if -nomonsters
234                 return false;
235         }
236         angle = (int)args[2]<<24;
237         while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL)
238         {
239                 if (mobjinfo[moType].flags2&MF2_FLOATBOB)
240                 {
241                         z = mobj->z - mobj->floorz;
242                 }
243                 else
244                 {
245                         z = mobj->z;
246                 }
247                 newMobj = P_SpawnMobj(mobj->x, mobj->y, z, moType);
248                 if(P_TestMobjLocation(newMobj) == false)
249                 { // Didn't fit
250                         P_RemoveMobj(newMobj);
251                 }
252                 else
253                 {
254                         newMobj->angle = angle;
255                         if(fog == true)
256                         {
257                                 fogMobj = P_SpawnMobj(mobj->x, mobj->y,
258                                         mobj->z+TELEFOGHEIGHT, MT_TFOG);
259                                 S_StartSound(fogMobj, SFX_TELEPORT);
260                         }
261                         newMobj->flags2 |= MF2_DROPPED; // Don't respawn
262                         if (newMobj->flags2&MF2_FLOATBOB)
263                         {
264                                 newMobj->special1 = newMobj->z - newMobj->floorz;
265                         }
266                         success = true;
267                 }
268         }
269         return success;
270 }
271
272 //==========================================================================
273 //
274 // EV_ThingActivate
275 //
276 //==========================================================================
277
278 boolean EV_ThingActivate(int tid)
279 {
280         mobj_t *mobj;
281         int searcher;
282         boolean success;
283
284         success = false;
285         searcher = -1;
286         while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL)
287         {
288                 if(ActivateThing(mobj) == true)
289                 {
290                         success = true;
291                 }
292         }
293         return success;
294 }
295
296 //==========================================================================
297 //
298 // EV_ThingDeactivate
299 //
300 //==========================================================================
301
302 boolean EV_ThingDeactivate(int tid)
303 {
304         mobj_t *mobj;
305         int searcher;
306         boolean success;
307
308         success = false;
309         searcher = -1;
310         while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL)
311         {
312                 if(DeactivateThing(mobj) == true)
313                 {
314                         success = true;
315                 }
316         }
317         return success;
318 }
319
320 //==========================================================================
321 //
322 // EV_ThingRemove
323 //
324 //==========================================================================
325
326 boolean EV_ThingRemove(int tid)
327 {
328         mobj_t *mobj;
329         int searcher;
330         boolean success;
331
332         success = false;
333         searcher = -1;
334         while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL)
335         {
336                 if (mobj->type == MT_BRIDGE)
337                 {
338                         A_BridgeRemove(mobj);
339                         return true;
340                 }
341                 P_RemoveMobj(mobj);
342                 success = true;
343         }
344         return success;
345 }
346
347 //==========================================================================
348 //
349 // EV_ThingDestroy
350 //
351 //==========================================================================
352
353 boolean EV_ThingDestroy(int tid)
354 {
355         mobj_t *mobj;
356         int searcher;
357         boolean success;
358
359         success = false;
360         searcher = -1;
361         while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL)
362         {
363                 if(mobj->flags&MF_SHOOTABLE)
364                 {
365                         P_DamageMobj(mobj, NULL, NULL, 10000);
366                         success = true;
367                 }
368         }
369         return success;
370 }
371
372 //==========================================================================
373 //
374 // EV_ThingMove
375 //
376 // arg[0] = tid
377 // arg[1] = speed
378 // arg[2] = angle (255 = use mobj angle)
379 // arg[3] = distance (pixels>>2)
380 //
381 //==========================================================================
382
383 /*
384 boolean EV_ThingMove(byte *args)
385 {
386         return false;
387 }
388 */
389
390 //==========================================================================
391 //
392 // ActivateThing
393 //
394 //==========================================================================
395
396 static boolean ActivateThing(mobj_t *mobj)
397 {
398         if(mobj->flags&MF_COUNTKILL)
399         { // Monster
400                 if(mobj->flags2&MF2_DORMANT)
401                 {
402                         mobj->flags2 &= ~MF2_DORMANT;
403                         mobj->tics = 1;
404                         return true;
405                 }
406                 return false;
407         }
408         switch(mobj->type)
409         {
410                 case MT_ZTWINEDTORCH:
411                 case MT_ZTWINEDTORCH_UNLIT:
412                         P_SetMobjState(mobj, S_ZTWINEDTORCH_1);
413                         S_StartSound(mobj, SFX_IGNITE);
414                         break;
415                 case MT_ZWALLTORCH:
416                 case MT_ZWALLTORCH_UNLIT:
417                         P_SetMobjState(mobj, S_ZWALLTORCH1);
418                         S_StartSound(mobj, SFX_IGNITE);
419                         break;
420                 case MT_ZGEMPEDESTAL:
421                         P_SetMobjState(mobj, S_ZGEMPEDESTAL2);
422                         break;
423                 case MT_ZWINGEDSTATUENOSKULL:
424                         P_SetMobjState(mobj, S_ZWINGEDSTATUENOSKULL2);
425                         break;
426                 case MT_THRUSTFLOOR_UP:
427                 case MT_THRUSTFLOOR_DOWN:
428                         if (mobj->args[0]==0)
429                         {
430                                 S_StartSound(mobj, SFX_THRUSTSPIKE_LOWER);
431                                 mobj->flags2 &= ~MF2_DONTDRAW;
432                                 if (mobj->args[1])
433                                         P_SetMobjState(mobj, S_BTHRUSTRAISE1);
434                                 else
435                                         P_SetMobjState(mobj, S_THRUSTRAISE1);
436                         }
437                         break;
438                 case MT_ZFIREBULL:
439                 case MT_ZFIREBULL_UNLIT:
440                         P_SetMobjState(mobj, S_ZFIREBULL_BIRTH);
441                         S_StartSound(mobj, SFX_IGNITE);
442                         break;
443                 case MT_ZBELL:
444                         if(mobj->health > 0)
445                         {
446                                 P_DamageMobj(mobj, NULL, NULL, 10); // 'ring' the bell
447                         }
448                         break;
449                 case MT_ZCAULDRON:
450                 case MT_ZCAULDRON_UNLIT:
451                         P_SetMobjState(mobj, S_ZCAULDRON1);
452                         S_StartSound(mobj, SFX_IGNITE);
453                         break;
454                 case MT_FLAME_SMALL:
455                         S_StartSound(mobj, SFX_IGNITE);
456                         P_SetMobjState(mobj, S_FLAME_SMALL1);
457                         break;
458                 case MT_FLAME_LARGE:
459                         S_StartSound(mobj, SFX_IGNITE);
460                         P_SetMobjState(mobj, S_FLAME_LARGE1);
461                         break;
462                 case MT_BAT_SPAWNER:
463                         P_SetMobjState(mobj, S_SPAWNBATS1);
464                         break;
465                 default:
466                         return false;
467                         break;
468         }
469         return true;
470 }
471
472 //==========================================================================
473 //
474 // DeactivateThing
475 //
476 //==========================================================================
477
478 static boolean DeactivateThing(mobj_t *mobj)
479 {
480         if(mobj->flags&MF_COUNTKILL)
481         { // Monster
482                 if(!(mobj->flags2&MF2_DORMANT))
483                 {
484                         mobj->flags2 |= MF2_DORMANT;
485                         mobj->tics = -1;
486                         return true;
487                 }
488                 return false;
489         }
490         switch(mobj->type)
491         {
492                 case MT_ZTWINEDTORCH:
493                 case MT_ZTWINEDTORCH_UNLIT:
494                         P_SetMobjState(mobj, S_ZTWINEDTORCH_UNLIT);
495                         break;
496                 case MT_ZWALLTORCH:
497                 case MT_ZWALLTORCH_UNLIT:
498                         P_SetMobjState(mobj, S_ZWALLTORCH_U);
499                         break;
500                 case MT_THRUSTFLOOR_UP:
501                 case MT_THRUSTFLOOR_DOWN:
502                         if (mobj->args[0]==1)
503                         {
504                                 S_StartSound(mobj, SFX_THRUSTSPIKE_RAISE);
505                                 if (mobj->args[1])
506                                         P_SetMobjState(mobj, S_BTHRUSTLOWER);
507                                 else
508                                         P_SetMobjState(mobj, S_THRUSTLOWER);
509                         }
510                         break;
511                 case MT_ZFIREBULL:
512                 case MT_ZFIREBULL_UNLIT:
513                         P_SetMobjState(mobj, S_ZFIREBULL_DEATH);
514                         break;
515                 case MT_ZCAULDRON:
516                 case MT_ZCAULDRON_UNLIT:
517                         P_SetMobjState(mobj, S_ZCAULDRON_U);
518                         break;
519                 case MT_FLAME_SMALL:
520                         P_SetMobjState(mobj, S_FLAME_SDORM1);
521                         break;
522                 case MT_FLAME_LARGE:
523                         P_SetMobjState(mobj, S_FLAME_LDORM1);
524                         break;
525                 case MT_BAT_SPAWNER:
526                         P_SetMobjState(mobj, S_SPAWNBATS_OFF);
527                         break;
528                 default:
529                         return false;
530                         break;
531         }
532         return true;
533 }
534