summaryrefslogtreecommitdiff
path: root/src/hexen/p_things.c
blob: 55f37418d75ba31276ffbca453da62290762eeb4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
//**************************************************************************
//**
//** p_things.c : Heretic 2 : Raven Software, Corp.
//**
//** $RCSfile: p_things.c,v $
//** $Revision: 1.36 $
//** $Date: 96/02/08 15:16:13 $
//** $Author: bgokey $
//**
//**************************************************************************

// HEADER FILES ------------------------------------------------------------

#include "h2def.h"
#include "p_local.h"
#include "soundst.h"

// MACROS ------------------------------------------------------------------

// TYPES -------------------------------------------------------------------

// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------

// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------

// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------

static boolean ActivateThing(mobj_t *mobj);
static boolean DeactivateThing(mobj_t *mobj);

// EXTERNAL DATA DECLARATIONS ----------------------------------------------

// PUBLIC DATA DEFINITIONS -------------------------------------------------

mobjtype_t TranslateThingType[] =
{
	MT_MAPSPOT,				// T_NONE
	MT_CENTAUR,				// T_CENTAUR
	MT_CENTAURLEADER,		// T_CENTAURLEADER
	MT_DEMON,				// T_DEMON
	MT_ETTIN,				// T_ETTIN
	MT_FIREDEMON,			// T_FIREGARGOYLE
	MT_SERPENT,				// T_WATERLURKER
	MT_SERPENTLEADER,		// T_WATERLURKERLEADER
	MT_WRAITH,				// T_WRAITH
	MT_WRAITHB,				// T_WRAITHBURIED
	MT_FIREBALL1,			// T_FIREBALL1
	MT_MANA1,				// T_MANA1
	MT_MANA2,				// T_MANA2
	MT_SPEEDBOOTS,			// T_ITEMBOOTS
	MT_ARTIEGG,				// T_ITEMEGG
	MT_ARTIFLY,				// T_ITEMFLIGHT
	MT_SUMMONMAULATOR,		// T_ITEMSUMMON
	MT_TELEPORTOTHER,		// T_ITEMTPORTOTHER
	MT_ARTITELEPORT,		// T_ITEMTELEPORT
	MT_BISHOP,				// T_BISHOP
	MT_ICEGUY,				// T_ICEGOLEM
	MT_BRIDGE,				// T_BRIDGE
	MT_BOOSTARMOR,			// T_DRAGONSKINBRACERS
	MT_HEALINGBOTTLE,		// T_ITEMHEALTHPOTION
	MT_HEALTHFLASK,			// T_ITEMHEALTHFLASK
	MT_ARTISUPERHEAL,		// T_ITEMHEALTHFULL
	MT_BOOSTMANA,			// T_ITEMBOOSTMANA
	MT_FW_AXE,				// T_FIGHTERAXE
	MT_FW_HAMMER,			// T_FIGHTERHAMMER
	MT_FW_SWORD1,			// T_FIGHTERSWORD1
	MT_FW_SWORD2,			// T_FIGHTERSWORD2
	MT_FW_SWORD3,			// T_FIGHTERSWORD3
	MT_CW_SERPSTAFF,		// T_CLERICSTAFF
	MT_CW_HOLY1,			// T_CLERICHOLY1
	MT_CW_HOLY2,			// T_CLERICHOLY2
	MT_CW_HOLY3,			// T_CLERICHOLY3
	MT_MW_CONE,				// T_MAGESHARDS
	MT_MW_STAFF1,			// T_MAGESTAFF1
	MT_MW_STAFF2,			// T_MAGESTAFF2
	MT_MW_STAFF3,			// T_MAGESTAFF3
	MT_EGGFX,				// T_MORPHBLAST
	MT_ROCK1,				// T_ROCK1
	MT_ROCK2,				// T_ROCK2
	MT_ROCK3,				// T_ROCK3
	MT_DIRT1,				// T_DIRT1
	MT_DIRT2,				// T_DIRT2
	MT_DIRT3,				// T_DIRT3
	MT_DIRT4,				// T_DIRT4
	MT_DIRT5,				// T_DIRT5
	MT_DIRT6,				// T_DIRT6
	MT_ARROW,				// T_ARROW
	MT_DART,				// T_DART
	MT_POISONDART,			// T_POISONDART
	MT_RIPPERBALL,			// T_RIPPERBALL
	MT_SGSHARD1,			// T_STAINEDGLASS1
	MT_SGSHARD2,			// T_STAINEDGLASS2
	MT_SGSHARD3,			// T_STAINEDGLASS3
	MT_SGSHARD4,			// T_STAINEDGLASS4
	MT_SGSHARD5,			// T_STAINEDGLASS5
	MT_SGSHARD6,			// T_STAINEDGLASS6
	MT_SGSHARD7,			// T_STAINEDGLASS7
	MT_SGSHARD8,			// T_STAINEDGLASS8
	MT_SGSHARD9,			// T_STAINEDGLASS9
	MT_SGSHARD0,			// T_STAINEDGLASS0
	MT_PROJECTILE_BLADE,	// T_BLADE
	MT_ICESHARD,			// T_ICESHARD
	MT_FLAME_SMALL,			// T_FLAME_SMALL
	MT_FLAME_LARGE,			// T_FLAME_LARGE
	MT_ARMOR_1,				// T_MESHARMOR
	MT_ARMOR_2,				// T_FALCONSHIELD
	MT_ARMOR_3,				// T_PLATINUMHELM
	MT_ARMOR_4,				// T_AMULETOFWARDING
	MT_ARTIPOISONBAG,		// T_ITEMFLECHETTE
	MT_ARTITORCH,			// T_ITEMTORCH
	MT_BLASTRADIUS,			// T_ITEMREPULSION
	MT_MANA3,				// T_MANA3
	MT_ARTIPUZZSKULL,		// T_PUZZSKULL
	MT_ARTIPUZZGEMBIG,		// T_PUZZGEMBIG
	MT_ARTIPUZZGEMRED,		// T_PUZZGEMRED
	MT_ARTIPUZZGEMGREEN1,	// T_PUZZGEMGREEN1
	MT_ARTIPUZZGEMGREEN2,	// T_PUZZGEMGREEN2
	MT_ARTIPUZZGEMBLUE1,	// T_PUZZGEMBLUE1
	MT_ARTIPUZZGEMBLUE2,	// T_PUZZGEMBLUE2
	MT_ARTIPUZZBOOK1,		// T_PUZZBOOK1
	MT_ARTIPUZZBOOK2,		// T_PUZZBOOK2
	MT_KEY1,				// T_METALKEY
	MT_KEY2,				// T_SMALLMETALKEY
	MT_KEY3,				// T_AXEKEY
	MT_KEY4,				// T_FIREKEY
	MT_KEY5,				// T_GREENKEY
	MT_KEY6,				// T_MACEKEY
	MT_KEY7,				// T_SILVERKEY
	MT_KEY8,				// T_RUSTYKEY
	MT_KEY9,				// T_HORNKEY
	MT_KEYA,				// T_SERPENTKEY
	MT_WATER_DRIP,			// T_WATERDRIP
	MT_FLAME_SMALL_TEMP,	// T_TEMPSMALLFLAME
	MT_FLAME_SMALL,			// T_PERMSMALLFLAME
	MT_FLAME_LARGE_TEMP,	// T_TEMPLARGEFLAME
	MT_FLAME_LARGE,			// T_PERMLARGEFLAME
	MT_DEMON_MASH,			// T_DEMON_MASH
	MT_DEMON2_MASH,			// T_DEMON2_MASH
	MT_ETTIN_MASH,			// T_ETTIN_MASH
	MT_CENTAUR_MASH,		// T_CENTAUR_MASH
	MT_THRUSTFLOOR_UP,		// T_THRUSTSPIKEUP
	MT_THRUSTFLOOR_DOWN,	// T_THRUSTSPIKEDOWN
	MT_WRAITHFX4,			// T_FLESH_DRIP1
	MT_WRAITHFX5,			// T_FLESH_DRIP2
	MT_WRAITHFX2			// T_SPARK_DRIP
};

