float CBasePlayer::GetPlayerMaxSpeed() { // player max speed is the lower limit of m_flMaxSpeed and sv_maxspeed float fMaxSpeed = sv_maxspeed.GetFloat(); if ( MaxSpeed() > 0.0f && MaxSpeed() < fMaxSpeed ) fMaxSpeed = MaxSpeed(); return fMaxSpeed; }
void CPlayerController::Update(const Vector &position, const Vector &velocity, float secondsToArrival, bool onground, IPhysicsObject *ground) { btVector3 bullTargetPosition, bullMaxVelocity; ConvertPosToBull(position, bullTargetPosition); ConvertPosToBull(velocity, bullMaxVelocity); // If the targets haven't changed, abort. if (bullMaxVelocity.distance2(m_maxVelocity) < FLT_EPSILON && bullTargetPosition.distance2(m_targetPosition) < FLT_EPSILON) { return; } m_targetPosition = bullTargetPosition; m_maxVelocity = bullMaxVelocity; m_enable = true; // FYI: The onground stuff includes any props we may be standing on as well as the world. // The ground is valid only if it's significantly heavier than our object ("Rideable physics" > our mass * 2) m_onground = onground; if (velocity.LengthSqr() <= 0.001f) { m_enable = false; ground = NULL; } else { MaxSpeed(velocity); } m_secondsToArrival = secondsToArrival; m_pGround = (CPhysicsObject *)ground; m_ticksSinceUpdate = 0; }
void Pellet::Update() { if (!HasImpacted()) { //calculate the steering force Vector2D DesiredVelocity = Vec2DNormalize(m_vTarget - Pos()) * MaxSpeed(); Vector2D sf = DesiredVelocity - Velocity(); //update the position Vector2D accel = sf / m_dMass; m_vVelocity += accel; //make sure vehicle does not exceed maximum velocity m_vVelocity.Truncate(m_dMaxSpeed); //update the position m_vPosition += m_vVelocity; TestForImpact(); } else if (!isVisibleToPlayer()) { m_bDead = true; } }
//------------------------------ Update --------------------------------------- //----------------------------------------------------------------------------- void Rocket::Update() { if (!m_bImpacted) { m_vVelocity = MaxSpeed() * Heading(); //make sure vehicle does not exceed maximum velocity m_vVelocity.Truncate(m_dMaxSpeed); //update the position m_vPosition += m_vVelocity; TestForImpact(); } else { m_dCurrentBlastRadius += script->GetDouble("Rocket_ExplosionDecayRate"); //when the rendered blast circle becomes equal in size to the blast radius //the rocket can be removed from the game if (m_dCurrentBlastRadius > m_dBlastRadius) { m_bDead = true; } } }
//------------------------------ Update --------------------------------------- //----------------------------------------------------------------------------- void Bolt::Update() { if (!m_bImpacted) { m_vVelocity = MaxSpeed() * Heading(); //make sure vehicle does not exceed maximum velocity m_vVelocity.Truncate(m_dMaxSpeed); //update the position m_vPosition += m_vVelocity; //if the projectile has reached the target position or it hits an entity //or wall it should explode/inflict damage/whatever and then mark itself //as dead //test to see if the line segment connecting the bolt's current position //and previous position intersects with any bots. Raven_Bot* hit = GetClosestIntersectingBot(m_vPosition - m_vVelocity, m_vPosition); //if hit if (hit) { m_bImpacted = true; m_bDead = true; //send a message to the bot to let it know it's been hit, and who the //shot came from Dispatcher->DispatchMsg(SEND_MSG_IMMEDIATELY, m_iShooterID, hit->ID(), Msg_TakeThatMF, (void*)&m_iDamageInflicted); } //test for impact with a wall double dist; if( FindClosestPointOfIntersectionWithWalls(m_vPosition - m_vVelocity, m_vPosition, dist, m_vImpactPoint, m_pWorld->GetMap()->GetWalls())) { m_bDead = true; m_bImpacted = true; m_vPosition = m_vImpactPoint; return; } } }
void CPlayerController::Update( const Vector& position, const Vector& velocity, bool onground, IPhysicsObject *ground ) { IVP_U_Point targetPositionIVP; IVP_U_Float_Point targetSpeedIVP; ConvertPositionToIVP( position, targetPositionIVP ); ConvertPositionToIVP( velocity, targetSpeedIVP ); // if the object hasn't moved, abort if ( targetSpeedIVP.quad_distance_to( &m_currentSpeed ) < 1e-6 ) { if ( targetPositionIVP.quad_distance_to( &m_targetPosition ) < 1e-6 ) { return; } } m_targetPosition = targetPositionIVP; m_currentSpeed = targetSpeedIVP; IVP_Real_Object *pivp = m_pObject->GetObject(); IVP_Core *pCore = pivp->get_core(); IVP_Environment *pEnv = pivp->get_environment(); pEnv->get_controller_manager()->ensure_core_in_simulation(pCore); m_enable = true; // m_onground makes this object anti-grav // UNDONE: Re-evaluate this m_onground = false;//onground; if ( velocity.LengthSqr() <= 0.1f ) { // no input velocity, just go where physics takes you. m_enable = false; ground = NULL; } else { MaxSpeed( velocity ); } }
void C_HL2MP_Player::AvoidPlayers( CUserCmd *pCmd ) { // This is only used in team play. if ( !HL2MPRules()->IsTeamplay() ) return; // Don't test if the player doesn't exist or is dead. if ( IsAlive() == false ) return; C_Team *pTeam = ( C_Team * )GetTeam(); if ( !pTeam ) return; // Up vector. static Vector vecUp( 0.0f, 0.0f, 1.0f ); Vector vecHL2MPPlayerCenter = GetAbsOrigin(); Vector vecHL2MPPlayerMin = GetPlayerMins(); Vector vecHL2MPPlayerMax = GetPlayerMaxs(); float flZHeight = vecHL2MPPlayerMax.z - vecHL2MPPlayerMin.z; vecHL2MPPlayerCenter.z += 0.5f * flZHeight; VectorAdd( vecHL2MPPlayerMin, vecHL2MPPlayerCenter, vecHL2MPPlayerMin ); VectorAdd( vecHL2MPPlayerMax, vecHL2MPPlayerCenter, vecHL2MPPlayerMax ); // Find an intersecting player or object. int nAvoidPlayerCount = 0; C_HL2MP_Player *pAvoidPlayerList[MAX_PLAYERS]; C_HL2MP_Player *pIntersectPlayer = NULL; float flAvoidRadius = 0.0f; Vector vecAvoidCenter, vecAvoidMin, vecAvoidMax; for ( int i = 0; i < pTeam->GetNumPlayers(); ++i ) { C_HL2MP_Player *pAvoidPlayer = static_cast< C_HL2MP_Player * >( pTeam->GetPlayer( i ) ); if ( pAvoidPlayer == NULL ) continue; // Is the avoid player me? if ( pAvoidPlayer == this ) continue; // Save as list to check against for objects. pAvoidPlayerList[nAvoidPlayerCount] = pAvoidPlayer; ++nAvoidPlayerCount; // Check to see if the avoid player is dormant. if ( pAvoidPlayer->IsDormant() ) continue; // Is the avoid player solid? if ( pAvoidPlayer->IsSolidFlagSet( FSOLID_NOT_SOLID ) ) continue; Vector t1, t2; vecAvoidCenter = pAvoidPlayer->GetAbsOrigin(); vecAvoidMin = pAvoidPlayer->GetPlayerMins(); vecAvoidMax = pAvoidPlayer->GetPlayerMaxs(); flZHeight = vecAvoidMax.z - vecAvoidMin.z; vecAvoidCenter.z += 0.5f * flZHeight; VectorAdd( vecAvoidMin, vecAvoidCenter, vecAvoidMin ); VectorAdd( vecAvoidMax, vecAvoidCenter, vecAvoidMax ); if ( IsBoxIntersectingBox( vecHL2MPPlayerMin, vecHL2MPPlayerMax, vecAvoidMin, vecAvoidMax ) ) { // Need to avoid this player. if ( !pIntersectPlayer ) { pIntersectPlayer = pAvoidPlayer; break; } } } // Anything to avoid? if ( !pIntersectPlayer ) return; // Calculate the push strength and direction. Vector vecDelta; // Avoid a player - they have precedence. if ( pIntersectPlayer ) { VectorSubtract( pIntersectPlayer->WorldSpaceCenter(), vecHL2MPPlayerCenter, vecDelta ); Vector vRad = pIntersectPlayer->WorldAlignMaxs() - pIntersectPlayer->WorldAlignMins(); vRad.z = 0; flAvoidRadius = vRad.Length(); } float flPushStrength = RemapValClamped( vecDelta.Length(), flAvoidRadius, 0, 0, hl2mp_max_separation_force.GetInt() ); //flPushScale; //Msg( "PushScale = %f\n", flPushStrength ); // Check to see if we have enough push strength to make a difference. if ( flPushStrength < 0.01f ) return; Vector vecPush; if ( GetAbsVelocity().Length2DSqr() > 0.1f ) { Vector vecVelocity = GetAbsVelocity(); vecVelocity.z = 0.0f; CrossProduct( vecUp, vecVelocity, vecPush ); VectorNormalize( vecPush ); } else { // We are not moving, but we're still intersecting. QAngle angView = pCmd->viewangles; angView.x = 0.0f; AngleVectors( angView, NULL, &vecPush, NULL ); } // Move away from the other player/object. Vector vecSeparationVelocity; if ( vecDelta.Dot( vecPush ) < 0 ) { vecSeparationVelocity = vecPush * flPushStrength; } else { vecSeparationVelocity = vecPush * -flPushStrength; } // Don't allow the max push speed to be greater than the max player speed. float flMaxPlayerSpeed = MaxSpeed(); float flCropFraction = 1.33333333f; if ( ( GetFlags() & FL_DUCKING ) && ( GetGroundEntity() != NULL ) ) { flMaxPlayerSpeed *= flCropFraction; } float flMaxPlayerSpeedSqr = flMaxPlayerSpeed * flMaxPlayerSpeed; if ( vecSeparationVelocity.LengthSqr() > flMaxPlayerSpeedSqr ) { vecSeparationVelocity.NormalizeInPlace(); VectorScale( vecSeparationVelocity, flMaxPlayerSpeed, vecSeparationVelocity ); } QAngle vAngles = pCmd->viewangles; vAngles.x = 0; Vector currentdir; Vector rightdir; AngleVectors( vAngles, ¤tdir, &rightdir, NULL ); Vector vDirection = vecSeparationVelocity; VectorNormalize( vDirection ); float fwd = currentdir.Dot( vDirection ); float rt = rightdir.Dot( vDirection ); float forward = fwd * flPushStrength; float side = rt * flPushStrength; //Msg( "fwd: %f - rt: %f - forward: %f - side: %f\n", fwd, rt, forward, side ); pCmd->forwardmove += forward; pCmd->sidemove += side; // Clamp the move to within legal limits, preserving direction. This is a little // complicated because we have different limits for forward, back, and side //Msg( "PRECLAMP: forwardmove=%f, sidemove=%f\n", pCmd->forwardmove, pCmd->sidemove ); float flForwardScale = 1.0f; if ( pCmd->forwardmove > fabs( cl_forwardspeed.GetFloat() ) ) { flForwardScale = fabs( cl_forwardspeed.GetFloat() ) / pCmd->forwardmove; } else if ( pCmd->forwardmove < -fabs( cl_backspeed.GetFloat() ) ) { flForwardScale = fabs( cl_backspeed.GetFloat() ) / fabs( pCmd->forwardmove ); } float flSideScale = 1.0f; if ( fabs( pCmd->sidemove ) > fabs( cl_sidespeed.GetFloat() ) ) { flSideScale = fabs( cl_sidespeed.GetFloat() ) / fabs( pCmd->sidemove ); } float flScale = min( flForwardScale, flSideScale ); pCmd->forwardmove *= flScale; pCmd->sidemove *= flScale; //Msg( "Pforwardmove=%f, sidemove=%f\n", pCmd->forwardmove, pCmd->sidemove ); }
//----------------- CalculateExpectedTimeToReachPosition ---------------------- // // returns a value indicating the time in seconds it will take the bot // to reach the given position at its current speed. //----------------------------------------------------------------------------- double Raven_Bot::CalculateTimeToReachPosition(Vector2D pos)const { return Vec2DDistance(Pos(), pos) / (MaxSpeed() * FrameRate); }
void CPushable :: Move( CBaseEntity *pOther, int push ) { entvars_t* pevToucher = pOther->pev; int playerTouch = 0; // Is entity standing on this pushable ? if ( FBitSet(pevToucher->flags,FL_ONGROUND) && pevToucher->groundentity && VARS(pevToucher->groundentity) == pev ) { // Only push if floating if ( pev->waterlevel > 0 ) pev->velocity.z += pevToucher->velocity.z * 0.1; return; } if ( pOther->IsPlayer() ) { if ( push && !(pevToucher->button & (IN_FORWARD|IN_USE)) ) // Don't push unless the player is pushing forward and NOT use (pull) return; playerTouch = 1; } float factor; if ( playerTouch ) { if ( !(pevToucher->flags & FL_ONGROUND) ) // Don't push away from jumping/falling players unless in water { if ( pev->waterlevel < 1 ) return; else factor = 0.1; } else factor = 1; } else factor = 0.25; pev->velocity.x += pevToucher->velocity.x * factor; pev->velocity.y += pevToucher->velocity.y * factor; float length = sqrt( pev->velocity.x * pev->velocity.x + pev->velocity.y * pev->velocity.y ); if ( push && (length > MaxSpeed()) ) { pev->velocity.x = (pev->velocity.x * MaxSpeed() / length ); pev->velocity.y = (pev->velocity.y * MaxSpeed() / length ); } if ( playerTouch ) { pevToucher->velocity.x = pev->velocity.x; pevToucher->velocity.y = pev->velocity.y; if ( (gpGlobals->time - m_soundTime) > 0.7 ) { m_soundTime = gpGlobals->time; if ( length > 0 && FBitSet(pev->flags,FL_ONGROUND) ) { m_lastSound = RANDOM_LONG(0,2); EMIT_SOUND(ENT(pev), CHAN_WEAPON, m_soundNames[m_lastSound], 0.5, ATTN_NORM); // SetThink( StopSound ); // pev->nextthink = pev->ltime + 0.1; } else STOP_SOUND( ENT(pev), CHAN_WEAPON, m_soundNames[m_lastSound] ); } } }
void CPushable :: Move( CBaseEntity *pOther, int push ) { entvars_t* pevToucher = pOther->pev; int playerTouch = 0; // Is entity standing on this pushable ? if ( FBitSet(pevToucher->flags,FL_ONGROUND) && pevToucher->groundentity && VARS(pevToucher->groundentity) == pev ) { // Only push if floating if ( pev->waterlevel > 0 && pev->watertype > CONTENT_FLYFIELD) pev->velocity.z += pevToucher->velocity.z * 0.1; return; } if ( pOther->IsPlayer() ) { if ( push && !(pevToucher->button & (IN_FORWARD|IN_USE)) ) // Don't push unless the player is pushing forward and NOT use (pull) return; playerTouch = 1; } float factor; if ( playerTouch ) { if ( !(pevToucher->flags & FL_ONGROUND) ) // Don't push away from jumping/falling players unless in water { if ( pev->waterlevel < 1 || pev->watertype <= CONTENT_FLYFIELD) return; else factor = 0.1; } else factor = 1; } else factor = 0.25; if (!push) factor = factor*0.5; Vector oldVelocity = pev->velocity; //LRC 1.8 pev->velocity.x += pevToucher->velocity.x * factor; pev->velocity.y += pevToucher->velocity.y * factor; float length = sqrt( pev->velocity.x * pev->velocity.x + pev->velocity.y * pev->velocity.y ); if ( push && (length > MaxSpeed()) ) { pev->velocity.x = (pev->velocity.x * MaxSpeed() / length ); pev->velocity.y = (pev->velocity.y * MaxSpeed() / length ); } if ( playerTouch ) { //LRC 1.8 if ( pev->spawnflags & SF_PUSH_NOSUPERPUSH ) { // don't accelerate the pushable to be faster than the person pushing it float playerSpeed = pevToucher->velocity.Length2D(); Vector playerPushDir = pevToucher->velocity/playerSpeed; playerPushDir.z = 0; float newdot = DotProduct( playerPushDir, pev->velocity ); // how fast we're going with respect to the playerPushDir float olddot = DotProduct( playerPushDir, oldVelocity ); // how fast we used to be going if ( /*olddot <= playerSpeed+0.1f &&*/ newdot > playerSpeed ) { // if it wasn't going too fast before, and now it is, adjust to the pusher's actual velocity pev->velocity.x -= playerPushDir.x * newdot; pev->velocity.y -= playerPushDir.y * newdot; pev->velocity.x += pevToucher->velocity.x; pev->velocity.y += pevToucher->velocity.y; } } pevToucher->velocity.x = pev->velocity.x; pevToucher->velocity.y = pev->velocity.y; if ( (gpGlobals->time - m_soundTime) > 0.7 ) { m_soundTime = gpGlobals->time; if ( length > 0 && FBitSet(pev->flags,FL_ONGROUND) ) { m_lastSound = RANDOM_LONG(0,2); EMIT_SOUND(ENT(pev), CHAN_WEAPON, m_soundNames[m_lastSound], 0.5, ATTN_NORM); // SetThink( StopSound ); // SetNextThink( 0.1 ); } else STOP_SOUND( ENT(pev), CHAN_WEAPON, m_soundNames[m_lastSound] ); } } }