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_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); }
static int removeThinker(thinker_t* th, void* context) { if(th->function == (thinkfunc_t) P_MobjThinker) P_MobjRemove((mobj_t *) th, true); else Z_Free(th); return false; // Continue iteration. }
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; }
dd_bool EV_ThingRemove(int tid) { mobj_t *mobj; int searcher; dd_bool success; success = false; searcher = -1; while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL) { if(mobj->type == MT_BRIDGE) { A_BridgeRemove(mobj); return true; } P_MobjRemove(mobj, false); success = true; } return success; }
void P_TouchSpecialMobj(mobj_t* special, mobj_t* toucher) { player_t* player; coord_t delta; itemtype_t item; delta = special->origin[VZ] - toucher->origin[VZ]; if(delta > toucher->height || delta < -8) { // Out of reach. return; } // Dead thing touching (can happen with a sliding player corpse). if(toucher->health <= 0) return; player = toucher->player; // Identify by sprite. if((item = getItemTypeBySprite(special->sprite)) != IT_NONE) { if(!pickupItem(player, item, (special->flags & MF_DROPPED)? true : false)) return; // Don't destroy the item. } else { App_Log(DE2_MAP_WARNING, "P_TouchSpecialMobj: Unknown gettable thing %i", (int) special->type); } if(special->flags & MF_COUNTITEM) { player->itemCount++; player->update |= PSF_COUNTERS; } P_MobjRemove(special, false); if(!mapSetup) player->bonusCount += BONUSADD; }
/** * Changes the class of the given player. Will not work if the player * is currently morphed. */ void P_PlayerChangeClass(player_t *player, playerclass_t newClass) { int i; DENG_ASSERT(player != 0); if(newClass < PCLASS_FIRST || newClass >= NUM_PLAYER_CLASSES) return; // Don't change if morphed. if(player->morphTics) return; if(!PCLASS_INFO(newClass)->userSelectable) return; player->class_ = newClass; cfg.playerClass[player - players] = newClass; P_ClassForPlayerWhenRespawning(player - players, true /*clear change request*/); // Take away armor. for(i = 0; i < NUMARMOR; ++i) { player->armorPoints[i] = 0; } player->update |= PSF_ARMOR_POINTS; P_PostMorphWeapon(player, WT_FIRST); if(player->plr->mo) { // Respawn the player and destroy the old mobj. mobj_t* oldMo = player->plr->mo; P_SpawnPlayer(player - players, newClass, oldMo->origin[VX], oldMo->origin[VY], oldMo->origin[VZ], oldMo->angle, 0, P_MobjIsCamera(oldMo), true); P_MobjRemove(oldMo, true); } }
static bool changeMobjState(mobj_t *mobj, statenum_t stateNum, bool doCallAction) { DENG_ASSERT(mobj != 0); // Skip zero-tic states -- call their action but then advance to the next. do { if(stateNum == S_NULL) { mobj->state = (state_t *) S_NULL; P_MobjRemove(mobj, false); return false; } Mobj_SetState(mobj, stateNum); mobj->turnTime = false; // $visangle-facetarget state_t *st = &STATES[stateNum]; // Call the action function? if(doCallAction && st->action) { if(shouldCallAction(mobj)) { void (*actioner)(mobj_t *); actioner = de::function_cast<void (*)(mobj_t *)>(st->action); actioner(mobj); } } stateNum = statenum_t(st->nextState); } while(!mobj->tics); // Return false if an action function removed the mobj. return mobj->thinker.function != (thinkfunc_t) NOPFUNC; }