dd_bool Smoother_IsMoving(Smoother const *sm) { DENG_ASSERT(sm); const pos_t *past = &sm->past; const pos_t *now = &sm->now; // The smoother is moving if the current past and present are different // points in time and space. return sm->at >= past->time && sm->at <= now->time && past->time < now->time && (!INRANGE_OF(past->xyz[VX], now->xyz[VX], SMOOTHER_MOVE_EPSILON) || !INRANGE_OF(past->xyz[VY], now->xyz[VY], SMOOTHER_MOVE_EPSILON) || !INRANGE_OF(past->xyz[VZ], now->xyz[VZ], SMOOTHER_MOVE_EPSILON)); }
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; }
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; }
void Mobj_XYMoveStopping(mobj_t *mo) { DENG_ASSERT(mo != 0); player_t *player = mo->player; if(player && (P_GetPlayerCheats(player) & CF_NOMOMENTUM)) { // Debug option for no sliding at all. mo->mom[MX] = mo->mom[MY] = 0; return; } if(mo->flags & (MF_MISSILE | MF_SKULLFLY)) { // No friction for missiles. return; } if(mo->origin[VZ] > mo->floorZ && !mo->onMobj && !(mo->flags2 & MF2_FLY)) { // No friction when falling. return; } #ifndef __JHEXEN__ if(cfg.slidingCorpses) { // $dropoff_fix: Add objects falling off ledges. Does not apply to players! if(((mo->flags & MF_CORPSE) || (mo->intFlags & MIF_FALLING)) && !mo->player) { // Do not stop sliding if halfway off a step with some momentum. if(!INRANGE_OF(mo->mom[MX], 0, DROPOFFMOMENTUM_THRESHOLD) || !INRANGE_OF(mo->mom[MY], 0, DROPOFFMOMENTUM_THRESHOLD)) { if(!FEQUAL(mo->floorZ, P_GetDoublep(Mobj_Sector(mo), DMU_FLOOR_HEIGHT))) return; } } } #endif bool isVoodooDoll = Mobj_IsVoodooDoll(mo); bool belowWalkStop = (INRANGE_OF(mo->mom[MX], 0, WALKSTOP_THRESHOLD) && INRANGE_OF(mo->mom[MY], 0, WALKSTOP_THRESHOLD)); bool belowStandSpeed = false; bool isMovingPlayer = false; if(player) { belowStandSpeed = (INRANGE_OF(mo->mom[MX], 0, STANDSPEED) && INRANGE_OF(mo->mom[MY], 0, STANDSPEED)); isMovingPlayer = (!FEQUAL(player->plr->forwardMove, 0) || !FEQUAL(player->plr->sideMove, 0)); } // Stop player walking animation (only real players). if(!isVoodooDoll && player && belowStandSpeed && !isMovingPlayer && !IS_NETWORK_SERVER) // Netgame servers use logic elsewhere for player animation. { // If in a walking frame, stop moving. if(P_PlayerInWalkState(player)) { P_MobjChangeState(player->plr->mo, statenum_t(PCLASS_INFO(player->class_)->normalState)); } } // Apply friction. if(belowWalkStop && !isMovingPlayer) { // $voodoodolls: Do not zero mom for voodoo dolls! if(!isVoodooDoll) { // Momentum is below the walkstop threshold; stop it completely. mo->mom[MX] = mo->mom[MY] = 0; // $voodoodolls: Stop view bobbing if this isn't a voodoo doll. if(player) player->bob = 0; } } else { coord_t friction = Mobj_Friction(mo); mo->mom[MX] *= friction; mo->mom[MY] *= friction; } }