mirror of
https://github.com/ValveSoftware/source-sdk-2013.git
synced 2025-04-08 11:01:33 +00:00
npc_missiledefense fix
https://developer.valvesoftware.com/wiki/Npc_missiledefense_Fix Also fixed .fgd file
This commit is contained in:
parent
ec3abfa601
commit
e72e9ae366
2 changed files with 390 additions and 142 deletions
|
@ -70,4 +70,74 @@
|
|||
0 : "No"
|
||||
1 : "Yes"
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
// lightprop("models/editor/spot.mdl") <---- use this once the orientation is unfucked
|
||||
@PointClass base(Targetname, Parentname, Angles) size(-2 -2 -2, 2 2 2) frustum(lightfov,nearz,farz,lightcolor,-1) = env_projectedtexture :
|
||||
"Projected texture entity."
|
||||
[
|
||||
spawnflags(flags) =
|
||||
[
|
||||
1 : "Enabled" : 1
|
||||
]
|
||||
|
||||
target(target_destination) : "target" : : "target"
|
||||
lightfov(float) : "FOV" : "90.0" : "FOV"
|
||||
nearz(float) : "NearZ" : "4.0" : "Near Z for projected texture"
|
||||
farz(float) : "FarZ" : "750.0" : "Far Z for projected texture"
|
||||
|
||||
enableshadows(Choices) : "Enable Shadows" : 0 : "Enables/disables shadows from this projected texture." =
|
||||
[
|
||||
0 : "No"
|
||||
1 : "Yes"
|
||||
]
|
||||
shadowquality(Choices) : "Shadow Quality" : 1 : "Quality of shadows." =
|
||||
[
|
||||
0 : "Low"
|
||||
1 : "High"
|
||||
]
|
||||
lightonlytarget(Choices) : "Light Only Target" : 0 : "Limit flashlight effect to only effect target entity." =
|
||||
[
|
||||
0 : "No"
|
||||
1 : "Yes"
|
||||
]
|
||||
lightworld(Choices) : "Light World" : 1 : "Control whether flashlight effects static world geometry." =
|
||||
[
|
||||
0 : "No"
|
||||
1 : "Yes"
|
||||
]
|
||||
lightcolor(color255) : "Light Color" : "255 255 255 200" : "Light Color RGB-Intensity"
|
||||
cameraspace(integer) : "Camera Space" : 0 : "Angles are interpreted as being relative to camera."
|
||||
texturename(material) : "Texture" : : "path/texture to be projected. Relative to main/materials/"
|
||||
|
||||
// Inputs
|
||||
input TurnOn(void) : "Turn on the texture"
|
||||
input TurnOff(void) : "Turn off the texture"
|
||||
input SetFOV(float) : "Set FOV"
|
||||
]
|
||||
|
||||
@NPCClass base(BaseNPC) studio("models/missile_defense.mdl") = npc_missiledefense : "A turret who takes down rockets from the player"
|
||||
[
|
||||
spawnflags(flags) =
|
||||
[
|
||||
65536 : "Vulnerable to bullets" : 0
|
||||
]
|
||||
|
||||
Health(Integer) : "Health" : 10
|
||||
TurretModel(studio) : "Turret Model" : "models/missile_defense.mdl"
|
||||
GibModel(studio) : "Gib Model" : "models/gibs/manhack_gib01.mdl"
|
||||
FireSound(sound) : "Fire Sound" : "npc/turret_floor/shoot1.wav"
|
||||
RotateSound(sound) : "Rotate Sound": "npc/turret_floor/ping.wav"
|
||||
ReloadSound(sound) : "Reload Sound": "vehicles/tank_readyfire1.wav"
|
||||
|
||||
StartOn(choices) : "Start On" : 1 =
|
||||
[
|
||||
0 : "No"
|
||||
1 : "Yes"
|
||||
]
|
||||
|
||||
// Inputs
|
||||
input TurnOn(void) : "Turn on: Look for enemies"
|
||||
input TurnOff(void) : "Turn off: Stop looking for enemies"
|
||||
]
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
@ -20,6 +21,11 @@
|
|||
#include "engine/IEngineSound.h"
|
||||
#include "ammodef.h"
|
||||
#include "hl2_shareddefs.h"
|
||||
#include "explode.h" //For the explosion
|
||||
#include "effect_dispatch_data.h" //Muzzleflash
|
||||
#include "te_effect_dispatch.h" //Muzzleflash
|
||||
//#include "ai_basenpc.h" //Ignite
|
||||
//#include "decals.h" //Scorch effect
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
@ -27,14 +33,19 @@
|
|||
#define MD_FULLAMMO 50
|
||||
|
||||
|
||||
#define MD_BC_YAW 0
|
||||
#define MD_BC_YAW 1
|
||||
#define MD_BC_PITCH 1
|
||||
#define MD_AP_LGUN 2
|
||||
#define MD_AP_RGUN 1
|
||||
#define MD_GIB_COUNT 4
|
||||
#define MD_GIB_MODEL "models/gibs/missile_defense_gibs.mdl"
|
||||
#define MD_YAW_SPEED 24
|
||||
#define MD_PITCH_SPEED 12
|
||||
//#define MD_GIB_MODEL "models/gibs/missile_defense_gibs.mdl"
|
||||
#define MD_YAW_SPEED 48
|
||||
#define MD_PITCH_SPEED 48
|
||||
|
||||
//------------------------------------
|
||||
// Spawnflags
|
||||
//------------------------------------
|
||||
#define SF_MISSILEDEFENSE_BULLETDMG (1 << 16) //Can be damaged with bullets? N on def
|
||||
|
||||
//=========================================================
|
||||
//=========================================================
|
||||
|
@ -58,17 +69,38 @@ public:
|
|||
|
||||
void Event_Killed( const CTakeDamageInfo &info );
|
||||
int OnTakeDamage_Alive( const CTakeDamageInfo &info );
|
||||
void Explode(const Vector &vecExplosionPos);
|
||||
void Gib();
|
||||
void GetGunAim( Vector *vecAim );
|
||||
void GetGunAim( Vector *vecAim );
|
||||
void TurretTurnOn(void);
|
||||
void DoMuzzleFlash(void);
|
||||
~CNPC_MissileDefense();
|
||||
|
||||
Vector m_vGunAng;
|
||||
int m_iAmmoLoaded;
|
||||
float m_flReloadedTime;
|
||||
|
||||
string_t m_sTurretModel;
|
||||
string_t m_sGibModel;
|
||||
string_t m_sFireSound;
|
||||
string_t m_sRotateSound;
|
||||
string_t m_sReloadSound;
|
||||
|
||||
int m_nStartOn;
|
||||
int m_nHealth;
|
||||
|
||||
// ----------------
|
||||
// Inputs
|
||||
// ----------------
|
||||
void InputTurnOn( inputdata_t &inputdata );
|
||||
void InputTurnOff( inputdata_t &inputdata );
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS( npc_missiledefense, CNPC_MissileDefense );
|
||||
|
||||
|
||||
ConVar sk_missiledefense_health( "sk_missiledefense_health","100");
|
||||
|
||||
//=========================================================
|
||||
//=========================================================
|
||||
BEGIN_DATADESC( CNPC_MissileDefense )
|
||||
|
@ -77,23 +109,162 @@ BEGIN_DATADESC( CNPC_MissileDefense )
|
|||
DEFINE_FIELD( m_flReloadedTime, FIELD_TIME ),
|
||||
DEFINE_FIELD( m_vGunAng, FIELD_VECTOR ),
|
||||
|
||||
DEFINE_KEYFIELD( m_sTurretModel, FIELD_STRING, "TurretModel" ),
|
||||
DEFINE_KEYFIELD( m_sGibModel, FIELD_STRING, "GibModel" ),
|
||||
DEFINE_KEYFIELD( m_sFireSound, FIELD_STRING, "FireSound" ),
|
||||
DEFINE_KEYFIELD( m_sRotateSound, FIELD_STRING, "RotateSound" ),
|
||||
DEFINE_KEYFIELD( m_sReloadSound, FIELD_STRING, "ReloadSound" ),
|
||||
DEFINE_KEYFIELD( m_nHealth, FIELD_INTEGER, "Health" ),
|
||||
|
||||
DEFINE_INPUT( m_nStartOn, FIELD_INTEGER, "StartOn" ),
|
||||
|
||||
DEFINE_FIELD( m_nStartOn, FIELD_BOOLEAN ), //Starts on?
|
||||
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "TurnOn", InputTurnOn ),
|
||||
DEFINE_INPUTFUNC( FIELD_VOID, "TurnOff", InputTurnOff ),
|
||||
|
||||
END_DATADESC()
|
||||
|
||||
//---------------------------------------------------------
|
||||
//---------------------------------------------------------
|
||||
void CNPC_MissileDefense::Precache( void )
|
||||
// ===================
|
||||
// Input Functions
|
||||
// ===================
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Purpose: Enables npc
|
||||
//--------------------------------------------------------------
|
||||
void CNPC_MissileDefense::InputTurnOn( inputdata_t &inputdata )
|
||||
{
|
||||
PrecacheModel("models/missile_defense.mdl");
|
||||
PrecacheModel(MD_GIB_MODEL);
|
||||
|
||||
PrecacheScriptSound( "NPC_MissileDefense.Attack" );
|
||||
PrecacheScriptSound( "NPC_MissileDefense.Reload" );
|
||||
PrecacheScriptSound( "NPC_MissileDefense.Turn" );
|
||||
m_nStartOn = 1;
|
||||
SetThink( &CNPC_MissileDefense::CallNPCThink );
|
||||
SetNextThink( gpGlobals->curtime );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Purpose: Disables npc
|
||||
//--------------------------------------------------------------
|
||||
void CNPC_MissileDefense::InputTurnOff( inputdata_t &inputdata )
|
||||
{
|
||||
m_nStartOn = 0;
|
||||
SetThink(NULL);
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------
|
||||
// Purpose: Precache models and sounds that are going to be used
|
||||
//--------------------------------------------------------------
|
||||
void CNPC_MissileDefense::Precache( void )
|
||||
{
|
||||
PrecacheModel(STRING(m_sTurretModel));
|
||||
PrecacheModel(STRING(m_sGibModel));
|
||||
|
||||
PrecacheScriptSound( STRING(m_sFireSound));
|
||||
PrecacheScriptSound( STRING(m_sRotateSound));
|
||||
PrecacheScriptSound( STRING(m_sReloadSound));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Purpose: Spawns the npc
|
||||
//---------------------------------------------------------
|
||||
void CNPC_MissileDefense::Spawn( void )
|
||||
{
|
||||
Precache();
|
||||
|
||||
//Gets gib model defined by the mapper
|
||||
char *szModel = (char *)STRING( m_sTurretModel );
|
||||
|
||||
SetModel( szModel );
|
||||
|
||||
UTIL_SetSize( this, Vector( -36, -36 , 0 ), Vector( 36, 36, 64 ) );
|
||||
|
||||
SetSolid( SOLID_BBOX );
|
||||
SetMoveType( MOVETYPE_NONE );
|
||||
m_takedamage = DAMAGE_YES;
|
||||
SetBloodColor( DONT_BLEED );
|
||||
|
||||
//Gets health defined by the mapper, if not set, get the cvar one
|
||||
if(!m_nHealth)
|
||||
{
|
||||
m_iHealth = sk_missiledefense_health.GetFloat();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_iHealth = m_nHealth;
|
||||
}
|
||||
|
||||
m_flFieldOfView = VIEW_FIELD_FULL; //0.4f
|
||||
m_NPCState = NPC_STATE_ALERT;
|
||||
CapabilitiesClear();
|
||||
CapabilitiesAdd ( bits_CAP_INNATE_RANGE_ATTACK1 );
|
||||
|
||||
// Hate missiles
|
||||
AddClassRelationship( CLASS_MISSILE, D_HT, 5 );
|
||||
|
||||
m_spawnflags |= SF_NPC_LONG_RANGE;
|
||||
|
||||
m_flReloadedTime = gpGlobals->curtime;
|
||||
|
||||
InitBoneControllers();
|
||||
|
||||
NPCInit();
|
||||
|
||||
SetBoneController( MD_BC_YAW, 0 ); //10
|
||||
SetBoneController( MD_BC_PITCH, 0 );
|
||||
|
||||
SetBodygroup( 1, 0 );
|
||||
SetBodygroup( 2, 0 );
|
||||
SetBodygroup( 3, 0 );
|
||||
SetBodygroup( 4, 0 );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose : Main AI work
|
||||
// Input :
|
||||
// Output :
|
||||
//------------------------------------------------------------------------------
|
||||
void CNPC_MissileDefense::RunAI( void )
|
||||
{
|
||||
|
||||
//If Starts On option isn't activated, disable AI
|
||||
if (m_nStartOn == 0)
|
||||
{
|
||||
SetThink(NULL);
|
||||
}
|
||||
|
||||
// If my enemy is dead clear the memory and reset m_hEnemy
|
||||
if ( ( GetEnemy() != NULL ) && ( GetEnemy()->IsAlive() == false ) )
|
||||
{
|
||||
ClearEnemyMemory();
|
||||
SetEnemy( NULL );
|
||||
}
|
||||
|
||||
if (GetEnemy() == NULL )
|
||||
{
|
||||
// We have to refresh our memories before finding enemies, so
|
||||
// dead enemies are cleared out before new ones are added.
|
||||
GetEnemies()->RefreshMemories();
|
||||
|
||||
GetSenses()->Look( 4092 );
|
||||
SetEnemy( BestEnemy( ) );
|
||||
|
||||
if (GetEnemy() != NULL)
|
||||
{
|
||||
m_iAmmoLoaded = MD_FULLAMMO;
|
||||
m_flReloadedTime = gpGlobals->curtime;
|
||||
}
|
||||
}
|
||||
|
||||
if( m_iAmmoLoaded < 1 && gpGlobals->curtime > m_flReloadedTime )
|
||||
{
|
||||
m_iAmmoLoaded = MD_FULLAMMO;
|
||||
}
|
||||
|
||||
AimGun();
|
||||
FireCannons();
|
||||
SetNextThink( gpGlobals->curtime + 0.05 );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Purpose: Starts aiming the gun
|
||||
//---------------------------------------------------------
|
||||
void CNPC_MissileDefense::GetGunAim( Vector *vecAim )
|
||||
{
|
||||
|
@ -116,7 +287,7 @@ void CNPC_MissileDefense::GetGunAim( Vector *vecAim )
|
|||
#define NOISE 0.035f
|
||||
#define MD_ATTN_CANNON 0.4
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
// Purpose : Open fire on the rocket
|
||||
// Input :
|
||||
// Output :
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -139,8 +310,10 @@ void CNPC_MissileDefense::FireCannons( void )
|
|||
}
|
||||
// ----------------------------------------------
|
||||
// Make sure gun it pointing in right direction
|
||||
//
|
||||
// Disabled, so it makes work fine the turret
|
||||
// ----------------------------------------------
|
||||
Vector vGunDir;
|
||||
/*Vector vGunDir;
|
||||
GetGunAim( &vGunDir );
|
||||
Vector vTargetPos;
|
||||
EnemyShootPosition(GetEnemy(),&vTargetPos);
|
||||
|
@ -152,17 +325,20 @@ void CNPC_MissileDefense::FireCannons( void )
|
|||
if (fDotPr < 0.95)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
|
||||
// ----------------------------------------------
|
||||
// -----------------------------------------------------------------------------------------
|
||||
// Check line of sight
|
||||
// ----------------------------------------------
|
||||
trace_t tr;
|
||||
//
|
||||
// For some unknown reason, with two or more turrets it makes them to do not fire. Disabled.
|
||||
// -----------------------------------------------------------------------------------------
|
||||
/*trace_t tr;
|
||||
AI_TraceLine( GetEnemy()->EyePosition(), GetAbsOrigin(), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr);
|
||||
if (tr.fraction < 1.0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
Vector vecRight;
|
||||
Vector vecDir;
|
||||
|
@ -182,12 +358,15 @@ void CNPC_MissileDefense::FireCannons( void )
|
|||
fSound = true;
|
||||
}
|
||||
|
||||
//Plays the fire sound
|
||||
char *sFireSound = (char *)STRING( m_sFireSound );
|
||||
EmitSound(sFireSound);
|
||||
|
||||
EmitSound( "NPC_MissileDefense.Attack" );
|
||||
DoMuzzleFlash();
|
||||
|
||||
Vector vecGun;
|
||||
QAngle vecAng;
|
||||
|
||||
|
||||
GetAttachment( MD_AP_LGUN, vecGun, vecAng );
|
||||
|
||||
Vector vecTarget;
|
||||
|
@ -218,7 +397,9 @@ void CNPC_MissileDefense::FireCannons( void )
|
|||
if( m_iAmmoLoaded < 1 )
|
||||
{
|
||||
// Incite a reload.
|
||||
EmitSound( "NPC_MissileDefense.Reload" );
|
||||
char *sReloadSound = (char *)STRING( m_sReloadSound );
|
||||
EmitSound(sReloadSound);
|
||||
|
||||
m_flReloadedTime = gpGlobals->curtime + 0.3;
|
||||
return;
|
||||
}
|
||||
|
@ -246,60 +427,34 @@ void CNPC_MissileDefense::FireCannons( void )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
//---------------------------------------------------------
|
||||
void CNPC_MissileDefense::Spawn( void )
|
||||
{
|
||||
Precache();
|
||||
|
||||
SetModel( "models/missile_defense.mdl" );
|
||||
UTIL_SetSize( this, Vector( -36, -36 , 0 ), Vector( 36, 36, 64 ) );
|
||||
|
||||
SetSolid( SOLID_BBOX );
|
||||
SetMoveType( MOVETYPE_NONE );
|
||||
m_takedamage = DAMAGE_YES;
|
||||
SetBloodColor( DONT_BLEED );
|
||||
m_iHealth = 10;
|
||||
m_flFieldOfView = 0.1;
|
||||
m_NPCState = NPC_STATE_NONE;
|
||||
CapabilitiesClear();
|
||||
CapabilitiesAdd ( bits_CAP_INNATE_RANGE_ATTACK1 );
|
||||
|
||||
// Hate missiles
|
||||
AddClassRelationship( CLASS_MISSILE, D_HT, 5 );
|
||||
|
||||
m_spawnflags |= SF_NPC_LONG_RANGE;
|
||||
|
||||
m_flReloadedTime = gpGlobals->curtime;
|
||||
|
||||
InitBoneControllers();
|
||||
|
||||
NPCInit();
|
||||
|
||||
SetBoneController( MD_BC_YAW, 10 );
|
||||
SetBoneController( MD_BC_PITCH, 0 );
|
||||
|
||||
SetBodygroup( 1, 1 );
|
||||
SetBodygroup( 2, 1 );
|
||||
SetBodygroup( 3, 1 );
|
||||
SetBodygroup( 4, 1 );
|
||||
|
||||
m_NPCState = NPC_STATE_IDLE;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
// Purpose : Takes damage only from blasts and bullets
|
||||
// Input :
|
||||
// Output :
|
||||
//------------------------------------------------------------------------------
|
||||
int CNPC_MissileDefense::OnTakeDamage_Alive( const CTakeDamageInfo &info )
|
||||
{
|
||||
|
||||
// Only take blast damage
|
||||
if (info.GetDamageType() & DMG_BLAST )
|
||||
{
|
||||
return BaseClass::OnTakeDamage_Alive( info );
|
||||
}
|
||||
|
||||
//
|
||||
// Bullets can damage it if their flag is checked
|
||||
//
|
||||
else if (info.GetDamageType() & DMG_BULLET)
|
||||
{
|
||||
if(HasSpawnFlags(SF_MISSILEDEFENSE_BULLETDMG))
|
||||
{
|
||||
return BaseClass::OnTakeDamage_Alive( info );
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
|
@ -307,23 +462,52 @@ int CNPC_MissileDefense::OnTakeDamage_Alive( const CTakeDamageInfo &info )
|
|||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
// Purpose : Stuff to do when gets killed
|
||||
// Input :
|
||||
// Output :
|
||||
//------------------------------------------------------------------------------
|
||||
void CNPC_MissileDefense::Event_Killed( const CTakeDamageInfo &info )
|
||||
{
|
||||
StopSound( "NPC_MissileDefense.Turn" );
|
||||
//Set on fire
|
||||
//Ignite( 60, false );
|
||||
|
||||
//Paint me black
|
||||
//Scorch( 8, 50 );
|
||||
|
||||
char *sRotateSound = (char *)STRING( m_sRotateSound );
|
||||
StopSound( sRotateSound );
|
||||
|
||||
CTakeDamageInfo dmgInfo = info;
|
||||
|
||||
Explode( dmgInfo.GetDamagePosition() );
|
||||
|
||||
Gib();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
// Purpose : Makes an explosion
|
||||
// Input :
|
||||
// Output :
|
||||
//------------------------------------------------------------------------------
|
||||
void CNPC_MissileDefense::Explode(const Vector &vecExplosionPos)
|
||||
{
|
||||
//Explodes!
|
||||
ExplosionCreate( vecExplosionPos, vec3_angle, this, 1000, 500.0f,
|
||||
SF_ENVEXPLOSION_NODAMAGE | SF_ENVEXPLOSION_NOSPARKS | SF_ENVEXPLOSION_NODLIGHTS |
|
||||
SF_ENVEXPLOSION_NOSMOKE | SF_ENVEXPLOSION_NOFIREBALLSMOKE, 0 );
|
||||
UTIL_ScreenShake( vecExplosionPos, 25.0, 150.0, 1.0, 750.0f, SHAKE_START );
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose : Gibs and some more effects when death
|
||||
// Input :
|
||||
// Output :
|
||||
//------------------------------------------------------------------------------
|
||||
void CNPC_MissileDefense::Gib(void)
|
||||
{
|
||||
//Gets gib model defined by the mapper
|
||||
char *szModelGib = (char *)STRING( m_sGibModel );
|
||||
|
||||
// Sparks
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
|
@ -333,6 +517,7 @@ void CNPC_MissileDefense::Gib(void)
|
|||
sparkPos.z += random->RandomFloat(-12,12);
|
||||
g_pEffects->Sparks(sparkPos);
|
||||
}
|
||||
|
||||
// Smoke
|
||||
UTIL_Smoke(GetAbsOrigin(), random->RandomInt(10, 15), 10);
|
||||
|
||||
|
@ -343,52 +528,15 @@ void CNPC_MissileDefense::Gib(void)
|
|||
&GetAbsOrigin(), 255, 180, 100, 0, 100, 0.1, 0 );
|
||||
|
||||
// Remove top parts
|
||||
SetBodygroup( 1, 0 );
|
||||
SetBodygroup( 2, 0 );
|
||||
SetBodygroup( 3, 0 );
|
||||
SetBodygroup( 4, 0 );
|
||||
SetBodygroup( 1, 1 );
|
||||
SetBodygroup( 2, 1 );
|
||||
SetBodygroup( 3, 1 );
|
||||
SetBodygroup( 4, 1 );
|
||||
m_takedamage = 0;
|
||||
SetThink(NULL);
|
||||
|
||||
|
||||
// Throw manhackgibs
|
||||
CGib::SpawnSpecificGibs( this, MD_GIB_COUNT, 300, 500, MD_GIB_MODEL);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
// Input :
|
||||
// Output :
|
||||
//------------------------------------------------------------------------------
|
||||
void CNPC_MissileDefense::RunAI( void )
|
||||
{
|
||||
// If my enemy is dead clear the memory and reset m_hEnemy
|
||||
if (GetEnemy() != NULL &&
|
||||
!GetEnemy()->IsAlive())
|
||||
{
|
||||
ClearEnemyMemory();
|
||||
SetEnemy( NULL );
|
||||
}
|
||||
|
||||
if (GetEnemy() == NULL )
|
||||
{
|
||||
GetSenses()->Look( 4092 );
|
||||
SetEnemy( BestEnemy( ) );
|
||||
|
||||
if (GetEnemy() != NULL)
|
||||
{
|
||||
m_iAmmoLoaded = MD_FULLAMMO;
|
||||
m_flReloadedTime = gpGlobals->curtime;
|
||||
}
|
||||
}
|
||||
|
||||
if( m_iAmmoLoaded < 1 && gpGlobals->curtime > m_flReloadedTime )
|
||||
{
|
||||
m_iAmmoLoaded = MD_FULLAMMO;
|
||||
}
|
||||
|
||||
AimGun();
|
||||
FireCannons();
|
||||
SetNextThink( gpGlobals->curtime + 0.05 );
|
||||
CGib::SpawnSpecificGibs( this, MD_GIB_COUNT, 300, 500, szModelGib);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -405,7 +553,7 @@ void CNPC_MissileDefense::EnemyShootPosition(CBaseEntity* pEnemy, Vector *vPosit
|
|||
}
|
||||
|
||||
*vPosition = pEnemy->GetAbsOrigin();
|
||||
|
||||
|
||||
// Add prediction but prevents us from flipping around as enemy approaches us
|
||||
float flDist = (pEnemy->GetAbsOrigin() - GetAbsOrigin()).Length();
|
||||
Vector vPredVel = pEnemy->GetSmoothedVelocity() * 0.5;
|
||||
|
@ -416,7 +564,7 @@ void CNPC_MissileDefense::EnemyShootPosition(CBaseEntity* pEnemy, Vector *vPosit
|
|||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Purpose :
|
||||
// Purpose : Moves the turret to aim the rocket
|
||||
// Input :
|
||||
// Output :
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -424,13 +572,14 @@ void CNPC_MissileDefense::AimGun( void )
|
|||
{
|
||||
if (GetEnemy() == NULL)
|
||||
{
|
||||
StopSound( "NPC_MissileDefense.Turn" );
|
||||
char *sRotateSound = (char *)STRING( m_sRotateSound );
|
||||
StopSound( sRotateSound );
|
||||
return;
|
||||
}
|
||||
|
||||
Vector forward, right, up;
|
||||
AngleVectors( GetLocalAngles(), &forward, &right, &up );
|
||||
|
||||
|
||||
// Get gun attachment points
|
||||
Vector vBasePos;
|
||||
QAngle vBaseAng;
|
||||
|
@ -450,37 +599,49 @@ void CNPC_MissileDefense::AimGun( void )
|
|||
QAngle angles;
|
||||
VectorAngles(vecOut, angles);
|
||||
|
||||
if (angles.y > 180)
|
||||
angles.y = angles.y - 360;
|
||||
if (angles.y < -180)
|
||||
angles.y = angles.y + 360;
|
||||
if (angles.x > 180)
|
||||
angles.x = angles.x - 360;
|
||||
if (angles.x < -180)
|
||||
angles.x = angles.x + 360;
|
||||
//Pitch for the cannons
|
||||
if (angles.x != m_vGunAng.x){
|
||||
float flDir = m_vGunAng.x > angles.x ? 1 : -1;
|
||||
angles.x += 0.1 * MD_PITCH_SPEED * flDir;
|
||||
|
||||
float flOldX = m_vGunAng.x;
|
||||
float flOldY = m_vGunAng.y;
|
||||
SetBoneController(1, angles.x - m_vGunAng.x);
|
||||
}
|
||||
|
||||
if (angles.x > m_vGunAng.x)
|
||||
m_vGunAng.x = MIN( angles.x, m_vGunAng.x + MD_PITCH_SPEED );
|
||||
if (angles.x < m_vGunAng.x)
|
||||
m_vGunAng.x = MAX( angles.x, m_vGunAng.x - MD_PITCH_SPEED );
|
||||
if (angles.y > m_vGunAng.y)
|
||||
m_vGunAng.y = MIN( angles.y, m_vGunAng.y + MD_YAW_SPEED );
|
||||
if (angles.y < m_vGunAng.y)
|
||||
m_vGunAng.y = MAX( angles.y, m_vGunAng.y - MD_YAW_SPEED );
|
||||
//Yaw for the cannons
|
||||
if (angles.y != m_vGunAng.y){
|
||||
float flDir = m_vGunAng.y > angles.y ? 1 : -1;
|
||||
float flDist = fabs(m_vGunAng.y - angles.y);
|
||||
|
||||
m_vGunAng.y = SetBoneController( MD_BC_YAW, m_vGunAng.y );
|
||||
m_vGunAng.x = SetBoneController( MD_BC_PITCH, m_vGunAng.x );
|
||||
if (flDist > 180){
|
||||
flDist = 360 - flDist;
|
||||
flDir =- flDir;
|
||||
}
|
||||
|
||||
if (flOldX != m_vGunAng.x || flOldY != m_vGunAng.y)
|
||||
angles.y += 0.1 * MD_YAW_SPEED * flDir;
|
||||
|
||||
if (angles.y < 0)
|
||||
angles.y += 360;
|
||||
else if (angles.y >= 360)
|
||||
angles.y -= 360;
|
||||
|
||||
if(flDist < (0.05 * MD_YAW_SPEED))
|
||||
angles.y = m_vGunAng.y;
|
||||
|
||||
SetBoneController(0, angles.y - m_vGunAng.y);
|
||||
}
|
||||
|
||||
//Plays movement sound
|
||||
if (angles.x != m_vGunAng.x || angles.y != m_vGunAng.y)
|
||||
{
|
||||
EmitSound( "NPC_MissileDefense.Turn" );
|
||||
//EmitSound( "NPC_FloorTurret.Alarm" );
|
||||
char *sRotateSound = (char *)STRING( m_sRotateSound );
|
||||
EmitSound( sRotateSound );
|
||||
}
|
||||
else
|
||||
{
|
||||
StopSound( "NPC_MissileDefense.Turn" );
|
||||
//StopSound( "NPC_FloorTurret.Alarm" );
|
||||
char *sRotateSound = (char *)STRING( m_sRotateSound );
|
||||
StopSound( sRotateSound );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -492,5 +653,22 @@ void CNPC_MissileDefense::AimGun( void )
|
|||
//------------------------------------------------------------------------------
|
||||
CNPC_MissileDefense::~CNPC_MissileDefense(void)
|
||||
{
|
||||
StopSound( "NPC_MissileDefense.Turn" );
|
||||
char *sRotateSound = (char *)STRING( m_sRotateSound );
|
||||
StopSound( sRotateSound );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Puts a muzzleflash on the cannons
|
||||
//-----------------------------------------------------------------------------
|
||||
void CNPC_MissileDefense::DoMuzzleFlash( void )
|
||||
{
|
||||
CEffectData data, data2;
|
||||
data.m_nEntIndex = entindex();
|
||||
data2.m_nEntIndex = entindex();
|
||||
data.m_nAttachmentIndex = LookupAttachment( "R_Gun_AtchPnt" );
|
||||
data2.m_nAttachmentIndex = LookupAttachment( "L_Gun_AtchPnt" );
|
||||
data.m_flScale = 1.0f;
|
||||
data2.m_flScale = 1.0f;
|
||||
DispatchEffect( "ChopperMuzzleFlash", data );
|
||||
DispatchEffect( "ChopperMuzzleFlash", data2 );
|
||||
}
|
Loading…
Reference in a new issue