Prediction/Sample weapon
From Valve Developer Community
This weapon will print data to the console when prediction events occur. Equip it with give weapon_test.
C++
Include this in both your client and server projects.
#include "cbase.h" #ifdef CLIENT_DLL #include "prediction.h" #define CTestWeapon C_TestWeapon #endif class CTestWeapon : public CBaseCombatWeapon { public: DECLARE_CLASS( CTestWeapon, CBaseCombatWeapon ); DECLARE_NETWORKCLASS(); #ifdef CLIENT_DLL DECLARE_PREDICTABLE(); virtual bool ShouldPredict(); #endif virtual bool IsPredicted() const { return true; } CTestWeapon() { SetPredictionEligible(true); iTest = 0; } void PrimaryAttack(); void SecondaryAttack(); void ShootBullet(bool bRapidFire); #ifdef GAME_DLL CNetworkVar( int, iTest ); #elif CLIENT_DLL int iTest; #endif }; LINK_ENTITY_TO_CLASS( weapon_test, CTestWeapon ); PRECACHE_WEAPON_REGISTER( weapon_test ); IMPLEMENT_NETWORKCLASS_ALIASED( TestWeapon, DT_TestWeapon ) #ifdef CLIENT_DLL BEGIN_PREDICTION_DATA( CTestWeapon ) DEFINE_PRED_FIELD( iTest, FIELD_INTEGER, FTYPEDESC_NOERRORCHECK) END_PREDICTION_DATA() bool CTestWeapon::ShouldPredict() { if ( GetOwner() && GetOwner() == C_BasePlayer::GetLocalPlayer() ) return true; else return BaseClass::ShouldPredict(); } void RecvProxy_TestWeapon( const CRecvProxyData *pData, void *pStruct, void *pOut ) { int value = *((unsigned long*)&pData->m_Value.m_Int); static int oldvalue = 0; if ( value != oldvalue ) Warning( "Client updated to shot %i\n", value ); oldvalue = value; *((unsigned long*)pOut) = value; } #endif // CLIENT_DLL BEGIN_NETWORK_TABLE( CTestWeapon, DT_TestWeapon ) #ifdef GAME_DLL SendPropInt( SENDINFO(iTest) ), #elif CLIENT_DLL RecvPropInt( RECVINFO(iTest),-1, RecvProxy_TestWeapon ), #endif END_NETWORK_TABLE() void CTestWeapon::PrimaryAttack() { ShootBullet(false); m_flNextPrimaryAttack = gpGlobals->curtime + 0.75; } void CTestWeapon::SecondaryAttack() { ShootBullet(true); m_flNextSecondaryAttack = gpGlobals->curtime + 0.25; } void CTestWeapon::ShootBullet(bool bRapidFire) { iTest++; #ifdef CLIENT_DLL if ( prediction->IsFirstTimePredicted() ) Msg( "Client made shot %i\n", iTest ); else Msg( "\tClient testing shot %i\n", iTest ); #elif GAME_DLL Warning("Server received shot %i\n",iTest); #endif FireBulletsInfo_t attack; CBasePlayer* pPlayer = ToBasePlayer( GetOwner() ); if ( pPlayer ) { pPlayer->RemoveAmmo( attack.m_iShots, m_iPrimaryAmmoType ); pPlayer->DoMuzzleFlash(); pPlayer->SetAnimation( PLAYER_ATTACK1 ); attack.m_vecSrc = pPlayer->Weapon_ShootPosition(); } else attack.m_vecSrc = GetOwner()->GetAbsOrigin(); attack.m_flDistance = MAX_TRACE_LENGTH; attack.m_iAmmoType = m_iPrimaryAmmoType; attack.m_iTracerFreq = 2; Vector fwd; AngleVectors(GetOwner()->GetAbsAngles(),&fwd); attack.m_vecDirShooting = fwd; if ( bRapidFire ) { attack.m_vecSpread = VECTOR_CONE_10DEGREES; attack.m_bPrimaryAttack = false; } GetOwner()->FireBullets( attack ); WeaponSound(SINGLE); SendWeaponAnim( GetPrimaryAttackActivity() ); }
Script
Save this as mod\scripts\weapon_test.txt. Remember to change the ammo in use from "pistol" to something your AmmoDef recognises.
WeaponData { printname "Prediction test weapon" viewmodel models/weapons/v_357.mdl playermodel models/weapons/w_357.mdl anim_prefix python bucket 1 bucket_position 1 clip_size -1 clip2_size -1 primary_ammo pistol secondary_ammo pistol weight 7 SoundData { empty Weapon_Pistol.Empty single_shot Weapon_357.Single } TextureData { weapon { font WeaponIcons character e } weapon_s { font WeaponIconsSelected character e } weapon_small { font WeaponIconsSmall character e } ammo { font WeaponIconsSmall character q } crosshair { font Crosshairs character Q } autoaim { file sprites/crosshairs x 0 y 48 width 24 height 24 } } }
