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,815 @@
|
||||
#include "cbase.h"
|
||||
#include "asw_alien_jumper.h"
|
||||
|
||||
#include "ai_route.h"
|
||||
#include "ai_hint.h"
|
||||
#include "ai_memory.h"
|
||||
#include "ai_moveprobe.h"
|
||||
#include "npcevent.h"
|
||||
#include "IEffects.h"
|
||||
#include "ndebugoverlay.h"
|
||||
#include "soundent.h"
|
||||
#include "soundenvelope.h"
|
||||
#include "ai_squad.h"
|
||||
#include "ai_network.h"
|
||||
#include "ai_pathfinder.h"
|
||||
#include "ai_navigator.h"
|
||||
#include "ai_senses.h"
|
||||
#include "npc_rollermine.h"
|
||||
#include "ai_blended_movement.h"
|
||||
#include "physics_prop_ragdoll.h"
|
||||
#include "iservervehicle.h"
|
||||
#include "player_pickup.h"
|
||||
#include "props.h"
|
||||
#include "antlion_dust.h"
|
||||
#include "decals.h"
|
||||
#include "prop_combine_ball.h"
|
||||
#include "eventqueue.h"
|
||||
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
ConVar asw_test_new_alien_jump( "asw_test_new_alien_jump", "1", FCVAR_ARCHIVE );
|
||||
extern ConVar asw_debug_aliens;
|
||||
extern ConVar sv_gravity;
|
||||
|
||||
int AE_ASW_ALIEN_START_JUMP;
|
||||
int AE_ASW_ALIEN_GLIDE;
|
||||
|
||||
#define ANTLION_JUMP_MIN 128.0f
|
||||
|
||||
#define ANTLION_JUMP_MAX_RISE 512.0f
|
||||
#define ANTLION_JUMP_MAX 1024.0f
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
SQUAD_SLOT_ALIEN_JUMP = LAST_SHARED_SQUADSLOT,
|
||||
};
|
||||
|
||||
int ACT_ASW_ALIEN_JUMP_START;
|
||||
int ACT_ASW_ALIEN_LAND;
|
||||
|
||||
|
||||
CASW_Alien_Jumper::CASW_Alien_Jumper()
|
||||
{
|
||||
m_flJumpTime = 0.0f;
|
||||
m_flNextJumpPushTime = 0.0f;
|
||||
|
||||
m_vecLastJumpAttempt.Init();
|
||||
m_vecSavedJump.Init();
|
||||
m_bForcedStuckJump = false;
|
||||
}
|
||||
|
||||
LINK_ENTITY_TO_CLASS( asw_alien_jumper, CASW_Alien_Jumper );
|
||||
|
||||
BEGIN_DATADESC( CASW_Alien_Jumper )
|
||||
DEFINE_FIELD( m_flJumpTime, FIELD_TIME ),
|
||||
DEFINE_FIELD( m_vecSavedJump, FIELD_VECTOR ),
|
||||
DEFINE_FIELD( m_vecLastJumpAttempt, FIELD_VECTOR ),
|
||||
DEFINE_FIELD( m_bDisableJump, FIELD_BOOLEAN ),
|
||||
DEFINE_FIELD( m_flNextJumpPushTime, FIELD_TIME ),
|
||||
DEFINE_FIELD( m_bForcedStuckJump, FIELD_BOOLEAN ),
|
||||
DEFINE_FIELD( m_bTriggerJumped, FIELD_BOOLEAN ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "EnableJump", InputEnableJump ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "DisableJump", InputDisableJump ),
|
||||
END_DATADESC()
|
||||
|
||||
void CASW_Alien_Jumper::Spawn()
|
||||
{
|
||||
BaseClass::Spawn();
|
||||
|
||||
CapabilitiesAdd( bits_CAP_MOVE_JUMP );
|
||||
m_bDisableJump = false;
|
||||
}
|
||||
|
||||
void CASW_Alien_Jumper::ManageFleeCapabilities( bool bEnable )
|
||||
{
|
||||
if ( bEnable == false )
|
||||
{
|
||||
//Remove the jump capabilty when we build our route.
|
||||
//We'll enable it back again after the route has been built.
|
||||
CapabilitiesRemove( bits_CAP_MOVE_JUMP );
|
||||
|
||||
if ( HasSpawnFlags( SF_ANTLION_USE_GROUNDCHECKS ) == false )
|
||||
CapabilitiesRemove( bits_CAP_SKIP_NAV_GROUND_CHECK );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_bDisableJump == false )
|
||||
CapabilitiesAdd( bits_CAP_MOVE_JUMP );
|
||||
|
||||
if ( HasSpawnFlags( SF_ANTLION_USE_GROUNDCHECKS ) == false )
|
||||
CapabilitiesAdd( bits_CAP_SKIP_NAV_GROUND_CHECK );
|
||||
}
|
||||
}
|
||||
|
||||
void CASW_Alien_Jumper::HandleAnimEvent( animevent_t *pEvent )
|
||||
{
|
||||
int nEvent = pEvent->Event();
|
||||
|
||||
if ( nEvent == AE_ASW_ALIEN_START_JUMP )
|
||||
{
|
||||
StartJump();
|
||||
return;
|
||||
}
|
||||
else if ( nEvent == AE_ASW_ALIEN_GLIDE )
|
||||
{
|
||||
SetActivity(ACT_GLIDE);
|
||||
return;
|
||||
}
|
||||
|
||||
BaseClass::HandleAnimEvent( pEvent );
|
||||
}
|
||||
|
||||
bool CASW_Alien_Jumper::IsUnusableNode(int iNodeID, CAI_Hint *pHint)
|
||||
{
|
||||
bool iBaseReturn = BaseClass::IsUnusableNode( iNodeID, pHint );
|
||||
|
||||
if ( asw_test_new_alien_jump.GetBool() == 0 )
|
||||
return iBaseReturn;
|
||||
|
||||
CAI_Node *pNode = GetNavigator()->GetNetwork()->GetNode( iNodeID );
|
||||
|
||||
if ( pNode )
|
||||
{
|
||||
if ( pNode->IsLocked() )
|
||||
return true;
|
||||
}
|
||||
|
||||
return iBaseReturn;
|
||||
}
|
||||
|
||||
void CASW_Alien_Jumper::LockJumpNode( void )
|
||||
{
|
||||
if ( HasSpawnFlags( SF_ANTLION_USE_GROUNDCHECKS ) == false )
|
||||
return;
|
||||
|
||||
if ( GetNavigator()->GetPath() == NULL )
|
||||
return;
|
||||
|
||||
if ( asw_test_new_alien_jump.GetBool() == false )
|
||||
return;
|
||||
|
||||
AI_Waypoint_t *pWaypoint = GetNavigator()->GetPath()->GetCurWaypoint();
|
||||
|
||||
while ( pWaypoint )
|
||||
{
|
||||
AI_Waypoint_t *pNextWaypoint = pWaypoint->GetNext();
|
||||
if ( pNextWaypoint && pNextWaypoint->NavType() == NAV_JUMP && pWaypoint->iNodeID != NO_NODE )
|
||||
{
|
||||
CAI_Node *pNode = GetNavigator()->GetNetwork()->GetNode( pWaypoint->iNodeID );
|
||||
|
||||
if ( pNode )
|
||||
{
|
||||
//NDebugOverlay::Box( pNode->GetOrigin(), Vector( -16, -16, -16 ), Vector( 16, 16, 16 ), 255, 0, 0, 0, 2 );
|
||||
pNode->Lock( 0.5f );
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pWaypoint = pWaypoint->GetNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CASW_Alien_Jumper::OnObstructionPreSteer( AILocalMoveGoal_t *pMoveGoal, float distClear, AIMoveResult_t *pResult )
|
||||
{
|
||||
bool iBaseReturn = BaseClass::OnObstructionPreSteer( pMoveGoal, distClear, pResult );
|
||||
|
||||
if ( asw_test_new_alien_jump.GetBool() == false )
|
||||
return iBaseReturn;
|
||||
|
||||
if ( HasSpawnFlags( SF_ANTLION_USE_GROUNDCHECKS ) == false )
|
||||
return iBaseReturn;
|
||||
|
||||
CAI_BaseNPC *pBlocker = pMoveGoal->directTrace.pObstruction->MyNPCPointer();
|
||||
|
||||
// push other jumpers out of the way?
|
||||
if ( pBlocker && pBlocker->Classify() == CLASS_ASW_DRONE )
|
||||
{
|
||||
// HACKHACK
|
||||
CASW_Alien_Jumper *pJumper = dynamic_cast< CASW_Alien_Jumper * > ( pBlocker );
|
||||
|
||||
if ( pJumper )
|
||||
{
|
||||
if ( pJumper->AllowedToBePushed() == true && GetEnemy() == NULL )
|
||||
{
|
||||
//NDebugOverlay::Box( pAntlion->GetAbsOrigin(), GetHullMins(), GetHullMaxs(), 0, 255, 0, 0, 2 );
|
||||
pJumper->GetMotor()->SetIdealYawToTarget( WorldSpaceCenter() );
|
||||
pJumper->SetSchedule( SCHED_MOVE_AWAY );
|
||||
pJumper->m_flNextJumpPushTime = gpGlobals->curtime + 2.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return iBaseReturn;
|
||||
}
|
||||
|
||||
bool CASW_Alien_Jumper::AllowedToBePushed( void )
|
||||
{
|
||||
if ( IsMoving() == false
|
||||
&& GetNavType() != NAV_JUMP && m_flNextJumpPushTime <= gpGlobals->curtime )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void CASW_Alien_Jumper::StartTask( const Task_t *pTask )
|
||||
{
|
||||
switch ( pTask->iTask )
|
||||
{
|
||||
case TASK_ASW_ALIEN_FACE_JUMP:
|
||||
break;
|
||||
|
||||
case TASK_ASW_ALIEN_JUMP:
|
||||
|
||||
if ( CheckLanding() )
|
||||
{
|
||||
TaskComplete();
|
||||
}
|
||||
break;
|
||||
case TASK_ASW_ALIEN_RETRY_JUMP:
|
||||
{
|
||||
if (!DoJumpTo(m_vecLastJumpAttempt))
|
||||
WaitAndRetryJump(m_vecLastJumpAttempt);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
BaseClass::StartTask( pTask );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CASW_Alien_Jumper::RunTask( const Task_t *pTask )
|
||||
{
|
||||
switch ( pTask->iTask )
|
||||
{
|
||||
case TASK_ASW_ALIEN_FACE_JUMP:
|
||||
{
|
||||
Vector jumpDir = m_vecSavedJump;
|
||||
VectorNormalize( jumpDir );
|
||||
|
||||
QAngle jumpAngles;
|
||||
VectorAngles( jumpDir, jumpAngles );
|
||||
|
||||
GetMotor()->SetIdealYawAndUpdate( jumpAngles[YAW], AI_KEEP_YAW_SPEED );
|
||||
SetTurnActivity();
|
||||
|
||||
if ( abs(GetMotor()->DeltaIdealYaw()) < 2 )
|
||||
{
|
||||
//Msg("Alien jumping: jumpyaw=%f delta=%f ang.y=%f\n",
|
||||
//jumpAngles[YAW], GetMotor()->DeltaIdealYaw(), GetLocalAngles().y);
|
||||
TaskComplete();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case TASK_ASW_ALIEN_JUMP:
|
||||
|
||||
if ( CheckLanding() )
|
||||
{
|
||||
TaskComplete();
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
BaseClass::RunTask( pTask );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Purpose: Returns true if a reasonable jumping distance
|
||||
bool CASW_Alien_Jumper::IsJumpLegal( const Vector &startPos, const Vector &apex, const Vector &endPos ) const
|
||||
{
|
||||
const float MAX_JUMP_RISE = 512;
|
||||
//const float MIN_JUMP_RISE = 16;
|
||||
const float MAX_JUMP_DROP = 512;
|
||||
const float MAX_JUMP_DISTANCE = 1024;
|
||||
const float MIN_JUMP_DISTANCE = 128;
|
||||
|
||||
// make sure we don't do really flat jumps
|
||||
//float fHeight = (apex.z - startPos.z);
|
||||
//Msg("checking legality of jump with height %f\n", fHeight);
|
||||
//if ((apex.z - startPos.z) < 10 || fHeight != 0)
|
||||
//return false;
|
||||
|
||||
//Adrian: Don't try to jump if my destination is right next to me.
|
||||
if ( ( endPos - GetAbsOrigin()).Length() < MIN_JUMP_DISTANCE )
|
||||
return false;
|
||||
|
||||
if ( HasSpawnFlags( SF_ANTLION_USE_GROUNDCHECKS ) && asw_test_new_alien_jump.GetBool() == true )
|
||||
{
|
||||
trace_t tr;
|
||||
AI_TraceHull( endPos, endPos, GetHullMins(), GetHullMaxs(), MASK_NPCSOLID, this, COLLISION_GROUP_NONE, &tr );
|
||||
|
||||
if ( tr.m_pEnt )
|
||||
{
|
||||
CAI_BaseNPC *pBlocker = tr.m_pEnt->MyNPCPointer();
|
||||
|
||||
if ( pBlocker && pBlocker->Classify() == CLASS_ASW_DRONE )
|
||||
{
|
||||
// HACKHACK - push other jumpers out of the way
|
||||
CASW_Alien_Jumper *pJumper = dynamic_cast< CASW_Alien_Jumper * > ( pBlocker );
|
||||
|
||||
if ( pJumper )
|
||||
{
|
||||
if ( pJumper->AllowedToBePushed() == true )
|
||||
{
|
||||
// NDebugOverlay::Line( GetAbsOrigin(), endPos, 255, 0, 0, 0, 2 );
|
||||
// NDebugOverlay::Box( pAntlion->GetAbsOrigin(), GetHullMins(), GetHullMaxs(), 0, 0, 255, 0, 2 );
|
||||
pJumper->GetMotor()->SetIdealYawToTarget( endPos );
|
||||
pJumper->SetSchedule( SCHED_MOVE_AWAY );
|
||||
pJumper->m_flNextJumpPushTime = gpGlobals->curtime + 2.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return BaseClass::IsJumpLegal( startPos, apex, endPos, MAX_JUMP_RISE, MAX_JUMP_DROP, MAX_JUMP_DISTANCE );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Output : Returns true on success, false on failure.
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CASW_Alien_Jumper::ShouldJump( void )
|
||||
{
|
||||
if ( GetEnemy() == NULL )
|
||||
return false;
|
||||
|
||||
// don't jump if we're stunned
|
||||
if (m_bElectroStunned)
|
||||
return false;
|
||||
|
||||
//Too soon to try to jump
|
||||
if ( m_flJumpTime > gpGlobals->curtime )
|
||||
return false;
|
||||
|
||||
// only jump if you're on the ground
|
||||
if (!(GetFlags() & FL_ONGROUND) || GetNavType() == NAV_JUMP )
|
||||
return false;
|
||||
|
||||
// Don't jump if I'm not allowed
|
||||
if ( ( CapabilitiesGet() & bits_CAP_MOVE_JUMP ) == false )
|
||||
return false;
|
||||
|
||||
Vector vEnemyForward, vForward;
|
||||
|
||||
GetEnemy()->GetVectors( &vEnemyForward, NULL, NULL );
|
||||
GetVectors( &vForward, NULL, NULL );
|
||||
|
||||
float flDot = DotProduct( vForward, vEnemyForward );
|
||||
|
||||
if ( flDot < 0.5f )
|
||||
flDot = 0.5f;
|
||||
|
||||
Vector vecPredictedPos;
|
||||
|
||||
//Get our likely position in two seconds
|
||||
UTIL_PredictedPosition( GetEnemy(), flDot * 2.5f, &vecPredictedPos );
|
||||
|
||||
// Don't jump if we're already near the target
|
||||
if ( ( GetAbsOrigin() - vecPredictedPos ).LengthSqr() < (512*512) )
|
||||
return false;
|
||||
|
||||
//Don't retest if the target hasn't moved enough
|
||||
//FIXME: Check your own distance from last attempt as well
|
||||
if ( ( ( m_vecLastJumpAttempt - vecPredictedPos ).LengthSqr() ) < (128*128) )
|
||||
{
|
||||
m_flJumpTime = gpGlobals->curtime + random->RandomFloat( 1.0f, 2.0f );
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector targetDir = ( vecPredictedPos - GetAbsOrigin() );
|
||||
|
||||
float flDist = VectorNormalize( targetDir );
|
||||
|
||||
// don't jump at target it it's very close
|
||||
if (flDist < ANTLION_JUMP_MIN)
|
||||
return false;
|
||||
|
||||
Vector targetPos = vecPredictedPos + ( targetDir * (GetHullWidth()*4.0f) );
|
||||
|
||||
// Try the jump
|
||||
AIMoveTrace_t moveTrace;
|
||||
GetMoveProbe()->MoveLimit( NAV_JUMP, GetAbsOrigin(), targetPos, MASK_NPCSOLID, GetNavTargetEntity(), &moveTrace );
|
||||
|
||||
//See if it succeeded
|
||||
if ( IsMoveBlocked( moveTrace.fStatus ) )
|
||||
{
|
||||
if ( asw_debug_aliens.GetInt() == 2 )
|
||||
{
|
||||
NDebugOverlay::Box( targetPos, GetHullMins(), GetHullMaxs(), 255, 0, 0, 0, 5 );
|
||||
NDebugOverlay::Line( GetAbsOrigin(), targetPos, 255, 0, 0, 0, 5 );
|
||||
}
|
||||
|
||||
m_flJumpTime = gpGlobals->curtime + random->RandomFloat( 1.0f, 2.0f );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( asw_debug_aliens.GetInt() == 2 )
|
||||
{
|
||||
NDebugOverlay::Box( targetPos, GetHullMins(), GetHullMaxs(), 0, 255, 0, 0, 5 );
|
||||
NDebugOverlay::Line( GetAbsOrigin(), targetPos, 0, 255, 0, 0, 5 );
|
||||
}
|
||||
|
||||
//Save this jump in case the next time fails
|
||||
m_vecSavedJump = moveTrace.vJumpVelocity;
|
||||
m_vecLastJumpAttempt = targetPos;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// note: mostly copied from shover parent (no clean way to call up and extend), with the jump part added
|
||||
int CASW_Alien_Jumper::SelectCombatSchedule( void )
|
||||
{
|
||||
//Physics target
|
||||
if ( HasCondition( COND_ALIEN_SHOVER_PHYSICS_TARGET ) )
|
||||
{
|
||||
//Msg("Alien shoving physics object from selectcombatschedule\n");
|
||||
return SCHED_ALIEN_SHOVER_PHYSICS_ATTACK;
|
||||
}
|
||||
|
||||
// Attack if we can
|
||||
if ( HasCondition(COND_CAN_MELEE_ATTACK1) )
|
||||
return SCHED_MELEE_ATTACK1;
|
||||
|
||||
// See if we can bash what's in our way, or roar
|
||||
if ( HasCondition( COND_ENEMY_UNREACHABLE ) )
|
||||
{
|
||||
int iUnreach = SelectUnreachableSchedule();
|
||||
if (iUnreach != -1)
|
||||
return iUnreach;
|
||||
}
|
||||
|
||||
// Try to jump
|
||||
if ( HasCondition( COND_ASW_ALIEN_CAN_JUMP ) )
|
||||
return SCHED_ASW_ALIEN_JUMP;
|
||||
|
||||
return BaseClass::BaseClass::SelectSchedule();
|
||||
}
|
||||
|
||||
void CASW_Alien_Jumper::StartJump( void )
|
||||
{
|
||||
if ( m_bForcedStuckJump == false )
|
||||
{
|
||||
//Must be jumping at an enemy
|
||||
if ( GetEnemy() == NULL )
|
||||
return;
|
||||
|
||||
//Don't jump if we're not on the ground
|
||||
if ( ( GetFlags() & FL_ONGROUND ) == false )
|
||||
return;
|
||||
}
|
||||
|
||||
//Take us off the ground
|
||||
SetGroundEntity( NULL );
|
||||
//Msg("Drone doing jump vec %f %f %f\n", m_vecSavedJump.x, m_vecSavedJump.y, m_vecSavedJump.z);
|
||||
SetAbsVelocity( m_vecSavedJump );
|
||||
|
||||
m_bForcedStuckJump = false;
|
||||
|
||||
//Setup our jump time so that we don't try it again too soon
|
||||
m_flJumpTime = gpGlobals->curtime + random->RandomInt( 2, 6 );
|
||||
}
|
||||
|
||||
|
||||
// Purpose: Monitor the antlion's jump to play the proper landing sequence
|
||||
bool CASW_Alien_Jumper::CheckLanding( void )
|
||||
{
|
||||
trace_t tr;
|
||||
Vector testPos;
|
||||
|
||||
//Amount of time to predict forward
|
||||
const float timeStep = 0.1f;
|
||||
|
||||
//Roughly looks one second into the future
|
||||
testPos = GetAbsOrigin() + ( GetAbsVelocity() * timeStep );
|
||||
testPos[2] -= ( 0.5 * sv_gravity.GetFloat() * GetGravity() * timeStep * timeStep);
|
||||
|
||||
if ( asw_debug_aliens.GetInt() == 2 )
|
||||
{
|
||||
NDebugOverlay::Line( GetAbsOrigin(), testPos, 255, 0, 0, 0, 0.5f );
|
||||
NDebugOverlay::Cross3D( m_vecSavedJump, -Vector(2,2,2), Vector(2,2,2), 0, 255, 0, true, 0.5f );
|
||||
}
|
||||
|
||||
// Look below
|
||||
AI_TraceHull( GetAbsOrigin(), testPos, NAI_Hull::Mins( GetHullType() ), NAI_Hull::Maxs( GetHullType() ), MASK_NPCSOLID, this, COLLISION_GROUP_NONE, &tr );
|
||||
|
||||
//See if we're about to contact, or have already contacted the ground
|
||||
if ( ( tr.fraction != 1.0f ) || ( GetFlags() & FL_ONGROUND ) )
|
||||
{
|
||||
int sequence = SelectWeightedSequence( (Activity)ACT_ASW_ALIEN_LAND );
|
||||
|
||||
if ( GetSequence() != sequence )
|
||||
{
|
||||
VacateStrategySlot();
|
||||
SetIdealActivity( (Activity) ACT_ASW_ALIEN_LAND );
|
||||
|
||||
CreateDust( false );
|
||||
EmitSound( "ASW_Drone.Land" );
|
||||
|
||||
// asw todo: make the alien attack here?
|
||||
//if ( GetEnemy() && GetEnemy()->IsPlayer() )
|
||||
//{
|
||||
//CBasePlayer *pPlayer = ToBasePlayer( GetEnemy() );
|
||||
|
||||
//if ( pPlayer && pPlayer->IsInAVehicle() == false )
|
||||
//MeleeAttack( ANTLION_MELEE1_RANGE, sk_antlion_swipe_damage.GetFloat(), QAngle( 4.0f, 0.0f, 0.0f ), Vector( -250.0f, 1.0f, 1.0f ) );
|
||||
//}
|
||||
|
||||
SetAbsVelocity( GetAbsVelocity() * 0.33f );
|
||||
return false;
|
||||
}
|
||||
|
||||
return IsActivityFinished();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CASW_Alien_Jumper::CreateDust( bool placeDecal )
|
||||
{
|
||||
trace_t tr;
|
||||
AI_TraceLine( GetAbsOrigin()+Vector(0,0,1), GetAbsOrigin()-Vector(0,0,64), MASK_SOLID_BRUSHONLY | CONTENTS_PLAYERCLIP | CONTENTS_MONSTERCLIP, this, COLLISION_GROUP_NONE, &tr );
|
||||
|
||||
if ( tr.fraction < 1.0f )
|
||||
{
|
||||
surfacedata_t *pdata = physprops->GetSurfaceData( tr.surface.surfaceProps );
|
||||
|
||||
if ( ( pdata->game.material == CHAR_TEX_CONCRETE ) ||
|
||||
( pdata->game.material == CHAR_TEX_DIRT ) ||
|
||||
( pdata->game.material == CHAR_TEX_SAND ) )
|
||||
{
|
||||
UTIL_CreateAntlionDust( tr.endpos + Vector(0,0,24), GetAbsAngles() );
|
||||
|
||||
if ( placeDecal )
|
||||
{
|
||||
UTIL_DecalTrace( &tr, "Antlion.Unburrow" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CASW_Alien_Jumper::BuildScheduleTestBits( void )
|
||||
{
|
||||
//Don't allow any modifications when scripted
|
||||
if ( m_NPCState == NPC_STATE_SCRIPT )
|
||||
return;
|
||||
|
||||
BaseClass::BuildScheduleTestBits();
|
||||
|
||||
//Make sure we interrupt a run schedule if we can jump
|
||||
if ( IsCurSchedule(SCHED_CHASE_ENEMY) && GetNavType() == NAV_GROUND )
|
||||
{
|
||||
SetCustomInterruptCondition( COND_ASW_ALIEN_CAN_JUMP );
|
||||
SetCustomInterruptCondition( COND_ENEMY_UNREACHABLE );
|
||||
}
|
||||
|
||||
|
||||
//Interrupt any schedule unless already fleeing, burrowing, burrowed, or unburrowing.
|
||||
if(!IsCurSchedule(SCHED_ASW_ALIEN_JUMP) &&
|
||||
( GetFlags() & FL_ONGROUND ) )
|
||||
{
|
||||
// Only do these if not jumping as well
|
||||
if (!IsCurSchedule(SCHED_ASW_ALIEN_JUMP))
|
||||
{
|
||||
if ( GetEnemy() == NULL )
|
||||
{
|
||||
SetCustomInterruptCondition( COND_HEAR_PHYSICS_DANGER );
|
||||
}
|
||||
//if ( GetNavType() != NAV_JUMP )
|
||||
//SetCustomInterruptCondition( COND_ANTLION_RECEIVED_ORDERS );
|
||||
}
|
||||
|
||||
//SetCustomInterruptCondition( COND_ANTLION_ON_NPC );
|
||||
}
|
||||
}
|
||||
|
||||
void CASW_Alien_Jumper::PrescheduleThink( void )
|
||||
{
|
||||
//New Enemy? Try to jump at him.
|
||||
if ( HasCondition( COND_NEW_ENEMY ) )
|
||||
{
|
||||
m_flJumpTime = 0.0f;
|
||||
}
|
||||
|
||||
if ( ShouldJump() )
|
||||
{
|
||||
SetCondition( COND_ASW_ALIEN_CAN_JUMP );
|
||||
}
|
||||
else
|
||||
{
|
||||
ClearCondition( COND_ASW_ALIEN_CAN_JUMP );
|
||||
}
|
||||
|
||||
BaseClass::PrescheduleThink();
|
||||
}
|
||||
|
||||
void CASW_Alien_Jumper::InputDisableJump( inputdata_t &inputdata )
|
||||
{
|
||||
m_bDisableJump = true;
|
||||
CapabilitiesRemove( bits_CAP_MOVE_JUMP );
|
||||
}
|
||||
|
||||
void CASW_Alien_Jumper::InputEnableJump( inputdata_t &inputdata )
|
||||
{
|
||||
m_bDisableJump = false;
|
||||
CapabilitiesAdd( bits_CAP_MOVE_JUMP );
|
||||
}
|
||||
|
||||
bool CASW_Alien_Jumper::IsJumping()
|
||||
{
|
||||
return IsCurSchedule(SCHED_ASW_ALIEN_JUMP);
|
||||
}
|
||||
|
||||
// make this alien jump off the head of the ent he's standing on
|
||||
bool CASW_Alien_Jumper::DoJumpOffHead()
|
||||
{
|
||||
//Too soon to try to jump
|
||||
if ( m_flJumpTime > gpGlobals->curtime )
|
||||
return false;
|
||||
|
||||
if (!(GetGroundEntity()) || GetNavType() == NAV_JUMP )
|
||||
return false;
|
||||
|
||||
// force this drone to have jumping capabilities
|
||||
m_bDisableJump = false;
|
||||
CapabilitiesAdd( bits_CAP_MOVE_JUMP );
|
||||
|
||||
//Vector vecDest = RandomVector(-1, 1);
|
||||
//vecDest.z = 0;
|
||||
//vecDest *= random->RandomFloat(30, 100);
|
||||
Vector vecDest;
|
||||
AngleVectors(GetAbsAngles(), &vecDest);
|
||||
vecDest *= 200.0f;
|
||||
vecDest += GetAbsOrigin();
|
||||
|
||||
// Try the jump
|
||||
AIMoveTrace_t moveTrace;
|
||||
GetMoveProbe()->MoveLimit( NAV_JUMP, GetAbsOrigin(), vecDest, MASK_NPCSOLID, NULL, &moveTrace );
|
||||
|
||||
//See if it succeeded
|
||||
if ( IsMoveBlocked( moveTrace.fStatus ) )
|
||||
{
|
||||
if ( asw_debug_aliens.GetInt() == 2 )
|
||||
{
|
||||
NDebugOverlay::Box( vecDest, GetHullMins(), GetHullMaxs(), 255, 0, 0, 0, 5 );
|
||||
NDebugOverlay::Line( GetAbsOrigin(), vecDest, 255, 0, 0, 0, 5 );
|
||||
}
|
||||
|
||||
m_flJumpTime = gpGlobals->curtime + random->RandomFloat( 1.0f, 2.0f );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( asw_debug_aliens.GetInt() == 2 )
|
||||
{
|
||||
NDebugOverlay::Box( vecDest, GetHullMins(), GetHullMaxs(), 0, 255, 0, 0, 5 );
|
||||
NDebugOverlay::Line( GetAbsOrigin(), vecDest, 0, 255, 0, 0, 5 );
|
||||
}
|
||||
|
||||
//Save this jump in case the next time fails
|
||||
m_vecSavedJump = moveTrace.vJumpVelocity;
|
||||
m_vecLastJumpAttempt = vecDest;
|
||||
SetSchedule(SCHED_ASW_ALIEN_JUMP);
|
||||
m_bForcedStuckJump = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CASW_Alien_Jumper::DoJumpTo(Vector &vecDest)
|
||||
{
|
||||
//Too soon to try to jump
|
||||
if ( m_flJumpTime > gpGlobals->curtime )
|
||||
return false;
|
||||
|
||||
// only jump if you're on the ground
|
||||
if (!(GetFlags() & FL_ONGROUND) || GetNavType() == NAV_JUMP )
|
||||
return false;
|
||||
|
||||
// Don't jump if I'm not allowed
|
||||
if ( ( CapabilitiesGet() & bits_CAP_MOVE_JUMP ) == false )
|
||||
return false;
|
||||
|
||||
// Try the jump
|
||||
AIMoveTrace_t moveTrace;
|
||||
GetMoveProbe()->MoveLimit( NAV_JUMP, GetAbsOrigin(), vecDest, MASK_NPCSOLID, NULL, &moveTrace );
|
||||
|
||||
//See if it succeeded
|
||||
if ( IsMoveBlocked( moveTrace.fStatus ) )
|
||||
{
|
||||
if ( asw_debug_aliens.GetInt() == 2 )
|
||||
{
|
||||
NDebugOverlay::Box( vecDest, GetHullMins(), GetHullMaxs(), 255, 0, 0, 0, 5 );
|
||||
NDebugOverlay::Line( GetAbsOrigin(), vecDest, 255, 0, 0, 0, 5 );
|
||||
}
|
||||
|
||||
m_flJumpTime = gpGlobals->curtime + random->RandomFloat( 1.0f, 2.0f );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( asw_debug_aliens.GetInt() == 2 )
|
||||
{
|
||||
NDebugOverlay::Box( vecDest, GetHullMins(), GetHullMaxs(), 0, 255, 0, 0, 5 );
|
||||
NDebugOverlay::Line( GetAbsOrigin(), vecDest, 0, 255, 0, 0, 5 );
|
||||
}
|
||||
|
||||
//Save this jump in case the next time fails
|
||||
m_vecSavedJump = moveTrace.vJumpVelocity;
|
||||
m_vecLastJumpAttempt = vecDest;
|
||||
SetSchedule(SCHED_ASW_ALIEN_JUMP);
|
||||
m_bForcedStuckJump = true;
|
||||
|
||||
//Msg("Drone saving jump vec %f %f %f\n", m_vecSavedJump.x, m_vecSavedJump.y, m_vecSavedJump.z);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CASW_Alien_Jumper::DoForcedJump( Vector &vecVelocity )
|
||||
{
|
||||
//Too soon to try to jump
|
||||
if ( m_flJumpTime > gpGlobals->curtime )
|
||||
return false;
|
||||
|
||||
// only jump if you're on the ground
|
||||
if (!(GetFlags() & FL_ONGROUND) || GetNavType() == NAV_JUMP )
|
||||
return false;
|
||||
|
||||
// Don't jump if I'm not allowed
|
||||
if ( ( CapabilitiesGet() & bits_CAP_MOVE_JUMP ) == false )
|
||||
return false;
|
||||
|
||||
m_vecSavedJump = vecVelocity;
|
||||
m_vecLastJumpAttempt = GetAbsOrigin() + vecVelocity * 100;
|
||||
SetSchedule(SCHED_ASW_ALIEN_JUMP);
|
||||
m_bForcedStuckJump = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CASW_Alien_Jumper::WaitAndRetryJump(Vector &vecDest)
|
||||
{
|
||||
m_vecLastJumpAttempt = vecDest;
|
||||
SetSchedule(SCHED_ASW_WAIT_AND_RETRY_JUMP);
|
||||
}
|
||||
|
||||
AI_BEGIN_CUSTOM_NPC( asw_alien_jumper, CASW_Alien_Jumper )
|
||||
//Conditions
|
||||
DECLARE_CONDITION( COND_ASW_ALIEN_CAN_JUMP )
|
||||
//Squad slots
|
||||
DECLARE_SQUADSLOT( SQUAD_SLOT_ALIEN_JUMP )
|
||||
//Tasks
|
||||
DECLARE_TASK( TASK_ASW_ALIEN_JUMP )
|
||||
DECLARE_TASK( TASK_ASW_ALIEN_FACE_JUMP )
|
||||
DECLARE_TASK( TASK_ASW_ALIEN_RETRY_JUMP )
|
||||
//Activities
|
||||
DECLARE_ACTIVITY( ACT_ASW_ALIEN_JUMP_START )
|
||||
DECLARE_ACTIVITY( ACT_ASW_ALIEN_LAND )
|
||||
//Events
|
||||
DECLARE_ANIMEVENT( AE_ASW_ALIEN_START_JUMP )
|
||||
DECLARE_ANIMEVENT( AE_ASW_ALIEN_GLIDE )
|
||||
|
||||
//Schedules
|
||||
|
||||
//==================================================
|
||||
// Jump
|
||||
//==================================================
|
||||
|
||||
DEFINE_SCHEDULE
|
||||
(
|
||||
SCHED_ASW_ALIEN_JUMP,
|
||||
|
||||
" Tasks"
|
||||
" TASK_STOP_MOVING 0"
|
||||
" TASK_ASW_ALIEN_FACE_JUMP 0"
|
||||
" TASK_PLAY_SEQUENCE ACTIVITY:ACT_ASW_ALIEN_JUMP_START"
|
||||
" TASK_ASW_ALIEN_JUMP 0"
|
||||
""
|
||||
" Interrupts"
|
||||
" COND_TASK_FAILED"
|
||||
)
|
||||
|
||||
DEFINE_SCHEDULE
|
||||
(
|
||||
SCHED_ASW_WAIT_AND_RETRY_JUMP,
|
||||
|
||||
" Tasks"
|
||||
" TASK_STOP_MOVING 0"
|
||||
" TASK_WAIT_RANDOM 1"
|
||||
" TASK_ASW_ALIEN_RETRY_JUMP 0"
|
||||
""
|
||||
" Interrupts"
|
||||
" COND_TASK_FAILED"
|
||||
)
|
||||
AI_END_CUSTOM_NPC()
|
||||
Reference in New Issue
Block a user