// PRIVATE DATA DEFINITIONS ------------------------------------------------

// CODE --------------------------------------------------------------------

//==========================================================================
//
// EV_ThingProjectile
//
//==========================================================================

boolean EV_ThingProjectile(byte *args, boolean gravity)
{
	int tid;
	angle_t angle;
	int fineAngle;
	fixed_t speed;
	fixed_t vspeed;
	mobjtype_t moType;
	mobj_t *mobj;
	mobj_t *newMobj;
	int searcher;
	boolean success;

	success = false;
	searcher = -1;
	tid = args[0];
	moType = TranslateThingType[args[1]];
	if(nomonsters && (mobjinfo[moType].flags&MF_COUNTKILL))
	{ // Don't spawn monsters if -nomonsters
		return false;
	}
	angle = (int)args[2]<<24;
	fineAngle = angle>>ANGLETOFINESHIFT;
	speed = (int)args[3]<<13;
	vspeed = (int)args[4]<<13;
	while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL)
	{
		newMobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, moType);
		if(newMobj->info->seesound)
		{
			S_StartSound(newMobj, newMobj->info->seesound);
		}
		newMobj->target = mobj; // Originator
		newMobj->angle = angle;
		newMobj->momx = FixedMul(speed, finecosine[fineAngle]);
		newMobj->momy = FixedMul(speed, finesine[fineAngle]);
		newMobj->momz = vspeed;
		newMobj->flags2 |= MF2_DROPPED; // Don't respawn
		if(gravity == true)
		{
			newMobj->flags &= ~MF_NOGRAVITY;
			newMobj->flags2 |= MF2_LOGRAV;
		}
		if(P_CheckMissileSpawn(newMobj) == true)
		{
			success = true;
		}
	}
	return success;
}

