Modified source engine (2017) developed by valve and leaked in 2020. Not for commercial purporses
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.

753 lines
21 KiB

#include "cbase.h"
#include "asw_triggers.h"
#include "asw_marine.h"
#include "asw_game_resource.h"
#include "asw_marine_resource.h"
#include "asw_marine_speech.h"
#include "asw_gamerules.h"
#include "asw_weapon.h"
#include "asw_util_shared.h"
#include "asw_melee_system.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
ConVar asw_synup_chatter_chance("asw_synup_chatter_chance", "0.2", FCVAR_CHEAT, "Chance of the synup chatter happening");
// Chance trigger - has a random chance of actually firing
LINK_ENTITY_TO_CLASS( trigger_asw_chance, CASW_Chance_Trigger_Multiple );
BEGIN_DATADESC( CASW_Chance_Trigger_Multiple )
DEFINE_KEYFIELD( m_fTriggerChance, FIELD_FLOAT, "TriggerChance" ),
// Function Pointers
DEFINE_FUNCTION(ChanceMultiTouch),
DEFINE_FUNCTION(MultiWaitOver ),
// Outputs
DEFINE_OUTPUT(m_OnTrigger, "OnTrigger")
END_DATADESC()
void CASW_Chance_Trigger_Multiple::Spawn( void )
{
BaseClass::Spawn();
InitTrigger();
if (m_flWait == 0)
{
m_flWait = 0.2;
}
ASSERTSZ(m_iHealth == 0, "trigger_multiple with health");
SetTouch( &CASW_Chance_Trigger_Multiple::ChanceMultiTouch );
}
//-----------------------------------------------------------------------------
// Purpose: Touch function. Activates the trigger.
// Input : pOther - The thing that touched us.
//-----------------------------------------------------------------------------
void CASW_Chance_Trigger_Multiple::ChanceMultiTouch(CBaseEntity *pOther)
{
if (PassesTriggerFilters(pOther))
{
ActivateChanceMultiTrigger( pOther );
}
}
void CASW_Chance_Trigger_Multiple::ActivateChanceMultiTrigger(CBaseEntity *pActivator)
{
if (GetNextThink() > gpGlobals->curtime)
return; // still waiting for reset time
m_hActivator = pActivator;
if (RandomFloat() < m_fTriggerChance)
m_OnTrigger.FireOutput(m_hActivator, this);
if (m_flWait > 0)
{
SetThink( &CASW_Chance_Trigger_Multiple::MultiWaitOver );
SetNextThink( gpGlobals->curtime + m_flWait );
}
else
{
// we can't just remove (self) here, because this is a touch function
// called while C code is looping through area links...
SetTouch( NULL );
SetNextThink( gpGlobals->curtime + 0.1f );
SetThink( &CASW_Chance_Trigger_Multiple::SUB_Remove );
}
}
void CASW_Chance_Trigger_Multiple::MultiWaitOver( void )
{
SetThink( NULL );
}
LINK_ENTITY_TO_CLASS( trigger_asw_random_target, CASW_Random_Target_Trigger_Multiple );
BEGIN_DATADESC( CASW_Random_Target_Trigger_Multiple )
DEFINE_KEYFIELD( m_iNumOutputs, FIELD_INTEGER, "NumOutputs" ),
// Function Pointers
DEFINE_FUNCTION(RandomMultiTouch),
DEFINE_FUNCTION(MultiWaitOver),
// Outputs
DEFINE_OUTPUT(m_OnTrigger1, "OnTrigger1"),
DEFINE_OUTPUT(m_OnTrigger2, "OnTrigger2"),
DEFINE_OUTPUT(m_OnTrigger3, "OnTrigger3"),
DEFINE_OUTPUT(m_OnTrigger4, "OnTrigger4"),
DEFINE_OUTPUT(m_OnTrigger5, "OnTrigger5"),
DEFINE_OUTPUT(m_OnTrigger6, "OnTrigger6"),
END_DATADESC()
void CASW_Random_Target_Trigger_Multiple::Spawn( void )
{
BaseClass::Spawn();
InitTrigger();
if (m_flWait == 0)
{
m_flWait = 0.2;
}
ASSERTSZ(m_iHealth == 0, "trigger_multiple with health");
SetTouch( &CASW_Random_Target_Trigger_Multiple::RandomMultiTouch );
}
//-----------------------------------------------------------------------------
// Purpose: Touch function. Activates the trigger.
// Input : pOther - The thing that touched us.
//-----------------------------------------------------------------------------
void CASW_Random_Target_Trigger_Multiple::RandomMultiTouch(CBaseEntity *pOther)
{
if (PassesTriggerFilters(pOther))
{
ActivateRandomMultiTrigger( pOther );
}
}
void CASW_Random_Target_Trigger_Multiple::ActivateRandomMultiTrigger(CBaseEntity *pActivator)
{
if (GetNextThink() > gpGlobals->curtime)
return; // still waiting for reset time
m_hActivator = pActivator;
int i = RandomInt(1, m_iNumOutputs);
switch (i)
{
case 2: m_OnTrigger2.FireOutput(m_hActivator, this); break;
case 3: m_OnTrigger3.FireOutput(m_hActivator, this); break;
case 4: m_OnTrigger4.FireOutput(m_hActivator, this); break;
case 5: m_OnTrigger5.FireOutput(m_hActivator, this); break;
case 6: m_OnTrigger6.FireOutput(m_hActivator, this); break;
default: m_OnTrigger1.FireOutput(m_hActivator, this); break;
}
if (m_flWait > 0)
{
SetThink( &CASW_Random_Target_Trigger_Multiple::MultiWaitOver );
SetNextThink( gpGlobals->curtime + m_flWait );
}
else
{
// we can't just remove (self) here, because this is a touch function
// called while C code is looping through area links...
SetTouch( NULL );
SetNextThink( gpGlobals->curtime + 0.1f );
SetThink( &CASW_Random_Target_Trigger_Multiple::SUB_Remove );
}
}
void CASW_Random_Target_Trigger_Multiple::MultiWaitOver( void )
{
SetThink( NULL );
}
LINK_ENTITY_TO_CLASS( trigger_asw_supplies_chatter, CASW_Supplies_Chatter_Trigger );
BEGIN_DATADESC( CASW_Supplies_Chatter_Trigger )
// Function Pointers
DEFINE_FUNCTION(SuppliesChatterTouch),
DEFINE_FUNCTION(MultiWaitOver ),
DEFINE_KEYFIELD(m_bNoAmmo, FIELD_BOOLEAN, "NoAmmo"),
// Outputs
DEFINE_OUTPUT(m_OnTrigger, "OnTrigger")
END_DATADESC()
void CASW_Supplies_Chatter_Trigger::Spawn( void )
{
BaseClass::Spawn();
InitTrigger();
if (m_flWait == 0)
{
m_flWait = 0.2;
}
ASSERTSZ(m_iHealth == 0, "trigger_multiple with health");
SetTouch( &CASW_Supplies_Chatter_Trigger::SuppliesChatterTouch );
}
//-----------------------------------------------------------------------------
// Purpose: Touch function. Activates the trigger.
// Input : pOther - The thing that touched us.
//-----------------------------------------------------------------------------
void CASW_Supplies_Chatter_Trigger::SuppliesChatterTouch(CBaseEntity *pOther)
{
if (PassesTriggerFilters(pOther) && pOther->Classify() == CLASS_ASW_MARINE)
{
ActivateSuppliesChatterTrigger( pOther );
}
}
void CASW_Supplies_Chatter_Trigger::ActivateSuppliesChatterTrigger(CBaseEntity *pActivator)
{
if (GetNextThink() > gpGlobals->curtime)
return; // still waiting for reset time
m_hActivator = pActivator;
m_OnTrigger.FireOutput(m_hActivator, this);
// pick a nearby marine to say the chatter
if ( ASWGameResource() )
{
CASW_Game_Resource *pGameResource = ASWGameResource();
// count how many are nearby
int iNearby = 0;
for (int i=0;i<pGameResource->GetMaxMarineResources();i++)
{
CASW_Marine_Resource *pMR = pGameResource->GetMarineResource(i);
CASW_Marine *pMarine = pMR ? pMR->GetMarineEntity() : NULL;
if (pMarine && (pActivator->GetAbsOrigin().DistTo(pMarine->GetAbsOrigin()) < 600)
&& pMarine->GetHealth() > 0)
iNearby++;
}
if (iNearby >= 2) // only do the speech if there are at least 2 marines nearby
{
int iChatter = random->RandomInt(0, iNearby-1);
for (int i=0;i<pGameResource->GetMaxMarineResources();i++)
{
CASW_Marine_Resource *pMR = pGameResource->GetMarineResource(i);
CASW_Marine *pMarine = pMR ? pMR->GetMarineEntity() : NULL;
if (pMarine && (pActivator->GetAbsOrigin().DistTo(pMarine->GetAbsOrigin()) < 600)
&& pMarine->GetHealth() > 0)
{
if (iChatter <= 0)
{
if (m_bNoAmmo)
pMarine->GetMarineSpeech()->Chatter(CHATTER_SUPPLIES);
else
pMarine->GetMarineSpeech()->Chatter(CHATTER_SUPPLIES_AMMO);
break;
}
iChatter--;
}
}
}
}
if (m_flWait > 0)
{
SetThink( &CASW_Supplies_Chatter_Trigger::MultiWaitOver );
SetNextThink( gpGlobals->curtime + m_flWait );
}
else
{
// we can't just remove (self) here, because this is a touch function
// called while C code is looping through area links...
SetTouch( NULL );
SetNextThink( gpGlobals->curtime + 0.1f );
SetThink( &CASW_Supplies_Chatter_Trigger::SUB_Remove );
}
}
void CASW_Supplies_Chatter_Trigger::MultiWaitOver( void )
{
SetThink( NULL );
}
LINK_ENTITY_TO_CLASS( trigger_asw_synup_chatter, CASW_SynUp_Chatter_Trigger );
BEGIN_DATADESC( CASW_SynUp_Chatter_Trigger )
// Function Pointers
DEFINE_FUNCTION(ChatterTouch),
DEFINE_FUNCTION(MultiWaitOver ),
// Outputs
DEFINE_OUTPUT(m_OnTrigger, "OnTrigger")
END_DATADESC()
void CASW_SynUp_Chatter_Trigger::Spawn( void )
{
BaseClass::Spawn();
InitTrigger();
m_flWait = 1.0f; // always retry (trigger deletes itself when the conversation takes place or could take place)
ASSERTSZ(m_iHealth == 0, "trigger_multiple with health");
SetTouch( &CASW_SynUp_Chatter_Trigger::ChatterTouch );
}
//-----------------------------------------------------------------------------
// Purpose: Touch function. Activates the trigger.
// Input : pOther - The thing that touched us.
//-----------------------------------------------------------------------------
void CASW_SynUp_Chatter_Trigger::ChatterTouch(CBaseEntity *pOther)
{
if (PassesTriggerFilters(pOther) && pOther->Classify() == CLASS_ASW_MARINE)
{
ActivateChatterTrigger( pOther );
}
}
void CASW_SynUp_Chatter_Trigger::ActivateChatterTrigger(CBaseEntity *pActivator)
{
if (GetNextThink() > gpGlobals->curtime)
return; // still waiting for reset time
m_hActivator = pActivator;
m_OnTrigger.FireOutput(m_hActivator, this);
float f = random->RandomFloat();
// pick a nearby marine to say the chatter
if ( ASWGameResource() )
{
CASW_Game_Resource *pGameResource = ASWGameResource();
// count how many are nearby
int iNearby = 0;
for (int i=0;i<pGameResource->GetMaxMarineResources();i++)
{
CASW_Marine_Resource *pMR = pGameResource->GetMarineResource(i);
CASW_Marine *pMarine = pMR ? pMR->GetMarineEntity() : NULL;
if (pMarine && (pActivator->GetAbsOrigin().DistTo(pMarine->GetAbsOrigin()) < 600)
&& pMarine->GetHealth() > 0 && pMarine->GetMarineProfile()
&& (pMarine->GetMarineProfile()->m_VoiceType == ASW_VOICE_VEGAS || pMarine->GetMarineProfile()->m_VoiceType == ASW_VOICE_CRASH))
iNearby++;
}
int iChatter = random->RandomInt(0, iNearby-1);
if (iNearby > 0)
{
for (int i=0;i<pGameResource->GetMaxMarineResources();i++)
{
CASW_Marine_Resource *pMR = pGameResource->GetMarineResource(i);
CASW_Marine *pMarine = pMR ? pMR->GetMarineEntity() : NULL;
if (pMarine && (pActivator->GetAbsOrigin().DistTo(pMarine->GetAbsOrigin()) < 600)
&& pMarine->GetHealth() > 0 && pMarine->GetMarineProfile()
&& (pMarine->GetMarineProfile()->m_VoiceType == ASW_VOICE_VEGAS || pMarine->GetMarineProfile()->m_VoiceType == ASW_VOICE_CRASH))
{
if (iChatter <= 0)
{
if (f <= asw_synup_chatter_chance.GetFloat())
{
CASW_MarineSpeech::StartConversation(CONV_SYNUP, pMarine);
}
else
{
}
m_flWait = 0;
break;
}
iChatter--;
}
}
}
}
if (m_flWait > 0)
{
SetThink( &CASW_SynUp_Chatter_Trigger::MultiWaitOver );
SetNextThink( gpGlobals->curtime + m_flWait );
}
else
{
// we can't just remove (self) here, because this is a touch function
// called while C code is looping through area links...
SetTouch( NULL );
SetNextThink( gpGlobals->curtime + 0.1f );
SetThink( &CASW_SynUp_Chatter_Trigger::SUB_Remove );
}
}
void CASW_SynUp_Chatter_Trigger::MultiWaitOver( void )
{
SetThink( NULL );
}
LINK_ENTITY_TO_CLASS( trigger_asw_marine_position, CASW_Marine_Position_Trigger );
BEGIN_DATADESC( CASW_Marine_Position_Trigger )
DEFINE_KEYFIELD( m_fDesiredFacing, FIELD_FLOAT, "DesiredFacing" ),
DEFINE_KEYFIELD( m_fTolerance, FIELD_FLOAT, "Tolerance" ),
// Function Pointers
DEFINE_FUNCTION(PositionTouch),
DEFINE_FUNCTION(MultiWaitOver ),
// Outputs
DEFINE_OUTPUT(m_OnTrigger, "OnTrigger"),
DEFINE_OUTPUT(m_OnMarineInPosition, "MarineInPosition"),
DEFINE_OUTPUT(m_OnMarineOutOfPosition, "MarineOutOfPosition"),
END_DATADESC()
void CASW_Marine_Position_Trigger::Spawn( void )
{
BaseClass::Spawn();
InitTrigger();
if (m_flWait == 0)
{
m_flWait = 0.2;
}
m_hMarine = NULL;
ASSERTSZ(m_iHealth == 0, "trigger_multiple with health");
SetTouch( &CASW_Marine_Position_Trigger::PositionTouch );
}
//-----------------------------------------------------------------------------
// Purpose: Touch function. Activates the trigger.
// Input : pOther - The thing that touched us.
//-----------------------------------------------------------------------------
void CASW_Marine_Position_Trigger::PositionTouch(CBaseEntity *pOther)
{
if (PassesTriggerFilters(pOther) && pOther->Classify() == CLASS_ASW_MARINE)
{
ActivatePositionTrigger( pOther );
}
}
void CASW_Marine_Position_Trigger::ActivatePositionTrigger(CBaseEntity *pActivator)
{
if (GetNextThink() > gpGlobals->curtime)
return; // still waiting for reset time
m_hActivator = pActivator;
m_OnTrigger.FireOutput(m_hActivator, this);
SetThink( &CASW_Marine_Position_Trigger::MultiWaitOver );
SetNextThink( gpGlobals->curtime + 0.1f );
}
void CASW_Marine_Position_Trigger::MultiWaitOver( void )
{
int iMarines = 0;
for (int i=0;i<m_hTouchingEntities.Count();i++)
{
CBaseEntity *pOther = m_hTouchingEntities[i];
if (pOther && pOther->Classify() == CLASS_ASW_MARINE)
{
iMarines++;
if (!m_hMarine.Get() || m_hMarine.Get() == pOther)
{
float fYawDiff = UTIL_AngleDiff(m_fDesiredFacing, pOther->EyeAngles()[YAW]);
bool bInPosition = fabs(fYawDiff) < m_fTolerance;
if (bInPosition && !m_hMarine.Get())
{
m_OnMarineInPosition.FireOutput(pOther, this);
m_hMarine = pOther;
}
else if (m_hMarine.Get() && !bInPosition)
{
m_OnMarineOutOfPosition.FireOutput(pOther, this);
m_hMarine = NULL;
}
}
}
}
if (iMarines <= 0)
{
SetThink( NULL ); // no more marines inside us, so clear think and allow retrigger
if (m_hMarine.Get())
{
m_OnMarineOutOfPosition.FireOutput(m_hMarine.Get(), this);
m_hMarine = NULL;
}
}
else
{
SetNextThink( gpGlobals->curtime + 0.1f ); // constantly check up on the marines inside us, NOTE: no more OnTriggers will fire while doing this
}
}
// -------------------------------------------------------------
// entity that fires outputs when a marine is healed
// -------------------------------------------------------------
LINK_ENTITY_TO_CLASS( asw_info_heal, CASW_Info_Heal );
BEGIN_DATADESC( CASW_Info_Heal )
DEFINE_OUTPUT( m_MarineHealed, "MarineHealed" ),
END_DATADESC()
void CASW_Info_Heal::Spawn()
{
BaseClass::Spawn();
if ( ASWGameRules() )
{
ASWGameRules()->SetInfoHeal( this );
}
}
void CASW_Info_Heal::OnMarineHealed( CASW_Marine *pHealer, CASW_Marine *pHealed, CASW_Weapon *pHealEquip )
{
m_MarineHealed.FireOutput(pHealed, pHealer);
}
// -------------------------------------------------------------
// entity that hurts the nearest marine, but doesn't kill him
// -------------------------------------------------------------
LINK_ENTITY_TO_CLASS( asw_hurt_nearest_marine, CASW_Hurt_Nearest_Marine );
BEGIN_DATADESC( CASW_Hurt_Nearest_Marine )
DEFINE_INPUTFUNC( FIELD_VOID, "HurtMarine", InputHurtMarine ),
END_DATADESC()
void CASW_Hurt_Nearest_Marine::InputHurtMarine( inputdata_t &inputdata )
{
// find the nearest marine
float distance = 0;
CBaseEntity *pMarine = UTIL_ASW_NearestMarine( GetAbsOrigin(), distance );
if ( pMarine )
{
if ( pMarine->GetHealth() > 35 )
{
pMarine->SetHealth( 35 );
}
CTakeDamageInfo info( this, this, Vector(0,0,0), GetAbsOrigin(), MIN( 5, pMarine->GetHealth() - 1 ), DMG_INFEST );
pMarine->TakeDamage( info );
}
else
{
Msg("asw_hurt_nearest_marine failed to find a nearest marine\n");
}
}
// -------------------------------------------------------------
// entity that sends an output when X marines are past an area
// Requires two triggers, one that fires when a marine is behind us and one when the marine is past us.
// -------------------------------------------------------------
LINK_ENTITY_TO_CLASS( asw_marines_past_area, CASW_Marines_Past_Area );
BEGIN_DATADESC( CASW_Marines_Past_Area )
DEFINE_KEYFIELD( m_iNumMarines, FIELD_INTEGER, "NumMarines" ),
DEFINE_OUTPUT( m_OutputMarinesPast, "MarinesPast" ),
DEFINE_INPUTFUNC( FIELD_VOID, "MarineInFront", InputMarineInFront ),
DEFINE_INPUTFUNC( FIELD_VOID, "MarineBehind", InputMarineBehind ),
END_DATADESC()
IMPLEMENT_AUTO_LIST( IASW_Marines_Past_Area_List );
CASW_Marines_Past_Area::CASW_Marines_Past_Area()
{
m_MarinesPast.Purge();
}
void CASW_Marines_Past_Area::OnMarineKilled( CASW_Marine *pKilledMarine )
{
int nMarineCount = 0;
CASW_Game_Resource *pGameResource = ASWGameResource();
if ( pGameResource )
{
for ( int i = 0; i < pGameResource->GetMaxMarineResources(); i++ )
{
CASW_Marine_Resource* pMR = pGameResource->GetMarineResource( i );
if ( !pMR )
continue;
CASW_Marine *pMarine = pMR->GetMarineEntity();
if ( !pMarine )
continue;
if ( pMarine != pKilledMarine && pMarine->IsAlive() )
{
nMarineCount++;
}
}
}
if ( pKilledMarine && m_MarinesPast.Find( pKilledMarine ) != m_MarinesPast.InvalidIndex() )
{
m_MarinesPast.FindAndRemove( pKilledMarine );
}
if ( ( m_iNumMarines != -1 && m_MarinesPast.Count() >= m_iNumMarines ) ||
( m_iNumMarines == -1 && nMarineCount > 0 && m_MarinesPast.Count() >= nMarineCount ) )
{
m_OutputMarinesPast.FireOutput( this, this );
}
}
void CASW_Marines_Past_Area::InputMarineInFront( inputdata_t &inputdata )
{
int nMarineCount = 0;
bool bAddedMarine = false;
CBaseTrigger *pTrigger = dynamic_cast<CBaseTrigger*>( inputdata.pCaller );
CASW_Game_Resource *pGameResource = ASWGameResource();
if ( pTrigger && pGameResource)
{
// go through all touching marines from the caller
for ( int i=0; i<pGameResource->GetMaxMarineResources(); i++ )
{
CASW_Marine_Resource* pMR = pGameResource->GetMarineResource( i );
if ( !pMR )
continue;
CASW_Marine *pMarine = pMR->GetMarineEntity();
if ( !pMarine )
continue;
if ( pMarine->IsAlive() )
{
nMarineCount++;
}
if ( pTrigger->IsTouching( pMarine ) )
{
if ( pMarine && m_MarinesPast.Find( pMarine ) == m_MarinesPast.InvalidIndex() )
{
m_MarinesPast.AddToTail( pMarine );
bAddedMarine = true;
}
}
}
}
else
{
CASW_Marine *pMarine = dynamic_cast<CASW_Marine*>( inputdata.pActivator );
if ( pMarine && m_MarinesPast.Find( pMarine ) == m_MarinesPast.InvalidIndex() )
{
m_MarinesPast.AddToTail( pMarine );
bAddedMarine = true;
if ( ( m_iNumMarines != -1 && m_MarinesPast.Count() >= m_iNumMarines ) ||
( m_iNumMarines == -1 && nMarineCount > 0 && m_MarinesPast.Count() >= nMarineCount ) )
{
m_OutputMarinesPast.FireOutput( pMarine, this );
}
}
}
if ( bAddedMarine &&
( m_iNumMarines != -1 && m_MarinesPast.Count() >= m_iNumMarines ) ||
( m_iNumMarines == -1 && nMarineCount > 0 && m_MarinesPast.Count() >= nMarineCount ) )
{
m_OutputMarinesPast.FireOutput( inputdata.pActivator, this );
}
}
void CASW_Marines_Past_Area::InputMarineBehind( inputdata_t &inputdata )
{
CBaseTrigger *pTrigger = dynamic_cast<CBaseTrigger*>( inputdata.pCaller );
CASW_Game_Resource *pGameResource = ASWGameResource();
if ( pTrigger && pGameResource)
{
// go through all touching marines from the caller
for ( int i=0; i<pGameResource->GetMaxMarineResources(); i++ )
{
CASW_Marine_Resource* pMR = pGameResource->GetMarineResource( i );
if ( !pMR )
continue;
CASW_Marine *pMarine = pMR->GetMarineEntity();
if ( !pMarine )
continue;
if ( pTrigger->IsTouching( pMarine ) )
{
if ( pMarine && m_MarinesPast.Find( pMarine ) != m_MarinesPast.InvalidIndex() )
{
m_MarinesPast.FindAndRemove( pMarine );
}
}
}
}
else
{
m_MarinesPast.FindAndRemove( inputdata.pActivator );
}
}
// ===========================
LINK_ENTITY_TO_CLASS( trigger_asw_marine_knockback, CASW_Marine_Knockback_Trigger );
BEGIN_DATADESC( CASW_Marine_Knockback_Trigger )
DEFINE_KEYFIELD( m_vecKnockbackDir, FIELD_VECTOR, "knockdir" ),
// Function Pointers
DEFINE_FUNCTION( KnockbackTriggerTouch ),
// Outputs
DEFINE_OUTPUT(m_OnKnockedBack, "OnKnockedBack")
END_DATADESC()
void CASW_Marine_Knockback_Trigger::Spawn( void )
{
BaseClass::Spawn();
InitTrigger();
ASSERTSZ(m_iHealth == 0, "trigger_multiple with health");
SetTouch( &CASW_Marine_Knockback_Trigger::KnockbackTriggerTouch );
}
//-----------------------------------------------------------------------------
// Purpose: Touch function. Activates the trigger.
// Input : pOther - The thing that touched us.
//-----------------------------------------------------------------------------
void CASW_Marine_Knockback_Trigger::KnockbackTriggerTouch(CBaseEntity *pOther)
{
if ( PassesTriggerFilters(pOther) && pOther->Classify() == CLASS_ASW_MARINE )
{
CASW_Marine *pMarine = assert_cast<CASW_Marine*>( pOther );
if ( pMarine )
{
CASW_Melee_Attack *pAttack = pMarine->GetCurrentMeleeAttack();
if ( !pAttack || !( pAttack->m_nAttackID == CASW_Melee_System::s_nKnockdownBackwardAttackID || pAttack->m_nAttackID == CASW_Melee_System::s_nKnockdownForwardAttackID ) )
{
if ( pMarine->GetForcedActionRequest() == 0 )
{
pMarine->Knockdown( this, m_vecKnockbackDir, true );
m_hActivator = pOther;
m_OnKnockedBack.FireOutput(pOther, this);
}
}
}
}
}