1313#endif 
1414
1515#ifdef  MAPBASE_MP
16+ #include  " takedamageinfo.h" 
1617#ifdef  HL2MP
1718#include  " c_hl2mp_playerresource.h" 
1819#endif 
2526
2627#define  PING_MAX_TIME 	2.0 
2728
29+ #ifdef  MAPBASE_MP
30+ BEGIN_RECV_TABLE_NOBASE ( C_AI_BaseNPC, DT_BaseNPCGameData )
31+ 	RecvPropInt( RECVINFO( m_iHealth ) ),
32+ 	RecvPropInt( RECVINFO( m_takedamage ) ),
33+ 	RecvPropInt( RECVINFO( m_bloodColor ) ),
34+ 	// RecvPropString( RECVINFO( m_szNetname ) ),	// Transmitted by player resource now
35+ 	RecvPropInt( RECVINFO( m_nDefaultPlayerRelationship ) ),
36+ END_RECV_TABLE();
37+ #endif 
38+ 
39+ #ifdef  CAI_BaseNPC
40+ #undef  CAI_BaseNPC
41+ #endif 
42+ 
2843IMPLEMENT_CLIENTCLASS_DT ( C_AI_BaseNPC, DT_AI_BaseNPC, CAI_BaseNPC )
2944	RecvPropInt( RECVINFO( m_lifeState ) ),
3045	RecvPropBool( RECVINFO( m_bPerformAvoidance ) ),
@@ -37,6 +52,9 @@ IMPLEMENT_CLIENTCLASS_DT( C_AI_BaseNPC, DT_AI_BaseNPC, CAI_BaseNPC )
3752	RecvPropInt( RECVINFO( m_bSpeedModActive ) ),
3853	RecvPropBool( RECVINFO( m_bImportanRagdoll ) ),
3954	RecvPropFloat( RECVINFO( m_flTimePingEffect ) ),
55+ #ifdef  MAPBASE_MP
56+ 	RecvPropDataTable ( " npc_gamedata"  , 0 , 0 , &REFERENCE_RECV_TABLE ( DT_BaseNPCGameData ) ),
57+ #endif
4058END_RECV_TABLE ()
4159
4260extern ConVar cl_npc_speedmod_intime;
@@ -53,6 +71,9 @@ bool NPC_IsImportantNPC( C_BaseAnimating *pAnimating )
5371
5472C_AI_BaseNPC::C_AI_BaseNPC ()
5573{
74+ #ifdef  MAPBASE_MP
75+ 	SetBloodColor ( DONT_BLEED );
76+ #endif 
5677}
5778
5879// -----------------------------------------------------------------------------
@@ -205,5 +226,89 @@ const char *C_AI_BaseNPC::GetPlayerName( void ) const
205226
206227	return  BaseClass::GetPlayerName ();
207228}
229+ 
230+ // -----------------------------------------------------------------------------
231+ //  Purpose: 
232+ // -----------------------------------------------------------------------------
233+ void  C_AI_BaseNPC::DispatchTraceAttack ( const  CTakeDamageInfo &info, const  Vector &vecDir, trace_t  *ptr, CDmgAccumulator *pAccumulator )
234+ {
235+ 	m_fNoDamageDecal = false ;
236+ 
237+ 	if  ( info.GetAttacker () && info.GetAttacker ()->IsPlayer () )
238+ 	{
239+ 		if  ( IsPlayerAlly ( ToBasePlayer ( info.GetAttacker () ) ) )
240+ 		{
241+ 			m_fNoDamageDecal = true ;
242+ 			return ;
243+ 		}
244+ 	}
245+ 
246+ 	BaseClass::DispatchTraceAttack ( info, vecDir, ptr, pAccumulator );
247+ }
248+ 
249+ // -----------------------------------------------------------------------------
250+ //  Purpose: 
251+ // -----------------------------------------------------------------------------
252+ void  C_AI_BaseNPC::DecalTrace ( trace_t  *pTrace, char  const  *decalName )
253+ {
254+ 	if  ( m_fNoDamageDecal )
255+ 	{
256+ 		//  Don't do impact decals when we shouldn't
257+ 		//  (adapts an existing hack from singleplayer HL2, see serverside counterpart)
258+ 		m_fNoDamageDecal = false ;
259+ 		return ;
260+ 	}
261+ 	BaseClass::DecalTrace ( pTrace, decalName );
262+ }
263+ 
264+ // -----------------------------------------------------------------------------
265+ //  Purpose: 
266+ // -----------------------------------------------------------------------------
267+ void  C_AI_BaseNPC::ImpactTrace ( trace_t  *pTrace, int  iDamageType, const  char  *pCustomImpactName )
268+ {
269+ 	if  ( m_fNoDamageDecal )
270+ 	{
271+ 		//  Don't do impact decals when we shouldn't
272+ 		//  (adapts an existing hack from singleplayer HL2, see serverside counterpart)
273+ 		m_fNoDamageDecal = false ;
274+ 		return ;
275+ 	}
276+ 	BaseClass::ImpactTrace ( pTrace, iDamageType, pCustomImpactName );
277+ }
278+ 
279+ // -----------------------------------------------------------------------------
280+ //  Purpose: 
281+ // -----------------------------------------------------------------------------
282+ bool  C_AI_BaseNPC::IsPlayerAlly ( C_BasePlayer *pPlayer )											
283+ { 
284+ 	if  ( pPlayer == NULL  )
285+ 	{
286+ 		pPlayer = C_BasePlayer::GetLocalPlayer ();
287+ 	}
288+ 
289+ 	if  ( pPlayer->GetTeamNumber () == TEAM_UNASSIGNED )
290+ 	{
291+ 		//  AI relationship code isn't available here, so we currently transmit a var from the server to determine if we're, at least generically, an ally
292+ 		return  (m_nDefaultPlayerRelationship == GR_TEAMMATE);
293+ 	}
294+ 	else  if  (GetTeamNumber () == pPlayer->GetTeamNumber ())
295+ 	{
296+ 		//  Same team probably means allies
297+ 		return  true ;
298+ 	}
299+ 
300+ 	return  false ;
301+ }
302+ 
303+ // -----------------------------------------------------------------------------
304+ //  Purpose: 
305+ // -----------------------------------------------------------------------------
306+ bool  C_AI_BaseNPC::IsNeutralTo ( C_BasePlayer *pPlayer )
307+ {
308+ 	if  ( IsPlayerAlly ( pPlayer ) )
309+ 		return  false ;
310+ 
311+ 	return  (m_nDefaultPlayerRelationship == GR_NOTTEAMMATE);
312+ }
208313#endif 
209314
0 commit comments