diff --git a/src/game/client/c_baseanimating.cpp b/src/game/client/c_baseanimating.cpp index 060c940972..c1c779baa1 100644 --- a/src/game/client/c_baseanimating.cpp +++ b/src/game/client/c_baseanimating.cpp @@ -1216,6 +1216,9 @@ CStudioHdr *C_BaseAnimating::OnNewModel() } m_BoneAccessor.Init( this, m_CachedBoneData.Base() ); // Always call this in case the studiohdr_t has changed. + // Reset the accumulated bone mask. + m_iAccumulatedBoneMask = 0; + // Free any IK data if (m_pIk) { @@ -2286,16 +2289,24 @@ bool C_BaseAnimating::PutAttachment( int number, const matrix3x4_t &attachmentTo return false; CAttachmentData *pAtt = &m_Attachments[number-1]; - if ( gpGlobals->frametime > 0 && pAtt->m_nLastFramecount > 0 && pAtt->m_nLastFramecount == gpGlobals->framecount - 1 ) + if ( gpGlobals->frametime > 0 && pAtt->m_nLastFramecount > 0 && pAtt->m_nLastFramecount < gpGlobals->framecount ) { Vector vecPreviousOrigin, vecOrigin; MatrixPosition( pAtt->m_AttachmentToWorld, vecPreviousOrigin ); MatrixPosition( attachmentToWorld, vecOrigin ); - pAtt->m_vOriginVelocity = (vecOrigin - vecPreviousOrigin) / gpGlobals->frametime; + + // compensate for the fact that the previous origin could have been multiple frames behind + pAtt->m_vOriginVelocity = (vecOrigin - vecPreviousOrigin) / (gpGlobals->frametime * (gpGlobals->framecount - pAtt->m_nLastFramecount)); + // only update the frame count if the position changed, so we don't have to recompute attachments + if ( !pAtt->m_vOriginVelocity.IsZero( 0.00001f ) ) + { + pAtt->m_nLastFramecount = gpGlobals->framecount; + } } else { pAtt->m_vOriginVelocity.Init(); + pAtt->m_nLastFramecount = gpGlobals->framecount; } pAtt->m_nLastFramecount = gpGlobals->framecount; pAtt->m_bAnglesComputed = false; @@ -2308,6 +2319,20 @@ bool C_BaseAnimating::PutAttachment( int number, const matrix3x4_t &attachmentTo return true; } +bool C_BaseAnimating::GetAttachmentDeferred( int number, matrix3x4_t& matrix ) +{ + if ( number < 1 || number > m_Attachments.Count() ) + return false; + + // allow visual effects (eg. particles) to be a frame behind bone setup so that there are not messy dependencies. + CAttachmentData* pAtt = &m_Attachments[number - 1]; + const bool bShouldUpdate = pAtt->m_nLastFramecount < gpGlobals->framecount - 1; + if ( bShouldUpdate && !CalcAttachments() ) + return false; + + matrix = pAtt->m_AttachmentToWorld; + return true; +} bool C_BaseAnimating::SetupBones_AttachmentHelper( CStudioHdr *hdr ) { @@ -3122,6 +3147,22 @@ bool C_BaseAnimating::SetupBones( matrix3x4_t *pBoneToWorldOut, int nMaxBones, i } } + // If we're setting up LOD N, we have set up all lower LODs also + // because lower LODs always use subsets of the bones of higher LODs. + int nLOD = 0; + int nMask = BONE_USED_BY_VERTEX_LOD0; + + for ( ; nLOD < MAX_NUM_LODS; ++nLOD, nMask <<= 1 ) + { + if ( boneMask & nMask ) + break; + } + + for ( ; nLOD < MAX_NUM_LODS; ++nLOD, nMask <<= 1 ) + { + boneMask |= nMask; + } + #ifdef DEBUG_BONE_SETUP_THREADING if ( cl_warn_thread_contested_bone_setup.GetBool() ) { @@ -3154,7 +3195,9 @@ bool C_BaseAnimating::SetupBones( matrix3x4_t *pBoneToWorldOut, int nMaxBones, i m_flLastBoneSetupTime = currentTime; } m_iPrevBoneMask = m_iAccumulatedBoneMask; - m_iAccumulatedBoneMask = 0; + + // Keep record of the fact that we've used attachments. Because of deferred attachments, we can't keep track from the previous frame. + m_iAccumulatedBoneMask = m_iAccumulatedBoneMask & BONE_USED_BY_ATTACHMENT; #ifdef STUDIO_ENABLE_PERF_COUNTERS CStudioHdr *hdr = GetModelPtr(); @@ -3189,7 +3232,7 @@ bool C_BaseAnimating::SetupBones( matrix3x4_t *pBoneToWorldOut, int nMaxBones, i return false; // Setup our transform based on render angles and origin. - matrix3x4_t parentTransform; + ALIGN16 matrix3x4_t parentTransform ALIGN16_POST; AngleMatrix( GetRenderAngles(), GetRenderOrigin(), parentTransform ); // Load the boneMask with the total of what was asked for last frame. diff --git a/src/game/client/c_baseanimating.h b/src/game/client/c_baseanimating.h index 5b25100933..927ebd5875 100644 --- a/src/game/client/c_baseanimating.h +++ b/src/game/client/c_baseanimating.h @@ -278,6 +278,7 @@ class C_BaseAnimating : public C_BaseEntity, private IModelLoadCallback // Attachments. bool GetAttachment( const char *szName, Vector &absOrigin ); bool GetAttachment( const char *szName, Vector &absOrigin, QAngle &absAngles ); + virtual bool GetAttachmentDeferred( int number, matrix3x4_t& matrix ); // Inherited from C_BaseEntity virtual bool GetAttachment( int number, Vector &origin ); diff --git a/src/game/client/c_baseflex.cpp b/src/game/client/c_baseflex.cpp index b63e43a101..1fbe86cb83 100644 --- a/src/game/client/c_baseflex.cpp +++ b/src/game/client/c_baseflex.cpp @@ -574,7 +574,7 @@ Vector C_BaseFlex::SetViewTarget( CStudioHdr *pStudioHdr ) if (m_iEyeAttachment > 0) { matrix3x4_t attToWorld; - if (!GetAttachment( m_iEyeAttachment, attToWorld )) + if (!GetAttachmentDeferred( m_iEyeAttachment, attToWorld )) { return Vector( 0, 0, 0); } diff --git a/src/game/client/c_smokestack.cpp b/src/game/client/c_smokestack.cpp index c2c0a9f0d3..7d2eac62d3 100644 --- a/src/game/client/c_smokestack.cpp +++ b/src/game/client/c_smokestack.cpp @@ -406,7 +406,7 @@ void C_SmokeStack::RenderParticles( CParticleRenderIterator *pIterator ) // makes it get translucent and fade out for a longer time. //float alpha = cosf( -M_PI_F + tLifetime * M_PI_F * 2.f ) * 0.5f + 0.5f; float tLifetime = pParticle->m_Lifetime * m_InvLifetime; - float alpha = TableCos( -M_PI_F + tLifetime * M_PI_F * 2.f ) * 0.5f + 0.5f; + float alpha = FastCos( -M_PI_F + tLifetime * M_PI_F * 2.f ) * 0.5f + 0.5f; if( tLifetime > 0.5f ) alpha *= alpha; diff --git a/src/game/client/glow_overlay.cpp b/src/game/client/glow_overlay.cpp index 7edecd8f0c..9cc12ddc03 100644 --- a/src/game/client/glow_overlay.cpp +++ b/src/game/client/glow_overlay.cpp @@ -159,7 +159,7 @@ void CGlowOverlay::UpdateSkyGlowObstruction( float zFar, bool bCacheFullSceneSta if ( PixelVisibility_IsAvailable() ) { // Trace a ray at the object. - Vector pos = CurrentViewOrigin() + m_vDirection * zFar * 0.999f; + Vector pos = CurrentViewOrigin() + m_vDirection * zFar * 0.99f; // UNDONE: Can probably do only the pixelvis query in this case if you can figure out where // to put it - or save the position of this trace diff --git a/src/game/client/in_steamcontroller.cpp b/src/game/client/in_steamcontroller.cpp index 62527970a0..c70a156913 100644 --- a/src/game/client/in_steamcontroller.cpp +++ b/src/game/client/in_steamcontroller.cpp @@ -69,8 +69,8 @@ void CInput::ApplySteamControllerCameraMove( QAngle& viewangles, CUserCmd *cmd, //roll the view angles so roll is 0 (the HL2 assumed state) and mouse adjustments are relative to the screen. //Assuming roll is unchanging, we want mouse left to translate to screen left at all times (same for right, up, and down) - ConVarRef cl_pitchdown ( "cl_pitchdown" ); - ConVarRef cl_pitchup ( "cl_pitchup" ); + static ConVarRef cl_pitchdown ( "cl_pitchdown" ); + static ConVarRef cl_pitchup ( "cl_pitchup" ); // Scale yaw and pitch inputs by sensitivity, and make sure they are within acceptable limits (important to avoid exploits, e.g. during Demoman charge we must restrict allowed yaw). float yaw = CAM_CapYaw( sc_yaw_sensitivity.GetFloat() * vecPosition.x ); diff --git a/src/game/client/tf/c_tf_player.cpp b/src/game/client/tf/c_tf_player.cpp index 73d464cc81..f90764406c 100644 --- a/src/game/client/tf/c_tf_player.cpp +++ b/src/game/client/tf/c_tf_player.cpp @@ -1329,6 +1329,20 @@ bool C_TFRagdoll::GetAttachment( int iAttachment, matrix3x4_t &attachmentToWorld } } +bool C_TFRagdoll::GetAttachmentDeferred( int iAttachment, matrix3x4_t& attachmentToWorld ) +{ + int iHeadAttachment = LookupAttachment( "head" ); + if ( IsDecapitation() && (iAttachment == iHeadAttachment) ) + { + MatrixCopy( m_mHeadAttachment, attachmentToWorld ); + return true; + } + else + { + return BaseClass::GetAttachmentDeferred( iAttachment, attachmentToWorld ); + } +} + //----------------------------------------------------------------------------- // Purpose: // Input : - @@ -1369,6 +1383,9 @@ bool C_TFRagdoll::IsRagdollVisible() #define DISSOLVE_FADE_OUT_START_TIME 2.0f #define DISSOLVE_FADE_OUT_END_TIME 2.0f +extern ConVar g_ragdoll_lvfadespeed; +extern ConVar g_ragdoll_fadespeed; + void C_TFRagdoll::ClientThink( void ) { SetNextClientThink( CLIENT_THINK_ALWAYS ); @@ -1510,9 +1527,16 @@ void C_TFRagdoll::ClientThink( void ) if ( m_bFadingOut == true ) { int iAlpha = GetRenderColor().a; - int iFadeSpeed = 600.0f; + int iFadeSpeed = ( g_RagdollLVManager.IsLowViolence() ) ? g_ragdoll_lvfadespeed.GetInt() : g_ragdoll_fadespeed.GetInt(); - iAlpha = MAX( iAlpha - ( iFadeSpeed * gpGlobals->frametime ), 0 ); + if (iFadeSpeed < 1) + { + iAlpha = 0; + } + else + { + iAlpha = MAX( iAlpha - ( iFadeSpeed * gpGlobals->frametime ), 0 ); + } SetRenderMode( kRenderTransAlpha ); SetRenderColorA( iAlpha ); @@ -1531,15 +1555,22 @@ void C_TFRagdoll::ClientThink( void ) if ( cl_ragdoll_forcefade.GetBool() ) { m_bFadingOut = true; - float flDelay = cl_ragdoll_fade_time.GetFloat() * 0.33f; - m_fDeathTime = gpGlobals->curtime + flDelay; - RemoveAllDecals(); - } - // Fade out after the specified delay. - StartFadeOut( cl_ragdoll_fade_time.GetFloat() * 0.33f ); - return; + float flDelay = cl_ragdoll_fade_time.GetFloat() * 0.33f; + if (flDelay > 0.01f) + { + m_fDeathTime = gpGlobals->curtime + flDelay; + return; + } + m_fDeathTime = -1; + } + else + { + // Fade out after the specified delay. + StartFadeOut( cl_ragdoll_fade_time.GetFloat() * 0.33f ); + return; + } } // Remove us if our death time has passed. @@ -6845,7 +6876,7 @@ int C_TFPlayer::DrawModel( int flags ) // Don't draw the model at all if we're fully invisible if ( GetEffectiveInvisibilityLevel() >= 1.0f ) { - if ( m_hHalloweenBombHat && ( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() < 90 ) && !m_hHalloweenBombHat->IsEffectActive( EF_NODRAW ) ) + if ( m_hHalloweenBombHat && ( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() < 90 || g_pMaterialSystemHardwareConfig->PreferReducedFillrate() ) && !m_hHalloweenBombHat->IsEffectActive( EF_NODRAW ) ) { m_hHalloweenBombHat->SetEffects( EF_NODRAW ); } @@ -6853,7 +6884,7 @@ int C_TFPlayer::DrawModel( int flags ) } else { - if ( m_hHalloweenBombHat && ( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() < 90 ) && m_hHalloweenBombHat->IsEffectActive( EF_NODRAW ) ) + if ( m_hHalloweenBombHat && ( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() < 90 || g_pMaterialSystemHardwareConfig->PreferReducedFillrate() ) && m_hHalloweenBombHat->IsEffectActive( EF_NODRAW ) ) { m_hHalloweenBombHat->RemoveEffects( EF_NODRAW ); } @@ -7504,7 +7535,7 @@ void C_TFPlayer::DropWearable( C_TFWearable *pItem, const breakablepropparams_t } pEntity->m_nSkin = m_nSkin; - pEntity->StartFadeOut( 15.0f ); + pEntity->StartFadeOut( cl_ragdoll_fade_time.GetFloat() ); IPhysicsObject *pPhysicsObject = pEntity->VPhysicsGetObject(); if ( !pPhysicsObject ) diff --git a/src/game/client/tf/c_tf_player.h b/src/game/client/tf/c_tf_player.h index 0fcee37308..c9520ed29e 100644 --- a/src/game/client/tf/c_tf_player.h +++ b/src/game/client/tf/c_tf_player.h @@ -1054,6 +1054,7 @@ class C_TFRagdoll : public C_BaseFlex int GetDamageCustom() { return m_iDamageCustom; } virtual bool GetAttachment( int iAttachment, matrix3x4_t &attachmentToWorld ); + virtual bool GetAttachmentDeferred( int iAttachment, matrix3x4_t& attachmentToWorld ); int GetClass() { return m_iClass; } diff --git a/src/game/client/tf/tf_hud_notification_panel.cpp b/src/game/client/tf/tf_hud_notification_panel.cpp index 26333fe5a5..487282eed8 100644 --- a/src/game/client/tf/tf_hud_notification_panel.cpp +++ b/src/game/client/tf/tf_hud_notification_panel.cpp @@ -101,7 +101,7 @@ void CHudNotificationPanel::MsgFunc_HudNotify( bf_read &msg ) // Ignore notifications in minmode if ( !bForceShow ) { - ConVarRef cl_hud_minmode( "cl_hud_minmode", true ); + static ConVarRef cl_hud_minmode( "cl_hud_minmode", true ); if ( cl_hud_minmode.IsValid() && cl_hud_minmode.GetBool() ) return; } @@ -140,7 +140,7 @@ void CHudNotificationPanel::MsgFunc_HudNotify( bf_read &msg ) void CHudNotificationPanel::MsgFunc_HudNotifyCustom( bf_read &msg ) { // Ignore notifications in minmode - ConVarRef cl_hud_minmode( "cl_hud_minmode", true ); + static ConVarRef cl_hud_minmode( "cl_hud_minmode", true ); if ( cl_hud_minmode.IsValid() && cl_hud_minmode.GetBool() ) return; diff --git a/src/game/client/tf/vgui/tf_classmenu.cpp b/src/game/client/tf/vgui/tf_classmenu.cpp index 3fd7eb0406..af49406478 100644 --- a/src/game/client/tf/vgui/tf_classmenu.cpp +++ b/src/game/client/tf/vgui/tf_classmenu.cpp @@ -1179,6 +1179,11 @@ void CTFClassMenu::SetVisible( bool state ) if ( state ) { + if (m_pTFPlayerModelPanel) + { + m_pTFPlayerModelPanel->SetVisible( true ); + } + engine->ServerCmd( "menuopen" ); // to the server engine->ClientCmd( "_cl_classmenuopen 1" ); // for other panels CBroadcastRecipientFilter filter; @@ -1198,6 +1203,11 @@ void CTFClassMenu::SetVisible( bool state ) { engine->ServerCmd( "menuclosed" ); engine->ClientCmd( "_cl_classmenuopen 0" ); + + if (m_pTFPlayerModelPanel) + { + m_pTFPlayerModelPanel->SetVisible( false ); + } if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() ) { diff --git a/src/game/client/viewrender.cpp b/src/game/client/viewrender.cpp index e49f44595d..b9fba9f8a0 100644 --- a/src/game/client/viewrender.cpp +++ b/src/game/client/viewrender.cpp @@ -2796,15 +2796,11 @@ void CViewRender::DetermineWaterRenderInfo( const VisibleFogVolumeInfo_t &fogVol // Gary says: I'm reverting this change so that water LOD works on dx9 for ep2. // Check if the water is out of the cheap water LOD range; if so, use cheap water -#ifdef _X360 if ( !bForceExpensive && ( bForceCheap || ( fogVolumeInfo.m_flDistanceToWater >= m_flCheapWaterEndDistance ) ) ) { return; } -#else - if ( ( (fogVolumeInfo.m_flDistanceToWater >= m_flCheapWaterEndDistance) && !bLocalReflection ) || bForceCheap ) - return; -#endif + // Get the material that is for the water surface that is visible and check to see // what render targets need to be rendered, if any. if ( !r_WaterDrawRefraction.GetBool() ) diff --git a/src/game/server/tf/entity_ammopack.cpp b/src/game/server/tf/entity_ammopack.cpp index b861661ed9..0339597db3 100644 --- a/src/game/server/tf/entity_ammopack.cpp +++ b/src/game/server/tf/entity_ammopack.cpp @@ -66,19 +66,19 @@ bool CAmmoPack::MyTouch( CBasePlayer *pPlayer ) float flPackRatio = PackRatios[GetPowerupSize()]; int iMaxPrimary = pTFPlayer->GetMaxAmmo(TF_AMMO_PRIMARY); - if ( pTFPlayer->GiveAmmo( ceil(iMaxPrimary * flPackRatio), TF_AMMO_PRIMARY, true, kAmmoSource_Pickup ) ) + if ( pTFPlayer->GiveAmmo( Ceil2Int(iMaxPrimary * flPackRatio), TF_AMMO_PRIMARY, true, kAmmoSource_Pickup ) ) { bSuccess = true; } int iMaxSecondary = pTFPlayer->GetMaxAmmo(TF_AMMO_SECONDARY); - if ( pTFPlayer->GiveAmmo( ceil(iMaxSecondary * flPackRatio), TF_AMMO_SECONDARY, true, kAmmoSource_Pickup ) ) + if ( pTFPlayer->GiveAmmo( Ceil2Int(iMaxSecondary * flPackRatio), TF_AMMO_SECONDARY, true, kAmmoSource_Pickup ) ) { bSuccess = true; } int iMaxMetal = pTFPlayer->GetMaxAmmo(TF_AMMO_METAL); - if ( pTFPlayer->GiveAmmo( ceil(iMaxMetal * flPackRatio), TF_AMMO_METAL, true, kAmmoSource_Pickup ) ) + if ( pTFPlayer->GiveAmmo( Ceil2Int(iMaxMetal * flPackRatio), TF_AMMO_METAL, true, kAmmoSource_Pickup ) ) { bSuccess = true; } @@ -112,7 +112,7 @@ bool CAmmoPack::MyTouch( CBasePlayer *pPlayer ) if ( pTFPlayer->IsPlayerClass( TF_CLASS_ENGINEER ) ) { int iMaxGrenades1 = pTFPlayer->GetMaxAmmo(TF_AMMO_GRENADES1); - if ( pTFPlayer->GiveAmmo( ceil(iMaxGrenades1 * flPackRatio), TF_AMMO_GRENADES1, true, kAmmoSource_Pickup ) ) + if ( pTFPlayer->GiveAmmo( Ceil2Int(iMaxGrenades1 * flPackRatio), TF_AMMO_GRENADES1, true, kAmmoSource_Pickup ) ) { bSuccess = true; } diff --git a/src/game/server/tf/entity_healthkit.cpp b/src/game/server/tf/entity_healthkit.cpp index c02121ece3..279579f1ea 100644 --- a/src/game/server/tf/entity_healthkit.cpp +++ b/src/game/server/tf/entity_healthkit.cpp @@ -90,7 +90,7 @@ bool CHealthKit::MyTouch( CBasePlayer *pPlayer ) { float flRuneHealthBonus = ( pTFPlayer->m_Shared.GetCarryingRuneType() != RUNE_KNOCKOUT ) ? pTFPlayer->GetRuneHealthBonus() : 0; - float flHealth = ceil( ( pPlayer->GetMaxHealth() - flRuneHealthBonus ) * PackRatios[GetPowerupSize()] ); + float flHealth = Ceil2Int( ( pPlayer->GetMaxHealth() - flRuneHealthBonus ) * PackRatios[GetPowerupSize()] ); CALL_ATTRIB_HOOK_FLOAT_ON_OTHER( pPlayer, flHealth, mult_health_frompacks ); @@ -116,7 +116,7 @@ bool CHealthKit::MyTouch( CBasePlayer *pPlayer ) { float flDisguiseHealth = pTFPlayer->m_Shared.GetDisguiseHealth(); float flDisguiseMaxHealth = pTFPlayer->m_Shared.GetDisguiseMaxHealth(); - float flHealthToAdd = ceil(flDisguiseMaxHealth * PackRatios[GetPowerupSize()]); + float flHealthToAdd = Ceil2Int(flDisguiseMaxHealth * PackRatios[GetPowerupSize()]); // don't want to add more than we're allowed to have if ( flHealthToAdd > flDisguiseMaxHealth - flDisguiseHealth ) @@ -248,19 +248,19 @@ bool CHealthAmmoKit::MyTouch( CBasePlayer *pPlayer ) float flPackRatio = PackRatios[GetPowerupSize()]; int iMaxPrimary = pTFPlayer->GetMaxAmmo( TF_AMMO_PRIMARY ); - if ( pTFPlayer->GiveAmmo( ceil( iMaxPrimary * flPackRatio ), TF_AMMO_PRIMARY, true, kAmmoSource_Pickup ) ) + if ( pTFPlayer->GiveAmmo( Ceil2Int( iMaxPrimary * flPackRatio ), TF_AMMO_PRIMARY, true, kAmmoSource_Pickup ) ) { bAmmoSuccess = true; } int iMaxSecondary = pTFPlayer->GetMaxAmmo( TF_AMMO_SECONDARY ); - if ( pTFPlayer->GiveAmmo( ceil( iMaxSecondary * flPackRatio ), TF_AMMO_SECONDARY, true, kAmmoSource_Pickup ) ) + if ( pTFPlayer->GiveAmmo( Ceil2Int( iMaxSecondary * flPackRatio ), TF_AMMO_SECONDARY, true, kAmmoSource_Pickup ) ) { bAmmoSuccess = true; } int iMaxMetal = pTFPlayer->GetMaxAmmo( TF_AMMO_METAL ); - if ( pTFPlayer->GiveAmmo( ceil( iMaxMetal * flPackRatio ), TF_AMMO_METAL, true, kAmmoSource_Pickup ) ) + if ( pTFPlayer->GiveAmmo( Ceil2Int( iMaxMetal * flPackRatio ), TF_AMMO_METAL, true, kAmmoSource_Pickup ) ) { bAmmoSuccess = true; } @@ -278,7 +278,7 @@ bool CHealthAmmoKit::MyTouch( CBasePlayer *pPlayer ) if ( pTFPlayer->IsPlayerClass( TF_CLASS_ENGINEER ) ) { int iMaxGrenades1 = pTFPlayer->GetMaxAmmo( TF_AMMO_GRENADES1 ); - if ( pTFPlayer->GiveAmmo( ceil( iMaxGrenades1 * flPackRatio ), TF_AMMO_GRENADES1, true, kAmmoSource_Pickup ) ) + if ( pTFPlayer->GiveAmmo( Ceil2Int( iMaxGrenades1 * flPackRatio ), TF_AMMO_GRENADES1, true, kAmmoSource_Pickup ) ) { bAmmoSuccess = true; } diff --git a/src/game/server/tf/tf_ammo_pack.cpp b/src/game/server/tf/tf_ammo_pack.cpp index bb35540356..7decf04154 100644 --- a/src/game/server/tf/tf_ammo_pack.cpp +++ b/src/game/server/tf/tf_ammo_pack.cpp @@ -345,10 +345,10 @@ void CTFAmmoPack::PackTouch( CBaseEntity *pOther ) } int iMaxPrimary = pPlayer->GetMaxAmmo(TF_AMMO_PRIMARY); - GiveAmmo( ceil( iMaxPrimary * m_flAmmoRatio ), TF_AMMO_PRIMARY ); + GiveAmmo( Ceil2Int( iMaxPrimary * m_flAmmoRatio ), TF_AMMO_PRIMARY ); int iMaxSecondary = pPlayer->GetMaxAmmo(TF_AMMO_SECONDARY); - GiveAmmo( ceil( iMaxSecondary * m_flAmmoRatio ), TF_AMMO_SECONDARY ); + GiveAmmo( Ceil2Int( iMaxSecondary * m_flAmmoRatio ), TF_AMMO_SECONDARY ); int iAmmoTaken = 0; @@ -393,7 +393,7 @@ void CTFAmmoPack::PackTouch( CBaseEntity *pOther ) if ( pPlayer->IsPlayerClass( TF_CLASS_ENGINEER ) ) { int iMaxGrenades1 = pPlayer->GetMaxAmmo( TF_AMMO_GRENADES1 ); - iAmmoTaken += pPlayer->GiveAmmo( ceil(iMaxGrenades1 * m_flAmmoRatio), TF_AMMO_GRENADES1 ); + iAmmoTaken += pPlayer->GiveAmmo( Ceil2Int(iMaxGrenades1 * m_flAmmoRatio), TF_AMMO_GRENADES1 ); } if ( m_PackType == AP_HALLOWEEN ) diff --git a/src/game/server/tf/tf_obj.cpp b/src/game/server/tf/tf_obj.cpp index c7a9e93a0a..0e03a52d87 100644 --- a/src/game/server/tf/tf_obj.cpp +++ b/src/game/server/tf/tf_obj.cpp @@ -1604,7 +1604,7 @@ void CBaseObject::SetHealth( float flHealth ) bool changed = m_flHealth != flHealth; m_flHealth = flHealth; - m_iHealth = ceil(m_flHealth); + m_iHealth = Ceil2Int(m_flHealth); /* @@ -2946,7 +2946,7 @@ int CBaseObject::Command_Repair( CTFPlayer *pActivator, float flAmount, float fl float flRepairAmountMax = flAmount * flRepairMod; int iRepairAmount = Min( RoundFloatToInt( flRepairAmountMax ), GetMaxHealth() - RoundFloatToInt( GetHealth() ) ); - int iRepairCost = ceil( (float)( iRepairAmount ) / flRepairToMetalRatio ); + int iRepairCost = Ceil2Int( (float)( iRepairAmount ) / flRepairToMetalRatio ); if ( iRepairCost > pActivator->GetBuildResources() ) { // What can we afford? diff --git a/src/game/server/tf/tf_obj_teleporter.cpp b/src/game/server/tf/tf_obj_teleporter.cpp index 723eb88ea2..0b5f6e3399 100644 --- a/src/game/server/tf/tf_obj_teleporter.cpp +++ b/src/game/server/tf/tf_obj_teleporter.cpp @@ -690,7 +690,7 @@ int CObjectTeleporter::Command_Repair( CTFPlayer *pActivator, float flAmount, fl { float flRepairAmountMax = flAmount * flRepairMod; int iRepairAmount = Min( flRepairAmountMax, pMatch->GetMaxHealth() - pMatch->GetHealth() ); - int iRepairCost = ceil( (float)iRepairAmount / flRepairToMetalRatio ); + int iRepairCost = Ceil2Int( (float)iRepairAmount / flRepairToMetalRatio ); if ( iRepairCost > pActivator->GetBuildResources() ) { // What can we afford? diff --git a/src/game/server/tf/tf_player.cpp b/src/game/server/tf/tf_player.cpp index cc2961679c..0ebf517f89 100644 --- a/src/game/server/tf/tf_player.cpp +++ b/src/game/server/tf/tf_player.cpp @@ -1879,7 +1879,7 @@ void CTFPlayer::RegenThink( void ) } else if ( m_flAccumulatedHealthRegen < -1.f ) { - nHealAmount = ceil( m_flAccumulatedHealthRegen ); + nHealAmount = Ceil2Int( m_flAccumulatedHealthRegen ); TakeDamage( CTakeDamageInfo( this, this, NULL, vec3_origin, WorldSpaceCenter(), nHealAmount * -1, DMG_GENERIC ) ); } @@ -2013,7 +2013,7 @@ void CTFPlayer::RuneRegenThink( void ) } else if ( m_flAccumulatedRuneHealthRegen < -1.0 ) { - nHealAmount = ceil( m_flAccumulatedRuneHealthRegen ); + nHealAmount = Ceil2Int( m_flAccumulatedRuneHealthRegen ); TakeDamage( CTakeDamageInfo( this, this, NULL, vec3_origin, WorldSpaceCenter(), nHealAmount * -1, DMG_GENERIC ) ); } diff --git a/src/game/shared/achievementmgr.cpp b/src/game/shared/achievementmgr.cpp index efa558422b..d36af88a0d 100644 --- a/src/game/shared/achievementmgr.cpp +++ b/src/game/shared/achievementmgr.cpp @@ -1087,7 +1087,7 @@ bool CAchievementMgr::CheckAchievementsEnabled() return false; } - ConVarRef tf_bot_offline_practice( "tf_bot_offline_practice" ); + static ConVarRef tf_bot_offline_practice( "tf_bot_offline_practice" ); // no achievements for offline practice if ( tf_bot_offline_practice.GetInt() != 0 ) { diff --git a/src/game/shared/baseviewmodel_shared.cpp b/src/game/shared/baseviewmodel_shared.cpp index 3b2d06f326..fbcbd464a4 100644 --- a/src/game/shared/baseviewmodel_shared.cpp +++ b/src/game/shared/baseviewmodel_shared.cpp @@ -727,6 +727,15 @@ bool CBaseViewModel::GetAttachment( int number, matrix3x4_t &matrix ) return BaseClass::GetAttachment( number, matrix ); } +bool C_BaseViewModel::GetAttachmentDeferred( int number, matrix3x4_t& matrix ) +{ + // Update priority for your own viewmodel (no deferral) + if ( m_hWeapon.Get() && m_hWeapon.Get()->WantsToOverrideViewmodelAttachments() ) + return m_hWeapon.Get()->GetAttachment( number, matrix ); + + return BaseClass::GetAttachment( number, matrix ); +} + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- diff --git a/src/game/shared/baseviewmodel_shared.h b/src/game/shared/baseviewmodel_shared.h index 5f1450e614..6ed1187371 100644 --- a/src/game/shared/baseviewmodel_shared.h +++ b/src/game/shared/baseviewmodel_shared.h @@ -172,6 +172,7 @@ class CBaseViewModel : public CBaseAnimating, public IHasOwner // Attachments virtual int LookupAttachment( const char *pAttachmentName ); virtual bool GetAttachment( int number, matrix3x4_t &matrix ); + virtual bool GetAttachmentDeferred( int number, matrix3x4_t& matrix ); virtual bool GetAttachment( int number, Vector &origin ); virtual bool GetAttachment( int number, Vector &origin, QAngle &angles ); virtual bool GetAttachmentVelocity( int number, Vector &originVel, Quaternion &angleVel ); diff --git a/src/game/shared/econ/econ_entity.cpp b/src/game/shared/econ/econ_entity.cpp index dd48f4c41a..90f8c86488 100644 --- a/src/game/shared/econ/econ_entity.cpp +++ b/src/game/shared/econ/econ_entity.cpp @@ -1983,6 +1983,14 @@ bool CEconEntity::GetAttachment( int number, matrix3x4_t &matrix ) return BaseClass::GetAttachment( number, matrix ); } +bool C_EconEntity::GetAttachmentDeferred( int number, matrix3x4_t& matrix ) +{ + if ( m_hViewmodelAttachment ) + return m_hViewmodelAttachment->GetAttachmentDeferred( number, matrix ); + + return BaseClass::GetAttachmentDeferred( number, matrix ); +} + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- diff --git a/src/game/shared/econ/econ_entity.h b/src/game/shared/econ/econ_entity.h index 5e5139fae3..de92ef7d5a 100644 --- a/src/game/shared/econ/econ_entity.h +++ b/src/game/shared/econ/econ_entity.h @@ -117,6 +117,7 @@ class CEconEntity : public CBaseAnimating, public IHasAttributes virtual bool GetAttachment( const char *szName, Vector &absOrigin ) { return BaseClass::GetAttachment(szName,absOrigin); } virtual bool GetAttachment( const char *szName, Vector &absOrigin, QAngle &absAngles ) { return BaseClass::GetAttachment(szName,absOrigin,absAngles); } virtual bool GetAttachment( int number, matrix3x4_t &matrix ); + virtual bool GetAttachmentDeferred( int number, matrix3x4_t& matrix ); virtual bool GetAttachment( int number, Vector &origin ); virtual bool GetAttachment( int number, Vector &origin, QAngle &angles ); virtual bool GetAttachmentVelocity( int number, Vector &originVel, Quaternion &angleVel ); diff --git a/src/game/shared/particle_property.cpp b/src/game/shared/particle_property.cpp index dc2f46c946..780463157b 100644 --- a/src/game/shared/particle_property.cpp +++ b/src/game/shared/particle_property.cpp @@ -605,10 +605,10 @@ void CParticleProperty::UpdateControlPoint( ParticleEffectList_t *pEffect, int i { matrix3x4_t attachmentToWorld; - if ( !pAnimating->GetAttachment( pPoint->iAttachmentPoint, attachmentToWorld ) ) + if ( !pAnimating->GetAttachmentDeferred( pPoint->iAttachmentPoint, attachmentToWorld ) ) { // try C_BaseAnimating if attach point is not on the weapon - if ( !pAnimating->C_BaseAnimating::GetAttachment( pPoint->iAttachmentPoint, attachmentToWorld ) ) + if ( !pAnimating->C_BaseAnimating::GetAttachmentDeferred( pPoint->iAttachmentPoint, attachmentToWorld ) ) { Warning( "Cannot update control point %d for effect '%s'.\n", pPoint->iAttachmentPoint, pEffect->pParticleEffect->GetEffectName() ); // Remove the effect cause this warning means something is orphaned diff --git a/src/game/shared/tf/tf_item_inventory.cpp b/src/game/shared/tf/tf_item_inventory.cpp index a371114598..de0a0935e1 100644 --- a/src/game/shared/tf/tf_item_inventory.cpp +++ b/src/game/shared/tf/tf_item_inventory.cpp @@ -964,7 +964,7 @@ void CTFPlayerInventory::LoadLocalLoadout() m_LoadoutItems[iClass][iSlot] = uItemId; CEconItemView *pItem = GetInventoryItemByItemID(uItemId); - if (pItem) { + if ( pItem && pItem->GetSOCData() ) { pItem->GetSOCData()->Equip(iClass, iSlot); } } diff --git a/src/game/shared/tf/tf_player_shared.cpp b/src/game/shared/tf/tf_player_shared.cpp index abe67cf9c0..3887a08299 100644 --- a/src/game/shared/tf/tf_player_shared.cpp +++ b/src/game/shared/tf/tf_player_shared.cpp @@ -10516,8 +10516,8 @@ void CTFPlayer::FireBullet( CTFWeaponBase *pWpn, const FireBulletsInfo_t &info, } #ifdef CLIENT_DLL -static ConVar tf_impactwatertimeenable( "tf_impactwatertimeenable", "0", FCVAR_CHEAT, "Draw impact debris effects." ); -static ConVar tf_impactwatertime( "tf_impactwatertime", "1.0f", FCVAR_CHEAT, "Draw impact debris effects." ); +static ConVar tf_impactwatertimeenable( "tf_impactwatertimeenable", "1", FCVAR_ARCHIVE, "Rate limit bullet impact effects on water." ); +static ConVar tf_impactwatertime( "tf_impactwatertime", "0.2f", FCVAR_ARCHIVE, "The interval between bullet impact effects on water." ); #endif //----------------------------------------------------------------------------- diff --git a/src/mathlib/mathlib_base.cpp b/src/mathlib/mathlib_base.cpp index 61d6779780..8a8ef75f33 100644 --- a/src/mathlib/mathlib_base.cpp +++ b/src/mathlib/mathlib_base.cpp @@ -115,15 +115,6 @@ float (*pfInvRSquared)(const float* v) = _InvRSquared; void (*pfFastSinCos)(float x, float* s, float* c) = SinCos; float (*pfFastCos)(float x) = cosf; -float SinCosTable[SIN_TABLE_SIZE]; -void InitSinCosTable() -{ - for( int i = 0; i < SIN_TABLE_SIZE; i++ ) - { - SinCosTable[i] = sin(i * 2.0 * M_PI / SIN_TABLE_SIZE); - } -} - qboolean VectorsEqual( const float *v1, const float *v2 ) { Assert( s_bMathlibInitialized ); @@ -3402,7 +3393,6 @@ void MathLib_Init( float gamma, float texGamma, float brightness, int overbright s_bMathlibInitialized = true; - InitSinCosTable(); BuildGammaTable( gamma, texGamma, brightness, overbright ); } diff --git a/src/public/mathlib/mathlib.h b/src/public/mathlib/mathlib.h index 01107d1995..d7146fa83d 100644 --- a/src/public/mathlib/mathlib.h +++ b/src/public/mathlib/mathlib.h @@ -436,34 +436,14 @@ inline vec_t RoundInt (vec_t in) int Q_log2(int val); -#define SIN_TABLE_SIZE 256 -#define FTOIBIAS 12582912.f -extern float SinCosTable[SIN_TABLE_SIZE]; - inline float TableCos( float theta ) { - union - { - int i; - float f; - } ftmp; - - // ideally, the following should compile down to: theta * constant + constant, changing any of these constants from defines sometimes fubars this. - ftmp.f = theta * ( float )( SIN_TABLE_SIZE / ( 2.0f * M_PI ) ) + ( FTOIBIAS + ( SIN_TABLE_SIZE / 4 ) ); - return SinCosTable[ ftmp.i & ( SIN_TABLE_SIZE - 1 ) ]; + return FastCos( theta ); } inline float TableSin( float theta ) { - union - { - int i; - float f; - } ftmp; - - // ideally, the following should compile down to: theta * constant + constant - ftmp.f = theta * ( float )( SIN_TABLE_SIZE / ( 2.0f * M_PI ) ) + FTOIBIAS; - return SinCosTable[ ftmp.i & ( SIN_TABLE_SIZE - 1 ) ]; + return sinf( theta ); } template @@ -1282,11 +1262,17 @@ inline int Floor2Int( float a ) { int RetVal; #if defined( PLATFORM_INTEL ) + +#if MAPBASE + RetVal = _mm_cvt_ss2si(_mm_set_ss(a + a - 0.5f)) >> 1; +#else // Convert to int and back, compare, subtract one if too big __m128 a128 = _mm_set_ss(a); RetVal = _mm_cvtss_si32(a128); __m128 rounded128 = _mm_cvt_si2ss(_mm_setzero_ps(), RetVal); RetVal -= _mm_comigt_ss( rounded128, a128 ); +#endif // MAPBASE + #else RetVal = static_cast( floor(a) ); #endif @@ -1339,11 +1325,17 @@ inline int Ceil2Int( float a ) { int RetVal; #if defined( PLATFORM_INTEL ) - // Convert to int and back, compare, add one if too small + +#if MAPBASE + RetVal = -(_mm_cvt_ss2si(_mm_set_ss(-0.5f - (a + a))) >> 1); +#else + // Convert to int and back, compare, add one if too small __m128 a128 = _mm_load_ss(&a); RetVal = _mm_cvtss_si32(a128); __m128 rounded128 = _mm_cvt_si2ss(_mm_setzero_ps(), RetVal); RetVal += _mm_comilt_ss( rounded128, a128 ); +#endif // MAPBASE + #else RetVal = static_cast( ceil(a) ); #endif