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