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.
304 lines
9.4 KiB
304 lines
9.4 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: A stationary gun that players can man |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
|
|
#include "cbase.h" |
|
#include "tf_obj_manned_plasmagun.h" |
|
#include "ammodef.h" |
|
#include "plasmaprojectile.h" |
|
#include "SoundEmitterSystem/isoundemittersystembase.h" |
|
#include "tf_gamerules.h" |
|
|
|
#define MANNED_PLASMAGUN_MINS Vector(-20, -20, 0) |
|
#define MANNED_PLASMAGUN_MAXS Vector( 20, 20, 55) |
|
#define MANNED_PLASMAGUN_ALIEN_MODEL "models/objects/obj_manned_plasmagun.mdl" |
|
#define MANNED_PLASMAGUN_HUMAN_MODEL "models/objects/human_obj_manned_plasmagun.mdl" |
|
|
|
#define MANNED_PLASMAGUN_RECHARGE_TIME 0.2 |
|
#define MANNED_PLASMAGUN_IDLE_RECHARGE_TIME 0.1 |
|
|
|
#define MANNED_PLASMAGUN_IDLE_TIME 2.0 |
|
|
|
#if !defined( CLIENT_DLL ) |
|
BEGIN_DATADESC( CObjectMannedPlasmagun ) |
|
|
|
DEFINE_THINKFUNC( RechargeThink ), |
|
|
|
END_DATADESC() |
|
#endif |
|
|
|
IMPLEMENT_NETWORKCLASS_ALIASED( ObjectMannedPlasmagun, DT_ObjectMannedPlasmagun ) |
|
|
|
BEGIN_NETWORK_TABLE( CObjectMannedPlasmagun, DT_ObjectMannedPlasmagun ) |
|
#if !defined( CLIENT_DLL ) |
|
SendPropTime( SENDINFO( m_flNextIdleTime ) ), |
|
SendPropInt( SENDINFO( m_bFiringLeft ), 1, SPROP_UNSIGNED ), |
|
|
|
SendPropInt( SENDINFO( m_nNextThinkTick ) ), |
|
#else |
|
RecvPropTime( RECVINFO( m_flNextIdleTime ) ), |
|
RecvPropInt( RECVINFO( m_bFiringLeft ) ), |
|
|
|
RecvPropInt ( RECVINFO( m_nNextThinkTick ) ), |
|
|
|
#endif |
|
END_NETWORK_TABLE() |
|
|
|
|
|
BEGIN_PREDICTION_DATA( CObjectMannedPlasmagun ) |
|
DEFINE_PRED_FIELD_TOL( m_flNextIdleTime, FIELD_FLOAT, FTYPEDESC_INSENDTABLE, TD_MSECTOLERANCE ), |
|
DEFINE_PRED_FIELD( m_bFiringLeft, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ), |
|
|
|
DEFINE_PRED_FIELD( m_nNextThinkTick, FIELD_INTEGER, FTYPEDESC_INSENDTABLE ), |
|
|
|
// DEFINE_FIELD( m_nRightBarrelAttachment, FIELD_INTEGER ), |
|
DEFINE_FIELD( m_nMaxAmmoCount, FIELD_INTEGER ), |
|
|
|
END_PREDICTION_DATA() |
|
|
|
LINK_ENTITY_TO_CLASS(obj_manned_plasmagun, CObjectMannedPlasmagun); |
|
PRECACHE_REGISTER(obj_manned_plasmagun); |
|
|
|
// CVars |
|
ConVar obj_manned_plasmagun_health( "obj_manned_plasmagun_health","100", FCVAR_REPLICATED, "Manned Plasmagun health" ); |
|
ConVar obj_manned_plasmagun_range_def( "obj_manned_plasmagun_range_def","1000", FCVAR_REPLICATED, "Defensive Manned Plasmagun range" ); |
|
ConVar obj_manned_plasmagun_range_off( "obj_manned_plasmagun_range_off","1000", FCVAR_REPLICATED, "Offensive Manned Plasmagun range" ); |
|
ConVar obj_manned_plasmagun_damage( "obj_manned_plasmagun_damage","20", FCVAR_REPLICATED, "Manned Plasmagun damage" ); |
|
ConVar obj_manned_plasmagun_radius( "obj_manned_plasmagun_radius","128", FCVAR_REPLICATED, "Manned Plasmagun explosive radius" ); |
|
ConVar obj_manned_plasmagun_clip( "obj_manned_plasmagun_clip","35", FCVAR_REPLICATED, "Manned Plasmagun's clip size" ); |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CObjectMannedPlasmagun::CObjectMannedPlasmagun() |
|
{ |
|
m_bFiringLeft = true; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CObjectMannedPlasmagun::Precache() |
|
{ |
|
BaseClass::Precache(); |
|
PrecacheModel( MANNED_PLASMAGUN_ALIEN_MODEL ); |
|
PrecacheModel( MANNED_PLASMAGUN_HUMAN_MODEL ); |
|
|
|
PrecacheScriptSound( "ObjectMannedPlasmagun.Fire" ); |
|
|
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CObjectMannedPlasmagun::SetupTeamModel( void ) |
|
{ |
|
// FIXME: When adding in build animations here, make sure C_ObjectBaseMannedGun::OnDataChanged |
|
// does the right thing on the client!! |
|
if ( GetTeamNumber() == TEAM_HUMANS ) |
|
{ |
|
SetMovementStyle( MOVEMENT_STYLE_BARREL_PIVOT ); |
|
SetModel( MANNED_PLASMAGUN_HUMAN_MODEL ); |
|
} |
|
else |
|
{ |
|
SetMovementStyle( MOVEMENT_STYLE_STANDARD ); |
|
SetModel( MANNED_PLASMAGUN_ALIEN_MODEL ); |
|
} |
|
|
|
// Call this to get all the attachment points happy |
|
OnModelSelected(); |
|
|
|
// Get our extra barrel |
|
m_nRightBarrelAttachment = LookupAttachment( "barrelR" ); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CObjectMannedPlasmagun::Spawn() |
|
{ |
|
Precache(); |
|
|
|
SetSolid( SOLID_BBOX ); |
|
|
|
SetSize( MANNED_PLASMAGUN_MINS, MANNED_PLASMAGUN_MAXS ); |
|
SetHealth( obj_manned_plasmagun_health.GetInt() ); |
|
|
|
SetNextThink( gpGlobals->curtime + MANNED_PLASMAGUN_IDLE_RECHARGE_TIME ); |
|
|
|
SetType( OBJ_MANNED_PLASMAGUN ); |
|
|
|
m_nAmmoCount = m_nMaxAmmoCount = obj_manned_plasmagun_clip.GetInt(); |
|
m_flNextAttack = gpGlobals->curtime; |
|
m_nAmmoType = GetAmmoDef()->Index( "RechargeEnergy" ); |
|
SetThink( RechargeThink ); |
|
|
|
BaseClass::Spawn(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Finished the build |
|
//----------------------------------------------------------------------------- |
|
void CObjectMannedPlasmagun::FinishedBuilding( void ) |
|
{ |
|
BaseClass::FinishedBuilding(); |
|
|
|
CalculateMaxRange( obj_manned_plasmagun_range_def.GetFloat(), obj_manned_plasmagun_range_off.GetFloat() ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Recharge think... |
|
//----------------------------------------------------------------------------- |
|
void CObjectMannedPlasmagun::RechargeThink( ) |
|
{ |
|
// Prevent manned guns from deteriorating |
|
ResetDeteriorationTime(); |
|
|
|
float flNextRechargeTime = MANNED_PLASMAGUN_RECHARGE_TIME; |
|
/* |
|
ROBIN: Remove idle recharging for now |
|
|
|
if (gpGlobals->curtime >= m_flNextIdleTime) |
|
flNextRechargeTime = MANNED_PLASMAGUN_IDLE_RECHARGE_TIME; |
|
else |
|
flNextRechargeTime = MANNED_PLASMAGUN_RECHARGE_TIME; |
|
*/ |
|
|
|
// If I'm EMPed, slow the recharge rate down |
|
if ( HasPowerup(POWERUP_EMP) ) |
|
{ |
|
flNextRechargeTime *= 1.5; |
|
} |
|
SetNextThink( gpGlobals->curtime + flNextRechargeTime ); |
|
|
|
// I can't do anything if I'm not active |
|
if ( !ShouldBeActive() ) |
|
return; |
|
|
|
if (m_nAmmoCount < m_nMaxAmmoCount) |
|
{ |
|
++m_nAmmoCount; |
|
} |
|
else |
|
{ |
|
// No need to think when it's full |
|
SetNextThink( gpGlobals->curtime + 5.0f ); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Plasma sentrygun's fire |
|
//----------------------------------------------------------------------------- |
|
void CObjectMannedPlasmagun::Fire( ) |
|
{ |
|
if (m_flNextAttack > gpGlobals->curtime) |
|
return; |
|
|
|
// Because the plasma sentrygun always thinks it has ammo (see below) |
|
// we might not have ammo here, in which case we should just abort. |
|
if ( !m_nAmmoCount ) |
|
return; |
|
|
|
// Make sure we think soon enough in case of firing... |
|
float flNextRecharge = gpGlobals->curtime + (HasPowerup(POWERUP_EMP) ? MANNED_PLASMAGUN_RECHARGE_TIME * 1.5 : MANNED_PLASMAGUN_RECHARGE_TIME); |
|
SetNextThink( gpGlobals->curtime + flNextRecharge ); |
|
|
|
// We have to flush the bone cache because it's possible that only the bone controllers |
|
// have changed since the bonecache was generated, and bone controllers aren't checked. |
|
InvalidateBoneCache(); |
|
|
|
QAngle vecAng; |
|
Vector vecSrc, vecAim; |
|
|
|
// Alternate barrels when firing |
|
if ( m_bFiringLeft ) |
|
{ |
|
// Aliens permanently fire left barrel because they have no right |
|
if ( GetTeamNumber() == TEAM_HUMANS ) |
|
{ |
|
m_bFiringLeft = false; |
|
} |
|
GetAttachment( m_nBarrelAttachment, vecSrc, vecAng ); |
|
SetActivity( ACT_VM_PRIMARYATTACK ); |
|
} |
|
else |
|
{ |
|
m_bFiringLeft = true; |
|
GetAttachment( m_nRightBarrelAttachment, vecSrc, vecAng ); |
|
SetActivity( ACT_VM_SECONDARYATTACK ); |
|
} |
|
|
|
// Get the distance to the target |
|
AngleVectors( vecAng, &vecAim, 0, 0 ); |
|
|
|
int damageType = GetAmmoDef()->DamageType( m_nAmmoType ); |
|
CBasePlasmaProjectile *pPlasma = CBasePlasmaProjectile::CreatePredicted( vecSrc, vecAim, Vector( 0, 0, 0 ), damageType, GetDriverPlayer() ); |
|
if ( pPlasma ) |
|
{ |
|
pPlasma->SetDamage( obj_manned_plasmagun_damage.GetFloat() ); |
|
pPlasma->m_hOwner = GetDriverPlayer(); |
|
//pPlasma->SetOwnerEntity( this ); |
|
pPlasma->SetMaxRange( m_flMaxRange ); |
|
if ( obj_manned_plasmagun_radius.GetFloat() ) |
|
{ |
|
pPlasma->SetExplosive( obj_manned_plasmagun_radius.GetFloat() ); |
|
} |
|
} |
|
|
|
CSoundParameters params; |
|
if ( GetParametersForSound( "ObjectMannedPlasmagun.Fire", params, NULL ) ) |
|
{ |
|
CPASAttenuationFilter filter( this, params.soundlevel ); |
|
if ( IsPredicted() ) |
|
{ |
|
filter.UsePredictionRules(); |
|
} |
|
EmitSound( filter, entindex(), "ObjectMannedPlasmagun.Fire" ); |
|
} |
|
// SetSentryAnim( TFTURRET_ANIM_FIRE ); |
|
DoMuzzleFlash(); |
|
|
|
--m_nAmmoCount; |
|
|
|
m_flNextIdleTime = gpGlobals->curtime + MANNED_PLASMAGUN_IDLE_TIME; |
|
|
|
// If I'm EMPed, slow the firing rate down |
|
m_flNextAttack = gpGlobals->curtime + ( HasPowerup(POWERUP_EMP) ? 0.3f : 0.1f ); |
|
} |
|
|
|
#if defined( CLIENT_DLL ) |
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
// Input : updateType - |
|
//----------------------------------------------------------------------------- |
|
void CObjectMannedPlasmagun::PostDataUpdate( DataUpdateType_t updateType ) |
|
{ |
|
BaseClass::PostDataUpdate( updateType ); |
|
|
|
bool teamchanged = GetTeamNumber() != m_nPreviousTeam; |
|
|
|
if ( teamchanged || |
|
updateType == DATA_UPDATE_CREATED ) |
|
{ |
|
C_BaseAnimating::AllowBoneAccess( true, false ); |
|
SetupTeamModel(); |
|
C_BaseAnimating::AllowBoneAccess( false, false ); |
|
} |
|
} |
|
|
|
void CObjectMannedPlasmagun::PreDataUpdate( DataUpdateType_t updateType ) |
|
{ |
|
BaseClass::PreDataUpdate( updateType ); |
|
|
|
m_nPreviousTeam = GetTeamNumber(); |
|
} |
|
|
|
#endif
|
|
|