void C_DECL A_PotteryExplode(mobj_t* actor) { int i, maxBits = (P_Random() & 3) + 3; mobj_t* potteryBit; for(i = 0; i < maxBits; ++i) { if((potteryBit = P_SpawnMobj(MT_POTTERYBIT1, actor->origin, P_Random() << 24, 0))) { P_MobjChangeState(potteryBit, P_GetState(potteryBit->type, SN_SPAWN) + (P_Random() % 5)); potteryBit->mom[MZ] = FIX2FLT(((P_Random() & 7) + 5) * (3 * FRACUNIT / 4)); potteryBit->mom[MX] = FIX2FLT((P_Random() - P_Random()) << 10); potteryBit->mom[MY] = FIX2FLT((P_Random() - P_Random()) << 10); } } S_StartSound(SFX_POTTERY_EXPLODE, potteryBit); if(actor->args[0]) { // Spawn an item. if(!G_Ruleset_NoMonsters() || !(MOBJINFO[TranslateThingType[actor->args[0]]]. flags & MF_COUNTKILL)) { // Only spawn monsters if not -nomonsters. P_SpawnMobj(TranslateThingType[actor->args[0]], actor->origin, actor->angle, 0); } } P_MobjRemove(actor, false); }
void C_DECL A_FogMove(mobj_t* actor) { coord_t speed = (coord_t) actor->args[0]; uint an; if(!(actor->args[4])) return; if(actor->args[3]-- <= 0) { P_MobjChangeStateNoAction(actor, P_GetState(actor->type, SN_DEATH)); return; } // Move the fog slightly/slowly up and down. Some fog patches are supposed // to move higher and some are supposed to stay close to the ground. // Unlike in the original Hexen, the move is done by applying momentum // to the cloud so that the movement is smooth. if((actor->args[3] % 4) == 0) { uint weaveindex = actor->special2; actor->mom[VZ] = FLOATBOBOFFSET(weaveindex) / TICSPERSEC; actor->special2 = (weaveindex + 1) & 63; } an = actor->angle >> ANGLETOFINESHIFT; actor->mom[MX] = speed * FIX2FLT(finecosine[an]); actor->mom[MY] = speed * FIX2FLT(finesine[an]); }
void C_DECL A_CorpseExplode(mobj_t* actor) { int i, n; mobj_t* mo; for(i = (P_Random() & 3) + 3; i; i--) { if((mo = P_SpawnMobj(MT_CORPSEBIT, actor->origin, P_Random() << 24, 0))) { P_MobjChangeState(mo, P_GetState(mo->type, SN_SPAWN) + (P_Random() % 3)); mo->mom[MZ] = FIX2FLT((P_Random() & 7) + 5) * .75f; mo->mom[MX] = FIX2FLT((P_Random() - P_Random()) << 10); mo->mom[MY] = FIX2FLT((P_Random() - P_Random()) << 10); } } // Spawn a skull. if((mo = P_SpawnMobj(MT_CORPSEBIT, actor->origin, P_Random() << 24, 0))) { P_MobjChangeState(mo, S_CORPSEBIT_4); n = (P_Random() & 7) + 5; mo->mom[MZ] = FIX2FLT(n) * .75f; mo->mom[MX] = FIX2FLT((P_Random() - P_Random()) << 10); mo->mom[MY] = FIX2FLT((P_Random() - P_Random()) << 10); S_StartSound(SFX_FIRED_DEATH, mo); } P_MobjRemove(actor, false); }
void C_DECL A_CheckThrowBomb(mobj_t* actor) { if(fabs(actor->mom[MX]) < 1.5f && fabs(actor->mom[MY]) < 1.5f && actor->mom[MZ] < 2 && actor->state == &STATES[S_THROWINGBOMB6]) { P_MobjChangeState(actor, S_THROWINGBOMB7); actor->origin[VZ] = actor->floorZ; actor->mom[MZ] = 0; actor->flags2 &= ~MF2_FLOORBOUNCE; actor->flags &= ~MF_MISSILE; actor->flags |= MF_VIEWALIGN; } if(!--actor->health) { P_MobjChangeState(actor, P_GetState(actor->type, SN_DEATH)); } }
void C_DECL A_PotteryChooseBit(mobj_t* actor) { P_MobjChangeState(actor, P_GetState(actor->type, SN_DEATH) + (P_Random() % 5) + 1); actor->tics = 256 + (P_Random() << 1); }
void P_KillMobj(mobj_t *source, mobj_t *target, dd_bool stomping) { mobjtype_t item; mobj_t* mo; unsigned int an; angle_t angle; if(!target) return; // Nothing to kill... target->flags &= ~(MF_SHOOTABLE | MF_FLOAT | MF_SKULLFLY); if(target->type != MT_SKULL) target->flags &= ~MF_NOGRAVITY; target->flags |= MF_CORPSE | MF_DROPOFF; target->flags2 &= ~MF2_PASSMOBJ; target->corpseTics = 0; target->height /= 2*2; if(source && source->player) { // Count for intermission. if(target->flags & MF_COUNTKILL) { source->player->killCount++; source->player->update |= PSF_COUNTERS; } if(target->player) { source->player->frags[target->player - players]++; NetSv_FragsForAll(source->player); NetSv_KillMessage(source->player, target->player, stomping); } } else if(!IS_NETGAME && (target->flags & MF_COUNTKILL)) { // Count all monster deaths (even those caused by other monsters). players[0].killCount++; } if(target->player) { // Count environment kills against the player. if(!source) { target->player->frags[target->player - players]++; NetSv_FragsForAll(target->player); NetSv_KillMessage(target->player, target->player, stomping); } target->flags &= ~MF_SOLID; target->flags2 &= ~MF2_FLY; target->player->powers[PT_FLIGHT] = 0; target->player->playerState = PST_DEAD; target->player->rebornWait = PLAYER_REBORN_TICS; target->player->update |= PSF_STATE; target->player->plr->flags |= DDPF_DEAD; P_DropWeapon(target->player); // Don't die with the automap open. ST_AutomapOpen(target->player - players, false, false); #if __JHERETIC__ || __JHEXEN__ Hu_InventoryOpen(target->player - players, false); #endif } if(target->health < -target->info->spawnHealth && P_GetState(target->type, SN_XDEATH)) { // Extreme death. P_MobjChangeState(target, P_GetState(target->type, SN_XDEATH)); } else { // Normal death. P_MobjChangeState(target, P_GetState(target->type, SN_DEATH)); } target->tics -= P_Random() & 3; if(target->tics < 1) target->tics = 1; // Enemies in Chex Quest don't drop stuff. if(gameMode == doom_chex) return; // Drop stuff. // This determines the kind of object spawned during the death frame // of a thing. switch(target->type) { case MT_WOLFSS: case MT_POSSESSED: item = MT_CLIP; break; case MT_SHOTGUY: item = MT_SHOTGUN; break; case MT_CHAINGUY: item = MT_CHAINGUN; break; default: return; } // Don't drop at the exact same place, causes Z flickering with // 3D sprites. angle = P_Random() << 24; an = angle >> ANGLETOFINESHIFT; if((mo = P_SpawnMobjXYZ(item, target->origin[VX] + 3 * FIX2FLT(finecosine[an]), target->origin[VY] + 3 * FIX2FLT(finesine[an]), 0, angle, MSF_Z_FLOOR))) mo->flags |= MF_DROPPED; // Special versions of items. }