void C_DECL A_CorpseBloodDrip(mobj_t* actor) { if(P_Random() > 128) return; P_SpawnMobjXYZ(MT_CORPSEBLOODDRIP, actor->origin[VX], actor->origin[VY], actor->origin[VZ] + actor->height / 2, actor->angle, 0); }
dd_bool EV_ThingSpawn(byte *args, dd_bool fog) { int tid, searcher; angle_t angle; mobj_t *mobj, *newMobj, *fogMobj; mobjtype_t moType; dd_bool success; //coord_t z; success = false; searcher = -1; tid = args[0]; moType = TranslateThingType[args[1]]; if(G_Ruleset_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) { //z = mobj->origin[VZ]; if((newMobj = P_SpawnMobj(moType, mobj->origin, angle, 0))) { if(P_TestMobjLocation(newMobj) == false) { // Didn't fit P_MobjRemove(newMobj, true); } else { if(fog) { if((fogMobj = P_SpawnMobjXYZ(MT_TFOG, mobj->origin[VX], mobj->origin[VY], mobj->origin[VZ] + TELEFOGHEIGHT, angle + ANG180, 0))) S_StartSound(SFX_TELEPORT, fogMobj); } newMobj->flags2 |= MF2_DROPPED; // Don't respawn if(newMobj->flags2 & MF2_FLOATBOB) { newMobj->special1 = FLT2FIX(newMobj->origin[VZ] - newMobj->floorZ); } success = true; } } } return success; }
void C_DECL A_PoisonBagInit(mobj_t* actor) { mobj_t* mo; if((mo = P_SpawnMobjXYZ(MT_POISONCLOUD, actor->origin[VX], actor->origin[VY], actor->origin[VZ] + 28, P_Random() << 24, 0))) { // Missile objects must move to impact other objects. mo->mom[MX] = FIX2FLT(1); mo->special1 = 24 + (P_Random() & 7); mo->special2 = 0; mo->target = actor->target; mo->radius = 20; mo->height = 30; mo->flags &= ~MF_NOCLIP; } }
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. }
int EV_Teleport(Line* line, int side, mobj_t* mo, dd_bool spawnFog) { mobj_t* dest; // Clients cannot teleport on their own. if(IS_CLIENT) return 0; if(mo->flags2 & MF2_NOTELEPORT) return 0; // Don't teleport if hit back of line, so you can get out of teleporter. if(side == 1) return 0; if((dest = getTeleportDestination(P_ToXLine(line)->tag)) != NULL) { // A suitable destination has been found. coord_t oldPos[3], aboveFloor; angle_t oldAngle; mobj_t* fog; uint an; memcpy(oldPos, mo->origin, sizeof(mo->origin)); oldAngle = mo->angle; aboveFloor = mo->origin[VZ] - mo->floorZ; if(!P_TeleportMove(mo, dest->origin[VX], dest->origin[VY], false)) return 0; mo->origin[VZ] = mo->floorZ; if(spawnFog) { // Spawn teleport fog at source and destination. if((fog = P_SpawnMobj(MT_TFOG, oldPos, oldAngle + ANG180, 0))) S_StartSound(SFX_TELEPT, fog); an = dest->angle >> ANGLETOFINESHIFT; if((fog = P_SpawnMobjXYZ(MT_TFOG, dest->origin[VX] + 20 * FIX2FLT(finecosine[an]), dest->origin[VY] + 20 * FIX2FLT(finesine[an]), mo->origin[VZ], dest->angle + ANG180, 0))) { // Emit sound, where? S_StartSound(SFX_TELEPT, fog); } } mo->angle = dest->angle; if(mo->flags2 & MF2_FLOORCLIP) { mo->floorClip = 0; if(FEQUAL(mo->origin[VZ], P_GetDoublep(Mobj_Sector(mo), DMU_FLOOR_HEIGHT))) { terraintype_t const *tt = P_MobjFloorTerrain(mo); if(tt->flags & TTF_FLOORCLIP) { mo->floorClip = 10; } } } mo->mom[MX] = mo->mom[MY] = mo->mom[MZ] = 0; // $voodoodolls Must be the real player. if(mo->player && mo->player->plr->mo == mo) { mo->reactionTime = 18; // Don't move for a bit. if(mo->player->powers[PT_FLIGHT] && aboveFloor > 0) { mo->origin[VZ] = mo->floorZ + aboveFloor; if(mo->origin[VZ] + mo->height > mo->ceilingZ) { mo->origin[VZ] = mo->ceilingZ - mo->height; } } else { //mo->dPlayer->clLookDir = 0; /* $unifiedangles */ mo->dPlayer->lookDir = 0; } mo->player->viewHeight = (coord_t) cfg.common.plrViewHeight; mo->player->viewHeightDelta = 0; mo->player->viewZ = mo->origin[VZ] + mo->player->viewHeight; mo->player->viewOffset[VX] = mo->player->viewOffset[VY] = mo->player->viewOffset[VZ] = 0; mo->player->bob = 0; //mo->dPlayer->clAngle = mo->angle; /* $unifiedangles */ mo->dPlayer->flags |= DDPF_FIXANGLES | DDPF_FIXORIGIN | DDPF_FIXMOM; } return 1; }
mobj_t *P_SpawnTeleFog(coord_t x, coord_t y, angle_t angle) { return P_SpawnMobjXYZ(MT_TFOG, x, y, TELEFOGHEIGHT, angle, MSF_Z_FLOOR); }