Esempio n. 1
0
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);
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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.
}
Esempio n. 4
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;
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
/**
 * 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);
    }
}
Esempio n. 8
0
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;
}