Exemplo 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);
}
Exemplo n.º 2
0
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]);
}
Exemplo n.º 3
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);
}
Exemplo n.º 4
0
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));
    }
}
Exemplo n.º 5
0
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);
}
Exemplo n.º 6
0
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.
}