initial
This commit is contained in:
332
game/client/cstrike15/Scaleform/HUD/sfhuddamageindicator.cpp
Normal file
332
game/client/cstrike15/Scaleform/HUD/sfhuddamageindicator.cpp
Normal file
@ -0,0 +1,332 @@
|
||||
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose: Displays HUD elements to indicate damage taken
|
||||
//
|
||||
//=====================================================================================//
|
||||
|
||||
#include "cbase.h"
|
||||
#include "hud.h"
|
||||
#include "hudelement.h"
|
||||
#include "hud_element_helper.h"
|
||||
#include "scaleformui/scaleformui.h"
|
||||
#include "sfhuddamageindicator.h"
|
||||
#include "vgui/ILocalize.h"
|
||||
#include "text_message.h"
|
||||
#include "hud_macros.h"
|
||||
#include "view.h"
|
||||
#include "sfhudfreezepanel.h"
|
||||
#include "sfhudreticle.h"
|
||||
#include "hltvcamera.h"
|
||||
#include "inputsystem/iinputsystem.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
DECLARE_HUDELEMENT( SFHudDamageIndicator );
|
||||
DECLARE_HUD_MESSAGE( SFHudDamageIndicator, Damage );
|
||||
|
||||
SFUI_BEGIN_GAME_API_DEF
|
||||
SFUI_END_GAME_API_DEF( SFHudDamageIndicator, DamageIndicatorModule );
|
||||
|
||||
extern ConVar cl_draw_only_deathnotices;
|
||||
|
||||
// [jason] Globals, extracted from the vgui version of the damage indicators. Comments are my own:
|
||||
|
||||
static float g_FadeScale = 2.f; // scale applied to delta-seconds to control the fade of the direction dmg indicators
|
||||
static float g_StartFadeThreshold = 0.4f; // scale at which the directional dmg indicator begins to auto-fade out (controlled entirely in Flash); used to be the point where it became invisible in VGui
|
||||
static float g_DetectDamageTakenInterval = 1.0f; // (in seconds) - if you haven't received new damage at least this recently, all direction indicators fade out at this point
|
||||
static float g_CloseDamageDistance = 50.f; // (in world units) - if damage received is closer than this to player, all directions light up
|
||||
static float g_DirectionDotTolerance = 0.3f; // incoming dmg direction dot product must be > this value in order for damage to be "from" this direction
|
||||
|
||||
|
||||
SFHudDamageIndicator::SFHudDamageIndicator( const char *value ) : SFHudFlashInterface( value ),
|
||||
m_flAttackFront(0.f),
|
||||
m_flAttackRear(0.f),
|
||||
m_flAttackLeft(0.f),
|
||||
m_flAttackRight(0.f),
|
||||
m_flFadeCompleteTime(0.f),
|
||||
m_lastFrameTime(0.f)
|
||||
{
|
||||
SetHiddenBits( HIDEHUD_HEALTH );
|
||||
HOOK_HUD_MESSAGE( SFHudDamageIndicator, Damage );
|
||||
}
|
||||
|
||||
SFHudDamageIndicator::~SFHudDamageIndicator()
|
||||
{
|
||||
}
|
||||
|
||||
void SFHudDamageIndicator::IndicateDamage( DamageDirection dmgDir, float newPercentage )
|
||||
{
|
||||
if ( m_bActive && m_FlashAPI )
|
||||
{
|
||||
WITH_SFVALUEARRAY_SLOT_LOCKED( data, 2 )
|
||||
{
|
||||
m_pScaleformUI->ValueArray_SetElement( data, 0, dmgDir );
|
||||
m_pScaleformUI->ValueArray_SetElement( data, 1, newPercentage );
|
||||
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "showDamageDirection", data, 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SFHudDamageIndicator::HideAll( void )
|
||||
{
|
||||
if ( m_FlashAPI )
|
||||
{
|
||||
WITH_SLOT_LOCKED
|
||||
{
|
||||
m_pScaleformUI->Value_InvokeWithoutReturn( m_FlashAPI, "hideAll", NULL, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define UPDATE_DIR_DAMAGE( dirValue, dirEnum ) \
|
||||
if ( dirValue > 0.f ) \
|
||||
{ \
|
||||
dirValue = MAX( 0.f, dirValue - flFade ); \
|
||||
if ( dirValue > g_StartFadeThreshold ) \
|
||||
{ \
|
||||
IndicateDamage( dirEnum, dirValue ); \
|
||||
} \
|
||||
else \
|
||||
{ /* start auto-fade at this level */ \
|
||||
dirValue = 0.f; \
|
||||
IndicateDamage( dirEnum, -1.f ); \
|
||||
} \
|
||||
}
|
||||
|
||||
void SFHudDamageIndicator::ProcessInput( void )
|
||||
{
|
||||
if ( m_flFadeCompleteTime > gpGlobals->curtime )
|
||||
{
|
||||
// We have recent damage information, propagate it to all damage directions:
|
||||
float flFade = ( gpGlobals->curtime - m_lastFrameTime ) * g_FadeScale;
|
||||
|
||||
UPDATE_DIR_DAMAGE( m_flAttackFront, SFDD_DamageUp );
|
||||
UPDATE_DIR_DAMAGE( m_flAttackRear, SFDD_DamageDown );
|
||||
UPDATE_DIR_DAMAGE( m_flAttackLeft, SFDD_DamageLeft );
|
||||
UPDATE_DIR_DAMAGE( m_flAttackRight, SFDD_DamageRight );
|
||||
}
|
||||
else
|
||||
{
|
||||
// We haven't received recent damage info, so begin to fade out all dmg directions
|
||||
if ( m_flAttackFront > 0.f ||
|
||||
m_flAttackRear > 0.f ||
|
||||
m_flAttackLeft > 0.f ||
|
||||
m_flAttackRight > 0.f )
|
||||
{
|
||||
m_flAttackFront = 0.0f;
|
||||
m_flAttackRear = 0.0f;
|
||||
m_flAttackRight = 0.0f;
|
||||
m_flAttackLeft = 0.0f;
|
||||
|
||||
// -1 causes all damage directions to fade down to zero from their current levels
|
||||
IndicateDamage( SFDD_DamageTotal, -1.f );
|
||||
}
|
||||
}
|
||||
|
||||
m_lastFrameTime = gpGlobals->curtime;
|
||||
}
|
||||
|
||||
void SFHudDamageIndicator::FlashReady( void )
|
||||
{
|
||||
// hide everything initially
|
||||
HideAll();
|
||||
}
|
||||
|
||||
bool SFHudDamageIndicator::PreUnloadFlash( void )
|
||||
{
|
||||
// $TODO: Anything to release?
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SFHudDamageIndicator::LevelInit( void )
|
||||
{
|
||||
if ( !FlashAPIIsValid() )
|
||||
{
|
||||
SFUI_REQUEST_ELEMENT( SF_SS_SLOT( GET_ACTIVE_SPLITSCREEN_SLOT() ), g_pScaleformUI, SFHudDamageIndicator, this, DamageIndicatorModule );
|
||||
}
|
||||
else
|
||||
{
|
||||
// When initially loaded, hide all indicators
|
||||
HideAll();
|
||||
}
|
||||
}
|
||||
|
||||
void SFHudDamageIndicator::LevelShutdown( void )
|
||||
{
|
||||
if ( FlashAPIIsValid() )
|
||||
{
|
||||
RemoveFlashElement();
|
||||
}
|
||||
}
|
||||
|
||||
void SFHudDamageIndicator::Reset( void )
|
||||
{
|
||||
m_flAttackFront = 0.0f;
|
||||
m_flAttackRear = 0.0f;
|
||||
m_flAttackRight = 0.0f;
|
||||
m_flAttackLeft = 0.0f;
|
||||
m_flFadeCompleteTime = 0.0f;
|
||||
|
||||
HideAll();
|
||||
}
|
||||
|
||||
bool SFHudDamageIndicator::ShouldDraw( void )
|
||||
{
|
||||
if ( IsTakingAFreezecamScreenshot() )
|
||||
return false;
|
||||
|
||||
return cl_drawhud.GetBool() && cl_draw_only_deathnotices.GetBool() == false && CHudElement::ShouldDraw();
|
||||
}
|
||||
|
||||
|
||||
void SFHudDamageIndicator::SetActive( bool bActive )
|
||||
{
|
||||
if ( m_bActive && !bActive )
|
||||
{
|
||||
HideAll();
|
||||
}
|
||||
|
||||
CHudElement::SetActive( bActive );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Message handler for Damage message
|
||||
//-----------------------------------------------------------------------------
|
||||
bool SFHudDamageIndicator::MsgFunc_Damage( const CCSUsrMsg_Damage &msg )
|
||||
{
|
||||
|
||||
C_BasePlayer *pVictimPlayer = NULL;
|
||||
if ( g_bEngineIsHLTV )
|
||||
{
|
||||
// Only show damage indicator for the player we are currently observing.
|
||||
if ( HLTVCamera()->GetMode() != OBS_MODE_IN_EYE )
|
||||
return true;
|
||||
|
||||
C_BaseEntity* pTarget = HLTVCamera()->GetPrimaryTarget();
|
||||
if ( !pTarget || !pTarget->IsPlayer() || pTarget->entindex() != msg.victim_entindex() )
|
||||
return true;
|
||||
|
||||
// This cast is safe because pTarget->IsPlayer() returned true above
|
||||
pVictimPlayer = static_cast< C_BasePlayer* >( pTarget );
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert( C_BasePlayer::GetLocalPlayer()->entindex() == msg.victim_entindex() );
|
||||
pVictimPlayer = C_BasePlayer::GetLocalPlayer();
|
||||
}
|
||||
|
||||
|
||||
int damageTaken = msg.amount();
|
||||
|
||||
if ( damageTaken > 0 )
|
||||
{
|
||||
Vector vecFrom;
|
||||
vecFrom.x = msg.inflictor_world_pos().x();
|
||||
vecFrom.y = msg.inflictor_world_pos().y();
|
||||
vecFrom.z = msg.inflictor_world_pos().z();
|
||||
|
||||
m_flFadeCompleteTime = gpGlobals->curtime + g_DetectDamageTakenInterval;
|
||||
CalcDamageDirection( vecFrom, pVictimPlayer );
|
||||
|
||||
// If we are using a Steam Controller, do haptics on the Steam Controller
|
||||
// to indicate getting hit.
|
||||
if ( g_pInputSystem->IsSteamControllerActive() && steamapicontext->SteamController() )
|
||||
{
|
||||
static ConVarRef steam_controller_haptics( "steam_controller_haptics" );
|
||||
if ( steam_controller_haptics.GetBool() )
|
||||
{
|
||||
ControllerHandle_t handles[MAX_STEAM_CONTROLLERS];
|
||||
int nControllers = steamapicontext->SteamController()->GetConnectedControllers( handles );
|
||||
|
||||
for ( int i = 0; i < nControllers; ++i )
|
||||
{
|
||||
float flLeft = m_flAttackLeft + m_flAttackFront*0.5 + m_flAttackRear*0.5;
|
||||
float flRight = m_flAttackRight + m_flAttackFront*0.5 + m_flAttackRear*0.5;
|
||||
float flTotal = flLeft + flRight;
|
||||
if ( flTotal > 0.0 )
|
||||
{
|
||||
flLeft /= flTotal;
|
||||
flRight /= flTotal;
|
||||
if ( flRight > 0 )
|
||||
{
|
||||
steamapicontext->SteamController()->TriggerHapticPulse( handles[ i ], k_ESteamControllerPad_Right, 2000*flRight );
|
||||
}
|
||||
|
||||
if ( flLeft > 0 )
|
||||
{
|
||||
steamapicontext->SteamController()->TriggerHapticPulse( handles[ i ], k_ESteamControllerPad_Left, 2000*flLeft );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// [jason] This code is duplicated from cs_hud_damageindicator.cpp:
|
||||
void SFHudDamageIndicator::CalcDamageDirection( const Vector &vecFrom, C_BasePlayer *pVictimPlayer )
|
||||
{
|
||||
// I assume this is done to detect damage from world (falling) and not display
|
||||
// an indicator for this. Old code was zeroing all indicator values here which caused
|
||||
// a bug if we were currently in mid-fade for a previous damage source.
|
||||
if ( vecFrom == vec3_origin )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !pVictimPlayer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Vector vecDelta = ( vecFrom - pVictimPlayer->GetRenderOrigin() );
|
||||
|
||||
if ( vecDelta.Length() <= g_CloseDamageDistance )
|
||||
{
|
||||
m_flAttackFront = 1.0f;
|
||||
m_flAttackRear = 1.0f;
|
||||
m_flAttackRight = 1.0f;
|
||||
m_flAttackLeft = 1.0f;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
VectorNormalize( vecDelta );
|
||||
|
||||
Vector forward;
|
||||
Vector right;
|
||||
AngleVectors( MainViewAngles( GET_ACTIVE_SPLITSCREEN_SLOT() ), &forward, &right, NULL );
|
||||
|
||||
float flFront = DotProduct( vecDelta, forward );
|
||||
float flSide = DotProduct( vecDelta, right );
|
||||
|
||||
if ( flFront > 0 )
|
||||
{
|
||||
if ( flFront > g_DirectionDotTolerance )
|
||||
m_flAttackFront = MAX( m_flAttackFront, flFront );
|
||||
}
|
||||
else
|
||||
{
|
||||
float f = fabs( flFront );
|
||||
if ( f > g_DirectionDotTolerance )
|
||||
m_flAttackRear = MAX( m_flAttackRear, f );
|
||||
}
|
||||
|
||||
if ( flSide > 0 )
|
||||
{
|
||||
if ( flSide > g_DirectionDotTolerance )
|
||||
m_flAttackRight = MAX( m_flAttackRight, flSide );
|
||||
}
|
||||
else
|
||||
{
|
||||
float f = fabs( flSide );
|
||||
if ( f > g_DirectionDotTolerance )
|
||||
m_flAttackLeft = MAX( m_flAttackLeft, f );
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user