//==========================================================================
//
// EV_ThingSpawn
//
//==========================================================================

boolean EV_ThingSpawn(byte *args, boolean fog)
{
	int tid;
	angle_t angle;
	mobj_t *mobj;
	mobj_t *newMobj;
	mobj_t *fogMobj;
	mobjtype_t moType;
	int searcher;
	boolean success;
	fixed_t z;

	success = false;
	searcher = -1;
	tid = args[0];
	moType = TranslateThingType[args[1]];
	if(nomonsters && (mobjinfo[moType].flags&MF_COUNTKILL))
	{ // Don't spawn monsters if -nomonsters
		return false;
	}
	angle = (int)args[2]<<24;
	while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL)
	{
		if (mobjinfo[moType].flags2&MF2_FLOATBOB)
		{
			z = mobj->z - mobj->floorz;
		}
		else
		{
			z = mobj->z;
		}
		newMobj = P_SpawnMobj(mobj->x, mobj->y, z, moType);
		if(P_TestMobjLocation(newMobj) == false)
		{ // Didn't fit
			P_RemoveMobj(newMobj);
		}
		else
		{
			newMobj->angle = angle;
			if(fog == true)
			{
				fogMobj = P_SpawnMobj(mobj->x, mobj->y,
					mobj->z+TELEFOGHEIGHT, MT_TFOG);
				S_StartSound(fogMobj, SFX_TELEPORT);
			}
			newMobj->flags2 |= MF2_DROPPED; // Don't respawn
			if (newMobj->flags2&MF2_FLOATBOB)
			{
				newMobj->special1 = newMobj->z - newMobj->floorz;
			}
			success = true;
		}
	}
	return success;
}

//==========================================================================
//
// EV_ThingActivate
//
//==========================================================================

boolean EV_ThingActivate(int tid)
{
	mobj_t *mobj;
	int searcher;
	boolean success;

	success = false;
	searcher = -1;
	while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL)
	{
		if(ActivateThing(mobj) == true)
		{
			success = true;
		}
	}
	return success;
}

//==========================================================================
//
// EV_ThingDeactivate
//
//==========================================================================

boolean EV_ThingDeactivate(int tid)
{
	mobj_t *mobj;
	int searcher;
	boolean success;

	success = false;
	searcher = -1;
	while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL)
	{
		if(DeactivateThing(mobj) == true)
		{
			success = true;
		}
	}
	return success;
}

//==========================================================================
//
// EV_ThingRemove
//
//==========================================================================

boolean EV_ThingRemove(int tid)
{
	mobj_t *mobj;
	int searcher;
	boolean success;

	success = false;
	searcher = -1;
	while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL)
	{
		if (mobj->type == MT_BRIDGE)
		{
			A_BridgeRemove(mobj);
			return true;
		}
		P_RemoveMobj(mobj);
		success = true;
	}
	return success;
}

//==========================================================================
//
// EV_ThingDestroy
//
//==========================================================================

boolean EV_ThingDestroy(int tid)
{
	mobj_t *mobj;
	int searcher;
	boolean success;

	success = false;
	searcher = -1;
	while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL)
	{
		if(mobj->flags&MF_SHOOTABLE)
		{
			P_DamageMobj(mobj, NULL, NULL, 10000);
			success = true;
		}
	}
	return success;
}

//==========================================================================
//
// EV_ThingMove
//
// arg[0] = tid
// arg[1] = speed
// arg[2] = angle (255 = use mobj angle)
// arg[3] = distance (pixels>>2)
//
//==========================================================================

/*
boolean EV_ThingMove(byte *args)
{
	return false;
}
*/

//==========================================================================
//
// ActivateThing
//
//==========================================================================

