//----------------------------------------------------------------------------- // Draws all the debugging info //----------------------------------------------------------------------------- void CDebugViewRender::Draw2DDebuggingInfo( const CViewSetup &view ) { if ( IsX360() && IsRetail() ) return; // HDRFIXME: Assert NULL rendertarget if ( mat_yuv.GetInt() && (engine->GetDXSupportLevel() >= 80) ) { IMaterial *pMaterial; pMaterial = materials->FindMaterial( "debug/yuv", TEXTURE_GROUP_OTHER, true ); if( !IsErrorMaterial( pMaterial ) ) { DrawScreenEffectMaterial( pMaterial, view.x, view.y, view.width, view.height ); } } if ( mat_hsv.GetInt() && (engine->GetDXSupportLevel() >= 90) ) { IMaterial *pMaterial; pMaterial = materials->FindMaterial( "debug/hsv", TEXTURE_GROUP_OTHER, true ); if( !IsErrorMaterial( pMaterial ) ) { DrawScreenEffectMaterial( pMaterial, view.x, view.y, view.width, view.height ); } } // Draw debugging lightmaps if ( mat_showlightmappage.GetInt() != -1 ) { CLightmapDebugView clientView( assert_cast<CViewRender *>( ::view ) ); clientView.Setup( view ); clientView.Draw(); } if ( cl_drawshadowtexture.GetInt() ) { int nSize = cl_shadowtextureoverlaysize.GetInt(); g_pClientShadowMgr->RenderShadowTexture( nSize, nSize ); } const char *pDrawMaterial = cl_drawmaterial.GetString(); if ( pDrawMaterial && pDrawMaterial[0] ) { RenderMaterial( pDrawMaterial ); } if ( mat_showwatertextures.GetBool() ) { OverlayWaterTextures(); } if ( mat_showcamerarendertarget.GetBool() ) { float w = mat_wateroverlaysize.GetFloat(); float h = mat_wateroverlaysize.GetFloat(); #ifdef PORTAL g_pPortalRender->OverlayPortalRenderTargets( w, h ); #else OverlayCameraRenderTarget( "debug/debugcamerarendertarget", 0, 0, w, h ); #endif } if ( mat_showframebuffertexture.GetBool() ) { // HDRFIXME: Get rid of these rendertarget sets assuming that the assert at the top of this function is true. CMatRenderContextPtr pRenderContext( materials ); pRenderContext->PushRenderTargetAndViewport( NULL ); OverlayFrameBufferTexture( 0 ); OverlayFrameBufferTexture( 1 ); pRenderContext->PopRenderTargetAndViewport( ); } const char *pDrawTexture = mat_drawTexture.GetString(); if ( pDrawTexture && pDrawTexture[0] ) { OverlayShowTexture( pDrawTexture, mat_drawTextureScale.GetFloat() ); } #ifdef _X360 if ( mat_drawColorRamp.GetBool() ) { OverlayColorRamp( mat_drawColorRamp.GetInt() == 2 ); } #endif if ( r_flashlightdrawdepth.GetBool() ) { shadowmgr->DrawFlashlightDepthTexture( ); } if ( mat_drawTitleSafe.GetBool() ) { OverlayTitleSafe(); } }
//----------------------------------------------------------------------------- // Purpose: Give the buster a slight attraction to striders. // Ported back from the magnade. //----------------------------------------------------------------------------- void CWeaponStriderBuster::BusterFlyThink() { if (IsAttachedToStrider()) return; // early out. Think no more. // If we're nosediving, forget about magnetism. if ( m_bNoseDiving ) { if ( VPhysicsGetObject() ) VPhysicsGetObject()->ApplyForceCenter( Vector( 0, 0, striderbuster_dive_force.GetFloat() ) ); SetNextThink(gpGlobals->curtime + 0.01f); return; } // seek? const float magradius = 38.0 * sk_striderbuster_magnet_multiplier.GetFloat(); // radius of strider hull times multiplier if (magradius > 0 && GetMoveType() == MOVETYPE_VPHYSICS && VPhysicsGetObject() ) { // find the nearest enemy. CBaseEntity *pList[16]; Vector origin = GetAbsOrigin(); // do a find in box ( a little faster than sphere ) int count; { Vector mins,maxs; mins = origin; mins -= magradius; maxs = origin; maxs += magradius; count = UTIL_EntitiesInBox(pList, 16, mins, maxs, FL_NPC); } float magradiusSq = Square( magradius ); float nearestDistSq = magradiusSq + 1; int bestFit = -1; Vector toTarget; // will be garbage unless something good is found CNPC_Strider *pBestStrider = NULL; for ( int ii = 0 ; ii < count ; ++ii ) { CNPC_Strider *pStrider = dynamic_cast<CNPC_Strider *>(pList[ii]); if ( pStrider && !pStrider->CarriedByDropship() ) // ShouldStickToEntity() doesn't work because the strider NPC isn't what we glue to { // get distance squared VectorSubtract( pStrider->GetAdjustedOrigin(), GetAbsOrigin(), toTarget ); //NDebugOverlay::Line( GetAbsOrigin(), GetAbsOrigin() + toTarget, 128, 0, 128, false, 0.1 ); float dSq = toTarget.LengthSqr(); if (dSq < nearestDistSq) { bestFit = ii; nearestDistSq = dSq; pBestStrider = pStrider; } } } if (bestFit >= 0) // we found something and should attract towards it. (hysterisis later?) { if ( striderbuster_debugseek.GetBool() ) { NDebugOverlay::Circle( GetAbsOrigin() + toTarget, magradius, 255, 255, 255, 255, true, .1 ); NDebugOverlay::Cross3D( GetAbsOrigin() + toTarget, magradius, 255, 255, 255, true, .1 ); } // force magnitude. float magnitude = GetMass() * striderbuster_magnetic_force_strider.GetFloat(); int falloff = striderbuster_falloff_power.GetInt(); switch (falloff) { case 1: VPhysicsGetObject()->ApplyForceCenter( toTarget * (magnitude / nearestDistSq) ); // dividing through by distance squared normalizes toTarget and gives a linear falloff break; case 2: VPhysicsGetObject()->ApplyForceCenter( toTarget * (magnitude / (nearestDistSq * sqrtf(nearestDistSq))) ); // dividing through by distance cubed normalizes toTarget and gives a quadratic falloff break; case 3: VPhysicsGetObject()->ApplyForceCenter( toTarget * (magnitude / (nearestDistSq * nearestDistSq)) ); // dividing through by distance fourth normalizes toTarget and gives a cubic falloff break; case 4: { Vector toTarget; pBestStrider->GetAttachment( "buster_target", toTarget ); if ( striderbuster_debugseek.GetBool() ) { NDebugOverlay::Cross3D( toTarget, magradius, 255, 0, 255, true, .1 ); NDebugOverlay::Cross3D( toTarget, magradius, 255, 0, 255, true, .1 ); } toTarget -= GetAbsOrigin(); toTarget.NormalizeInPlace(); VPhysicsGetObject()->ApplyForceCenter( toTarget * magnitude ); } break; default: // arbitrary powers VPhysicsGetObject()->ApplyForceCenter( toTarget * (magnitude * powf(nearestDistSq,(falloff+1.0f)/2)) ); // square root for distance instead of squared, add one to normalize toTarget break; } } SetNextThink(gpGlobals->curtime + 0.01f); } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- C_ASW_Prop_Physics::C_ASW_Prop_Physics( void ) : m_MotionBlurObject( this, asw_phys_prop_motion_blur_scale.GetFloat() ) { m_bClientOnFire = false; }
// ----------------------------------------------------------------------------- // Purpose: // Note: Think function to delay the impact decal until the animation is finished // playing. // ----------------------------------------------------------------------------- void CTFWeaponBaseMelee::Smack( void ) { trace_t trace; CBasePlayer *pPlayer = GetPlayerOwner(); if ( !pPlayer ) return; #if !defined (CLIENT_DLL) // Move other players back to history positions based on local player's lag lagcompensation->StartLagCompensation( pPlayer, pPlayer->GetCurrentCommand() ); #endif // We hit, setup the smack. if ( DoSwingTrace( trace ) ) { // Hit sound - immediate. if( trace.m_pEnt->IsPlayer() ) { WeaponSound( MELEE_HIT ); } else { WeaponSound( MELEE_HIT_WORLD ); } // Get the current player. CTFPlayer *pPlayer = GetTFPlayerOwner(); if ( !pPlayer ) return; Vector vecForward; AngleVectors( pPlayer->EyeAngles(), &vecForward ); Vector vecSwingStart = pPlayer->Weapon_ShootPosition(); Vector vecSwingEnd = vecSwingStart + vecForward * 48; #ifndef CLIENT_DLL // Do Damage. int iCustomDamage = TF_DMG_CUSTOM_NONE; float flDamage = GetMeleeDamage( trace.m_pEnt, iCustomDamage ); int iDmgType = DMG_BULLET | DMG_NEVERGIB | DMG_CLUB; if ( IsCurrentAttackACrit() ) { // TODO: Not removing the old critical path yet, but the new custom damage is marking criticals as well for melee now. iDmgType |= DMG_CRITICAL; } CTakeDamageInfo info( pPlayer, pPlayer, flDamage, iDmgType, iCustomDamage ); CalculateMeleeDamageForce( &info, vecForward, vecSwingEnd, 1.0f / flDamage * tf_meleeattackforcescale.GetFloat() ); trace.m_pEnt->DispatchTraceAttack( info, vecForward, &trace ); ApplyMultiDamage(); OnEntityHit( trace.m_pEnt ); #endif // Don't impact trace friendly players or objects if ( trace.m_pEnt && trace.m_pEnt->GetTeamNumber() != pPlayer->GetTeamNumber() ) { #ifdef CLIENT_DLL UTIL_ImpactTrace( &trace, DMG_CLUB ); #endif m_bConnected = true; } } #if !defined (CLIENT_DLL) lagcompensation->FinishLagCompensation( pPlayer ); #endif }
//----------------------------------------------------------------------------- // Purpose: // Input : &forward - // flMass - // Output : Vector //----------------------------------------------------------------------------- Vector CWeaponStriderBuster::PhysGunLaunchVelocity( const Vector &forward, float flMass ) { return ( striderbuster_shot_velocity.GetFloat() * forward ); }
void CWeaponIFMSteadyCam::ItemPostFrame() { CBasePlayer *pPlayer = GetPlayerOwner(); if ( !pPlayer ) return; float flSensitivity = ifm_steadycam_sensitivity.GetFloat(); Vector2D vecOldActualViewOffset = m_vecActualViewOffset.AsVector2D(); if ( pPlayer->m_nButtons & IN_ATTACK ) { const CUserCmd *pUserCmd = pPlayer->GetCurrentUserCommand(); m_vecActualViewOffset.x += pUserCmd->mousedx * flSensitivity; m_vecActualViewOffset.y += pUserCmd->mousedy * flSensitivity; } else { if ( !m_bIsLocked && !m_bInDirectMode ) { float flDamp = ifm_steadycam_rotatedamp.GetFloat(); m_vecActualViewOffset.x *= flDamp; m_vecActualViewOffset.y *= flDamp; } } // Add noise if ( !m_bIsLocked ) { float flNoise = ifm_steadycam_noise.GetFloat(); if ( flNoise > 0.0f ) { CUniformRandomStream stream; stream.SetSeed( (int)(gpGlobals->curtime * 100) ); CGaussianRandomStream gauss( &stream ); float dx = gauss.RandomFloat( 0.0f, flNoise ); float dy = gauss.RandomFloat( 0.0f, flNoise ); m_vecActualViewOffset.x += dx; m_vecActualViewOffset.y += dy; } } ComputeViewOffset(); if ( pPlayer->m_nButtons & IN_ZOOM ) { const CUserCmd *pUserCmd = pPlayer->GetCurrentUserCommand(); m_flFOVOffsetY += pUserCmd->mousedy * flSensitivity; } else { float flDamp = ifm_steadycam_zoomdamp.GetFloat(); m_flFOVOffsetY *= flDamp; } m_flFOV += m_flFOVOffsetY * ifm_steadycam_zoomspeed.GetFloat() / 1000.0f; m_flFOV = clamp( m_flFOV, 0.5f, 160.0f ); if ( pPlayer->m_nButtons & IN_WALK ) { const CUserCmd *pUserCmd = pPlayer->GetCurrentUserCommand(); m_flArmLength -= ifm_steadycam_armspeed.GetFloat() * pUserCmd->mousedy; } if ( pPlayer->GetImpulse() == 87 ) { ToggleDirectMode(); } if ( pPlayer->GetImpulse() == 89 ) { m_bInSpringMode = !m_bInSpringMode; } if ( pPlayer->m_afButtonPressed & IN_USE ) { LockCamera(); } if ( pPlayer->m_afButtonPressed & IN_ATTACK2 ) { m_bFullScreen = !m_bFullScreen; } if ( pPlayer->GetImpulse() == 88 ) { // Make the view angles exactly match the player m_vecViewOffset.Init(); m_vecActualViewOffset.Init(); m_vecOffset.Init(); m_vec2DVelocity.Init(); m_hLockTarget.Set( NULL ); m_flArmLength = 0.0f; if ( m_bIsLocked ) { LockCamera(); } m_angRelativeAngles = pPlayer->EyeAngles(); m_flFOV = pPlayer->GetFOV(); } UpdateRelativeOrientation(); TransmitRenderInfo(); }
void CRecharge::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { // if it's not a player, ignore if ( !pActivator->IsPlayer() ) return; // if there is no juice left, turn it off if (m_iJuice <= 0) { SetTextureFrameIndex( 1 ); Off(); } // if the player doesn't have the suit, or there is no juice left, make the deny noise if ( m_iJuice <= 0 ) { if (m_flSoundTime <= gpGlobals->curtime) { m_flSoundTime = gpGlobals->curtime + 0.62; EmitSound( "SuitRecharge.Deny" ); } return; } SetNextThink( gpGlobals->curtime + 0.25 ); SetThink(Off); // Time to recharge yet? if (m_flNextCharge >= gpGlobals->curtime) return; // Make sure that we have a caller if (!pActivator) return; m_hActivator = pActivator; //only recharge the player if (!m_hActivator->IsPlayer() ) return; // Play the on sound or the looping charging sound if (!m_iOn) { m_iOn++; EmitSound( "SuitRecharge.Start" ); m_flSoundTime = 0.56 + gpGlobals->curtime; } if ((m_iOn == 1) && (m_flSoundTime <= gpGlobals->curtime)) { m_iOn++; CPASAttenuationFilter filter( this, "SuitRecharge.ChargingLoop" ); filter.MakeReliable(); EmitSound( filter, entindex(), "SuitRecharge.ChargingLoop" ); } CBasePlayer *pl = (CBasePlayer *) m_hActivator.Get(); // charge the player if (pl->ArmorValue() < 100) { m_iJuice--; pl->IncrementArmorValue( 1, 100 ); } // Send the output. float flRemaining = m_iJuice / sk_suitcharger.GetFloat(); m_OutRemainingCharge.Set(flRemaining, pActivator, this); // govern the rate of charge m_flNextCharge = gpGlobals->curtime + 0.1; }
bool C_PhysPropClientside::Initialize() { if ( InitializeAsClientEntity( STRING(GetModelName()), RENDER_GROUP_OPAQUE_ENTITY ) == false ) { return false; } const model_t *mod = GetModel(); if ( mod ) { Vector mins, maxs; modelinfo->GetModelBounds( mod, mins, maxs ); SetCollisionBounds( mins, maxs ); } solid_t tmpSolid; // Create the object in the physics system if ( !PhysModelParseSolid( tmpSolid, this, GetModelIndex() ) ) { DevMsg("C_PhysPropClientside::Initialize: PhysModelParseSolid failed for entity %i.\n", GetModelIndex() ); return false; } else { m_pPhysicsObject = VPhysicsInitNormal( SOLID_VPHYSICS, 0, m_spawnflags & SF_PHYSPROP_START_ASLEEP, &tmpSolid ); if ( !m_pPhysicsObject ) { // failed to create a physics object DevMsg(" C_PhysPropClientside::Initialize: VPhysicsInitNormal() failed for %s.\n", STRING(GetModelName()) ); return false; } } // We want touch calls when we hit the world unsigned int flags = VPhysicsGetObject()->GetCallbackFlags(); VPhysicsGetObject()->SetCallbackFlags( flags | CALLBACK_GLOBAL_TOUCH_STATIC ); if ( m_spawnflags & SF_PHYSPROP_MOTIONDISABLED ) { m_pPhysicsObject->EnableMotion( false ); } Spawn(); // loads breakable & prop data if ( m_iPhysicsMode == PHYSICS_MULTIPLAYER_AUTODETECT ) { m_iPhysicsMode = GetAutoMultiplayerPhysicsMode( CollisionProp()->OBBSize(), m_pPhysicsObject->GetMass() ); } if ( m_spawnflags & SF_PHYSPROP_FORCE_SERVER_SIDE ) { // forced to be server-side by map maker return false; } if ( m_iPhysicsMode != PHYSICS_MULTIPLAYER_CLIENTSIDE ) { // spawn only clientside entities return false; } else { if ( engine->IsInEditMode() ) { // don't spawn in map edit mode return false; } } if ( m_fadeMinDist < 0 ) { // start fading out at 75% of r_propsmaxdist m_fadeMaxDist = r_propsmaxdist.GetFloat(); m_fadeMinDist = r_propsmaxdist.GetFloat() * 0.75f; } // player can push it away SetCollisionGroup( COLLISION_GROUP_PUSHAWAY ); UpdatePartitionListEntry(); CollisionProp()->UpdatePartition(); SetBlocksLOS( false ); // this should be a small object // Set up shadows; do it here so that objects can change shadowcasting state CreateShadow(); UpdateVisibility(); SetNextClientThink( CLIENT_THINK_NEVER ); return true; }
void C_SDKRagdoll::CreateRagdoll() { // First, initialize all our data. If we have the player's entity on our client, // then we can make ourselves start out exactly where the player is. C_SDKPlayer *pPlayer = dynamic_cast< C_SDKPlayer* >( m_hPlayer.Get() ); if ( pPlayer && !pPlayer->IsDormant() ) { // move my current model instance to the ragdoll's so decals are preserved. pPlayer->SnatchModelInstance( this ); VarMapping_t *varMap = GetVarMapping(); // Copy all the interpolated vars from the player entity. // The entity uses the interpolated history to get bone velocity. if ( !pPlayer->IsLocalPlayer() && pPlayer->IsInterpolationEnabled() ) { Interp_Copy( pPlayer ); SetAbsAngles( pPlayer->GetRenderAngles() ); GetRotationInterpolator().Reset(0.0f); m_flAnimTime = pPlayer->m_flAnimTime; SetSequence( pPlayer->GetSequence() ); m_flPlaybackRate = pPlayer->GetPlaybackRate(); } else { // This is the local player, so set them in a default // pose and slam their velocity, angles and origin SetAbsOrigin( m_vecRagdollOrigin ); SetAbsAngles( pPlayer->GetRenderAngles() ); SetAbsVelocity( m_vecRagdollVelocity ); int iSeq = LookupSequence( "RagdollSpawn" ); // hax, find a neutral standing pose if ( iSeq == -1 ) { Assert( false ); // missing look_idle? iSeq = 0; } SetSequence( iSeq ); // look_idle, basic pose SetCycle( 0.0 ); Interp_Reset( varMap ); } m_nBody = pPlayer->GetBody(); } else { // overwrite network origin so later interpolation will // use this position SetNetworkOrigin( m_vecRagdollOrigin ); SetAbsOrigin( m_vecRagdollOrigin ); SetAbsVelocity( m_vecRagdollVelocity ); Interp_Reset( GetVarMapping() ); } SetModelIndex( m_nModelIndex ); // Turn it into a ragdoll. if ( cl_ragdoll_physics_enable.GetInt() ) { // Make us a ragdoll.. //m_nRenderFX = kRenderFxRagdoll; //SetRenderMode(kRenderFxRagdoll); matrix3x4a_t boneDelta0[MAXSTUDIOBONES]; matrix3x4a_t boneDelta1[MAXSTUDIOBONES]; matrix3x4a_t currentBones[MAXSTUDIOBONES]; const float boneDt = 0.05f; if ( pPlayer && pPlayer == C_BasePlayer::GetLocalPlayer() ) { pPlayer->GetRagdollInitBoneArrays( boneDelta0, boneDelta1, currentBones, boneDt ); } else { GetRagdollInitBoneArrays( boneDelta0, boneDelta1, currentBones, boneDt ); } InitAsClientRagdoll( boneDelta0, boneDelta1, currentBones, boneDt ); } else { //ClientLeafSystem()->SetRenderGroup( GetRenderHandle(), RENDER_GROUP_TRANSLUCENT_ENTITY ); } // Fade out the ragdoll in a while StartFadeOut( cl_ragdoll_fade_time.GetFloat() ); SetNextClientThink( gpGlobals->curtime + 5.0f ); }
void C_SDKRootPanel::RenderDeathFrame( void ) { int iWidth = ScreenWidth(); int iHeight = ScreenHeight(); int iTopBarHeight = 150; int iBottomBarHeight = 75; surface()->DrawSetColor(Color(0, 0, 0, 255)); surface()->DrawFilledRect( 0, 0, iWidth, iTopBarHeight ); surface()->DrawFilledRect( 0, iHeight-iBottomBarHeight, iWidth, iHeight ); if (m_hDeathFrameLarge == vgui::INVALID_FONT) { vgui::HScheme scheme = vgui::scheme()->GetScheme( "ClientScheme" ); vgui::IScheme *pScheme = vgui::scheme()->GetIScheme( scheme ); m_hDeathFrameLarge = pScheme->GetFont("DeathFrameLarge", false); m_hDeathFrameMedium = pScheme->GetFont("DeathFrameMedium", false); m_hDeathFrameSmall = pScheme->GetFont("DeathFrameSmall", false); } std::wstring sKilledBy; C_SDKPlayer* pPlayer = C_SDKPlayer::GetLocalOrSpectatedPlayer(); C_SDKPlayer* pKiller = pPlayer->GetKiller(); if (!m_flKilledByStartTime) m_flKilledByStartTime = gpGlobals->curtime; float flLerpTime = da_deathframe_lerp_time.GetFloat(); wchar_t* pszScreenshot = g_pVGuiLocalize->Find("#DA_DeathFrame_Screenshot"); if (pszScreenshot) { wchar_t szScreenshot[512]; UTIL_ReplaceKeyBindings( pszScreenshot, wcslen(pszScreenshot)*sizeof(wchar_t), szScreenshot, sizeof( szScreenshot ) ); float flXOffset = RemapValClamped(Bias(RemapValClamped(gpGlobals->curtime, m_flKilledByStartTime + 0.5f, m_flKilledByStartTime + 0.5f + flLerpTime, 0, 1), 0.8f), 0, 1, -iWidth*2/3, 0); int iWide, iTall; surface()->GetTextSize(m_hDeathFrameSmall, pszScreenshot, iWide, iTall); surface()->DrawSetTextFont(m_hDeathFrameSmall); surface()->DrawSetTextPos(10 + flXOffset, 10); surface()->DrawSetTextColor(Color(255, 255, 255, 255)); surface()->DrawPrintText(szScreenshot, wcslen(szScreenshot)); } if (pKiller != pPlayer) { wchar_t* pszKilledBy = g_pVGuiLocalize->Find("#DA_DeathFrame_KilledBy"); float flKilledByXOffset = RemapValClamped(Bias(RemapValClamped(gpGlobals->curtime, m_flKilledByStartTime, m_flKilledByStartTime + flLerpTime, 0, 1), 0.8f), 0, 1, -iWidth*2/3, 0); if (pszKilledBy) { int iWide, iTall; surface()->GetTextSize(m_hDeathFrameLarge, pszKilledBy, iWide, iTall); surface()->DrawSetTextFont(m_hDeathFrameLarge); surface()->DrawSetTextPos(flKilledByXOffset + iWidth/2 - iWide/2, 10); surface()->DrawSetTextColor(Color(255, 255, 255, 255)); surface()->DrawPrintText(pszKilledBy, wcslen(pszKilledBy)); } wchar_t wszPlayerName[MAX_PLAYER_NAME_LENGTH]; if (pKiller) g_pVGuiLocalize->ConvertANSIToUnicode( pKiller->GetPlayerName(), wszPlayerName, sizeof(wszPlayerName) ); else { wchar_t* pszTheGround; switch (((int)m_flKilledByStartTime)%3) // Effectively a random number. { case 0: default: pszTheGround = g_pVGuiLocalize->Find("#DA_DeathFrame_TheGround"); break; case 1: pszTheGround = g_pVGuiLocalize->Find("#DA_DeathFrame_SuddenStop"); break; case 2: pszTheGround = g_pVGuiLocalize->Find("#DA_DeathFrame_Gravity"); break; } if (pszTheGround) wcscpy(wszPlayerName, pszTheGround); else wcscpy(wszPlayerName, L"The Ground"); } int iWide, iTall; surface()->GetTextSize(m_hDeathFrameLarge, wszPlayerName, iWide, iTall); surface()->DrawSetTextFont(m_hDeathFrameLarge); surface()->DrawSetTextPos(flKilledByXOffset + iWidth/2 - iWide/2, 20 + surface()->GetFontTall(m_hDeathFrameLarge)); surface()->DrawSetTextColor(Color(255, 255, 255, 255)); surface()->DrawPrintText(wszPlayerName, wcslen(wszPlayerName)); } float flWeaponXOffset = RemapValClamped(Bias(RemapValClamped(gpGlobals->curtime, m_flKilledByStartTime + 0.2f, m_flKilledByStartTime + 0.2f + flLerpTime, 0, 1), 0.8f), 0, 1, iWidth*2/3, 0); wchar_t* pszWeaponOfChoice = g_pVGuiLocalize->Find("#DA_DeathFrame_WeaponOfChoice"); if (pKiller && pszWeaponOfChoice && pKiller->GetActiveSDKWeapon()) { wchar_t* pszWeaponName = g_pVGuiLocalize->Find(pKiller->GetActiveSDKWeapon()->GetPrintName()); if (pszWeaponName) { std::wstring sMessage = std::wstring(pszWeaponOfChoice) + pszWeaponName; int iWide, iTall; surface()->GetTextSize(m_hDeathFrameMedium, sMessage.c_str(), iWide, iTall); surface()->DrawSetTextFont(m_hDeathFrameMedium); surface()->DrawSetTextPos(flWeaponXOffset + iWidth/2 - iWide/2, iHeight - iTall - 20); surface()->DrawSetTextColor(Color(255, 255, 255, 255)); surface()->DrawPrintText(sMessage.c_str(), sMessage.length()); } } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void C_FuncPhysicsRespawnZone::ClientThink( void ) { RespawnProps(); SetNextClientThink( gpGlobals->curtime + (cl_phys_props_respawnrate.GetFloat() * RandomFloat(1.0,1.1)) ); }
//----------------------------------------------------------------------------- // Purpose: Breaks the breakable. m_hBreaker is the entity that caused us to break. //----------------------------------------------------------------------------- void CBreakable::Die( void ) { Vector vecVelocity;// shard velocity char cFlag = 0; int pitch; float fvol; pitch = 95 + random->RandomInt(0,29); if (pitch > 97 && pitch < 103) { pitch = 100; } // The more negative m_iHealth, the louder // the sound should be. fvol = random->RandomFloat(0.85, 1.0) + (abs(m_iHealth.Get()) / 100.0); if (fvol > 1.0) { fvol = 1.0; } const char *soundname = NULL; switch (m_Material) { default: break; case matGlass: soundname = "Breakable.Glass"; cFlag = BREAK_GLASS; break; case matWood: soundname = "Breakable.Crate"; cFlag = BREAK_WOOD; break; case matComputer: soundname = "Breakable.Computer"; cFlag = BREAK_METAL; break; case matMetal: soundname = "Breakable.Metal"; cFlag = BREAK_METAL; break; case matFlesh: case matWeb: soundname = "Breakable.Flesh"; cFlag = BREAK_FLESH; break; case matRocks: case matCinderBlock: soundname = "Breakable.Concrete"; cFlag = BREAK_CONCRETE; break; case matCeilingTile: soundname = "Breakable.Ceiling"; break; } if ( soundname ) { if ( m_hBreaker && m_hBreaker->IsPlayer() ) { IGameEvent * event = gameeventmanager->CreateEvent( "break_breakable" ); if ( event ) { event->SetInt( "userid", ToBasePlayer( m_hBreaker )->GetUserID() ); event->SetInt( "entindex", entindex() ); event->SetInt( "material", cFlag ); gameeventmanager->FireEvent( event ); } } CSoundParameters params; if ( GetParametersForSound( soundname, params, NULL ) ) { CPASAttenuationFilter filter( this ); EmitSound_t ep; ep.m_nChannel = params.channel; ep.m_pSoundName = params.soundname; ep.m_flVolume = fvol; ep.m_SoundLevel = params.soundlevel; ep.m_nPitch = pitch; EmitSound( filter, entindex(), ep ); } } switch( m_Explosion ) { case expDirected: vecVelocity = g_vecAttackDir * -200; break; case expUsePrecise: { AngleVectors( m_GibDir, &vecVelocity, NULL, NULL ); vecVelocity *= 200; } break; case expRandom: vecVelocity.x = 0; vecVelocity.y = 0; vecVelocity.z = 0; break; default: DevMsg("**ERROR - Unspecified gib dir method in func_breakable!\n"); break; } Vector vecSpot = WorldSpaceCenter(); CPVSFilter filter2( vecSpot ); int iModelIndex = 0; CCollisionProperty *pCollisionProp = CollisionProp(); Vector vSize = pCollisionProp->OBBSize(); int iCount = ( vSize[0] * vSize[1] + vSize[1] * vSize[2] + vSize[2] * vSize[0] ) / ( 3 * 12 * 12 ); if ( iCount > func_break_max_pieces.GetInt() ) { iCount = func_break_max_pieces.GetInt(); } if ( !breakable_disable_gib_limit.GetBool() && iCount ) { if ( m_PerformanceMode == PM_NO_GIBS ) { iCount = 0; } else if ( m_PerformanceMode == PM_REDUCED_GIBS ) { int iNewCount = iCount * func_break_reduction_factor.GetFloat(); iCount = MAX( iNewCount, 1 ); } } if ( m_iszModelName != NULL_STRING ) { for ( int i = 0; i < iCount; i++ ) { iModelIndex = modelinfo->GetModelIndex( g_PropDataSystem.GetRandomChunkModel( STRING( m_iszModelName ) ) ); // All objects except the first one in this run are marked as slaves... int slaveFlag = 0; if ( i != 0 ) { slaveFlag = BREAK_SLAVE; } te->BreakModel( filter2, 0.0, vecSpot, pCollisionProp->GetCollisionAngles(), vSize, vecVelocity, iModelIndex, 100, 1, 2.5, cFlag | slaveFlag ); } } ResetOnGroundFlags(); // Don't fire something that could fire myself SetName( NULL_STRING ); AddSolidFlags( FSOLID_NOT_SOLID ); // Fire targets on break m_OnBreak.FireOutput( m_hBreaker, this ); VPhysicsDestroyObject(); SetThink( &CBreakable::SUB_Remove ); SetNextThink( gpGlobals->curtime + 0.1f ); if ( m_iszSpawnObject != NULL_STRING ) { CBaseEntity::Create( STRING(m_iszSpawnObject), vecSpot, pCollisionProp->GetCollisionAngles(), this ); } if ( Explodable() ) { ExplosionCreate( vecSpot, pCollisionProp->GetCollisionAngles(), this, GetExplosiveDamage(), GetExplosiveRadius(), true ); } }
void CASW_Health_Regen::Think() { BaseClass::Think(); CBaseEntity* pEntity = NULL; while ((pEntity = gEntList.FindEntityByClassname( pEntity, "asw_marine" )) != NULL) { CASW_Marine *pMarine = dynamic_cast<CASW_Marine*>(pEntity); if (pMarine) { int cur_health = pMarine->GetHealth(); int max_health = pMarine->GetMaxHealth(); int regen_ammount = rm_health_regen_amount.GetInt(); if (cur_health < max_health) { //Check if this marine is dead. if (cur_health < 1) continue; int result_health = cur_health + regen_ammount; if (result_health > max_health) result_health = max_health; // if (pMarine->m_bKnockedOut) // { // result_health = cur_health - 3; // if (result_health <= 0) // { // CTakeDamageInfo info( // pMarine, // pMarine, // Vector(0,0,0), // GetAbsOrigin(), // 100, // DMG_NEVERGIB); // pMarine->TakeDamage(info); // } // else // { // pMarine->SetHealth(result_health); // } // } // else // { if (!pMarine->m_bKnockedOut && ASWGameRules()->m_iHpRegen) pMarine->SetHealth(result_health); // riflemod: incapacitated marines have decreasing hp if (pMarine->m_bKnockedOut) { int decreased_hp = pMarine->GetHealth() - rm_health_decrease_amount.GetInt(); if (decreased_hp <= 0) { pMarine->SetKnockedOut(false); pMarine->SetHealth(1); // HACK int allow_revive = ASWGameRules()->m_iAllowRevive; ASWGameRules()->m_iAllowRevive = 0; CTakeDamageInfo info(this, this, Vector(0, 0, 0), GetAbsOrigin(), 100, DMG_NEVERGIB); pMarine->TakeDamage(info); ASWGameRules()->m_iAllowRevive = allow_revive; } else pMarine->SetHealth(decreased_hp); } // } } } } SetNextThink( gpGlobals->curtime + rm_health_regen_interval.GetFloat()); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWeaponLaserRifle::PrimaryAttack( void ) { CBaseTFPlayer *pPlayer = ToBaseTFPlayer( m_hOwner ); if ( !pPlayer ) return; if ( !ComputeEMPFireState() ) return; WeaponSound(SINGLE); PlayAttackAnimation( GetPrimaryAttackActivity() ); pPlayer->m_fEffects |= EF_MUZZLEFLASH; // Fire the beam: BLOW OFF AUTOAIM Vector vecSrc = pPlayer->Weapon_ShootPosition( pPlayer->GetOrigin() ); Vector vecAiming, right, up; pPlayer->EyeVectors( &vecAiming, &right, &up); Vector vecSpread = VECTOR_CONE_4DEGREES; // Get endpoint float x, y, z; do { x = random->RandomFloat(-0.5,0.5) + random->RandomFloat(-0.5,0.5); y = random->RandomFloat(-0.5,0.5) + random->RandomFloat(-0.5,0.5); z = x*x+y*y; } while (z > 1); Vector vecDir = vecAiming + x * vecSpread.x * right + y * vecSpread.y * up; Vector vecEnd = vecSrc + vecDir * weapon_laserrifle_range.GetFloat(); trace_t tr; float damagefactor = TFGameRules()->WeaponTraceLine(vecSrc, vecEnd, MASK_SHOT, pPlayer, DMG_ENERGYBEAM, &tr); // Hit target? if (tr.fraction != 1.0) { CBaseEntity *pEntity = CBaseEntity::Instance(tr.u.ent); if ( pEntity ) { ClearMultiDamage(); float flDamage = GetDamage( (tr.endpos - vecSrc).Length(), tr.hitgroup ); flDamage *= damagefactor; pEntity->TraceAttack( CTakeDamageInfo( pPlayer, pPlayer, flDamage, DMG_ENERGYBEAM ), vecDir, &tr ); ApplyMultiDamage( pPlayer, pPlayer ); } g_pEffects->EnergySplash( tr.endpos, tr.plane.normal ); } // Get hacked gun position AngleVectors( pPlayer->EyeAngles() + pPlayer->m_Local.m_vecPunchAngle, NULL, &right, NULL ); Vector vecTracerSrc = vecSrc + Vector (0,0,-8) + right * 12 + vecDir * 16; // Laser beam CBroadcastRecipientFilter filter; te->BeamPoints( filter, 0.0, &vecTracerSrc, &tr.endpos, m_iSpriteTexture, 0, // Halo index 0, // Start frame 0, // Frame rate 0.2, // Life 15, // Width 15, // EndWidth 0, // FadeLength 0, // Amplitude 200, // r 200, // g 255, // b 255, // a 255 ); // speed pPlayer->m_iAmmo[m_iPrimaryAmmoType]--; m_flNextPrimaryAttack = gpGlobals->curtime + GetFireRate(); CheckRemoveDisguise(); }
void C_BaseHLPlayer::PerformClientSideNPCSpeedModifiers( float flFrameTime, CUserCmd *pCmd ) { if ( m_hClosestNPC == NULL ) { if ( m_flSpeedMod != cl_forwardspeed.GetFloat() ) { float flDeltaTime = (m_flSpeedModTime - gpGlobals->curtime); m_flSpeedMod = RemapValClamped( flDeltaTime, cl_npc_speedmod_outtime.GetFloat(), 0, m_flExitSpeedMod, cl_forwardspeed.GetFloat() ); } } else { C_AI_BaseNPC *pNPC = dynamic_cast< C_AI_BaseNPC *>( m_hClosestNPC.Get() ); if ( pNPC ) { float flDist = (GetAbsOrigin() - pNPC->GetAbsOrigin()).LengthSqr(); bool bShouldModSpeed = false; // Within range? if ( flDist < pNPC->GetSpeedModifyRadius() ) { // Now, only slowdown if we're facing & running parallel to the target's movement // Facing check first (in 2D) Vector vecTargetOrigin = pNPC->GetAbsOrigin(); Vector los = ( vecTargetOrigin - EyePosition() ); los.z = 0; VectorNormalize( los ); Vector facingDir; AngleVectors( GetAbsAngles(), &facingDir ); float flDot = DotProduct( los, facingDir ); if ( flDot > 0.8 ) { /* // Velocity check (abort if the target isn't moving) Vector vecTargetVelocity; pNPC->EstimateAbsVelocity( vecTargetVelocity ); float flSpeed = VectorNormalize(vecTargetVelocity); Vector vecMyVelocity = GetAbsVelocity(); VectorNormalize(vecMyVelocity); if ( flSpeed > 1.0 ) { // Velocity roughly parallel? if ( DotProduct(vecTargetVelocity,vecMyVelocity) > 0.4 ) { bShouldModSpeed = true; } } else { // NPC's not moving, slow down if we're moving at him //Msg("Dot: %.2f\n", DotProduct( los, vecMyVelocity ) ); if ( DotProduct( los, vecMyVelocity ) > 0.8 ) { bShouldModSpeed = true; } } */ bShouldModSpeed = true; } } if ( !bShouldModSpeed ) { m_hClosestNPC = NULL; m_flSpeedModTime = gpGlobals->curtime + cl_npc_speedmod_outtime.GetFloat(); m_flExitSpeedMod = m_flSpeedMod; return; } else { if ( m_flSpeedMod != pNPC->GetSpeedModifySpeed() ) { float flDeltaTime = (m_flSpeedModTime - gpGlobals->curtime); m_flSpeedMod = RemapValClamped( flDeltaTime, cl_npc_speedmod_intime.GetFloat(), 0, cl_forwardspeed.GetFloat(), pNPC->GetSpeedModifySpeed() ); } } } } if ( pCmd->forwardmove > 0.0f ) { pCmd->forwardmove = clamp( pCmd->forwardmove, -m_flSpeedMod, m_flSpeedMod ); } else { pCmd->forwardmove = clamp( pCmd->forwardmove, -m_flSpeedMod, m_flSpeedMod ); } pCmd->sidemove = clamp( pCmd->sidemove, -m_flSpeedMod, m_flSpeedMod ); //Msg( "fwd %f right %f\n", pCmd->forwardmove, pCmd->sidemove ); }
void C_SDKPlayer::AvoidPlayers( CUserCmd *pCmd ) { // Player Avoidance is only active with teams #if defined ( SDK_USE_TEAMS ) // Don't test if the player doesn't exist or is dead. if ( IsAlive() == false ) return; C_SDKTeam *pTeam = ( C_SDKTeam * )GetTeam(); if ( !pTeam ) return; // Up vector. static Vector vecUp( 0.0f, 0.0f, 1.0f ); Vector vecSDKPlayerCenter = GetAbsOrigin(); Vector vecSDKPlayerMin = GetPlayerMins(); Vector vecSDKPlayerMax = GetPlayerMaxs(); float flZHeight = vecSDKPlayerMax.z - vecSDKPlayerMin.z; vecSDKPlayerCenter.z += 0.5f * flZHeight; VectorAdd( vecSDKPlayerMin, vecSDKPlayerCenter, vecSDKPlayerMin ); VectorAdd( vecSDKPlayerMax, vecSDKPlayerCenter, vecSDKPlayerMax ); // Find an intersecting player or object. int nAvoidPlayerCount = 0; C_SDKPlayer *pAvoidPlayerList[MAX_PLAYERS]; C_SDKPlayer *pIntersectPlayer = NULL; float flAvoidRadius = 0.0f; Vector vecAvoidCenter, vecAvoidMin, vecAvoidMax; for ( int i = 0; i < pTeam->GetNumPlayers(); ++i ) { C_SDKPlayer *pAvoidPlayer = static_cast< C_SDKPlayer * >( 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( vecSDKPlayerMin, vecSDKPlayerMax, 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(), vecSDKPlayerCenter, vecDelta ); Vector vRad = pIntersectPlayer->WorldAlignMaxs() - pIntersectPlayer->WorldAlignMins(); vRad.z = 0; flAvoidRadius = vRad.Length(); } float flPushStrength = RemapValClamped( vecDelta.Length(), flAvoidRadius, 0, 0, sdk_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 ); #endif }
void CWeaponIFMSteadyCam::UpdateRelativeOrientation() { if ( m_bIsLocked ) return; if ( m_bInDirectMode ) { UpdateDirectRelativeOrientation(); return; } if ( ( m_vecViewOffset.x == 0.0f ) && ( m_vecViewOffset.y == 0.0f ) ) return; // Compute a player to steadycam matrix VMatrix steadyCamToPlayer; MatrixFromAngles( m_angRelativeAngles, steadyCamToPlayer ); MatrixSetColumn( steadyCamToPlayer, 3, m_vecRelativePosition ); Vector vecCurrentForward; MatrixGetColumn( steadyCamToPlayer, 0, &vecCurrentForward ); // Create a ray in steadycam space float flMaxD = 1.0f / tan( M_PI * m_flFOV / 360.0f ); // Remap offsets into normalized space float flViewX = m_vecViewOffset.x / ( 384 / 2 ); float flViewY = m_vecViewOffset.y / ( 288 / 2 ); flViewX *= flMaxD * ifm_steadycam_mousefactor.GetFloat(); flViewY *= flMaxD * ifm_steadycam_mousefactor.GetFloat(); Vector vecSelectionDir( 1.0f, -flViewX, -flViewY ); VectorNormalize( vecSelectionDir ); // Rotate the ray into player coordinates Vector vecDesiredDirection; Vector3DMultiply( steadyCamToPlayer, vecSelectionDir, vecDesiredDirection ); float flDot = DotProduct( vecDesiredDirection, vecCurrentForward ); flDot = clamp( flDot, -1.0f, 1.0f ); float flAngle = 180.0f * acos( flDot ) / M_PI; if ( flAngle < 1e-3 ) { matrix3x4_t mat; MatrixFromForwardDirection( vecDesiredDirection, mat ); MatrixAngles( mat, m_angRelativeAngles ); return; } Vector vecAxis; CrossProduct( vecCurrentForward, vecDesiredDirection, vecAxis ); VectorNormalize( vecAxis ); float flRotateRate = ifm_steadycam_rotaterate.GetFloat(); if ( flRotateRate < 1.0f ) { flRotateRate = 1.0f; } float flRateFactor = flAngle / flRotateRate; flRateFactor *= flRateFactor * flRateFactor; float flRate = flRateFactor * 30.0f; float flMaxAngle = gpGlobals->frametime * flRate; flAngle = clamp( flAngle, 0.0f, flMaxAngle ); Vector vecNewForard; VMatrix rotation; MatrixBuildRotationAboutAxis( rotation, vecAxis, flAngle ); Vector3DMultiply( rotation, vecCurrentForward, vecNewForard ); matrix3x4_t mat; MatrixFromForwardDirection( vecNewForard, mat ); MatrixAngles( mat, m_angRelativeAngles ); Assert( m_angRelativeAngles.IsValid() ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- bool CASW_PropJeep::CanExitVehicle( CBaseEntity *pEntity ) { return ( !m_bEnterAnimOn && !m_bExitAnimOn && !m_bLocked && (m_nSpeed <= asw_g_jeepexitspeed.GetFloat() ) ); }
ActionResult<CTFBot> CTFBotCapturePoint::Update(CTFBot *actor, float dt) { if (TFGameRules()->InSetup()) { this->m_PathFollower.Invalidate(); this->m_ctRecomputePath.Start(RandomFloat(1.0f, 2.0f)); return ActionResult<CTFBot>::Continue(); } CTeamControlPoint *point = actor->GetMyControlPoint(); if (point == nullptr) { return ActionResult<CTFBot>::SuspendFor(new CTFBotSeekAndDestroy(10.0f), "Seek and destroy until a point becomes available"); } if (point->GetTeamNumber() == actor->GetTeamNumber()) { return ActionResult<CTFBot>::ChangeTo(new CTFBotDefendPoint(), "We need to defend our point(s)"); } const CKnownEntity *threat = actor->GetVisionInterface()->GetPrimaryKnownThreat(false); if (threat != nullptr && threat->IsVisibleRecently()) { actor->EquipBestWeaponForThreat(threat); } if ((!actor->IsPointBeingCaptured(point) || actor->GetTimeSinceWeaponFired() < 2.0f) && !actor->IsCapturingPoint() && !TFGameRules()->InOvertime() && actor->GetTimeLeftToCapture() >= tf_bot_offense_must_push_time.GetFloat() && !TFGameRules()->IsInTraining() && !actor->IsNearPoint(point) && threat != nullptr && threat->IsVisibleRecently()) { float duration = RandomFloat(tf_bot_capture_seek_and_destroy_min_duration.GetFloat(), tf_bot_capture_seek_and_destroy_max_duration.GetFloat()); return ActionResult<CTFBot>::SuspendFor(new CTFBotSeekAndDestroy(duration), "Too early to capture - hunting"); } if (actor->IsCapturingPoint()) { if (point->GetPointIndex() > 7) { return ActionResult<CTFBot>::Continue(); } // TODO // ... // Path::Compute } if (this->m_ctRecomputePath.IsElapsed()) { VPROF_BUDGET("CTFBotCapturePoint::Update( repath )", "NextBot"); CTFBotPathCost cost_func(actor, SAFEST_ROUTE); this->m_PathFollower.Compute(actor, point->GetAbsOrigin(), cost_func, 0.0f, true); this->m_ctRecomputePath.Start(RandomFloat(2.0f, 3.0f)); } if (TFGameRules()->IsInTraining() && !actor->IsAnyPointBeingCaptured() && this->m_PathFollower.GetLength() < 1000.0f) { actor->SpeakConceptIfAllowed(MP_CONCEPT_PLAYER_GO); } else { this->m_PathFollower.Update(actor); } return ActionResult<CTFBot>::Continue(); }
static void ScaleChangeCallback_f( ConVar *var, char const *pOldString ) { g_ViewportScale = mat_viewportscale.GetFloat(); g_ViewportOOScale = 1.0f / g_ViewportScale; g_nFrameBuffersToClear = 3; }
void CRecharge::Recharge(void) { m_iJuice = sk_suitcharger.GetFloat(); SetTextureFrameIndex( 0 ); SetThink( SUB_DoNothing ); }
//----------------------------------------------------------------------------- // Purpose: Returns a pointer to a healable target //----------------------------------------------------------------------------- bool CWeaponMedigun::FindAndHealTargets( void ) { CTFPlayer *pOwner = ToTFPlayer( GetOwnerEntity() ); if ( !pOwner ) return false; bool bFound = false; // Maintaining beam to existing target? CBaseEntity *pTarget = m_hHealingTarget; if ( pTarget && pTarget->IsAlive() ) { MaintainTargetInSlot(); } else { FindNewTargetForSlot(); } CBaseEntity *pNewTarget = m_hHealingTarget; if ( pNewTarget && pNewTarget->IsAlive() ) { CTFPlayer *pTFPlayer = ToTFPlayer( pNewTarget ); #ifdef GAME_DLL // HACK: For now, just deal with players if ( pTFPlayer ) { if ( pTarget != pNewTarget && pNewTarget->IsPlayer() ) { pTFPlayer->m_Shared.Heal( pOwner, GetHealRate() ); } pTFPlayer->m_Shared.RecalculateChargeEffects( false ); } if ( m_flReleaseStartedAt && m_flReleaseStartedAt < (gpGlobals->curtime + 0.2) ) { // When we start the release, everyone we heal rockets to full health pNewTarget->TakeHealth( pNewTarget->GetMaxHealth(), DMG_GENERIC ); } #endif bFound = true; // Charge up our power if we're not releasing it, and our target // isn't receiving any benefit from our healing. if ( !m_bChargeRelease ) { if ( pTFPlayer ) { int iBoostMax = floor( pTFPlayer->m_Shared.GetMaxBuffedHealth() * 0.95); if ( weapon_medigun_charge_rate.GetFloat() ) { float flChargeAmount = gpGlobals->frametime / weapon_medigun_charge_rate.GetFloat(); // Reduced charge for healing fully healed guys if ( pNewTarget->GetHealth() >= iBoostMax && ( TFGameRules() && !TFGameRules()->InSetup() ) ) { flChargeAmount *= 0.5; } int iTotalHealers = pTFPlayer->m_Shared.GetNumHealers(); if ( iTotalHealers > 1 ) { flChargeAmount /= (float)iTotalHealers; } float flNewLevel = min( m_flChargeLevel + flChargeAmount, 1.0 ); #ifdef GAME_DLL if ( flNewLevel >= 1.0 && m_flChargeLevel < 1.0 ) { pOwner->SpeakConceptIfAllowed( MP_CONCEPT_MEDIC_CHARGEREADY ); if ( pTFPlayer ) { pTFPlayer->SpeakConceptIfAllowed( MP_CONCEPT_HEALTARGET_CHARGEREADY ); } } #endif m_flChargeLevel = flNewLevel; } } } } return bFound; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CNPC_Crow::Spawn( void ) { BaseClass::Spawn(); #ifdef _XBOX // Always fade the corpse AddSpawnFlags( SF_NPC_FADE_CORPSE ); #endif // _XBOX char *szModel = (char *)STRING( GetModelName() ); if (!szModel || !*szModel) { szModel = "models/crow.mdl"; SetModelName( AllocPooledString(szModel) ); } Precache(); SetModel( szModel ); m_iHealth = sk_crow_health.GetFloat(); SetHullType(HULL_TINY); SetHullSizeNormal(); SetSolid( SOLID_BBOX ); SetMoveType( MOVETYPE_STEP ); m_flFieldOfView = VIEW_FIELD_FULL; SetViewOffset( Vector(6, 0, 11) ); // Position of the eyes relative to NPC's origin. m_flGroundIdleMoveTime = gpGlobals->curtime + random->RandomFloat( 0.0f, 5.0f ); SetBloodColor( BLOOD_COLOR_RED ); m_NPCState = NPC_STATE_NONE; m_nMorale = random->RandomInt( 0, 12 ); SetCollisionGroup( HL2COLLISION_GROUP_CROW ); CapabilitiesClear(); bool bFlying = ( ( m_spawnflags & SF_CROW_FLYING ) != 0 ); SetFlyingState( bFlying ? FlyState_Flying : FlyState_Walking ); // We don't mind zombies so much. They smell good! AddClassRelationship( CLASS_ZOMBIE, D_NU, 0 ); m_bSoar = false; m_bOnJeep = false; m_flSoarTime = gpGlobals->curtime; NPCInit(); m_iBirdType = BIRDTYPE_CROW; m_vLastStoredOrigin = vec3_origin; m_flLastStuckCheck = gpGlobals->curtime; m_flDangerSoundTime = gpGlobals->curtime; SetGoalEnt( NULL ); }
//----------------------------------------------------------------------------- // Purpose: Overloaded to handle the hold-down healing //----------------------------------------------------------------------------- void CWeaponMedigun::ItemPostFrame( void ) { CTFPlayer *pOwner = ToTFPlayer( GetOwnerEntity() ); if ( !pOwner ) return; // If we're lowered, we're not allowed to fire if ( CanAttack() == false ) { RemoveHealingTarget( true ); return; } #if !defined( CLIENT_DLL ) if ( AppliesModifier() ) { m_DamageModifier.SetModifier( weapon_medigun_damage_modifier.GetFloat() ); } #endif // Try to start healing m_bAttacking = false; if ( pOwner->GetMedigunAutoHeal() ) { if ( pOwner->m_nButtons & IN_ATTACK ) { if ( m_bCanChangeTarget ) { RemoveHealingTarget(); #if defined( CLIENT_DLL ) m_bPlayingSound = false; StopHealSound(); #endif // can't change again until we release the attack button m_bCanChangeTarget = false; } } else { m_bCanChangeTarget = true; } if ( m_bHealing || ( pOwner->m_nButtons & IN_ATTACK ) ) { PrimaryAttack(); m_bAttacking = true; } } else { if ( /*m_bChargeRelease || */ pOwner->m_nButtons & IN_ATTACK ) { PrimaryAttack(); m_bAttacking = true; } else if ( m_bHealing ) { // Detach from the player if they release the attack button. RemoveHealingTarget(); } } if ( pOwner->m_nButtons & IN_ATTACK2 ) { SecondaryAttack(); } WeaponIdle(); }
virtual float GetAutoAimRadius( void ) { return striderbuster_autoaim_radius.GetFloat(); }
//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CAI_FearBehavior::GatherConditions() { BaseClass::GatherConditions(); ClearCondition( COND_FEAR_ENEMY_CLOSE ); ClearCondition( COND_FEAR_ENEMY_TOO_CLOSE ); if( GetEnemy() ) { float flEnemyDistSqr = GetAbsOrigin().DistToSqr(GetEnemy()->GetAbsOrigin()); if( flEnemyDistSqr < FEAR_ENEMY_TOLERANCE_TOO_CLOSE_DIST_SQR ) { SetCondition( COND_FEAR_ENEMY_TOO_CLOSE ); if( IsInASafePlace() ) { SpoilSafePlace(); } } else if( flEnemyDistSqr < FEAR_ENEMY_TOLERANCE_CLOSE_DIST_SQR && GetEnemy()->GetEnemy() == GetOuter() ) { // Only become scared of an enemy at this range if they're my enemy, too SetCondition( COND_FEAR_ENEMY_CLOSE ); if( IsInASafePlace() ) { SpoilSafePlace(); } } } ClearCondition(COND_FEAR_SEPARATED_FROM_PLAYER); // Check for separation from the player // -The player is farther away than 60 feet // -I haven't seen the player in 2 seconds // // Here's the distance check: CBasePlayer *pPlayer = AI_GetSinglePlayer(); if( pPlayer != NULL && GetAbsOrigin().DistToSqr(pPlayer->GetAbsOrigin()) >= Square( ai_fear_player_dist.GetFloat() * 1.5f ) ) { SetCondition(COND_FEAR_SEPARATED_FROM_PLAYER); } // Here's the visibility check. We can't skip this because it's time-sensitive if( GetOuter()->FVisible(pPlayer) ) { m_flTimePlayerLastVisible = gpGlobals->curtime; } else { if( gpGlobals->curtime - m_flTimePlayerLastVisible >= 2.0f ) { SetCondition(COND_FEAR_SEPARATED_FROM_PLAYER); } } if( HasCondition(COND_FEAR_SEPARATED_FROM_PLAYER) ) { //Msg("I am separated from player\n"); if( IsInASafePlace() ) { SpoilSafePlace(); } } }
float DM_GetRespawnWait() { return cssdm_respawn_wait.GetFloat(); }
//----------------------------------------------------------------------------- // Client-side obstacle avoidance //----------------------------------------------------------------------------- void C_BaseHLPlayer::PerformClientSideObstacleAvoidance( float flFrameTime, CUserCmd *pCmd ) { // Don't avoid if noclipping or in movetype none switch ( GetMoveType() ) { case MOVETYPE_NOCLIP: case MOVETYPE_NONE: case MOVETYPE_OBSERVER: return; default: break; } // Try to steer away from any objects/players we might interpenetrate Vector size = WorldAlignSize(); float radius = 0.7f * sqrt( size.x * size.x + size.y * size.y ); float curspeed = GetLocalVelocity().Length2D(); //int slot = 1; //engine->Con_NPrintf( slot++, "speed %f\n", curspeed ); //engine->Con_NPrintf( slot++, "radius %f\n", radius ); // If running, use a larger radius float factor = 1.0f; if ( curspeed > 150.0f ) { curspeed = MIN( 2048.0f, curspeed ); factor = ( 1.0f + ( curspeed - 150.0f ) / 150.0f ); //engine->Con_NPrintf( slot++, "scaleup (%f) to radius %f\n", factor, radius * factor ); radius = radius * factor; } Vector currentdir; Vector rightdir; QAngle vAngles = pCmd->viewangles; vAngles.x = 0; AngleVectors( vAngles, ¤tdir, &rightdir, NULL ); bool istryingtomove = false; bool ismovingforward = false; if ( fabs( pCmd->forwardmove ) > 0.0f || fabs( pCmd->sidemove ) > 0.0f ) { istryingtomove = true; if ( pCmd->forwardmove > 1.0f ) { ismovingforward = true; } } if ( istryingtomove == true ) radius *= 1.3f; CPlayerAndObjectEnumerator avoid( radius ); partition->EnumerateElementsInSphere( PARTITION_CLIENT_SOLID_EDICTS, GetAbsOrigin(), radius, false, &avoid ); // Okay, decide how to avoid if there's anything close by int c = avoid.GetObjectCount(); if ( c <= 0 ) return; //engine->Con_NPrintf( slot++, "moving %s forward %s\n", istryingtomove ? "true" : "false", ismovingforward ? "true" : "false" ); float adjustforwardmove = 0.0f; float adjustsidemove = 0.0f; for ( int i = 0; i < c; i++ ) { C_AI_BaseNPC *obj = dynamic_cast< C_AI_BaseNPC *>(avoid.GetObject( i )); if( !obj ) continue; Vector vecToObject = obj->GetAbsOrigin() - GetAbsOrigin(); float flDist = vecToObject.Length2D(); // Figure out a 2D radius for the object Vector vecWorldMins, vecWorldMaxs; obj->CollisionProp()->WorldSpaceAABB( &vecWorldMins, &vecWorldMaxs ); Vector objSize = vecWorldMaxs - vecWorldMins; float objectradius = 0.5f * sqrt( objSize.x * objSize.x + objSize.y * objSize.y ); //Don't run this code if the NPC is not moving UNLESS we are in stuck inside of them. if ( !obj->IsMoving() && flDist > objectradius ) continue; if ( flDist > objectradius && obj->IsEffectActive( EF_NODRAW ) ) { obj->RemoveEffects( EF_NODRAW ); } Vector vecNPCVelocity; obj->EstimateAbsVelocity( vecNPCVelocity ); float flNPCSpeed = VectorNormalize( vecNPCVelocity ); Vector vPlayerVel = GetAbsVelocity(); VectorNormalize( vPlayerVel ); float flHit1, flHit2; Vector vRayDir = vecToObject; VectorNormalize( vRayDir ); float flVelProduct = DotProduct( vecNPCVelocity, vPlayerVel ); float flDirProduct = DotProduct( vRayDir, vPlayerVel ); if ( !IntersectInfiniteRayWithSphere( GetAbsOrigin(), vRayDir, obj->GetAbsOrigin(), radius, &flHit1, &flHit2 ) ) continue; Vector dirToObject = -vecToObject; VectorNormalize( dirToObject ); float fwd = 0; float rt = 0; float sidescale = 2.0f; float forwardscale = 1.0f; bool foundResult = false; Vector vMoveDir = vecNPCVelocity; if ( flNPCSpeed > 0.001f ) { // This NPC is moving. First try deflecting the player left or right relative to the NPC's velocity. // Start with whatever side they're on relative to the NPC's velocity. Vector vecNPCTrajectoryRight = CrossProduct( vecNPCVelocity, Vector( 0, 0, 1) ); int iDirection = ( vecNPCTrajectoryRight.Dot( dirToObject ) > 0 ) ? 1 : -1; for ( int nTries = 0; nTries < 2; nTries++ ) { Vector vecTryMove = vecNPCTrajectoryRight * iDirection; VectorNormalize( vecTryMove ); Vector vTestPosition = GetAbsOrigin() + vecTryMove * radius * 2; if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) ) { fwd = currentdir.Dot( vecTryMove ); rt = rightdir.Dot( vecTryMove ); //Msg( "PUSH DEFLECT fwd=%f, rt=%f\n", fwd, rt ); foundResult = true; break; } else { // Try the other direction. iDirection *= -1; } } } else { // the object isn't moving, so try moving opposite the way it's facing Vector vecNPCForward; obj->GetVectors( &vecNPCForward, NULL, NULL ); Vector vTestPosition = GetAbsOrigin() - vecNPCForward * radius * 2; if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) ) { fwd = currentdir.Dot( -vecNPCForward ); rt = rightdir.Dot( -vecNPCForward ); if ( flDist < objectradius ) { obj->AddEffects( EF_NODRAW ); } //Msg( "PUSH AWAY FACE fwd=%f, rt=%f\n", fwd, rt ); foundResult = true; } } if ( !foundResult ) { // test if we can move in the direction the object is moving Vector vTestPosition = GetAbsOrigin() + vMoveDir * radius * 2; if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) ) { fwd = currentdir.Dot( vMoveDir ); rt = rightdir.Dot( vMoveDir ); if ( flDist < objectradius ) { obj->AddEffects( EF_NODRAW ); } //Msg( "PUSH ALONG fwd=%f, rt=%f\n", fwd, rt ); foundResult = true; } else { // try moving directly away from the object Vector vTestPosition = GetAbsOrigin() - dirToObject * radius * 2; if ( TestMove( vTestPosition, size.z * 2, radius * 2, obj->GetAbsOrigin(), vMoveDir ) ) { fwd = currentdir.Dot( -dirToObject ); rt = rightdir.Dot( -dirToObject ); foundResult = true; //Msg( "PUSH AWAY fwd=%f, rt=%f\n", fwd, rt ); } } } if ( !foundResult ) { // test if we can move through the object Vector vTestPosition = GetAbsOrigin() - vMoveDir * radius * 2; fwd = currentdir.Dot( -vMoveDir ); rt = rightdir.Dot( -vMoveDir ); if ( flDist < objectradius ) { obj->AddEffects( EF_NODRAW ); } //Msg( "PUSH THROUGH fwd=%f, rt=%f\n", fwd, rt ); foundResult = true; } // If running, then do a lot more sideways veer since we're not going to do anything to // forward velocity if ( istryingtomove ) { sidescale = 6.0f; } if ( flVelProduct > 0.0f && flDirProduct > 0.0f ) { sidescale = 0.1f; } float force = 1.0f; float forward = forwardscale * fwd * force * AVOID_SPEED; float side = sidescale * rt * force * AVOID_SPEED; adjustforwardmove += forward; adjustsidemove += side; } pCmd->forwardmove += adjustforwardmove; pCmd->sidemove += adjustsidemove; // 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( "POSTCLAMP: forwardmove=%f, sidemove=%f\n", pCmd->forwardmove, pCmd->sidemove ); }
//----------------------------------------------------------------------------- // Purpose: Render current view into specified rectangle // Input : *rect - is computed by CVideoMode_Common::GetClientViewRect() //----------------------------------------------------------------------------- void CViewRender::Render( vrect_t *rect ) { Assert(s_DbgSetupOrigin == m_View.origin); Assert(s_DbgSetupAngles == m_View.angles); VPROF_BUDGET( "CViewRender::Render", "CViewRender::Render" ); tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ ); vrect_t vr = *rect; // Stub out the material system if necessary. CMatStubHandler matStub; engine->EngineStats_BeginFrame(); // Assume normal vis m_bForceNoVis = false; C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); // Set for console commands, etc. render->SetMainView ( m_View.origin, m_View.angles ); for( StereoEye_t eEye = GetFirstEye(); eEye <= GetLastEye(); eEye = (StereoEye_t)(eEye+1) ) { CViewSetup &view = GetView( eEye ); #if 0 && defined( CSTRIKE_DLL ) const bool bPlayingBackReplay = g_pEngineClientReplay && g_pEngineClientReplay->IsPlayingReplayDemo(); if ( pPlayer && !bPlayingBackReplay ) { C_BasePlayer *pViewTarget = pPlayer; if ( pPlayer->IsObserver() && pPlayer->GetObserverMode() == OBS_MODE_IN_EYE ) { pViewTarget = dynamic_cast<C_BasePlayer*>( pPlayer->GetObserverTarget() ); } if ( pViewTarget ) { float targetFOV = (float)pViewTarget->m_iFOV; if ( targetFOV == 0 ) { // FOV of 0 means use the default FOV targetFOV = g_pGameRules->DefaultFOV(); } float deltaFOV = view.fov - m_flLastFOV; float FOVDirection = targetFOV - pViewTarget->m_iFOVStart; // Clamp FOV changes to stop FOV oscillation if ( ( deltaFOV < 0.0f && FOVDirection > 0.0f ) || ( deltaFOV > 0.0f && FOVDirection < 0.0f ) ) { view.fov = m_flLastFOV; } // Catch case where FOV overshoots its target FOV if ( ( view.fov < targetFOV && FOVDirection <= 0.0f ) || ( view.fov > targetFOV && FOVDirection >= 0.0f ) ) { view.fov = targetFOV; } m_flLastFOV = view.fov; } } #endif static ConVarRef sv_restrict_aspect_ratio_fov( "sv_restrict_aspect_ratio_fov" ); float aspectRatio = engine->GetScreenAspectRatio() * 0.75f; // / (4/3) float limitedAspectRatio = aspectRatio; if ( ( sv_restrict_aspect_ratio_fov.GetInt() > 0 && engine->IsWindowedMode() && gpGlobals->maxClients > 1 ) || sv_restrict_aspect_ratio_fov.GetInt() == 2 ) { limitedAspectRatio = MIN( aspectRatio, 1.85f * 0.75f ); // cap out the FOV advantage at a 1.85:1 ratio (about the widest any legit user should be) } view.fov = ScaleFOVByWidthRatio( view.fov, limitedAspectRatio ); view.fovViewmodel = ScaleFOVByWidthRatio( view.fovViewmodel, aspectRatio ); // Let the client mode hook stuff. g_pClientMode->PreRender(&view); g_pClientMode->AdjustEngineViewport( vr.x, vr.y, vr.width, vr.height ); ToolFramework_AdjustEngineViewport( vr.x, vr.y, vr.width, vr.height ); float flViewportScale = mat_viewportscale.GetFloat(); view.m_nUnscaledX = vr.x; view.m_nUnscaledY = vr.y; view.m_nUnscaledWidth = vr.width; view.m_nUnscaledHeight = vr.height; switch( eEye ) { case STEREO_EYE_MONO: { #if 0 // Good test mode for debugging viewports that are not full-size. view.width = vr.width * flViewportScale * 0.75f; view.height = vr.height * flViewportScale * 0.75f; view.x = vr.x + view.width * 0.10f; view.y = vr.y + view.height * 0.20f; #else view.x = vr.x * flViewportScale; view.y = vr.y * flViewportScale; view.width = vr.width * flViewportScale; view.height = vr.height * flViewportScale; #endif float engineAspectRatio = engine->GetScreenAspectRatio(); view.m_flAspectRatio = ( engineAspectRatio > 0.0f ) ? engineAspectRatio : ( (float)view.width / (float)view.height ); } break; case STEREO_EYE_RIGHT: case STEREO_EYE_LEFT: { g_pSourceVR->GetViewportBounds( (ISourceVirtualReality::VREye)(eEye - 1 ), &view.x, &view.y, &view.width, &view.height ); view.m_nUnscaledWidth = view.width; view.m_nUnscaledHeight = view.height; view.m_nUnscaledX = view.x; view.m_nUnscaledY = view.y; } break; default: Assert ( false ); break; } // if we still don't have an aspect ratio, compute it from the view size if( view.m_flAspectRatio <= 0.f ) view.m_flAspectRatio = (float)view.width / (float)view.height; int nClearFlags = VIEW_CLEAR_DEPTH | VIEW_CLEAR_STENCIL; if( gl_clear_randomcolor.GetBool() ) { CMatRenderContextPtr pRenderContext( materials ); pRenderContext->ClearColor3ub( rand()%256, rand()%256, rand()%256 ); pRenderContext->ClearBuffers( true, false, false ); pRenderContext->Release(); } else if ( gl_clear.GetBool() ) { nClearFlags |= VIEW_CLEAR_COLOR; } else if ( IsPosix() ) { MaterialAdapterInfo_t adapterInfo; materials->GetDisplayAdapterInfo( materials->GetCurrentAdapter(), adapterInfo ); // On Posix, on ATI, we always clear color if we're antialiasing if ( adapterInfo.m_VendorID == 0x1002 ) { if ( g_pMaterialSystem->GetCurrentConfigForVideoCard().m_nAASamples > 0 ) { nClearFlags |= VIEW_CLEAR_COLOR; } } } // Determine if we should draw view model ( client mode override ) bool drawViewModel = g_pClientMode->ShouldDrawViewModel(); if ( cl_leveloverview.GetFloat() > 0 ) { SetUpOverView(); nClearFlags |= VIEW_CLEAR_COLOR; drawViewModel = false; } // Apply any player specific overrides if ( pPlayer ) { // Override view model if necessary if ( !pPlayer->m_Local.m_bDrawViewmodel ) { drawViewModel = false; } } int flags = 0; if( eEye == STEREO_EYE_MONO || eEye == STEREO_EYE_LEFT || ( g_ClientVirtualReality.ShouldRenderHUDInWorld() ) ) { flags = RENDERVIEW_DRAWHUD; } if ( drawViewModel ) { flags |= RENDERVIEW_DRAWVIEWMODEL; } if( eEye == STEREO_EYE_RIGHT ) { // we should use the monitor view from the left eye for both eyes flags |= RENDERVIEW_SUPPRESSMONITORRENDERING; } RenderView( view, nClearFlags, flags ); if ( UseVR() ) { bool bDoUndistort = ! engine->IsTakingScreenshot(); if ( bDoUndistort ) { g_ClientVirtualReality.PostProcessFrame( eEye ); } // logic here all cloned from code in viewrender.cpp around RenderHUDQuad: // figure out if we really want to draw the HUD based on freeze cam bool bInFreezeCam = ( pPlayer && pPlayer->GetObserverMode() == OBS_MODE_FREEZECAM ); // draw the HUD after the view model so its "I'm closer" depth queues work right. if( !bInFreezeCam && g_ClientVirtualReality.ShouldRenderHUDInWorld() ) { // TODO - a bit of a shonky test - basically trying to catch the main menu, the briefing screen, the loadout screen, etc. bool bTranslucent = !g_pMatSystemSurface->IsCursorVisible(); g_ClientVirtualReality.OverlayHUDQuadWithUndistort( view, bDoUndistort, g_pClientMode->ShouldBlackoutAroundHUD(), bTranslucent ); } } } // TODO: should these be inside or outside the stereo eye stuff? g_pClientMode->PostRender(); engine->EngineStats_EndFrame(); #if !defined( _X360 ) // Stop stubbing the material system so we can see the budget panel matStub.End(); #endif // Draw all of the UI stuff "fullscreen" // (this is not health, ammo, etc. Nor is it pre-game briefing interface stuff - this is the stuff that appears when you hit Esc in-game) // In stereo mode this is rendered inside of RenderView so it goes into the render target if( !g_ClientVirtualReality.ShouldRenderHUDInWorld() ) { CViewSetup view2d; view2d.x = rect->x; view2d.y = rect->y; view2d.width = rect->width; view2d.height = rect->height; render->Push2DView( view2d, 0, NULL, GetFrustum() ); render->VGui_Paint( PAINT_UIPANELS | PAINT_CURSOR ); render->PopView( GetFrustum() ); } }
void CFlextalkActor::ProcessSceneEvents( void ) { if ( HasSceneEvents() ) { BaseClass::ProcessSceneEvents( ); return; } // only do this if they have more than eyelid movement if (GetNumFlexControllers() > 2) { const char *pszExpression = flex_expression.GetString(); if (pszExpression && pszExpression[0] == '+' && pszExpression[1] != '\0') { int i; int j = atoi( &pszExpression[1] ); for (i = 0; i < GetNumFlexControllers(); i++) { m_flextarget[m_flexnum] = 0; } for (i = 0; i < 35 && predef_flexcontroller_names[i]; i++) { m_flexnum = LookupFlex( predef_flexcontroller_names[i] ); m_flextarget[m_flexnum] = predef_flexcontroller_values[j][i]; // Msg( "%s %.3f\n", predef_flexcontroller_names[i], predef_flexcontroller_values[j][i] ); } } else if (pszExpression && pszExpression[0] != '\0' && strcmp(pszExpression, "+") != 0) { char szExpression[128]; char szTemp[32]; Q_strncpy( szExpression, pszExpression ,sizeof(szExpression)); char *pszExpression = szExpression; while (*pszExpression != '\0') { if (*pszExpression == '+') *pszExpression = ' '; pszExpression++; } pszExpression = szExpression; while (*pszExpression) { if (*pszExpression != ' ') { if (*pszExpression == '-') { for (LocalFlexController_t i = LocalFlexController_t(0); i < GetNumFlexControllers(); i++) { m_flextarget[i] = 0; } } else if (*pszExpression == '?') { for (LocalFlexController_t i = LocalFlexController_t(0); i < GetNumFlexControllers(); i++) { Msg( "\"%s\" ", GetFlexControllerName( i ) ); } Msg( "\n" ); flex_expression.SetValue( "" ); } else { if (sscanf( pszExpression, "%31s", szTemp ) == 1) { m_flexnum = LookupFlex( szTemp ); if (m_flexnum != LocalFlexController_t(-1) && m_flextarget[m_flexnum] != 1) { m_flextarget[m_flexnum] = 1.0; // SetFlexTarget( m_flexnum ); } pszExpression += strlen( szTemp ) - 1; } } } pszExpression++; } } else if (m_flextime < gpGlobals->curtime) { m_flextime = gpGlobals->curtime + random->RandomFloat( 0.3, 0.5 ) * (30.0 / GetNumFlexControllers()); m_flexnum = (LocalFlexController_t)random->RandomInt( 0, GetNumFlexControllers() - 1 ); if (m_flextarget[m_flexnum] == 1) { m_flextarget[m_flexnum] = 0; } else if (stricmp( GetFlexControllerType( m_flexnum ), "phoneme" ) != 0) { if (strstr( GetFlexControllerName( m_flexnum ), "upper_raiser" ) == NULL) { Msg( "%s:%s\n", GetFlexControllerType( m_flexnum ), GetFlexControllerName( m_flexnum ) ); SetFlexTarget( m_flexnum, random->RandomFloat( 0.5, 1.0 ) ); } } } // slide it up. for (LocalFlexController_t i = LocalFlexController_t(0); i < GetNumFlexControllers(); i++) { float weight = GetFlexWeight( i ); if (weight != m_flextarget[i]) { weight = weight + (m_flextarget[i] - weight) / random->RandomFloat( 2.0, 4.0 ); } weight = clamp( weight, 0.0f, 1.0f ); SetFlexWeight( i, weight ); } if (flex_talk.GetInt() == -1) { m_istalking = 1; char pszSentence[256]; Q_snprintf( pszSentence,sizeof(pszSentence), "%s%d", STRING(m_iszSentence), m_sentence++ ); int sentenceIndex = engine->SentenceIndexFromName( pszSentence ); if (sentenceIndex >= 0) { Msg( "%d : %s\n", sentenceIndex, pszSentence ); CPASAttenuationFilter filter( this ); CBaseEntity::EmitSentenceByIndex( filter, entindex(), CHAN_VOICE, sentenceIndex, 1, SNDLVL_TALKING, 0, PITCH_NORM ); } else { m_sentence = 0; } flex_talk.SetValue( "0" ); } else if (flex_talk.GetInt() == -2) { m_flNextEyeLookTime = gpGlobals->curtime + 1000.0; } else if (flex_talk.GetInt() == -3) { m_flNextEyeLookTime = gpGlobals->curtime; flex_talk.SetValue( "0" ); } else if (flex_talk.GetInt() == -4) { AddLookTarget( UTIL_PlayerByIndex( 1 ), 0.5, flex_looktime.GetFloat() ); flex_talk.SetValue( "0" ); } else if (flex_talk.GetInt() == -5) { PickLookTarget( true ); flex_talk.SetValue( "0" ); } } }