Counter Strike : Global Offensive Source Code
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
// C_NextBot.cpp
// Client-side implementation of Next generation bot system
// Author: Michael Booth, April 2005
// Copyright (c) 2005 Turtle Rock Studios, Inc. - All Rights Reserved
#include "cbase.h"
#include "C_NextBot.h"
#include "debugoverlay_shared.h"
#include <bitbuf.h>
#include "viewrender.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#undef NextBot
ConVar NextBotShadowDist( "nb_shadow_dist", "400" );
//-----------------------------------------------------------------------------
IMPLEMENT_CLIENTCLASS_DT( C_NextBotCombatCharacter, DT_NextBot, NextBotCombatCharacter ) END_RECV_TABLE()
//-----------------------------------------------------------------------------
C_NextBotCombatCharacter::C_NextBotCombatCharacter() { // Left4Dead have surfaces too steep for IK to work properly
m_EntClientFlags |= ENTCLIENTFLAG_DONTUSEIK;
m_shadowType = SHADOWS_SIMPLE; m_forcedShadowType = SHADOWS_NONE; m_bForceShadowType = false;
TheClientNextBots().Register( this ); }
//-----------------------------------------------------------------------------
C_NextBotCombatCharacter::~C_NextBotCombatCharacter() { TheClientNextBots().UnRegister( this ); }
//-----------------------------------------------------------------------------
void C_NextBotCombatCharacter::Spawn( void ) { BaseClass::Spawn(); }
//-----------------------------------------------------------------------------
void C_NextBotCombatCharacter::UpdateClientSideAnimation() { if (IsDormant()) { return; }
BaseClass::UpdateClientSideAnimation(); }
//--------------------------------------------------------------------------------------------------------
void C_NextBotCombatCharacter::UpdateShadowLOD( void ) { ShadowType_t oldShadowType = m_shadowType;
if ( m_bForceShadowType ) { m_shadowType = m_forcedShadowType; } else { #ifdef NEED_SPLITSCREEN_INTEGRATION
FOR_EACH_VALID_SPLITSCREEN_PLAYER( hh ) { C_BasePlayer *pl = C_BasePlayer::GetLocalPlayer(hh); if ( pl ) { Vector delta = GetAbsOrigin() - C_BasePlayer::GetLocalPlayer(hh)->GetAbsOrigin(); #else
{ if ( C_BasePlayer::GetLocalPlayer() ) { Vector delta = GetAbsOrigin() - C_BasePlayer::GetLocalPlayer()->GetAbsOrigin(); #endif
if ( delta.IsLengthLessThan( NextBotShadowDist.GetFloat() ) ) { m_shadowType = SHADOWS_RENDER_TO_TEXTURE_DYNAMIC; } else { m_shadowType = SHADOWS_SIMPLE; } } else { m_shadowType = SHADOWS_SIMPLE; } } }
if ( oldShadowType != m_shadowType ) { DestroyShadow(); } }
//--------------------------------------------------------------------------------------------------------
ShadowType_t C_NextBotCombatCharacter::ShadowCastType( void ) { if ( !IsVisible() ) return SHADOWS_NONE;
if ( m_shadowTimer.IsElapsed() ) { m_shadowTimer.Start( 0.15f ); UpdateShadowLOD(); }
return m_shadowType; }
//--------------------------------------------------------------------------------------------------------
bool C_NextBotCombatCharacter::GetForcedShadowCastType( ShadowType_t* pForcedShadowType ) const { if ( pForcedShadowType ) { *pForcedShadowType = m_forcedShadowType; } return m_bForceShadowType; }
//--------------------------------------------------------------------------------------------------------
/**
* Singleton accessor. * By returning a reference, we guarantee construction of the * instance before its first use. */ C_NextBotManager &TheClientNextBots( void ) { static C_NextBotManager manager; return manager; }
//--------------------------------------------------------------------------------------------------------
C_NextBotManager::C_NextBotManager( void ) { }
//--------------------------------------------------------------------------------------------------------
C_NextBotManager::~C_NextBotManager() { }
//--------------------------------------------------------------------------------------------------------
void C_NextBotManager::Register( C_NextBotCombatCharacter *bot ) { m_botList.AddToTail( bot ); }
//--------------------------------------------------------------------------------------------------------
void C_NextBotManager::UnRegister( C_NextBotCombatCharacter *bot ) { m_botList.FindAndRemove( bot ); }
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool C_NextBotManager::SetupInFrustumData( void ) { #ifdef ENABLE_AFTER_INTEGRATION
// Done already this frame.
if ( IsInFrustumDataValid() ) return true;
// Can we use the view data yet?
if ( !FrustumCache()->IsValid() ) return false;
// Get the number of active bots.
int nBotCount = m_botList.Count();
// Reset.
for ( int iBot = 0; iBot < nBotCount; ++iBot ) { // Get the current bot.
C_NextBotCombatCharacter *pBot = m_botList[iBot]; if ( !pBot ) continue;
pBot->InitFrustumData(); }
FOR_EACH_VALID_SPLITSCREEN_PLAYER( iSlot ) { ACTIVE_SPLITSCREEN_PLAYER_GUARD( iSlot ); // Get the active local player.
C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); if ( !pPlayer ) continue;
for ( int iBot = 0; iBot < nBotCount; ++iBot ) { // Get the current bot.
C_NextBotCombatCharacter *pBot = m_botList[iBot]; if ( !pBot ) continue;
// Are we in the view frustum?
Vector vecMin, vecMax; pBot->CollisionProp()->WorldSpaceAABB( &vecMin, &vecMax ); bool bInFrustum = !FrustumCache()->m_Frustums[iSlot].CullBox( vecMin, vecMax ); if ( bInFrustum ) { Vector vecSegment; VectorSubtract( pBot->GetAbsOrigin(), pPlayer->GetAbsOrigin(), vecSegment ); float flDistance = vecSegment.LengthSqr(); if ( flDistance < pBot->GetInFrustumDistanceSqr() ) { pBot->SetInFrustumDistanceSqr( flDistance ); }
pBot->SetInFrustum( true ); } } }
// Mark as setup this frame.
m_nInFrustumFrame = gpGlobals->framecount; #endif
return true; }
//--------------------------------------------------------------------------------------------------------
|