// Actual work code IterationRetval_t CPlayerAndObjectEnumerator::EnumElement( IHandleEntity *pHandleEntity ) { if ( !m_pLocal ) return ITERATION_STOP; C_BaseEntity *pEnt = ClientEntityList().GetBaseEntityFromHandle( pHandleEntity->GetRefEHandle() ); if ( pEnt == NULL ) return ITERATION_CONTINUE; if ( pEnt == m_pLocal ) return ITERATION_CONTINUE; if ( !pEnt->IsPlayer() && !pEnt->IsBaseObject() ) { return ITERATION_CONTINUE; } // Ignore vehicles, since they have vcollide collisions that's push me away if ( pEnt->GetCollisionGroup() == COLLISION_GROUP_VEHICLE ) return ITERATION_CONTINUE; // If it's solid to player movement, don't steer around it since we'll just bump into it if ( pEnt->GetCollisionGroup() == TFCOLLISION_GROUP_OBJECT_SOLIDTOPLAYERMOVEMENT ) return ITERATION_CONTINUE; Vector deltaPos = pEnt->GetAbsOrigin() - m_pLocal->GetAbsOrigin(); if ( deltaPos.LengthSqr() > m_flRadiusSquared ) return ITERATION_CONTINUE; CHandle< C_BaseEntity > h; h = pEnt; m_Objects.AddToTail( h ); return ITERATION_CONTINUE; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CTFFreezePanel::FireGameEvent( IGameEvent * event ) { const char *pEventName = event->GetName(); if ( Q_strcmp( "player_death", pEventName ) == 0 ) { // see if the local player died int iPlayerIndexVictim = engine->GetPlayerForUserID( event->GetInt( "userid" ) ); C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer(); if ( pLocalPlayer && iPlayerIndexVictim == pLocalPlayer->entindex() ) { // the local player is dead, see if this is a new nemesis or a revenge if ( event->GetInt( "dominated" ) > 0 ) { m_iShowNemesisPanel = SHOW_NEW_NEMESIS; } else if ( event->GetInt( "revenge" ) > 0 ) { m_iShowNemesisPanel = SHOW_REVENGE; } else { m_iShowNemesisPanel = SHOW_NO_NEMESIS; } } } else if ( Q_strcmp( "hide_freezepanel", pEventName ) == 0 ) { Hide(); } else if ( Q_strcmp( "freezecam_started", pEventName ) == 0 ) { ShowCalloutsIn( 1.0 ); ShowSnapshotPanelIn( 1.25 ); } else if ( Q_strcmp( "teamplay_win_panel", pEventName ) == 0 ) { Hide(); } else if ( Q_strcmp( "show_freezepanel", pEventName ) == 0 ) { C_TF_PlayerResource *tf_PR = dynamic_cast<C_TF_PlayerResource *>(g_PR); if ( !tf_PR ) { m_pNemesisSubPanel->SetDialogVariable( "nemesisname", NULL ); return; } Show(); ShowSnapshotPanel( false ); m_bHoldingAfterScreenshot = false; if ( m_iBasePanelOriginalX > -1 && m_iBasePanelOriginalY > -1 ) { m_pBasePanel->SetPos( m_iBasePanelOriginalX, m_iBasePanelOriginalY ); } // Get the entity who killed us m_iKillerIndex = event->GetInt( "killer" ); C_BaseEntity *pKiller = ClientEntityList().GetBaseEntity( m_iKillerIndex ); int xp,yp; GetPos( xp, yp ); if ( TFGameRules()->RoundHasBeenWon() ) { SetPos( xp, m_iYBase - YRES(50) ); } else { SetPos( xp, m_iYBase ); } if ( pKiller ) { CTFPlayer *pPlayer = ToTFPlayer ( pKiller ); int iMaxBuffedHealth = 0; if ( pPlayer ) { iMaxBuffedHealth = pPlayer->m_Shared.GetMaxBuffedHealth(); } int iKillerHealth = pKiller->GetHealth(); if ( !pKiller->IsAlive() ) { iKillerHealth = 0; } m_pKillerHealth->SetHealth( iKillerHealth, pKiller->GetMaxHealth(), iMaxBuffedHealth ); if ( pKiller->IsPlayer() ) { C_TFPlayer *pVictim = C_TFPlayer::GetLocalTFPlayer(); CTFPlayer *pTFKiller = ToTFPlayer( pKiller ); //If this was just a regular kill but this guy is our nemesis then just show it. if ( pVictim && pTFKiller && pTFKiller->m_Shared.IsPlayerDominated( pVictim->entindex() ) ) { if ( !pKiller->IsAlive() ) { m_pFreezeLabel->SetText( "#FreezePanel_Nemesis_Dead" ); } else { m_pFreezeLabel->SetText( "#FreezePanel_Nemesis" ); } } else { if ( !pKiller->IsAlive() ) { m_pFreezeLabel->SetText( "#FreezePanel_Killer_Dead" ); } else { m_pFreezeLabel->SetText( "#FreezePanel_Killer" ); } } m_pBasePanel->SetDialogVariable( "killername", g_PR->GetPlayerName( m_iKillerIndex ) ); if ( m_pAvatar ) { m_pAvatar->SetPlayer( (C_BasePlayer*)pKiller ); } } else if ( pKiller->IsBaseObject() ) { C_BaseObject *pObj = assert_cast<C_BaseObject *>( pKiller ); C_TFPlayer *pOwner = pObj->GetOwner(); Assert( pOwner && "Why does this object not have an owner?" ); if ( pOwner ) { m_iKillerIndex = pOwner->entindex(); m_pBasePanel->SetDialogVariable( "killername", g_PR->GetPlayerName( m_iKillerIndex ) ); if ( m_pAvatar ) { m_pAvatar->SetPlayer( pOwner ); } pKiller = pOwner; } if ( m_pFreezeLabel ) { if ( pKiller && !pKiller->IsAlive() ) { m_pFreezeLabel->SetText( "#FreezePanel_KillerObject_Dead" ); } else { m_pFreezeLabel->SetText( "#FreezePanel_KillerObject" ); } } const char *pszStatusName = pObj->GetStatusName(); wchar_t *wszLocalized = g_pVGuiLocalize->Find( pszStatusName ); if ( !wszLocalized ) { m_pBasePanel->SetDialogVariable( "objectkiller", pszStatusName ); } else { m_pBasePanel->SetDialogVariable( "objectkiller", wszLocalized ); } } else if ( m_pFreezeLabel ) { if ( !pKiller->IsAlive() ) { m_pFreezeLabel->SetText( "#FreezePanel_Killer_Dead" ); } else { m_pFreezeLabel->SetText( "#FreezePanel_Killer" ); } } } // see if we should show nemesis panel const wchar_t *pchNemesisText = NULL; switch ( m_iShowNemesisPanel ) { case SHOW_NO_NEMESIS: { C_TFPlayer *pVictim = C_TFPlayer::GetLocalTFPlayer(); CTFPlayer *pTFKiller = ToTFPlayer( pKiller ); //If this was just a regular kill but this guy is our nemesis then just show it. if ( pTFKiller && pTFKiller->m_Shared.IsPlayerDominated( pVictim->entindex() ) ) { pchNemesisText = g_pVGuiLocalize->Find( "#TF_FreezeNemesis" ); } } break; case SHOW_NEW_NEMESIS: { C_TFPlayer *pVictim = C_TFPlayer::GetLocalTFPlayer(); CTFPlayer *pTFKiller = ToTFPlayer( pKiller ); // check to see if killer is still the nemesis of victim; victim may have managed to kill him after victim's // death by grenade or some such, extracting revenge and clearing nemesis condition if ( pTFKiller && pTFKiller->m_Shared.IsPlayerDominated( pVictim->entindex() ) ) { pchNemesisText = g_pVGuiLocalize->Find( "#TF_NewNemesis" ); } } break; case SHOW_REVENGE: pchNemesisText = g_pVGuiLocalize->Find( "#TF_GotRevenge" ); break; default: Assert( false ); // invalid value break; } m_pNemesisSubPanel->SetDialogVariable( "nemesisname", pchNemesisText ); ShowNemesisPanel( NULL != pchNemesisText ); m_iShowNemesisPanel = SHOW_NO_NEMESIS; } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CTargetID::UpdateID( void ) { wchar_t sIDString[ MAX_ID_STRING ] = L""; wchar_t sDataString[ MAX_ID_STRING ] = L""; C_TFPlayer *pLocalTFPlayer = C_TFPlayer::GetLocalTFPlayer(); if ( !pLocalTFPlayer ) return; // Get our target's ent index Assert( m_iTargetEntIndex ); // Is this an entindex sent by the server? if ( m_iTargetEntIndex ) { C_BaseEntity *pEnt = cl_entitylist->GetEnt( m_iTargetEntIndex ); if ( !pEnt ) return; bool bShowHealth = false; float flHealth = 0; float flMaxHealth = 1; int iMaxBuffedHealth = 0; int iColorNum = TEAM_UNASSIGNED; // Some entities we always want to check, cause the text may change // even while we're looking at it // Is it a player? if ( IsPlayerIndex( m_iTargetEntIndex ) ) { const char *printFormatString = NULL; wchar_t wszPlayerName[ MAX_PLAYER_NAME_LENGTH ]; bool bDisguisedTarget = false; bool bDisguisedEnemy = false; C_TFPlayer *pPlayer = static_cast<C_TFPlayer*>( pEnt ); if ( !pPlayer ) return; C_TFPlayer *pDisguiseTarget = NULL; g_pVGuiLocalize->ConvertANSIToUnicode( pPlayer->GetPlayerName(), wszPlayerName, sizeof(wszPlayerName) ); // determine if the target is a disguised spy (either friendly or enemy) if ( pPlayer->m_Shared.InCond( TF_COND_DISGUISED ) && // they're disguised //!pPlayer->m_Shared.InCond( TF_COND_DISGUISING ) && // they're not in the process of disguising !pPlayer->m_Shared.InCond( TF_COND_STEALTHED ) ) // they're not cloaked { bDisguisedTarget = true; pDisguiseTarget = ToTFPlayer( pPlayer->m_Shared.GetDisguiseTarget() ); } iColorNum = pPlayer->GetTeamNumber(); if ( bDisguisedTarget ) { // is the target a disguised enemy spy? if ( pPlayer->IsEnemyPlayer() ) { if ( pDisguiseTarget ) { bDisguisedEnemy = true; // change the player name g_pVGuiLocalize->ConvertANSIToUnicode( pDisguiseTarget->GetPlayerName(), wszPlayerName, sizeof(wszPlayerName) ); // Show their disguise team color. iColorNum = pPlayer->m_Shared.GetDisguiseTeam(); } } else { // The target is a disguised friendly spy. They appear to the player with no disguise. Add the disguise // team & class to the target ID element. bool bDisguisedAsEnemy = ( pPlayer->m_Shared.GetDisguiseTeam() != pPlayer->GetTeamNumber() ); const wchar_t *wszAlignment = g_pVGuiLocalize->Find( bDisguisedAsEnemy ? "#TF_enemy" : "#TF_friendly" ); int classindex = pPlayer->m_Shared.GetDisguiseClass(); const wchar_t *wszClassName = g_pVGuiLocalize->Find( g_aPlayerClassNames[classindex] ); // build a string with disguise information g_pVGuiLocalize->ConstructString( sDataString, sizeof(sDataString), g_pVGuiLocalize->Find( "#TF_playerid_friendlyspy_disguise" ), 2, wszAlignment, wszClassName ); } } if ( pPlayer->IsPlayerClass( TF_CLASS_MEDIC ) ) { wchar_t wszChargeLevel[ 10 ]; _snwprintf( wszChargeLevel, ARRAYSIZE(wszChargeLevel) - 1, L"%.0f", pPlayer->MedicGetChargeLevel() * 100 ); wszChargeLevel[ ARRAYSIZE(wszChargeLevel)-1 ] = '\0'; g_pVGuiLocalize->ConstructString( sDataString, sizeof(sDataString), g_pVGuiLocalize->Find( "#TF_playerid_mediccharge" ), 1, wszChargeLevel ); } if (pLocalTFPlayer->GetTeamNumber() == TEAM_SPECTATOR || pPlayer->InSameTeam(pLocalTFPlayer) || (bDisguisedEnemy && pPlayer->m_Shared.GetDisguiseTeam() == pLocalTFPlayer->GetTeamNumber())) { printFormatString = "#TF_playerid_sameteam"; bShowHealth = true; } else if ( pLocalTFPlayer->IsPlayerClass( TF_CLASS_SPY ) && !pPlayer->m_Shared.InCond( TF_COND_STEALTHED ) ) { // Spy can see enemy's health. printFormatString = "#TF_playerid_diffteam"; bShowHealth = true; } if ( bShowHealth ) { C_TF_PlayerResource *tf_PR = dynamic_cast<C_TF_PlayerResource *>(g_PR); if ( tf_PR ) { flMaxHealth = tf_PR->GetMaxHealth( m_iTargetEntIndex ); iMaxBuffedHealth = pPlayer->m_Shared.GetMaxBuffedHealth(); if ( bDisguisedEnemy ) { flHealth = (float)pPlayer->m_Shared.GetDisguiseHealth(); } else { flHealth = (float)pPlayer->GetHealth(); } } else { bShowHealth = false; } } if ( printFormatString ) { wchar_t *pszPrepend = GetPrepend(); if ( !pszPrepend || !pszPrepend[0] ) { pszPrepend = L""; } g_pVGuiLocalize->ConstructString( sIDString, sizeof(sIDString), g_pVGuiLocalize->Find(printFormatString), 2, pszPrepend, wszPlayerName ); } } else { // see if it is an object if ( pEnt->IsBaseObject() ) { C_BaseObject *pObj = assert_cast<C_BaseObject *>( pEnt ); pObj->GetTargetIDString( sIDString, sizeof(sIDString) ); pObj->GetTargetIDDataString( sDataString, sizeof(sDataString) ); bShowHealth = true; flHealth = pObj->GetHealth(); flMaxHealth = pObj->GetMaxHealth(); C_TFPlayer *pBuilder = pObj->GetBuilder(); iColorNum = pBuilder ? pBuilder->GetTeamNumber() : pObj->GetTeamNumber(); } else if ( pEnt->IsNPC() ) { C_AI_BaseNPC *pNPC = assert_cast<C_AI_BaseNPC *>( pEnt ); pNPC->GetTargetIDString( sIDString, sizeof(sIDString) ); pNPC->GetTargetIDDataString( sDataString, sizeof(sDataString) ); bShowHealth = true; flHealth = pNPC->GetHealth(); flMaxHealth = pNPC->GetMaxHealth(); iMaxBuffedHealth = pNPC->GetMaxBuffedHealth(); iColorNum = pNPC->GetTeamNumber(); } } // Setup health icon if ( !pEnt->IsAlive() ) { flHealth = 0; // fixup for health being 1 when dead } SetColorForTargetTeam( iColorNum ); m_pTargetHealth->SetHealth( flHealth, flMaxHealth, iMaxBuffedHealth ); m_pTargetHealth->SetVisible( bShowHealth ); int iNameW, iDataW, iIgnored; m_pTargetNameLabel->GetContentSize( iNameW, iIgnored ); m_pTargetDataLabel->GetContentSize( iDataW, iIgnored ); // Target name if ( sIDString[0] ) { sIDString[ ARRAYSIZE(sIDString)-1 ] = '\0'; m_pTargetNameLabel->SetVisible(true); // TODO: Support if( hud_centerid.GetInt() == 0 ) SetDialogVariable( "targetname", sIDString ); } else { m_pTargetNameLabel->SetVisible(false); m_pTargetNameLabel->SetText(""); } // Extra target data if ( sDataString[0] ) { sDataString[ ARRAYSIZE(sDataString)-1 ] = '\0'; m_pTargetDataLabel->SetVisible(true); SetDialogVariable( "targetdata", sDataString ); } else { m_pTargetDataLabel->SetVisible(false); m_pTargetDataLabel->SetText(""); } int iPostNameW, iPostDataW; m_pTargetNameLabel->GetContentSize( iPostNameW, iIgnored ); m_pTargetDataLabel->GetContentSize( iPostDataW, iIgnored ); if ( m_bLayoutOnUpdate || (iPostDataW != iDataW) || (iPostNameW != iNameW) ) { InvalidateLayout( true ); m_bLayoutOnUpdate = false; } } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- bool CTargetID::ShouldDraw( void ) { if ( !CHudElement::ShouldDraw() ) return false; C_TFPlayer *pLocalTFPlayer = C_TFPlayer::GetLocalTFPlayer(); if ( !pLocalTFPlayer ) return false; // Get our target's ent index m_iTargetEntIndex = CalculateTargetIndex(pLocalTFPlayer); if ( !m_iTargetEntIndex ) { // Check to see if we should clear our ID if ( m_flLastChangeTime && ( gpGlobals->curtime > m_flLastChangeTime ) ) { m_flLastChangeTime = 0; m_iLastEntIndex = 0; } else { // Keep re-using the old one m_iTargetEntIndex = m_iLastEntIndex; } } else { m_flLastChangeTime = gpGlobals->curtime; } bool bReturn = false; if ( m_iTargetEntIndex ) { C_BaseEntity *pEnt = cl_entitylist->GetEnt( m_iTargetEntIndex ); if ( pEnt ) { if ( IsPlayerIndex( m_iTargetEntIndex ) ) { C_TFPlayer *pPlayer = static_cast<C_TFPlayer*>( pEnt ); bool bDisguisedEnemy = false; if ( pPlayer->m_Shared.InCond( TF_COND_DISGUISED ) && // they're disguised !pPlayer->m_Shared.InCond( TF_COND_DISGUISING ) && // they're not in the process of disguising !pPlayer->m_Shared.InCond( TF_COND_STEALTHED ) ) // they're not cloaked { bDisguisedEnemy = (ToTFPlayer( pPlayer->m_Shared.GetDisguiseTarget() ) != NULL); } bReturn = (pLocalTFPlayer->GetTeamNumber() == TEAM_SPECTATOR || pLocalTFPlayer->InSameTeam(pEnt) || (bDisguisedEnemy && pPlayer->m_Shared.GetDisguiseTeam() == pLocalTFPlayer->GetTeamNumber()) || (pLocalTFPlayer->IsPlayerClass( TF_CLASS_SPY ) && !pPlayer->m_Shared.InCond( TF_COND_STEALTHED )) ); } else if ( pEnt->IsBaseObject() && (pLocalTFPlayer->InSameTeam( pEnt ) || pLocalTFPlayer->IsPlayerClass( TF_CLASS_SPY ) || pLocalTFPlayer->GetTeamNumber() == TEAM_SPECTATOR) ) { bReturn = true; } else if ( pEnt->IsNPC() ) { bReturn = ( pLocalTFPlayer->GetTeamNumber() == TEAM_SPECTATOR || pLocalTFPlayer->InSameTeam( pEnt ) || pLocalTFPlayer->IsPlayerClass( TF_CLASS_SPY ) ); } } } if ( bReturn ) { if ( !IsVisible() || (m_iTargetEntIndex != m_iLastEntIndex) ) { m_iLastEntIndex = m_iTargetEntIndex; m_bLayoutOnUpdate = true; } UpdateID(); } return bReturn; }