static boolean ActivateThing(mobj_t *mobj)
{
	if(mobj->flags&MF_COUNTKILL)
	{ // Monster
		if(mobj->flags2&MF2_DORMANT)
		{
			mobj->flags2 &= ~MF2_DORMANT;
			mobj->tics = 1;
			return true;
		}
		return false;
	}
	switch(mobj->type)
	{
		case MT_ZTWINEDTORCH:
		case MT_ZTWINEDTORCH_UNLIT:
			P_SetMobjState(mobj, S_ZTWINEDTORCH_1);
			S_StartSound(mobj, SFX_IGNITE);
			break;
		case MT_ZWALLTORCH:
		case MT_ZWALLTORCH_UNLIT:
			P_SetMobjState(mobj, S_ZWALLTORCH1);
			S_StartSound(mobj, SFX_IGNITE);
			break;
		case MT_ZGEMPEDESTAL:
			P_SetMobjState(mobj, S_ZGEMPEDESTAL2);
			break;
		case MT_ZWINGEDSTATUENOSKULL:
			P_SetMobjState(mobj, S_ZWINGEDSTATUENOSKULL2);
			break;
		case MT_THRUSTFLOOR_UP:
		case MT_THRUSTFLOOR_DOWN:
			if (mobj->args[0]==0)
			{
				S_StartSound(mobj, SFX_THRUSTSPIKE_LOWER);
				mobj->flags2 &= ~MF2_DONTDRAW;
				if (mobj->args[1])
					P_SetMobjState(mobj, S_BTHRUSTRAISE1);
				else
					P_SetMobjState(mobj, S_THRUSTRAISE1);
			}
			break;
		case MT_ZFIREBULL:
		case MT_ZFIREBULL_UNLIT:
			P_SetMobjState(mobj, S_ZFIREBULL_BIRTH);
			S_StartSound(mobj, SFX_IGNITE);
			break;
		case MT_ZBELL:
			if(mobj->health > 0)
			{
				P_DamageMobj(mobj, NULL, NULL, 10); // 'ring' the bell
			}
			break;
		case MT_ZCAULDRON:
		case MT_ZCAULDRON_UNLIT:
			P_SetMobjState(mobj, S_ZCAULDRON1);
			S_StartSound(mobj, SFX_IGNITE);
			break;
		case MT_FLAME_SMALL:
			S_StartSound(mobj, SFX_IGNITE);
			P_SetMobjState(mobj, S_FLAME_SMALL1);
			break;
		case MT_FLAME_LARGE:
			S_StartSound(mobj, SFX_IGNITE);
			P_SetMobjState(mobj, S_FLAME_LARGE1);
			break;
		case MT_BAT_SPAWNER:
			P_SetMobjState(mobj, S_SPAWNBATS1);
			break;
		default:
			return false;
			break;
	}
	return true;
}

//==========================================================================
//
// DeactivateThing
//
//==========================================================================

static boolean DeactivateThing(mobj_t *mobj)
{
	if(mobj->flags&MF_COUNTKILL)
	{ // Monster
		if(!(mobj->flags2&MF2_DORMANT))
		{
			mobj->flags2 |= MF2_DORMANT;
			mobj->tics = -1;
			return true;
		}
		return false;
	}
	switch(mobj->type)
	{
		case MT_ZTWINEDTORCH:
		case MT_ZTWINEDTORCH_UNLIT:
			P_SetMobjState(mobj, S_ZTWINEDTORCH_UNLIT);
			break;
		case MT_ZWALLTORCH:
		case MT_ZWALLTORCH_UNLIT:
			P_SetMobjState(mobj, S_ZWALLTORCH_U);
			break;
		case MT_THRUSTFLOOR_UP:
		case MT_THRUSTFLOOR_DOWN:
			if (mobj->args[0]==1)
			{
				S_StartSound(mobj, SFX_THRUSTSPIKE_RAISE);
				if (mobj->args[1])
					P_SetMobjState(mobj, S_BTHRUSTLOWER);
				else
					P_SetMobjState(mobj, S_THRUSTLOWER);
			}
			break;
		case MT_ZFIREBULL:
		case MT_ZFIREBULL_UNLIT:
			P_SetMobjState(mobj, S_ZFIREBULL_DEATH);
			break;
		case MT_ZCAULDRON:
		case MT_ZCAULDRON_UNLIT:
			P_SetMobjState(mobj, S_ZCAULDRON_U);
			break;
		case MT_FLAME_SMALL:
			P_SetMobjState(mobj, S_FLAME_SDORM1);
			break;
		case MT_FLAME_LARGE:
			P_SetMobjState(mobj, S_FLAME_LDORM1);
			break;
		case MT_BAT_SPAWNER:
			P_SetMobjState(mobj, S_SPAWNBATS_OFF);
			break;
		default:
			return false;
			break;
	}
	return true;
}