mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-09 10:19:38 +00:00
1
This commit is contained in:
@@ -0,0 +1,188 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
#include "cbase.h"
|
||||
|
||||
#include "tf_player.h"
|
||||
#include "tf_projectile_arrow.h"
|
||||
#include "tf_weapon_grenade_pipebomb.h"
|
||||
#include "archer_proxy.h"
|
||||
|
||||
LINK_ENTITY_TO_CLASS( archer_proxy, CTFArcherProxy );
|
||||
|
||||
|
||||
ConVar tf_archer_proxy_fire_rate( "tf_archer_proxy_fire_rate", "1", FCVAR_CHEAT );
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
void CTFArcherProxy::Precache( void )
|
||||
{
|
||||
// don't need to precache, since player does this for us
|
||||
BaseClass::Precache();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
void CTFArcherProxy::Spawn( void )
|
||||
{
|
||||
BaseClass::Spawn();
|
||||
|
||||
SetThink( &CTFArcherProxy::Update );
|
||||
SetNextThink( gpGlobals->curtime + RandomFloat( 0.1, 1.0f ) * tf_archer_proxy_fire_rate.GetFloat() );
|
||||
|
||||
m_state = HIDDEN;
|
||||
m_timer.Invalidate();
|
||||
AddEffects( EF_NODRAW );
|
||||
m_homePos = GetAbsOrigin();
|
||||
|
||||
SetModel( "models/weapons/w_models/w_arrow.mdl" );
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------
|
||||
CTFPlayer *CTFArcherProxy::SelectTarget( void )
|
||||
{
|
||||
// collect everyone
|
||||
CUtlVector< CTFPlayer * > playerVector;
|
||||
CollectPlayers( &playerVector, TF_TEAM_RED, COLLECT_ONLY_LIVING_PLAYERS );
|
||||
CollectPlayers( &playerVector, TF_TEAM_BLUE, COLLECT_ONLY_LIVING_PLAYERS, APPEND_PLAYERS );
|
||||
|
||||
CTFPlayer *newVictim = NULL;
|
||||
float victimRangeSq = FLT_MAX;
|
||||
trace_t result;
|
||||
|
||||
for( int i=0; i<playerVector.Count(); ++i )
|
||||
{
|
||||
float rangeSq = ( playerVector[i]->GetAbsOrigin() - GetAbsOrigin() ).LengthSqr();
|
||||
if ( rangeSq < victimRangeSq )
|
||||
{
|
||||
UTIL_TraceLine( GetAbsOrigin(), playerVector[i]->EyePosition(), MASK_SOLID, this, COLLISION_GROUP_DEBRIS, &result );
|
||||
|
||||
if ( !result.DidHit() )
|
||||
{
|
||||
newVictim = playerVector[i];
|
||||
victimRangeSq = rangeSq;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return newVictim;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
void CTFArcherProxy::Update( void )
|
||||
{
|
||||
SetNextThink( gpGlobals->curtime );
|
||||
|
||||
switch( m_state )
|
||||
{
|
||||
case HIDDEN:
|
||||
m_state = EMERGE;
|
||||
RemoveEffects( EF_NODRAW );
|
||||
m_timer.Start( 1.0f );
|
||||
break;
|
||||
|
||||
case EMERGE:
|
||||
m_state = AIM_AND_FIRE;
|
||||
m_timer.Start( 1.0f );
|
||||
break;
|
||||
|
||||
case AIM_AND_FIRE:
|
||||
{
|
||||
CTFPlayer *target = SelectTarget();
|
||||
if ( target )
|
||||
{
|
||||
Vector to = target->GetAbsOrigin() - GetAbsOrigin();
|
||||
QAngle angles;
|
||||
VectorAngles( to, angles );
|
||||
|
||||
SetAbsAngles( angles );
|
||||
|
||||
if ( m_timer.IsElapsed() )
|
||||
{
|
||||
ShootArrowAt( target );
|
||||
// ShootGrenadeAt( target );
|
||||
|
||||
m_state = HIDE;
|
||||
m_timer.Start( 1.0f );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case HIDE:
|
||||
if ( m_timer.IsElapsed() )
|
||||
{
|
||||
m_state = HIDDEN;
|
||||
AddEffects( EF_NODRAW );
|
||||
m_timer.Start( 1.0f );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
void CTFArcherProxy::ShootArrowAt( CBaseEntity *target )
|
||||
{
|
||||
if ( !target )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Vector to = target->EyePosition() - GetAbsOrigin();
|
||||
to.NormalizeInPlace();
|
||||
|
||||
QAngle angles;
|
||||
VectorAngles( to, angles );
|
||||
|
||||
const float arrowSpeed = 2600.0f;
|
||||
const float arrowGravity = 0.1f;
|
||||
CTFProjectile_Arrow *arrow = CTFProjectile_Arrow::Create( GetAbsOrigin() + 20.0f * to, angles, arrowSpeed, arrowGravity, TF_PROJECTILE_ARROW, this, this );
|
||||
if ( arrow )
|
||||
{
|
||||
arrow->SetLauncher( this );
|
||||
arrow->SetCritical( false );
|
||||
arrow->SetDamage( 100.0f );
|
||||
|
||||
EmitSound( "Weapon_CompoundBow.Single" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
void CTFArcherProxy::ShootGrenadeAt( CBaseEntity *target )
|
||||
{
|
||||
if ( !target )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Vector to = target->EyePosition() - GetAbsOrigin();
|
||||
to.NormalizeInPlace();
|
||||
|
||||
QAngle angles;
|
||||
VectorAngles( to, angles );
|
||||
|
||||
|
||||
float launchSpeed = 1000.0f;
|
||||
Vector velocity = ( to * launchSpeed ) + ( Vector( 0, 0, 1.0f ) * 200.0f );
|
||||
AngularImpulse angVelocity = AngularImpulse( 600, random->RandomInt( -1200, 1200 ), 0 );
|
||||
|
||||
CTFGrenadePipebombProjectile *grenade = static_cast< CTFGrenadePipebombProjectile * >( CBaseEntity::CreateNoSpawn( "tf_projectile_pipe", GetAbsOrigin(), angles, NULL ) );
|
||||
if ( grenade )
|
||||
{
|
||||
// Set the pipebomb mode before calling spawn, so the model & associated vphysics get setup properly
|
||||
grenade->SetPipebombMode();
|
||||
DispatchSpawn( grenade );
|
||||
|
||||
const int damage = 100;
|
||||
const float radius = 100.0f;
|
||||
|
||||
grenade->InitGrenade( velocity, angVelocity, NULL, damage, radius );
|
||||
grenade->m_flFullDamage = grenade->GetDamage();
|
||||
grenade->ApplyLocalAngularVelocityImpulse( angVelocity );
|
||||
grenade->SetCritical( false );
|
||||
grenade->SetLauncher( this );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user