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.
159 lines
4.7 KiB
159 lines
4.7 KiB
#include "cbase.h" |
|
#include "asw_shareddefs.h" |
|
#include "asw_jump_trigger.h" |
|
#include "asw_drone_advanced.h" |
|
#include "asw_util_shared.h" |
|
#include "asw_marine.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
LINK_ENTITY_TO_CLASS( trigger_asw_jump, CASW_Jump_Trigger ); |
|
|
|
|
|
BEGIN_DATADESC( CASW_Jump_Trigger ) |
|
DEFINE_FUNCTION( VolumeTouch ), |
|
DEFINE_KEYFIELD( m_JumpDestName, FIELD_STRING, "JumpDestName" ), |
|
DEFINE_KEYFIELD( m_fMinMarineDistance, FIELD_STRING, "MinMarineDist" ), |
|
DEFINE_KEYFIELD( m_bClearOrders, FIELD_BOOLEAN, "ClearOrders" ), |
|
DEFINE_KEYFIELD( m_bCheckEnemyDirection, FIELD_BOOLEAN, "CheckEnemyDirection" ), |
|
DEFINE_KEYFIELD( m_bOneJumpPerAlien, FIELD_BOOLEAN, "CheckTriggerJumped" ), |
|
DEFINE_KEYFIELD( m_bRetryFailedJumps, FIELD_BOOLEAN, "RetryFailedJumps" ), |
|
DEFINE_KEYFIELD( m_bForceJump, FIELD_BOOLEAN, "ForceJump" ), |
|
DEFINE_KEYFIELD( m_ForceAngle, FIELD_VECTOR, "ForceAngle" ), |
|
DEFINE_KEYFIELD( m_fForceSpeed, FIELD_FLOAT, "ForceSpeed" ), |
|
DEFINE_ARRAY( m_vecJumpDestination, FIELD_FLOAT, ASW_MAX_JUMP_DESTS ), // NOTE: MUST BE IN LOCAL SPACE, NOT POSITION_VECTOR!!! (see CBaseEntity::Restore) |
|
END_DATADESC() |
|
|
|
CASW_Jump_Trigger::CASW_Jump_Trigger() |
|
{ |
|
|
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Touch function. Activates the trigger. |
|
// Input : pOther - The thing that touched us. |
|
//----------------------------------------------------------------------------- |
|
void CASW_Jump_Trigger::VolumeTouch(CBaseEntity *pOther) |
|
{ |
|
CASW_Alien_Jumper *pJumper = dynamic_cast<CASW_Alien_Jumper*>(pOther); |
|
if (pJumper && ( pJumper->CapabilitiesGet() & bits_CAP_MOVE_JUMP ) |
|
&& !pJumper->IsJumping() && ( pJumper->GetFlags() & FL_ONGROUND ) ) |
|
|
|
{ |
|
bool bJumped = false; |
|
|
|
if ( m_bForceJump && m_fForceSpeed != 0 ) |
|
{ |
|
Vector vecVelocity; |
|
AngleVectors( m_ForceAngle, &vecVelocity ); |
|
vecVelocity *= m_fForceSpeed; |
|
bJumped = pJumper->DoForcedJump( vecVelocity ); |
|
} |
|
else |
|
{ |
|
// pick a jump dest |
|
int iChosen = random->RandomInt(0, m_iNumJumpDests-1); |
|
if (!ReasonableJump(pJumper, iChosen)) |
|
{ |
|
// the dest was blocked, so we're going to just go and try all our dests |
|
iChosen = -1; |
|
for (int i=0;i<m_iNumJumpDests;i++) |
|
{ |
|
if (ReasonableJump(pJumper, i)) |
|
{ |
|
iChosen = i; |
|
break; |
|
} |
|
} |
|
if (iChosen == -1) // all dests blocked |
|
return; |
|
} |
|
// don't jump if a marine is too near us |
|
float marine_distance = 0; |
|
CASW_Marine *pMarine = UTIL_ASW_NearestMarine(pJumper->GetAbsOrigin(), marine_distance); |
|
if (pMarine && marine_distance < m_fMinMarineDistance) |
|
{ |
|
return; |
|
} |
|
|
|
bJumped = pJumper->DoJumpTo(m_vecJumpDestination[iChosen]); |
|
|
|
if ( !bJumped ) |
|
{ |
|
bool bHasOrders = ( pJumper->m_AlienOrders != AOT_None ); |
|
if ( m_bRetryFailedJumps && !bHasOrders ) // don't stop and wait for retry if we're still moving somewhere |
|
pJumper->WaitAndRetryJump( m_vecJumpDestination[iChosen] ); |
|
} |
|
} |
|
|
|
// start to jump |
|
pJumper->m_bTriggerJumped = true; |
|
|
|
// clear the jumpers previous orders |
|
if ( bJumped && m_bClearOrders ) |
|
{ |
|
pJumper->SetAlienOrders(AOT_None, vec3_origin, NULL); |
|
} |
|
} |
|
} |
|
|
|
bool CASW_Jump_Trigger::ReasonableJump(CASW_Alien_Jumper *pJumper, int iJumpNum) |
|
{ |
|
if (!pJumper) |
|
return false; |
|
|
|
if (m_bOneJumpPerAlien && pJumper->m_bTriggerJumped) |
|
return false; |
|
|
|
if (!pJumper->GetEnemy()) // let him jump if he has no enemy |
|
return true; |
|
|
|
if (!m_bCheckEnemyDirection) // let him jump if he doesn't care about the direction of his enemy |
|
return true; |
|
|
|
// if he does have an enemy, check it's in the direction of the jump |
|
float fEnemyYaw = UTIL_VecToYaw(pJumper->GetEnemy()->GetAbsOrigin() - pJumper->GetAbsOrigin()); |
|
float fJumpYaw = UTIL_VecToYaw(m_vecJumpDestination[iJumpNum] - pJumper->GetAbsOrigin()); |
|
|
|
return fabs(UTIL_AngleDiff(fEnemyYaw, fJumpYaw)) < 90; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Called when spawning, after keyvalues have been handled. |
|
//----------------------------------------------------------------------------- |
|
void CASW_Jump_Trigger::Spawn( void ) |
|
{ |
|
BaseClass::Spawn(); |
|
|
|
InitTrigger(); |
|
|
|
if ( m_flWait == 0 ) |
|
{ |
|
m_flWait = 0.2; |
|
} |
|
|
|
ASSERTSZ( m_iHealth == 0, "trigger_asw_jump with health" ); |
|
|
|
// find the target this use area is attached to |
|
m_iNumJumpDests = 0; |
|
|
|
CBaseEntity *pEnt = gEntList.FindEntityByName( NULL, m_JumpDestName, NULL ); |
|
while ( pEnt ) |
|
{ |
|
m_vecJumpDestination[m_iNumJumpDests] = pEnt->GetAbsOrigin(); |
|
m_iNumJumpDests++; |
|
|
|
pEnt = gEntList.FindEntityByName(pEnt, m_JumpDestName, NULL); |
|
} |
|
|
|
if ( m_iNumJumpDests > 0 || m_bForceJump ) |
|
{ |
|
SetTouch( &CASW_Jump_Trigger::VolumeTouch ); |
|
} |
|
else |
|
{ |
|
Msg("Error: trigger_asw_jump has no valid destinations.\n"); |
|
} |
|
//Assert(!m_hUseTarget); |
|
} |