sqwarmed/sdk_src/game/shared/swarm/asw_alien_shared.cpp

170 lines
4.4 KiB
C++
Raw Permalink Normal View History

2024-08-29 19:18:30 -04:00
#include "cbase.h"
#ifdef CLIENT_DLL
#include "c_asw_alien.h"
#include "c_asw_player.h"
#include "igameevents.h"
#include "asw_util_shared.h"
#else
#include "asw_alien.h"
#include "asw_player.h"
#endif
#include "asw_fx_shared.h"
#include "takedamageinfo.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#ifdef GAME_DLL
extern ConVar showhitlocation;
#endif
ConVar asw_drone_weak_from_behind( "asw_drone_weak_from_behind", "0", FCVAR_CHEAT | FCVAR_REPLICATED, "Drones take double damage from behind" );
ConVar asw_alien_mining_laser_damage_scale( "asw_alien_mining_laser_damage_scale", "0.25f", FCVAR_CHEAT | FCVAR_REPLICATED );
ConVar asw_alien_debug_death_style( "asw_alien_debug_death_style", "0", FCVAR_CHEAT | FCVAR_REPLICATED, "For debugging alien deaths" );
void CASW_Alien::TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr )
{
#ifdef GAME_DLL
m_fNoDamageDecal = false;
if ( m_takedamage == DAMAGE_NO )
return;
#endif
CTakeDamageInfo subInfo = info;
#ifdef GAME_DLL
SetLastHitGroup( ptr->hitgroup );
m_nForceBone = ptr->physicsbone; // save this bone for physics forces
#endif
Assert( m_nForceBone > -255 && m_nForceBone < 256 );
// mining laser does reduced damage
if ( info.GetDamageType() & DMG_ENERGYBEAM )
{
subInfo.ScaleDamage( asw_alien_mining_laser_damage_scale.GetFloat() );
}
if ( subInfo.GetDamage() >= 1.0 && !(subInfo.GetDamageType() & DMG_SHOCK )
&& !( subInfo.GetDamageType() & DMG_BURN ) )
{
#ifdef GAME_DLL
Bleed( subInfo, ptr->endpos + m_LagCompensation.GetLagCompensationOffset(), vecDir, ptr );
if ( ptr->hitgroup == HITGROUP_HEAD && m_iHealth - subInfo.GetDamage() > 0 )
{
m_fNoDamageDecal = true;
}
#else
Bleed( subInfo, ptr->endpos, vecDir, ptr );
//OnHurt();
#endif
}
if( !info.GetInflictor() )
{
subInfo.SetInflictor( info.GetAttacker() );
}
AddMultiDamage( subInfo, this );
#ifdef GAME_DLL
#else
CASW_Marine *pMarine = dynamic_cast<CASW_Marine*>( subInfo.GetAttacker() );
CASW_Player *pPlayerAttacker = NULL;
if ( pMarine )
{
pPlayerAttacker = pMarine->GetCommander();
}
IGameEvent * event = gameeventmanager->CreateEvent( "alien_hurt" );
if ( event )
{
event->SetInt( "attacker", ( pPlayerAttacker ? pPlayerAttacker->GetUserID() : 0 ) );
event->SetInt( "entindex", entindex() );
event->SetInt( "amount", subInfo.GetDamage() );
gameeventmanager->FireEventClientSide( event );
}
UTIL_ASW_ClientFloatingDamageNumber( subInfo );
#endif
}
void CASW_Alien::Bleed( const CTakeDamageInfo &info, const Vector &vecPos, const Vector &vecDir, trace_t *ptr )
{
UTIL_ASW_DroneBleed( vecPos, -vecDir, 4 );
DoBloodDecal( info.GetDamage(), vecPos, vecDir, ptr, info.GetDamageType() );
}
void CASW_Alien::DoBloodDecal( float flDamage, const Vector &vecPos, const Vector &vecDir, trace_t *ptr, int bitsDamageType )
{
if ( ( BloodColor() == DONT_BLEED) || ( BloodColor() == BLOOD_COLOR_MECH ) )
{
return;
}
if (flDamage == 0)
return;
if ( !( bitsDamageType & ( DMG_CRUSH | DMG_BULLET | DMG_SLASH | DMG_BLAST | DMG_CLUB | DMG_AIRBOAT ) ) )
return;
// make blood decal on the wall!
trace_t Bloodtr;
Vector vecTraceDir;
float flNoise;
int cCount;
int i;
#ifdef GAME_DLL
if ( !IsAlive() )
{
// dealing with a dead npc.
if ( GetMaxHealth() <= 0 )
{
// no blood decal for a npc that has already decalled its limit.
return;
}
else
{
m_iMaxHealth -= 1;
}
}
#endif
if (flDamage < 10)
{
flNoise = 0.1;
cCount = 1;
}
else if (flDamage < 25)
{
flNoise = 0.2;
cCount = 2;
}
else
{
flNoise = 0.3;
cCount = 4;
}
float flTraceDist = (bitsDamageType & DMG_AIRBOAT) ? 384 : 172;
for ( i = 0 ; i < cCount ; i++ )
{
vecTraceDir = vecDir * -1;// trace in the opposite direction the shot came from (the direction the shot is going)
vecTraceDir.x += random->RandomFloat( -flNoise, flNoise );
vecTraceDir.y += random->RandomFloat( -flNoise, flNoise );
vecTraceDir.z += random->RandomFloat( -flNoise, flNoise );
// Don't bleed on grates.
UTIL_TraceLine( vecPos, vecPos + vecTraceDir * -flTraceDist, MASK_SOLID_BRUSHONLY & ~CONTENTS_GRATE, this, COLLISION_GROUP_NONE, &Bloodtr);
if ( Bloodtr.fraction != 1.0 )
{
UTIL_BloodDecalTrace( &Bloodtr, BloodColor() );
}
}
}