ref: 8bd16fed5b196ae0d0c05e2d8412b2e7b08901ba
dir: /p_things.c/
//************************************************************************** //** //** p_things.c : Heretic 2 : Raven Software, Corp. //** //** $Revision: 373 $ //** $Date: 2009-05-19 21:14:28 +0300 (Tue, 19 May 2009) $ //** //************************************************************************** // HEADER FILES ------------------------------------------------------------ #include "h2stdinc.h" #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; } 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; } return true; }