📄 c_weapon_mortar.cpp
字号:
//======== (C) Copyright 1999, 2000 Valve, L.L.C. All rights reserved. ========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// 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" );
}
//-----------------------------------------------------------------------------
// 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( int *x, int *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", NULL );
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" );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -