diff options
Diffstat (limited to 'src/hexen/p_things.c')
-rw-r--r-- | src/hexen/p_things.c | 545 |
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..db0d89cc --- /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 = 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; +} |