mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-31 22:49:19 +00:00
upload "kind" alien swarm
This commit is contained in:
@@ -0,0 +1,753 @@
|
||||
#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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user