summaryrefslogtreecommitdiff
path: root/src/hexen/p_things.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/hexen/p_things.c')
-rw-r--r--src/hexen/p_things.c545
1 files changed, 545 insertions, 0 deletions
diff --git a/src/hexen/p_things.c b/src/hexen/p_things.c
new file mode 100644
index 00000000..5e137100
--- /dev/null
+++ b/src/hexen/p_things.c
@@ -0,0 +1,545 @@
+// Emacs style mode select -*- C++ -*-
+//-----------------------------------------------------------------------------
+//
+// Copyright(C) 1993-1996 Id Software, Inc.
+// Copyright(C) 1993-2008 Raven Software
+// Copyright(C) 2008 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+// 02111-1307, USA.
+//
+//-----------------------------------------------------------------------------
+
+
+// HEADER FILES ------------------------------------------------------------
+
+#include "h2def.h"
+#include "p_local.h"
+#include "s_sound.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.i = 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;
+}