Exemplo n.º 1
0
int P_CameraXYMovement(mobj_t *mo)
{
    if(!P_MobjIsCamera(mo))
        return false;
#if __JDOOM__ || __JDOOM64__
    if(mo->flags & MF_NOCLIP ||
       // This is a very rough check! Sometimes you get stuck in things.
       P_CheckPositionXYZ(mo, mo->origin[VX] + mo->mom[MX], mo->origin[VY] + mo->mom[MY], mo->origin[VZ]))
    {
#endif

        P_MobjUnsetOrigin(mo);
        mo->origin[VX] += mo->mom[MX];
        mo->origin[VY] += mo->mom[MY];
        P_MobjSetOrigin(mo);
        P_CheckPositionXY(mo, mo->origin[VX], mo->origin[VY]);
        mo->floorZ = tmFloorZ;
        mo->ceilingZ = tmCeilingZ;

#if __JDOOM__ || __JDOOM64__
    }
#endif

    // Friction.
    if(!INRANGE_OF(mo->player->brain.forwardMove, 0, CAMERA_FRICTION_THRESHOLD) ||
       !INRANGE_OF(mo->player->brain.sideMove, 0, CAMERA_FRICTION_THRESHOLD) ||
       !INRANGE_OF(mo->player->brain.upMove, 0, CAMERA_FRICTION_THRESHOLD))
    {
        // While moving; normal friction applies.
        mo->mom[MX] *= FRICTION_NORMAL;
        mo->mom[MY] *= FRICTION_NORMAL;
    }
    else
    {
        // Else lose momentum, quickly!.
        mo->mom[MX] *= FRICTION_HIGH;
        mo->mom[MY] *= FRICTION_HIGH;
    }

    return true;
}
Exemplo n.º 2
0
int P_CameraZMovement(mobj_t *mo)
{
    if(!P_MobjIsCamera(mo))
        return false;

    mo->origin[VZ] += mo->mom[MZ];

    // Friction.
    if(!INRANGE_OF(mo->player->brain.forwardMove, 0, CAMERA_FRICTION_THRESHOLD) ||
       !INRANGE_OF(mo->player->brain.sideMove, 0, CAMERA_FRICTION_THRESHOLD) ||
       !INRANGE_OF(mo->player->brain.upMove, 0, CAMERA_FRICTION_THRESHOLD))
    {   // While moving; normal friction applies.
        mo->mom[MZ] *= FRICTION_NORMAL;
    }
    else
    {   // Else, lose momentum quickly!.
        mo->mom[MZ] *= FRICTION_HIGH;
    }

    return true;
}
Exemplo n.º 3
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);
    }
}
Exemplo n.º 4
0
dd_bool Mobj_LookForPlayers(mobj_t *mo, dd_bool allAround)
{
    int const playerCount = P_CountPlayersInGame();

    // Nobody to target?
    if(!playerCount) return false;

    int const from = mo->lastLook % MAXPLAYERS;
    int const to   = (from + MAXPLAYERS - 1) % MAXPLAYERS;

    int cand         = from;
    int tries        = 0;
    bool foundTarget = false;
    for(; cand != to; cand = (cand < (MAXPLAYERS - 1)? cand + 1 : 0))
    {
        player_t *player = players + cand;

        // Is player in the game?
        if(!player->plr->inGame) continue;

        mobj_t *plrmo = player->plr->mo;
        if(!plrmo) continue;

        // Do not target camera players.
        if(P_MobjIsCamera(plrmo)) continue;

        // Only look ahead a fixed number of times.
        if(tries++ == 2) break;

        // Do not target dead players.
        if(player->health <= 0) continue;

        // Within sight?
        if(!P_CheckSight(mo, plrmo)) continue;

        if(!allAround)
        {
            angle_t an = M_PointToAngle2(mo->origin, plrmo->origin);
            an -= mo->angle;

            if(an > ANG90 && an < ANG270)
            {
                // If real close, react anyway.
                coord_t dist = M_ApproxDistance(plrmo->origin[VX] - mo->origin[VX],
                                                plrmo->origin[VY] - mo->origin[VY]);
                // Behind us?
                if(dist > MELEERANGE) continue;
            }
        }

#if __JHERETIC__ || __JHEXEN__
        // If player is invisible we may not detect if too far or randomly.
        if(plrmo->flags & MF_SHADOW)
        {
            if((M_ApproxDistance(plrmo->origin[VX] - mo->origin[VX],
                                 plrmo->origin[VY] - mo->origin[VY]) > 2 * MELEERANGE) &&
               M_ApproxDistance(plrmo->mom[MX], plrmo->mom[MY]) < 5)
            {
                // Too far; can't detect.
                continue;
            }

            // Randomly overlook the player regardless.
            if(P_Random() < 225) continue;
        }
#endif

#if __JHEXEN__
        // Minotaurs do not target their master.
        if(mo->type == MT_MINOTAUR && mo->tracer &&
           mo->tracer->player == player) continue;
#endif

        // Found our quarry.
        mo->target = plrmo;
        foundTarget = true;
    }

    // Start looking from here next time.
    mo->lastLook = cand;
    return foundTarget;
}