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.
634 lines
17 KiB
634 lines
17 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: Client's CWeaponMortar class |
|
// |
|
// $Workfile: $ |
|
// $Date: $ |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
#include "cbase.h" |
|
#include "hud.h" |
|
#include "hudelement.h" |
|
#include "in_buttons.h" |
|
#include "ground_line.h" |
|
#include "clientmode_tfnormal.h" |
|
#include "vgui_basepanel.h" |
|
#include "c_tf_basecombatweapon.h" |
|
#include "engine/IEngineSound.h" |
|
#include "iinput.h" |
|
#include "imessagechars.h" |
|
#include "c_weapon__stubs.h" |
|
|
|
//============================================================================= |
|
// Purpose: Hud Element for Mortar firing |
|
//============================================================================= |
|
class CHudMortar : public CHudElement, public vgui::Panel |
|
{ |
|
DECLARE_CLASS_SIMPLE( CHudMortar, vgui::Panel ); |
|
|
|
public: |
|
DECLARE_MULTIPLY_INHERITED(); |
|
|
|
CHudMortar( const char *pElementName ); |
|
virtual void Paint( void ); |
|
|
|
float m_flPower; |
|
float m_flFiringPower; |
|
float m_flFiringAccuracy; |
|
float m_flReset; |
|
}; |
|
|
|
DECLARE_HUDELEMENT( CHudMortar ); |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CHudMortar::CHudMortar( const char *pElementName ) : |
|
CHudElement( pElementName ), vgui::Panel( NULL, pElementName ) |
|
{ |
|
m_flPower = 0; |
|
m_flFiringPower = 0; |
|
m_flFiringAccuracy = 0; |
|
m_flReset = 0; |
|
SetPaintBackgroundEnabled( false ); |
|
SetAutoDelete( false ); |
|
SetName( "mortar" ); |
|
|
|
SetHiddenBits( HIDEHUD_PLAYERDEAD ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CHudMortar::Paint() |
|
{ |
|
// Clear out markers |
|
if ( m_flReset && m_flReset < gpGlobals->curtime ) |
|
{ |
|
m_flFiringPower = 0; |
|
m_flFiringAccuracy = 0; |
|
m_flReset = 0; |
|
} |
|
|
|
int w, h; |
|
GetSize( w, h ); |
|
|
|
// Use an eighth of the height for each side |
|
int iOffset = h / 8; |
|
int iBarHeight = h - (2 * iOffset); |
|
int iZero = (w / 5); |
|
int iMarker = iZero + (m_flPower * (w - iZero)); |
|
int iPower = iZero + (m_flFiringPower * (w - iZero)); |
|
int iAccuracy = iZero + (m_flFiringAccuracy * (w - iZero)); |
|
|
|
// Shade the bar |
|
int alpha = 205; |
|
int colorAmt = 255; |
|
int nSegs = 20; |
|
|
|
int i; |
|
for(i=0; i < nSegs; i++) |
|
{ |
|
int left = iZero + (i*w) / nSegs; |
|
int right = iZero + ((i+1)*w) / nSegs; |
|
|
|
// Don't draw past the marker |
|
if ( m_flFiringPower && right > iPower ) |
|
right = iPower; |
|
else if ( !m_flFiringPower && right > iMarker ) |
|
right = iMarker; |
|
|
|
vgui::surface()->DrawSetColor( ((i + 5) * colorAmt) / nSegs, 0, 0, alpha ); |
|
vgui::surface()->DrawFilledRect( left, iOffset, right, iBarHeight); |
|
} |
|
|
|
// Shade back from zero |
|
nSegs = 10; |
|
for(i=0; i < nSegs; i++) |
|
{ |
|
int left = (i*iZero) / nSegs; |
|
int right = ((i+1)*iZero) / nSegs; |
|
|
|
if ( m_flFiringAccuracy && left < iAccuracy ) |
|
left = iAccuracy; |
|
else if ( !m_flFiringAccuracy && left < iMarker ) |
|
left = iMarker; |
|
|
|
vgui::surface()->DrawSetColor( ((nSegs - i) * colorAmt) / nSegs, 0, 0, alpha ); |
|
vgui::surface()->DrawFilledRect(left, iOffset, right, iBarHeight); |
|
} |
|
|
|
// Draw the zero marker |
|
vgui::surface()->DrawSetColor(255,255,255,255); |
|
vgui::surface()->DrawFilledRect(iZero-2, iOffset, iZero+2, iBarHeight); |
|
|
|
// Draw the marker |
|
vgui::surface()->DrawSetColor(255,255,255,255); |
|
vgui::surface()->DrawFilledRect(iMarker-1, 0, iMarker+1, h); |
|
|
|
// Draw the power mark if we've set one |
|
if ( m_flFiringPower ) |
|
{ |
|
vgui::surface()->DrawSetColor(255,255,255,255); |
|
vgui::surface()->DrawFilledRect(iPower-1, iOffset, iPower+1, iBarHeight); |
|
} |
|
|
|
// Draw the accuracy mark if we've set one |
|
if ( m_flFiringAccuracy ) |
|
{ |
|
vgui::surface()->DrawSetColor(255,255,255,255); |
|
vgui::surface()->DrawFilledRect(iAccuracy-1, iOffset, iAccuracy+1, iBarHeight); |
|
} |
|
|
|
// Draw box |
|
vgui::surface()->DrawSetColor(255,255,255,255); |
|
vgui::surface()->DrawOutlinedRect(0, iOffset, w, iBarHeight); |
|
} |
|
|
|
static ConVar g_CVMortarGroundLineUpdateInterval( "mortar_groundlineupdateinterval", "0.1", 0, "Number of seconds, mininum, between ground line position updates." ); |
|
|
|
|
|
//============================================================================= |
|
// Purpose: Client version of CWeaponMortar |
|
//============================================================================= |
|
class C_WeaponMortar : public C_BaseTFCombatWeapon |
|
{ |
|
public: |
|
DECLARE_CLASS( C_WeaponMortar, C_BaseTFCombatWeapon ); |
|
DECLARE_CLIENTCLASS(); |
|
DECLARE_PREDICTABLE(); |
|
|
|
C_WeaponMortar(); |
|
~C_WeaponMortar(); |
|
|
|
void FireMortar( void ); |
|
|
|
virtual void PreDataUpdate( DataUpdateType_t updateType ); |
|
virtual void OnDataChanged( DataUpdateType_t updateType ); |
|
virtual void HandleInput( void ); |
|
virtual void Redraw(); |
|
virtual void OverrideMouseInput( float *x, float *y ); |
|
|
|
// Deploy / Holster |
|
virtual bool Deploy( void ); |
|
virtual bool Holster( CBaseCombatWeapon *pSwitchingTo = NULL ); |
|
|
|
// Mortar Data |
|
bool m_bCarried; |
|
bool m_bMortarReloading; |
|
Vector m_vecMortarOrigin; |
|
Vector m_vecMortarAngles; |
|
float m_flPrevMortarServerYaw; |
|
float m_flMortarYaw; |
|
float m_flPrevMortarYaw; |
|
|
|
// Input Handling |
|
float m_flNextClick; |
|
float m_flAccuracySpeed; |
|
int m_iFiringState; |
|
bool m_bRotating; |
|
|
|
CGroundLine *m_pGroundLine; |
|
CGroundLine *m_pDarkLine; |
|
CHudMortar *m_pPowerBar; |
|
IMaterial *m_pRotateIcon; |
|
|
|
vgui::HFont m_hFontText; |
|
|
|
private: |
|
C_WeaponMortar( const C_WeaponMortar & ); |
|
|
|
float m_flLastGroundlineUpdateTime; |
|
|
|
}; |
|
|
|
STUB_WEAPON_CLASS_IMPLEMENT( weapon_mortar, C_WeaponMortar ); |
|
|
|
IMPLEMENT_CLIENTCLASS_DT(C_WeaponMortar, DT_WeaponMortar, CWeaponMortar) |
|
RecvPropInt( RECVINFO(m_bCarried) ), |
|
RecvPropInt( RECVINFO(m_bMortarReloading) ), |
|
RecvPropVector( RECVINFO(m_vecMortarOrigin) ), |
|
RecvPropVector( RECVINFO(m_vecMortarAngles) ), |
|
END_RECV_TABLE() |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
C_WeaponMortar::C_WeaponMortar() |
|
{ |
|
m_bCarried = true; |
|
m_bMortarReloading = false; |
|
m_iFiringState = MORTAR_IDLE; |
|
m_flNextClick = 0; |
|
m_flAccuracySpeed = 0; |
|
m_bRotating = false; |
|
m_pGroundLine = NULL; |
|
m_pDarkLine = NULL; |
|
m_flMortarYaw = 0; |
|
m_flPrevMortarYaw = -1; |
|
|
|
m_pRotateIcon = materials->FindMaterial( "Hud/mortar/mortar_rotate", TEXTURE_GROUP_VGUI ); |
|
m_pRotateIcon->IncrementReferenceCount(); |
|
|
|
m_pPowerBar = GET_HUDELEMENT( CHudMortar ); |
|
|
|
m_flLastGroundlineUpdateTime = 0.0f; |
|
|
|
m_hFontText = g_hFontTrebuchet24; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
C_WeaponMortar::~C_WeaponMortar() |
|
{ |
|
m_pPowerBar->SetParent( (vgui::Panel *)NULL ); |
|
|
|
if ( m_pRotateIcon != NULL ) |
|
{ |
|
m_pRotateIcon->DecrementReferenceCount(); |
|
m_pRotateIcon = NULL; |
|
} |
|
|
|
if ( m_pGroundLine ) |
|
{ |
|
delete m_pGroundLine; |
|
} |
|
if ( m_pDarkLine ) |
|
{ |
|
delete m_pDarkLine; |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void C_WeaponMortar::PreDataUpdate( DataUpdateType_t updateType ) |
|
{ |
|
BaseClass::PreDataUpdate(updateType); |
|
|
|
m_flPrevMortarServerYaw = m_vecMortarAngles.y; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void C_WeaponMortar::OnDataChanged( DataUpdateType_t updateType ) |
|
{ |
|
BaseClass::OnDataChanged(updateType); |
|
|
|
// If the mortar's being carried by some other player, don't make a ground line |
|
if ( !IsCarriedByLocalPlayer() ) |
|
return; |
|
|
|
// Draw power chart if the mortar is deployed |
|
if ( !m_bCarried && !m_bMortarReloading ) |
|
{ |
|
vgui::Panel *pParent = GetClientModeNormal()->GetViewport(); |
|
int parentWidth, parentHeight; |
|
pParent->GetSize(parentWidth, parentHeight); |
|
|
|
int iWidth = 256; |
|
int iHeight = 40; |
|
int iX = (parentWidth - iWidth) / 2; |
|
int iY = (parentHeight - 200); |
|
|
|
// Only show the power bar if the mortar's the active weapon |
|
if ( IsActiveByLocalPlayer() ) |
|
{ |
|
m_pPowerBar->SetBounds( iX, iY, iWidth, iHeight ); |
|
m_pPowerBar->SetParent(pParent); |
|
} |
|
else |
|
{ |
|
m_pPowerBar->SetParent( (vgui::Panel *)NULL ); |
|
} |
|
|
|
if ( !m_bRotating && m_flPrevMortarServerYaw != m_vecMortarAngles.y ) |
|
{ |
|
m_flMortarYaw = m_vecMortarAngles.y; |
|
} |
|
|
|
// Create the Ground lines |
|
if ( !m_pGroundLine ) |
|
{ |
|
m_pGroundLine = new CGroundLine(); |
|
m_pGroundLine->Init( "player/support/mortarline" ); |
|
} |
|
if ( !m_pDarkLine ) |
|
{ |
|
m_pDarkLine = new CGroundLine(); |
|
m_pDarkLine->Init( "player/support/mortarline" ); |
|
} |
|
} |
|
else |
|
{ |
|
m_pPowerBar->SetParent( (vgui::Panel *)NULL ); |
|
|
|
if ( m_pGroundLine ) |
|
{ |
|
delete m_pGroundLine; |
|
m_pGroundLine = NULL; |
|
} |
|
if ( m_pDarkLine ) |
|
{ |
|
delete m_pDarkLine; |
|
m_pDarkLine = NULL; |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void C_WeaponMortar::HandleInput( void ) |
|
{ |
|
// If it's being carried, ignore input |
|
if ( m_bCarried ) |
|
return; |
|
// If the player's dead, ignore input |
|
C_BaseTFPlayer *pPlayer = C_BaseTFPlayer::GetLocalPlayer(); |
|
if ( pPlayer == NULL ) |
|
return; |
|
if ( pPlayer->GetHealth() < 1 ) |
|
return; |
|
|
|
// Ignore input if it's reloading |
|
if ( m_bMortarReloading ) |
|
return; |
|
|
|
// Secondary fire rotates the mortar |
|
if ( gHUD.m_iKeyBits & IN_ATTACK2 ) |
|
{ |
|
if ( pPlayer->HasPowerup(POWERUP_EMP) ) |
|
{ |
|
CLocalPlayerFilter filter; |
|
EmitSound( filter, SOUND_FROM_LOCAL_PLAYER, "WeaponMortar.EMPed" ); |
|
return; |
|
} |
|
m_bRotating = true; |
|
|
|
gHUD.m_iKeyBits &= ~IN_ATTACK2; |
|
|
|
// Prevent firing while rotating |
|
m_pPowerBar->SetParent( (vgui::Panel *)NULL ); |
|
return; |
|
} |
|
else |
|
{ |
|
if ( m_bRotating ) |
|
{ |
|
// Bring up the firing bar again |
|
vgui::Panel *pParent = GetClientModeNormal()->GetViewport(); |
|
m_pPowerBar->SetParent(pParent); |
|
m_bRotating = false; |
|
} |
|
} |
|
|
|
// Primary fire launches mortars |
|
if (gHUD.m_iKeyBits & IN_ATTACK) |
|
{ |
|
if ( pPlayer->HasPowerup(POWERUP_EMP) ) |
|
{ |
|
CLocalPlayerFilter filter; |
|
EmitSound( filter, SOUND_FROM_LOCAL_PLAYER, "WeaponMortar.EMPed" ); |
|
return; |
|
} |
|
|
|
if ( m_flNextClick <= gpGlobals->curtime ) |
|
{ |
|
// Play click animation |
|
// SendWeaponAnim( ACT_SLAM_DETONATOR_DETONATE ); |
|
|
|
// Switch states |
|
switch( m_iFiringState ) |
|
{ |
|
case MORTAR_IDLE: |
|
m_iFiringState = MORTAR_CHARGING_POWER; |
|
break; |
|
case MORTAR_CHARGING_POWER: |
|
m_pPowerBar->m_flFiringPower = m_pPowerBar->m_flPower; |
|
m_iFiringState = MORTAR_CHARGING_ACCURACY; |
|
break; |
|
case MORTAR_CHARGING_ACCURACY: |
|
m_pPowerBar->m_flFiringAccuracy = m_pPowerBar->m_flPower; |
|
m_iFiringState = MORTAR_IDLE; |
|
|
|
FireMortar(); |
|
break; |
|
default: |
|
break; |
|
} |
|
|
|
input->ClearInputButton( IN_ATTACK ); |
|
gHUD.m_iKeyBits &= ~IN_ATTACK; |
|
|
|
m_flNextClick = gpGlobals->curtime + 0.05; |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void C_WeaponMortar::Redraw() |
|
{ |
|
BaseClass::Redraw(); |
|
|
|
// If the player's dead, abort |
|
C_BaseTFPlayer *pPlayer = C_BaseTFPlayer::GetLocalPlayer(); |
|
if ( pPlayer == NULL ) |
|
return; |
|
if ( pPlayer->GetHealth() < 1 ) |
|
{ |
|
m_iFiringState = MORTAR_IDLE; |
|
m_bCarried = true; |
|
return; |
|
} |
|
|
|
// If it's reloading, tell the player |
|
if ( m_bMortarReloading ) |
|
{ |
|
int width, height; |
|
messagechars->GetStringLength( m_hFontText, &width, &height, "Mortar is reloading..." ); |
|
messagechars->DrawString( m_hFontText, (ScreenWidth() - width) / 2, YRES(350), 192, 192, 192, 255, "Mortar is reloading...", IMessageChars::MESSAGESTRINGID_NONE ); |
|
return; |
|
} |
|
|
|
// Handle power charging |
|
switch( m_iFiringState ) |
|
{ |
|
case MORTAR_IDLE: |
|
m_pPowerBar->m_flPower = 0; |
|
break; |
|
case MORTAR_CHARGING_POWER: |
|
m_pPowerBar->m_flPower = MIN( m_pPowerBar->m_flPower + ( (1.0 / MORTAR_CHARGE_POWER_RATE) * gpGlobals->curtimeDelta), 1.0f); |
|
m_pPowerBar->m_flFiringPower = 0; |
|
m_pPowerBar->m_flFiringAccuracy = 0; |
|
if ( m_pPowerBar->m_flPower >= 1.0 ) |
|
{ |
|
// Hit Max, start going down |
|
m_pPowerBar->m_flFiringPower = m_pPowerBar->m_flPower; |
|
m_iFiringState = MORTAR_CHARGING_ACCURACY; |
|
m_flNextClick = gpGlobals->curtime + 0.25; |
|
} |
|
break; |
|
case MORTAR_CHARGING_ACCURACY: |
|
// Calculate accuracy speed |
|
m_flAccuracySpeed = (1.0 / MORTAR_CHARGE_ACCURACY_RATE); |
|
if ( m_pPowerBar->m_flFiringPower > 0.5 ) |
|
{ |
|
// Shots over halfway suffer an increased speed to the accuracy power, making accurate shots harder |
|
float flAdjustedPower = (m_pPowerBar->m_flFiringPower - 0.5) * 3.0; |
|
m_flAccuracySpeed += (m_pPowerBar->m_flFiringPower * flAdjustedPower); |
|
} |
|
|
|
m_pPowerBar->m_flPower = MAX( m_pPowerBar->m_flPower - ( m_flAccuracySpeed * gpGlobals->curtimeDelta), -0.25f); |
|
if ( m_pPowerBar->m_flPower <= -0.25 ) |
|
{ |
|
// Hit Min, fire mortar |
|
m_pPowerBar->m_flFiringAccuracy = m_pPowerBar->m_flPower; |
|
m_iFiringState = MORTAR_IDLE; |
|
|
|
FireMortar(); |
|
m_flNextClick = gpGlobals->curtime + 0.25; |
|
} |
|
break; |
|
default: |
|
break; |
|
} |
|
|
|
// Draw the rotate icon if the player's rotating the mortar |
|
if ( m_bRotating ) |
|
{ |
|
vgui::Panel *pParent = GetClientModeNormal()->GetViewport(); |
|
int parentWidth, parentHeight; |
|
pParent->GetSize(parentWidth, parentHeight); |
|
int iWidth = 64; |
|
int iHeight = 64; |
|
int iX = (parentWidth - iWidth) / 2; |
|
int iY = (parentHeight - 216); |
|
|
|
IMesh* pMesh = materials->GetDynamicMesh( true, NULL, NULL, m_pRotateIcon ); |
|
|
|
CMeshBuilder meshBuilder; |
|
meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); |
|
|
|
meshBuilder.Color3f( 1.0, 1.0, 1.0 ); |
|
meshBuilder.TexCoord2f( 0,0,0 ); |
|
meshBuilder.Position3f( iX,iY,0 ); |
|
meshBuilder.AdvanceVertex(); |
|
|
|
meshBuilder.Color3f( 1.0, 1.0, 1.0 ); |
|
meshBuilder.TexCoord2f( 0,1,0 ); |
|
meshBuilder.Position3f( iX+iWidth, iY, 0 ); |
|
meshBuilder.AdvanceVertex(); |
|
|
|
meshBuilder.Color3f( 1.0, 1.0, 1.0 ); |
|
meshBuilder.TexCoord2f( 0,1,1 ); |
|
meshBuilder.Position3f( iX+iWidth, iY+iHeight, 0 ); |
|
meshBuilder.AdvanceVertex(); |
|
|
|
meshBuilder.Color3f( 1.0, 1.0, 1.0 ); |
|
meshBuilder.TexCoord2f( 0,0,1 ); |
|
meshBuilder.Position3f( iX, iY+iHeight, 0 ); |
|
meshBuilder.AdvanceVertex(); |
|
|
|
meshBuilder.End(); |
|
pMesh->Draw(); |
|
} |
|
|
|
// Update the ground line if it's moved |
|
if ( !m_bCarried && (m_flPrevMortarYaw != m_flMortarYaw ) && |
|
gpGlobals->curtime > m_flLastGroundlineUpdateTime + g_CVMortarGroundLineUpdateInterval.GetFloat() ) |
|
{ |
|
// Create the Ground line start & end points |
|
Vector vecForward; |
|
AngleVectors( QAngle( 0, m_flMortarYaw, 0 ), &vecForward ); |
|
Vector vecStart = m_vecMortarOrigin + (vecForward * MORTAR_RANGE_MIN); |
|
|
|
float flRange = MORTAR_RANGE_MAX_INITIAL; |
|
if ( pPlayer->HasNamedTechnology( "mortar_range" ) ) |
|
flRange = MORTAR_RANGE_MAX_UPGRADED; |
|
Vector vecEnd = m_vecMortarOrigin + (vecForward * flRange); |
|
|
|
m_pDarkLine->SetParameters( m_vecMortarOrigin, vecStart, Vector( 0.1,0.1,0.1 ), Vector( 0.1,0.1,0.1 ), 0.5, 22 ); |
|
m_pGroundLine->SetParameters( vecStart, vecEnd, Vector(0,1,0), Vector(1,0,0), 0.5, 22 ); |
|
|
|
m_flPrevMortarYaw = m_flMortarYaw; |
|
|
|
m_flLastGroundlineUpdateTime = gpGlobals->curtime; |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Capture mouse input for mortar rotation |
|
//----------------------------------------------------------------------------- |
|
void C_WeaponMortar::OverrideMouseInput( float *x, float *y ) |
|
{ |
|
if ( !m_bRotating ) |
|
return; |
|
|
|
float flX = ( *x ) * 0.05f; |
|
|
|
m_flMortarYaw = anglemod(m_flMortarYaw - flX); |
|
|
|
*x = 0.0f; |
|
*y = 0.0f; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Weapon's been deployed |
|
//----------------------------------------------------------------------------- |
|
bool C_WeaponMortar::Deploy( void ) |
|
{ |
|
if ( m_pDarkLine ) |
|
{ |
|
m_pDarkLine->SetVisible( true ); |
|
} |
|
if ( m_pGroundLine ) |
|
{ |
|
m_pGroundLine->SetVisible( true ); |
|
} |
|
|
|
return BaseClass::Deploy(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Weapon's been holstered |
|
//----------------------------------------------------------------------------- |
|
bool C_WeaponMortar::Holster( C_BaseCombatWeapon *pSwitchingTo ) |
|
{ |
|
if ( m_pDarkLine ) |
|
{ |
|
m_pDarkLine->SetVisible( false ); |
|
} |
|
if ( m_pGroundLine ) |
|
{ |
|
m_pGroundLine->SetVisible( false ); |
|
} |
|
|
|
return BaseClass::Holster( pSwitchingTo ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void C_WeaponMortar::FireMortar( void ) |
|
{ |
|
// Clamp inaccuracy |
|
float flTempAcc = m_pPowerBar->m_flFiringAccuracy; |
|
if ( flTempAcc > 0.25 ) |
|
flTempAcc = 0.25; |
|
else if ( flTempAcc < -0.25 ) |
|
flTempAcc = -0.25; |
|
|
|
// HACKHACK: This is an amazingly bad way to do it. Replace this when the |
|
// client DLL can insert commands into the usercmds |
|
char szbuf[48]; |
|
Q_snprintf( szbuf, sizeof( szbuf ), "mortar %0.2f %0.2f %0.2f\n", m_pPowerBar->m_flFiringPower, flTempAcc, m_flMortarYaw ); |
|
engine->ClientCmd(szbuf); |
|
|
|
// Tell the power bar to reset soon |
|
m_pPowerBar->m_flReset = gpGlobals->curtime + 1.0; |
|
} |