📄 c_weapon_mortar.cpp
字号:
}
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( int *x, int *y )
{
if ( !m_bRotating )
return;
float flX = ((float)*x) * 0.05;
m_flMortarYaw = anglemod(m_flMortarYaw - flX);
*x = 0;
*y = 0;
}
//-----------------------------------------------------------------------------
// 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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -