715 lines
17 KiB
C++
715 lines
17 KiB
C++
#include "cbase.h"
|
|
#include "in_buttons.h"
|
|
#include "soundenvelope.h"
|
|
|
|
#ifdef CLIENT_DLL
|
|
#include "c_asw_player.h"
|
|
#include "c_asw_weapon.h"
|
|
#include "c_asw_marine.h"
|
|
#include "c_asw_door_area.h"
|
|
#include "c_asw_door.h"
|
|
#include "c_asw_marine_resource.h"
|
|
#include "FX.h"
|
|
#define CASW_Marine C_ASW_Marine
|
|
#define CASW_Door_Area C_ASW_Door_Area
|
|
#define CASW_Door C_ASW_Door
|
|
#else
|
|
#include "asw_marine.h"
|
|
#include "asw_player.h"
|
|
#include "asw_weapon.h"
|
|
#include "asw_door_area.h"
|
|
#include "asw_door.h"
|
|
#include "npcevent.h"
|
|
#include "shot_manipulator.h"
|
|
#include "asw_gamerules.h"
|
|
#include "asw_marine_resource.h"
|
|
#endif
|
|
#include "asw_marine_skills.h"
|
|
#include "asw_weapon_welder_shared.h"
|
|
#include "asw_weapon_parse.h"
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
#include "tier0/memdbgon.h"
|
|
|
|
IMPLEMENT_NETWORKCLASS_ALIASED( ASW_Weapon_Welder, DT_ASW_Weapon_Welder )
|
|
|
|
BEGIN_NETWORK_TABLE( CASW_Weapon_Welder, DT_ASW_Weapon_Welder )
|
|
#ifdef CLIENT_DLL
|
|
// recvprops
|
|
RecvPropBool (RECVINFO(m_bWeldSeal)),
|
|
#else
|
|
// sendprops
|
|
SendPropBool (SENDINFO(m_bWeldSeal)),
|
|
#endif
|
|
END_NETWORK_TABLE()
|
|
|
|
BEGIN_PREDICTION_DATA( CASW_Weapon_Welder )
|
|
|
|
END_PREDICTION_DATA()
|
|
|
|
LINK_ENTITY_TO_CLASS( asw_weapon_welder, CASW_Weapon_Welder );
|
|
PRECACHE_WEAPON_REGISTER(asw_weapon_welder);
|
|
|
|
#ifndef CLIENT_DLL
|
|
|
|
//---------------------------------------------------------
|
|
// Save/Restore
|
|
//---------------------------------------------------------
|
|
BEGIN_DATADESC( CASW_Weapon_Welder )
|
|
DEFINE_FIELD( m_iAutomaticWeldDirection, FIELD_INTEGER ),
|
|
END_DATADESC()
|
|
|
|
#endif /* not client */
|
|
|
|
CASW_Weapon_Welder::CASW_Weapon_Welder()
|
|
{
|
|
m_fWeldTime = 0;
|
|
m_bWeldSeal = false;
|
|
m_pWeldDoor = NULL;
|
|
m_pWeldingSound = NULL;
|
|
m_bPlayingWelderSound = false;
|
|
|
|
#ifdef CLIENT_DLL
|
|
m_bWeldSealLast = false;
|
|
#endif
|
|
}
|
|
|
|
|
|
CASW_Weapon_Welder::~CASW_Weapon_Welder()
|
|
{
|
|
if ( m_pWeldingSound )
|
|
{
|
|
CSoundEnvelopeController::GetController().Shutdown(m_pWeldingSound);
|
|
}
|
|
|
|
#ifdef CLIENT_DLL
|
|
if ( m_hWeldEffects )
|
|
{
|
|
ParticleProp()->StopEmissionAndDestroyImmediately( m_hWeldEffects );
|
|
m_hWeldEffects = NULL;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void CASW_Weapon_Welder::Precache()
|
|
{
|
|
// precache the weapon model here?
|
|
PrecacheScriptSound("ASW_Welder.WeldLoop");
|
|
PrecacheParticleSystem( "welding_door_seal" );
|
|
PrecacheParticleSystem( "welding_door_cut" );
|
|
BaseClass::Precache();
|
|
}
|
|
|
|
void CASW_Weapon_Welder::PrimaryAttack( void )
|
|
{
|
|
WeldDoor( true ); // seal
|
|
}
|
|
|
|
void CASW_Weapon_Welder::SecondaryAttack( void )
|
|
{
|
|
WeldDoor( false ); // cut
|
|
}
|
|
|
|
void CASW_Weapon_Welder::WeldDoor(bool bSeal)
|
|
{
|
|
CASW_Marine *pMarine = GetMarine();
|
|
if ( !pMarine || !pMarine->GetCommander() )
|
|
return;
|
|
|
|
bool bWelding = false;
|
|
|
|
CASW_Door* pDoor = FindDoor();
|
|
if ( pDoor )
|
|
{
|
|
bWelding = true;
|
|
|
|
Vector vecFacingPoint = pDoor->GetWeldFacingPoint(pMarine);
|
|
Vector diff = vecFacingPoint - pMarine->GetAbsOrigin();
|
|
diff.z = 0;
|
|
VectorNormalize(diff);
|
|
QAngle angCurrentFacing = pMarine->ASWEyeAngles();
|
|
Vector vecCurrentFacing = vec3_origin;
|
|
AngleVectors(angCurrentFacing, &vecCurrentFacing);
|
|
vecCurrentFacing.z = 0;
|
|
VectorNormalize(vecCurrentFacing);
|
|
bool bFacing = DotProduct(diff, vecCurrentFacing) > 0.6f;
|
|
if ( !pMarine->IsInhabited() )
|
|
{
|
|
bFacing = true; // AI marines don't know how to face the door yet
|
|
}
|
|
if ( bFacing && !pDoor->IsOpen() )
|
|
{
|
|
// do our muzzle flash, if we're going to alter the weld some
|
|
if ( bSeal && pDoor->GetSealAmount() < 1.0f )
|
|
{
|
|
pMarine->DoMuzzleFlash();
|
|
m_bIsFiring = true;
|
|
}
|
|
else if ( !bSeal && pDoor->GetSealAmount() > 0 )
|
|
{
|
|
pMarine->DoMuzzleFlash();
|
|
m_bIsFiring = true;
|
|
}
|
|
}
|
|
#ifdef CLIENT_DLL
|
|
pMarine->SetFacingPoint(vecFacingPoint, GetFireRate()*2.0f);
|
|
#else
|
|
if ( gpGlobals->maxClients <= 1 )
|
|
{
|
|
pMarine->SetFacingPoint(vecFacingPoint, GetFireRate()*2.0f);
|
|
}
|
|
#endif
|
|
if ( bFacing )
|
|
{
|
|
if ( pDoor->IsOpen() )
|
|
{
|
|
#ifndef CLIENT_DLL
|
|
if ( bSeal )
|
|
{
|
|
pDoor->CloseForWeld( pMarine ); // shut the door first, so we can start welding it
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
// tell the weapon to weld over the next fire rate interval
|
|
m_fWeldTime = GetFireRate() + 0.004f;
|
|
m_bWeldSeal = bSeal;
|
|
#ifndef CLIENT_DLL
|
|
m_pWeldDoor = pDoor;
|
|
//Msg( "Setting weld door to %d\n", pDoor->entindex() );
|
|
// network door which door we're working on so all players can see progress
|
|
if ( pMarine->GetMarineResource() )
|
|
pMarine->GetMarineResource()->m_hWeldingDoor = pDoor;
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//Msg( "Couldn't find door to weld\n" );
|
|
}
|
|
|
|
if ( pMarine->GetActiveWeapon() != this )
|
|
{
|
|
bool bAttack1, bAttack2, bReload, bOldReload, bOldAttack1;
|
|
GetButtons( bAttack1, bAttack2, bReload, bOldReload, bOldAttack1 );
|
|
|
|
if ( bAttack1 || bAttack2 || bReload || pMarine->GetCurrentMeleeAttack() )
|
|
{
|
|
bWelding = false;
|
|
}
|
|
}
|
|
|
|
if ( !bWelding )
|
|
{
|
|
m_iAutomaticWeldDirection = 0;
|
|
m_bShotDelayed = false;
|
|
#ifdef GAME_DLL
|
|
if ( pMarine->GetMarineResource() )
|
|
{
|
|
pMarine->GetMarineResource()->m_hWeldingDoor = NULL;
|
|
}
|
|
|
|
m_pWeldDoor = NULL;
|
|
|
|
pMarine->OnWeldFinished();
|
|
#endif
|
|
m_bIsFiring = false;
|
|
}
|
|
else
|
|
{
|
|
if ( bSeal )
|
|
{
|
|
m_flNextPrimaryAttack = m_flNextPrimaryAttack + GetFireRate();
|
|
}
|
|
else
|
|
{
|
|
m_flNextSecondaryAttack = m_flNextSecondaryAttack + GetFireRate();
|
|
}
|
|
}
|
|
}
|
|
|
|
// make the weapon weld if needed
|
|
|
|
void CASW_Weapon_Welder::ItemPostFrame()
|
|
{
|
|
#ifndef CLIENT_DLL
|
|
CASW_Marine *pMarine = GetMarine();
|
|
if ( !pMarine || !pMarine->GetCommander() )
|
|
{
|
|
if ( m_bPlayingWelderSound )
|
|
{
|
|
m_bIsFiring = false;
|
|
|
|
if ( pMarine->GetMarineResource() )
|
|
{
|
|
pMarine->GetMarineResource()->m_hWeldingDoor = NULL;
|
|
}
|
|
|
|
m_pWeldDoor = NULL;
|
|
|
|
pMarine->OnWeldFinished();
|
|
//Msg( "Clearing weld door as no marine\n" );
|
|
}
|
|
return BaseItemPostFrame();
|
|
}
|
|
|
|
if ( m_fWeldTime > 0 && m_pWeldDoor )
|
|
{
|
|
m_fWeldTime -= gpGlobals->frametime;
|
|
|
|
if ( m_fWeldTime <= 0 )
|
|
{
|
|
m_bIsFiring = false;
|
|
if ( pMarine->GetMarineResource() )
|
|
{
|
|
pMarine->GetMarineResource()->m_hWeldingDoor = NULL;
|
|
}
|
|
}
|
|
|
|
float fSkillScale = MarineSkills()->GetHighestSkillValueNearby(pMarine->GetAbsOrigin(), ENGINEERING_AURA_RADIUS,
|
|
ASW_MARINE_SKILL_ENGINEERING, ASW_MARINE_SUBSKILL_ENGINEERING_WELDING);
|
|
|
|
CASW_Marine *pSkillMarine = MarineSkills()->GetLastSkillMarine();
|
|
if ( fSkillScale > 0.0f && pSkillMarine && pSkillMarine->GetMarineResource() )
|
|
{
|
|
pSkillMarine->m_fUsingEngineeringAura = gpGlobals->curtime;
|
|
m_pWeldDoor->m_fSkillMarineHelping = gpGlobals->curtime;
|
|
}
|
|
else
|
|
{
|
|
m_pWeldDoor->m_fSkillMarineHelping = 0;
|
|
}
|
|
|
|
if ( fSkillScale < 1.0 )
|
|
{
|
|
fSkillScale = 0.6f;
|
|
}
|
|
|
|
float fSealAmount = gpGlobals->frametime * fSkillScale;
|
|
m_pWeldDoor->WeldDoor( m_bWeldSeal, fSealAmount, pMarine ); // if the door is shut, we can weld
|
|
}
|
|
#else
|
|
if ( m_fWeldTime > 0 )
|
|
{
|
|
m_fWeldTime -= gpGlobals->frametime;
|
|
if ( m_fWeldTime <= 0 )
|
|
{
|
|
m_bIsFiring = false;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// check for ending automatic welding
|
|
if ( m_bShotDelayed )
|
|
{
|
|
if ( m_pWeldDoor )
|
|
{
|
|
if ( ( m_iAutomaticWeldDirection > 0 && m_pWeldDoor->GetSealAmount() >= 1.0f ) ||
|
|
( m_iAutomaticWeldDirection < 0 && m_pWeldDoor->GetSealAmount() <= 0.0f ) )
|
|
{
|
|
m_bShotDelayed = false;
|
|
#ifdef GAME_DLL
|
|
if ( pMarine->GetMarineResource() )
|
|
{
|
|
pMarine->GetMarineResource()->m_hWeldingDoor = NULL;
|
|
}
|
|
m_pWeldDoor = NULL;
|
|
pMarine->OnWeldFinished();
|
|
#endif
|
|
m_bIsFiring = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( !FindDoor() )
|
|
{
|
|
m_bShotDelayed = false;
|
|
#ifdef GAME_DLL
|
|
if ( pMarine->GetMarineResource() )
|
|
{
|
|
pMarine->GetMarineResource()->m_hWeldingDoor = NULL;
|
|
}
|
|
m_pWeldDoor = NULL;
|
|
pMarine->OnWeldFinished();
|
|
#endif
|
|
m_bIsFiring = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
BaseItemPostFrame();
|
|
}
|
|
|
|
// simplified version of the one in CASW_Weapon, don't worry about ammo or clips for the welder
|
|
void CASW_Weapon_Welder::BaseItemPostFrame()
|
|
{
|
|
//CBasePlayer *pOwner = GetCommander();
|
|
CASW_Marine* pOwner = GetMarine();
|
|
|
|
if (!pOwner)
|
|
return;
|
|
|
|
bool bAttack1, bAttack2, bReload, bOldReload, bOldAttack1;
|
|
GetButtons(bAttack1, bAttack2, bReload, bOldReload, bOldAttack1 );
|
|
|
|
// check for automatic welding
|
|
if ( m_bShotDelayed )
|
|
{
|
|
if ( m_iAutomaticWeldDirection > 0 )
|
|
{
|
|
bAttack1 = true;
|
|
//Msg( "doing automatic attack1 since bShotDelayed\n" );
|
|
}
|
|
else if ( m_iAutomaticWeldDirection < 0 )
|
|
{
|
|
bAttack2 = true;
|
|
//Msg( "doing automatic attack2 since bShotDelayed\n" );
|
|
}
|
|
}
|
|
|
|
//Track the duration of the fire
|
|
//FIXME: Check for IN_ATTACK2 as well?
|
|
//FIXME: What if we're calling ItemBusyFrame?
|
|
m_fFireDuration = bAttack1 ? ( m_fFireDuration + gpGlobals->frametime ) : 0.0f;
|
|
|
|
if ( UsesClipsForAmmo1() )
|
|
{
|
|
CheckReload();
|
|
}
|
|
|
|
bool bFired = false;
|
|
|
|
if ( bAttack2 && m_flNextSecondaryAttack <= gpGlobals->curtime )
|
|
{
|
|
bFired = true;
|
|
SecondaryAttack();
|
|
}
|
|
|
|
if ( !bFired && bAttack1 && m_flNextPrimaryAttack <= gpGlobals->curtime )
|
|
{
|
|
// If the firing button was just pressed, reset the firing time
|
|
if ( pOwner && bAttack1 )
|
|
{
|
|
m_flNextPrimaryAttack = gpGlobals->curtime;
|
|
}
|
|
|
|
PrimaryAttack();
|
|
}
|
|
|
|
if ( !bAttack1 && !bAttack2 )
|
|
m_bIsFiring = false;
|
|
|
|
// -----------------------
|
|
// No buttons down
|
|
// -----------------------
|
|
if (!(bAttack1 || bAttack2 || bReload))
|
|
{
|
|
// no fire buttons down or reloading
|
|
if ( !ReloadOrSwitchWeapons() && !m_bInReload )
|
|
{
|
|
WeaponIdle();
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef CLIENT_DLL
|
|
void CASW_Weapon_Welder::ProcessMuzzleFlashEvent()
|
|
{
|
|
// attach muzzle flash particle system effect
|
|
int iAttachment = GetMuzzleAttachment();
|
|
if ( iAttachment > 0 )
|
|
{
|
|
Vector sparkOrigin, sparkNormal;
|
|
QAngle sparkAngles;
|
|
|
|
if ( GetAttachment( iAttachment, sparkOrigin, sparkAngles ) )
|
|
{
|
|
AngleVectors(sparkAngles, &sparkNormal);
|
|
FX_Sparks( sparkOrigin, 1, 1, sparkNormal, 3, 32, 128 ); // disabled for now
|
|
}
|
|
}
|
|
C_BaseCombatWeapon::ProcessMuzzleFlashEvent();
|
|
OnMuzzleFlashed();
|
|
}
|
|
|
|
void CASW_Weapon_Welder::OnDataChanged( DataUpdateType_t type )
|
|
{
|
|
BaseClass::OnDataChanged( type );
|
|
|
|
if ( type == DATA_UPDATE_CREATED )
|
|
{
|
|
// We want to think every frame.
|
|
SetNextClientThink( CLIENT_THINK_ALWAYS );
|
|
}
|
|
|
|
UpdateDoorWeldingEffects();
|
|
}
|
|
|
|
void CASW_Weapon_Welder::ClientThink()
|
|
{
|
|
BaseClass::ClientThink();
|
|
|
|
UpdateDoorWeldingEffects();
|
|
}
|
|
|
|
void CASW_Weapon_Welder::UpdateDoorWeldingEffects( void )
|
|
{
|
|
if ( !m_bIsFiring || !GetMarine() || !GetMarine()->GetMarineResource() )
|
|
{
|
|
RemoveWeldingEffects();
|
|
StopWelderSound();
|
|
return;
|
|
}
|
|
|
|
C_ASW_Door* pDoor = GetMarine()->GetMarineResource()->m_hWeldingDoor.Get();
|
|
if ( !pDoor || pDoor->IsOpen() )
|
|
{
|
|
RemoveWeldingEffects();
|
|
StopWelderSound();
|
|
return;
|
|
}
|
|
|
|
StartWelderSound();
|
|
|
|
if ( !m_hWeldEffects || m_bWeldSealLast != m_bWeldSeal )
|
|
{
|
|
CreateWeldingEffects( pDoor );
|
|
}
|
|
|
|
if ( m_hWeldEffects )
|
|
{
|
|
m_hWeldEffects->SetControlPoint( 0, pDoor->GetWeldFacingPoint( GetMarine() ) );
|
|
m_hWeldEffects->SetControlPointForwardVector( 0, pDoor->GetSparkNormal( GetMarine() ) );
|
|
}
|
|
|
|
m_bWeldSealLast = m_bWeldSeal;
|
|
}
|
|
|
|
void CASW_Weapon_Welder::CreateWeldingEffects( C_ASW_Door* pDoor )
|
|
{
|
|
if ( !m_bIsFiring || !GetOwner() || !pDoor )
|
|
return;
|
|
|
|
if ( m_hWeldEffects )
|
|
{
|
|
RemoveWeldingEffects();
|
|
}
|
|
|
|
if ( !m_hWeldEffects )
|
|
{
|
|
if ( m_bWeldSeal )
|
|
m_hWeldEffects = ParticleProp()->Create( "welding_door_seal", PATTACH_CUSTOMORIGIN );
|
|
else
|
|
m_hWeldEffects = ParticleProp()->Create( "welding_door_cut", PATTACH_CUSTOMORIGIN );
|
|
|
|
if ( m_hWeldEffects )
|
|
{
|
|
m_hWeldEffects->SetControlPoint( 0, pDoor->GetSparkNormal( GetMarine() ) );
|
|
m_hWeldEffects->SetControlPointForwardVector( 0, pDoor->GetWeldFacingPoint( GetMarine() ) );
|
|
}
|
|
|
|
/*
|
|
m_pLaserPointerEffect->SetControlPoint( 1, vecOrigin );
|
|
m_pLaserPointerEffect->SetControlPoint( 2, tr.endpos );
|
|
m_pLaserPointerEffect->SetControlPointForwardVector ( 1, vecDirShooting );
|
|
Vector vecImpactY, vecImpactZ;
|
|
VectorVectors( tr.plane.normal, vecImpactY, vecImpactZ );
|
|
vecImpactY *= -1.0f;
|
|
m_pLaserPointerEffect->SetControlPointOrientation( 2, vecImpactY, vecImpactZ, tr.plane.normal );
|
|
m_pLaserPointerEffect->SetControlPoint( 3, Vector( alpha, 0, 0 ) );
|
|
|
|
if ( m_hWeldEffects )
|
|
{
|
|
ParticleProp()->AddControlPoint( m_pLaserPointerEffect, 1, this, PATTACH_CUSTOMORIGIN );
|
|
ParticleProp()->AddControlPoint( m_pLaserPointerEffect, 2, this, PATTACH_CUSTOMORIGIN );
|
|
}
|
|
*/
|
|
}
|
|
}
|
|
|
|
void CASW_Weapon_Welder::RemoveWeldingEffects( void )
|
|
{
|
|
if ( m_hWeldEffects )
|
|
{
|
|
m_hWeldEffects->StopEmission( false, false, true );
|
|
m_hWeldEffects = NULL;
|
|
}
|
|
}
|
|
#endif // CLIENT_DLL
|
|
|
|
// get the continuous welding sound for this weapon
|
|
// in multiplayer, server doesn't send the sound to the owning player as he'll make the sound himself clientside
|
|
CSoundPatch *CASW_Weapon_Welder::GetWelderSound( void )
|
|
{
|
|
if ( m_pWeldingSound == NULL )
|
|
{
|
|
#ifdef CLIENT_DLL
|
|
CPASAttenuationFilter filter( this );
|
|
#else
|
|
CPASAttenuationFilter filter( this );
|
|
if ( gpGlobals->maxClients > 1 )
|
|
{
|
|
CASW_Marine *pMarine = GetMarine();
|
|
if (pMarine)
|
|
{
|
|
CASW_Player *pPlayer = pMarine->GetCommander();
|
|
if ( pPlayer )
|
|
filter.RemoveRecipient(pPlayer);
|
|
}
|
|
}
|
|
#endif
|
|
m_pWeldingSound = CSoundEnvelopeController::GetController().SoundCreate( filter, entindex(), CHAN_AUTO, "ASW_Welder.WeldLoop", ATTN_NORM );
|
|
}
|
|
|
|
return m_pWeldingSound;
|
|
}
|
|
|
|
void CASW_Weapon_Welder::StartWelderSound()
|
|
{
|
|
if ( GetWelderSound() && !m_bPlayingWelderSound )
|
|
{
|
|
m_bPlayingWelderSound = true;
|
|
CSoundEnvelopeController::GetController().Play( GetWelderSound(), 1.0f, 100 );
|
|
}
|
|
}
|
|
|
|
void CASW_Weapon_Welder::StopWelderSound()
|
|
{
|
|
if ( m_pWeldingSound && m_bPlayingWelderSound )
|
|
{
|
|
m_bPlayingWelderSound = false;
|
|
|
|
CSoundEnvelopeController::GetController().SoundFadeOut( m_pWeldingSound, 0.1f, true );
|
|
m_pWeldingSound = NULL;
|
|
//Msg( "Stopping welder sound\n" );
|
|
}
|
|
}
|
|
|
|
bool CASW_Weapon_Welder::OffhandActivate()
|
|
{
|
|
CASW_Marine *pMarine = GetMarine();
|
|
if ( !pMarine || !pMarine->GetCommander() )
|
|
return false;
|
|
|
|
bool bRecommendedSeal = false;
|
|
|
|
float fSealAmount = -1.0f;
|
|
|
|
CASW_Door *pDoor = FindDoor();
|
|
if ( pDoor )
|
|
{
|
|
fSealAmount = pDoor->GetSealAmount();
|
|
bRecommendedSeal = pDoor->IsRecommendedSeal();
|
|
}
|
|
|
|
if ( fSealAmount < 0.0f )
|
|
{
|
|
return true;
|
|
}
|
|
|
|
// start automatic welding
|
|
if ( !m_bShotDelayed )
|
|
{
|
|
m_bShotDelayed = true;
|
|
#ifdef GAME_DLL
|
|
pMarine->OnWeldStarted();
|
|
#endif
|
|
if ( fSealAmount == 0.0f || ( bRecommendedSeal && fSealAmount < 1.0f ) )
|
|
{
|
|
m_iAutomaticWeldDirection = 1;
|
|
}
|
|
else
|
|
{
|
|
// default to unsealing the door
|
|
m_iAutomaticWeldDirection = -1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// already welding, just flip direction
|
|
m_iAutomaticWeldDirection = -m_iAutomaticWeldDirection;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
float CASW_Weapon_Welder::GetFireRate()
|
|
{
|
|
//float flRate = 0.07f;
|
|
float flRate = GetWeaponInfo()->m_flFireRate;
|
|
|
|
//CALL_ATTRIB_HOOK_FLOAT( flRate, mod_fire_rate );
|
|
|
|
return flRate;
|
|
}
|
|
|
|
CASW_Door* CASW_Weapon_Welder::FindDoor()
|
|
{
|
|
CASW_Marine *pMarine = GetMarine();
|
|
if ( !pMarine )
|
|
return NULL;
|
|
|
|
if ( pMarine->IsInhabited() )
|
|
{
|
|
CASW_Player *pPlayer = pMarine->GetCommander();
|
|
if ( !pPlayer )
|
|
return NULL;
|
|
|
|
// find our door area
|
|
for ( int i = 0; i < pPlayer->GetNumUseEntities(); i++ )
|
|
{
|
|
CBaseEntity* pEnt = pPlayer->GetUseEntity( i );
|
|
CASW_Door_Area* pDoorArea = dynamic_cast< CASW_Door_Area* >( pEnt );
|
|
if ( pDoorArea )
|
|
{
|
|
CASW_Door* pDoor = pDoorArea->GetASWDoor();
|
|
if ( pDoor && pDoor->GetHealth() > 0 )
|
|
{
|
|
return pDoor;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
#ifdef GAME_DLL
|
|
CASW_Door_Area *pClosestArea = NULL;
|
|
float flClosestDist = FLT_MAX;
|
|
|
|
for ( int i = 0; i < IASW_Use_Area_List::AutoList().Count(); i++ )
|
|
{
|
|
CASW_Use_Area *pArea = static_cast< CASW_Use_Area* >( IASW_Use_Area_List::AutoList()[ i ] );
|
|
if ( pArea->Classify() == CLASS_ASW_DOOR_AREA )
|
|
{
|
|
CASW_Door_Area *pDoorArea = assert_cast<CASW_Door_Area*>( pArea );
|
|
CASW_Door* pDoor = pDoorArea->GetASWDoor();
|
|
if ( !pDoor || pDoor->GetHealth() <= 0 )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
float flDist = GetAbsOrigin().DistTo( pArea->WorldSpaceCenter() );
|
|
if ( flDist < flClosestDist && pArea->CollisionProp()->IsPointInBounds( pMarine->WorldSpaceCenter() ) )
|
|
{
|
|
flClosestDist = flDist;
|
|
pClosestArea = pDoorArea;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( pClosestArea )
|
|
{
|
|
CASW_Door* pDoor = pClosestArea->GetASWDoor();
|
|
if ( pDoor )
|
|
{
|
|
return pDoor;
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
return NULL;
|
|
}
|