sqwarmed/sdk_src/game/shared/swarm/asw_weapon_pdw_shared.cpp

331 lines
8.9 KiB
C++

#include "cbase.h"
#include "asw_weapon_pdw_shared.h"
#include "in_buttons.h"
#ifdef CLIENT_DLL
#include "c_asw_player.h"
#include "c_asw_weapon.h"
#include "c_asw_marine.h"
#include "c_te_legacytempents.h"
#include "c_breakableprop.h"
#include "fx.h"
#include "c_asw_fx.h"
#define CASW_Marine C_ASW_Marine
#else
#include "asw_lag_compensation.h"
#include "asw_marine.h"
#include "asw_player.h"
#include "asw_weapon.h"
#include "asw_marine_resource.h"
#include "npcevent.h"
#include "shot_manipulator.h"
#include "asw_marine_speech.h"
#include "asw_weapon_ammo_bag_shared.h"
#endif
#include "asw_marine_skills.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_PDW, DT_ASW_Weapon_PDW )
BEGIN_NETWORK_TABLE( CASW_Weapon_PDW, DT_ASW_Weapon_PDW )
#ifdef CLIENT_DLL
// recvprops
RecvPropBool(RECVINFO(m_bBulletMod)),
#else
// sendprops
SendPropBool(SENDINFO(m_bBulletMod)),
#endif
END_NETWORK_TABLE()
BEGIN_PREDICTION_DATA( CASW_Weapon_PDW )
#ifdef CLIENT_DLL
DEFINE_PRED_FIELD( m_bBulletMod, FIELD_BOOLEAN, FTYPEDESC_INSENDTABLE ),
#endif
END_PREDICTION_DATA()
LINK_ENTITY_TO_CLASS( asw_weapon_pdw, CASW_Weapon_PDW );
PRECACHE_WEAPON_REGISTER(asw_weapon_pdw);
ConVar asw_pdw_max_shooting_distance( "asw_pdw_max_shooting_distance", "400", FCVAR_REPLICATED, "Maximum distance of the hitscan weapons." );
extern ConVar asw_weapon_max_shooting_distance;
extern ConVar asw_weapon_force_scale;
CASW_Weapon_PDW::CASW_Weapon_PDW()
{
m_bBulletMod = false;
}
CASW_Weapon_PDW::~CASW_Weapon_PDW()
{
}
#ifndef CLIENT_DLL
extern ConVar asw_debug_marine_damage;
//---------------------------------------------------------
// Save/Restore
//---------------------------------------------------------
BEGIN_DATADESC( CASW_Weapon_PDW )
END_DATADESC()
void CASW_Weapon_PDW::Spawn()
{
BaseClass::Spawn();
}
// just dry fire by default
void CASW_Weapon_PDW::SecondaryAttack( void )
{
// Only the player fires this way so we can cast
CASW_Player *pPlayer = GetCommander();
if (!pPlayer)
return;
CASW_Marine *pMarine = GetMarine();
if (!pMarine)
return;
SendWeaponAnim( ACT_VM_DRYFIRE );
BaseClass::WeaponSound( EMPTY );
m_flNextSecondaryAttack = gpGlobals->curtime + 0.5f;
}
#endif /* not client */
void CASW_Weapon_PDW::Precache()
{
// precache the weapon model here?
BaseClass::Precache();
}
void CASW_Weapon_PDW::PrimaryAttack()
{
// If my clip is empty (and I use clips) start reload
if ( UsesClipsForAmmo1() && !m_iClip1 )
{
Reload();
return;
}
CASW_Player *pPlayer = GetCommander();
CASW_Marine *pMarine = GetMarine();
if (pMarine) // firing from a marine
{
m_bIsFiring = true;
// MUST call sound before removing a round from the clip of a CMachineGun
WeaponSound(SINGLE);
if (m_iClip1 <= AmmoClickPoint())
{
LowAmmoSound();
}
// tell the marine to tell its weapon to draw the muzzle flash
pMarine->DoMuzzleFlash();
// sets the animation on the weapon model iteself
SendWeaponAnim( GetPrimaryAttackActivity() );
// sets the animation on the marine holding this weapon
//pMarine->SetAnimation( PLAYER_ATTACK1 );
#ifdef GAME_DLL // check for turning on lag compensation
if (pPlayer && pMarine->IsInhabited())
{
CASW_Lag_Compensation::RequestLagCompensation( pPlayer, pPlayer->GetCurrentUserCommand() );
}
#endif
FireBulletsInfo_t info;
info.m_vecSrc = pMarine->Weapon_ShootPosition( );
if ( pPlayer && pMarine->IsInhabited() )
{
info.m_vecDirShooting = pPlayer->GetAutoaimVectorForMarine(pMarine, GetAutoAimAmount(), GetVerticalAdjustOnlyAutoAimAmount()); // 45 degrees = 0.707106781187
}
else
{
#ifdef CLIENT_DLL
Msg("Error, clientside firing of a weapon that's being controlled by an AI marine\n");
#else
info.m_vecDirShooting = pMarine->GetActualShootTrajectory( info.m_vecSrc );
#endif
}
// To make the firing framerate independent, we may have to fire more than one bullet here on low-framerate systems,
// especially if the weapon we're firing has a really fast rate of fire.
info.m_iShots = 0;
float fireRate = GetFireRate();
while ( m_flNextPrimaryAttack <= gpGlobals->curtime )
{
m_flNextPrimaryAttack = m_flNextPrimaryAttack + fireRate;
info.m_iShots++;
if ( !fireRate )
break;
}
// Make sure we don't fire more than the amount in the clip
if ( UsesClipsForAmmo1() )
{
info.m_iShots = MIN( info.m_iShots, m_iClip1 );
for (int k=0;k<info.m_iShots;k++)
{
//if (m_bBulletMod)
{
m_iClip1 -= 1;
#ifdef GAME_DLL
CASW_Marine *pMarine = GetMarine();
if (pMarine && m_iClip1 <= 0 && pMarine->GetAmmoCount(m_iPrimaryAmmoType) <= 0 )
{
// check he doesn't have ammo in an ammo bay
CASW_Weapon_Ammo_Bag* pAmmoBag = dynamic_cast<CASW_Weapon_Ammo_Bag*>(pMarine->GetASWWeapon(0));
if (!pAmmoBag)
pAmmoBag = dynamic_cast<CASW_Weapon_Ammo_Bag*>(pMarine->GetASWWeapon(1));
if (!pAmmoBag || !pAmmoBag->CanGiveAmmoToWeapon(this))
pMarine->OnWeaponOutOfAmmo(true);
}
#endif
}
//m_bBulletMod = !m_bBulletMod;
}
}
else
{
info.m_iShots = MIN( info.m_iShots, pMarine->GetAmmoCount( m_iPrimaryAmmoType ) );
for (int k=0;k<info.m_iShots;k++)
{
if (m_bBulletMod)
pMarine->RemoveAmmo( info.m_iShots, m_iPrimaryAmmoType );;
m_bBulletMod = !m_bBulletMod;
}
}
info.m_flDistance = asw_weapon_max_shooting_distance.GetFloat();
info.m_iAmmoType = m_iPrimaryAmmoType;
info.m_iTracerFreq = 1; // asw tracer test everytime
info.m_vecSpread = pMarine->GetActiveWeapon()->GetBulletSpread();
info.m_flDamage = GetWeaponDamage();
info.m_flDamageForceScale = asw_weapon_force_scale.GetFloat();
#ifndef CLIENT_DLL
if (asw_debug_marine_damage.GetBool())
Msg("Weapon dmg = %f\n", info.m_flDamage);
info.m_flDamage *= pMarine->GetMarineResource()->OnFired_GetDamageScale();
#endif
pMarine->FireBullets( info );
// increment shooting stats
#ifndef CLIENT_DLL
if (pMarine && pMarine->GetMarineResource())
{
pMarine->GetMarineResource()->UsedWeapon(this, info.m_iShots);
pMarine->OnWeaponFired( this, info.m_iShots );
}
#endif
}
}
int CASW_Weapon_PDW::ASW_SelectWeaponActivity(int idealActivity)
{
switch( idealActivity )
{
case ACT_WALK: idealActivity = ACT_MP_WALK_ITEM1; break;
case ACT_RUN: idealActivity = ACT_MP_RUN_ITEM1; break;
case ACT_IDLE: idealActivity = ACT_MP_STAND_ITEM1; break;
case ACT_RELOAD: idealActivity = ACT_RELOAD_PISTOL; break; // short (pistol) reload
case ACT_RANGE_ATTACK1: idealActivity = ACT_MP_ATTACK_STAND_ITEM1; break;
case ACT_CROUCHIDLE: idealActivity = ACT_MP_CROUCHWALK_ITEM1; break;
case ACT_JUMP: idealActivity = ACT_MP_JUMP_ITEM1; break;
default:
return BaseClass::ASW_SelectWeaponActivity(idealActivity);
}
return idealActivity;
}
float CASW_Weapon_PDW::GetWeaponDamage()
{
//float flDamage = 18.0f;
float flDamage = GetWeaponInfo()->m_flBaseDamage;
if ( GetMarine() )
{
flDamage += MarineSkills()->GetSkillBasedValueByMarine(GetMarine(), ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_PDW_DMG);
}
//CALL_ATTRIB_HOOK_FLOAT( flDamage, mod_damage_done );
return flDamage;
}
#ifdef CLIENT_DLL
void CASW_Weapon_PDW::OnMuzzleFlashed()
{
BaseClass::OnMuzzleFlashed();
// UNDONE: flash both guns from ASWUTracerDual
// int iAttachment = LookupAttachment( "muzzle_flash_l" );
// if ( iAttachment > 0 )
// {
// float flScale = GetMuzzleFlashScale();
// if (GetMuzzleFlashRed())
// {
// FX_ASW_RedMuzzleEffectAttached( flScale, GetRefEHandle(), iAttachment, NULL, false );
// }
// else
// {
// FX_ASW_MuzzleEffectAttached( flScale, GetRefEHandle(), iAttachment, NULL, false );
// }
// }
}
float CASW_Weapon_PDW::GetMuzzleFlashScale( void )
{
return BaseClass::GetMuzzleFlashScale();
/*
// if we haven't calculated the muzzle scale based on the carrying marine's skill yet, then do so
if (m_fMuzzleFlashScale == -1)
{
C_ASW_Marine *pMarine = GetMarine();
if (pMarine)
m_fMuzzleFlashScale = 2.0f * MarineSkills()->GetSkillBasedValueByMarine(pMarine, ASW_MARINE_SKILL_ACCURACY, ASW_MARINE_SUBSKILL_ACCURACY_MUZZLE);
else
return 2.0f;
}
return m_fMuzzleFlashScale;
*/
}
bool CASW_Weapon_PDW::GetMuzzleFlashRed()
{
return BaseClass::GetMuzzleFlashRed();
//return ((GetMuzzleFlashScale() / 2.0f) >= 1.15f); // red if our muzzle flash is the biggest size based on our skill
}
#endif
// user message based tracer type
const char* CASW_Weapon_PDW::GetUTracerType()
{
return "ASWUTracerDual";
}
float CASW_Weapon_PDW::GetFireRate()
{
//float flRate = 0.035f;
float flRate = GetWeaponInfo()->m_flFireRate;
//CALL_ATTRIB_HOOK_FLOAT( flRate, mod_fire_rate );
return flRate;
}