//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CPropAirboat::FireGun( void ) { // Trace from eyes and see what we hit. Vector vecEyeDirection; m_hPlayer->EyeVectors( &vecEyeDirection, NULL, NULL ); Vector vecEndPos = m_hPlayer->EyePosition() + ( vecEyeDirection * MAX_TRACE_LENGTH ); trace_t trace; UTIL_TraceLine( m_hPlayer->EyePosition(), vecEndPos, MASK_SHOT, this, COLLISION_GROUP_NONE, &trace ); if ( trace.m_pEnt ) { // Get the gun position. Vector vecGunPosition; QAngle vecGunAngles; GetAttachment( LookupAttachment( "gun_barrel" ), vecGunPosition, vecGunAngles ); // Get a ray from the gun to the target. Vector vecRay = trace.endpos - vecGunPosition; VectorNormalize( vecRay ); CAmmoDef *pAmmoDef = GetAmmoDef(); int ammoType = pAmmoDef->Index( "MediumRound" ); FireBullets( 1, vecGunPosition, vecRay, vec3_origin, 4096, ammoType ); } }
CAmmoDef* GetAmmoDef() { static CAmmoDef def; static bool bInitted = false; if ( !bInitted ) { bInitted = true; def.AddAmmoType( AMMO_JAVELIN, DMG_BULLET, TRACER_LINE, 0, 0, 50/*max carry*/, 1, 0 ); } return &def; }
//----------------------------------------------------------------------------- // Purpose: Returns how much damage the given ammo type should do to the victim // when fired by the attacker. // Input : pAttacker - Dude what shot the gun. // pVictim - Dude what done got shot. // nAmmoType - What been shot out. // Output : How much hurt to put on dude what done got shot (pVictim). //----------------------------------------------------------------------------- float CGameRules::GetAmmoDamage( CBaseEntity *pAttacker, CBaseEntity *pVictim, int nAmmoType ) { float flDamage = 0; CAmmoDef *pAmmoDef = GetAmmoDef(); if ( pAttacker->IsPlayer() ) { flDamage = pAmmoDef->PlrDamage( nAmmoType ); } else { flDamage = pAmmoDef->NPCDamage( nAmmoType ); } return flDamage; }
CAmmoDef* GetAmmoDef() { static CAmmoDef def; static bool bInitted = false; if ( !bInitted ) { bInitted = true; // def.AddAmmoType( BULLET_PLAYER_50AE, DMG_BULLET, TRACER_LINE, 0, 0, "ammo_50AE_max", 2400, 0, 10, 14 ); def.AddAmmoType( AMMO_GRENADE, DMG_BLAST, TRACER_LINE, 0, 0, 1/*max carry*/, 1, 0 ); def.AddAmmoType( AMMO_BULLETS, DMG_BULLET, TRACER_LINE, 0, 0, 1/*max carry*/, 1, 0 ); } return &def; }
CAmmoDef* GetAmmoDef() { static CAmmoDef def; static bool bInitted = false; if ( !bInitted ) { bInitted = true; // Start at 1 here and skip the dummy ammo type to make CAmmoDef use the same indices // as our #defines. for ( int i=1; i < TFC_NUM_AMMO_TYPES; i++ ) { def.AddAmmoType( g_AmmoTypeNames[i], DMG_BULLET, TRACER_LINE, 0, 0, "ammo_max", 2400, 10, 14 ); Assert( def.Index( g_AmmoTypeNames[i] ) == i ); } } return &def; }
//------------------------------------------------ // Spawn //------------------------------------------------ void CASW_PropJeep::Spawn( void ) { // Setup vehicle as a real-wheels car. SetVehicleType( VEHICLE_TYPE_CAR_WHEELS ); BaseClass::Spawn(); m_flHandbrakeTime = gpGlobals->curtime + 0.1; m_bInitialHandbrake = false; m_flMinimumSpeedToEnterExit = LOCK_SPEED; m_nBulletType = GetAmmoDef()->Index("GaussEnergy"); if ( m_bHasGun ) { SetBodygroup( 1, true ); } else { SetBodygroup( 1, false ); } // Initialize pose parameters SetPoseParameter( JEEP_GUN_YAW, 0 ); SetPoseParameter( JEEP_GUN_PITCH, 0 ); m_nSpinPos = 0; SetPoseParameter( JEEP_GUN_SPIN, m_nSpinPos ); m_aimYaw = 0; m_aimPitch = 0; AddSolidFlags( FSOLID_NOT_STANDABLE ); CAmmoDef *pAmmoDef = GetAmmoDef(); m_nAmmoType = pAmmoDef->Index("GaussEnergy"); // normal HL2 vehicles don't feel nice in a network game // so destroy ourselves and spawn the serverside component of our custom ASW client authorative vehicle system }
//------------------------------------------------ // Spawn //------------------------------------------------ void CPropJeep::Spawn( void ) { // Setup vehicle as a real-wheels car. SetVehicleType( VEHICLE_TYPE_CAR_WHEELS ); BaseClass::Spawn(); m_flHandbrakeTime = gpGlobals->curtime + 0.1; m_bInitialHandbrake = false; m_VehiclePhysics.SetHasBrakePedal( false ); m_flMinimumSpeedToEnterExit = LOCK_SPEED; m_nBulletType = GetAmmoDef()->Index("GaussEnergy"); if ( m_bHasGun ) { SetBodygroup( 1, true ); } else { SetBodygroup( 1, false ); } // Initialize pose parameters SetPoseParameter( JEEP_GUN_YAW, 0 ); SetPoseParameter( JEEP_GUN_PITCH, 0 ); m_nSpinPos = 0; SetPoseParameter( JEEP_GUN_SPIN, m_nSpinPos ); m_aimYaw = 0; m_aimPitch = 0; AddSolidFlags( FSOLID_NOT_STANDABLE ); CAmmoDef *pAmmoDef = GetAmmoDef(); m_nAmmoType = pAmmoDef->Index("GaussEnergy"); }
CAmmoDef* GetAmmoDef() { static CAmmoDef def; static bool bInitted = false; if ( !bInitted ) { bInitted = true; def.AddAmmoType( "9x19mm", DMG_BULLET, TRACER_LINE_AND_WHIZ, 0, 0, 200/*max carry*/, 1, 0 ); def.AddAmmoType( "762x51mm", DMG_BULLET, TRACER_LINE_AND_WHIZ, 0, 0, 200/*max carry*/, 1, 0 ); def.AddAmmoType( "45acp", DMG_BULLET, TRACER_LINE_AND_WHIZ, 0, 0, 200/*max carry*/, 1, 0 ); def.AddAmmoType( "buckshot", DMG_BUCKSHOT, TRACER_NONE, 0, 0, 50/*max carry*/, 1, 0 ); def.AddAmmoType( "grenades", DMG_BLAST, TRACER_NONE, 0, 0, 5/*max carry*/, 1, 0 ); //Tony; added for the sdk_jeep def.AddAmmoType( "JeepAmmo", DMG_SHOCK, TRACER_NONE, "sdk_jeep_weapon_damage", "sdk_jeep_weapon_damage", "sdk_jeep_max_rounds", BULLET_IMPULSE(650, 8000), 0 ); } return &def; }
CAmmoDef *GetAmmoDef() { static CAmmoDef def; static bool bInitted = false; if ( !bInitted ) { bInitted = true; def.AddAmmoType("AR2", DMG_BULLET, TRACER_LINE_AND_WHIZ, "sk_plr_dmg_ar2", "sk_npc_dmg_ar2", "sk_max_ar2", BULLET_IMPULSE(200, 1225), 0 ); def.AddAmmoType("AlyxGun", DMG_BULLET, TRACER_LINE, "sk_plr_dmg_alyxgun", "sk_npc_dmg_alyxgun", "sk_max_alyxgun", BULLET_IMPULSE(200, 1225), 0 ); def.AddAmmoType("Pistol", DMG_BULLET, TRACER_LINE_AND_WHIZ, "sk_plr_dmg_pistol", "sk_npc_dmg_pistol", "sk_max_pistol", BULLET_IMPULSE(200, 1225), 0 ); def.AddAmmoType("SMG1", DMG_BULLET, TRACER_LINE_AND_WHIZ, "sk_plr_dmg_smg1", "sk_npc_dmg_smg1", "sk_max_smg1", BULLET_IMPULSE(200, 1225), 0 ); def.AddAmmoType("357", DMG_BULLET, TRACER_LINE_AND_WHIZ, "sk_plr_dmg_357", "sk_npc_dmg_357", "sk_max_357", BULLET_IMPULSE(800, 5000), 0 ); def.AddAmmoType("XBowBolt", DMG_BULLET, TRACER_LINE, "sk_plr_dmg_crossbow", "sk_npc_dmg_crossbow", "sk_max_crossbow", BULLET_IMPULSE(800, 8000), 0 ); def.AddAmmoType("Buckshot", DMG_BULLET | DMG_BUCKSHOT, TRACER_LINE, "sk_plr_dmg_buckshot", "sk_npc_dmg_buckshot", "sk_max_buckshot", BULLET_IMPULSE(400, 1200), 0 ); def.AddAmmoType("RPG_Round", DMG_BURN, TRACER_NONE, "sk_plr_dmg_rpg_round", "sk_npc_dmg_rpg_round", "sk_max_rpg_round", 0, 0 ); def.AddAmmoType("SMG1_Grenade", DMG_BURN, TRACER_NONE, "sk_plr_dmg_smg1_grenade", "sk_npc_dmg_smg1_grenade", "sk_max_smg1_grenade", 0, 0 ); def.AddAmmoType("Grenade", DMG_BURN, TRACER_NONE, "sk_plr_dmg_grenade", "sk_npc_dmg_grenade", "sk_max_grenade", 0, 0); def.AddAmmoType("Thumper", DMG_SONIC, TRACER_NONE, 10, 10, 2, 0, 0 ); def.AddAmmoType("Gravity", DMG_CLUB, TRACER_NONE, 0, 0, 8, 0, 0 ); def.AddAmmoType("Battery", DMG_CLUB, TRACER_NONE, NULL, NULL, NULL, 0, 0 ); def.AddAmmoType("GaussEnergy", DMG_SHOCK, TRACER_NONE, "sk_jeep_gauss_damage", "sk_jeep_gauss_damage", "sk_max_gauss_round", BULLET_IMPULSE(650, 8000), 0 ); // hit like a 10kg weight at 400 in/s def.AddAmmoType("CombineCannon", DMG_BULLET, TRACER_LINE, "sk_npc_dmg_gunship_to_plr", "sk_npc_dmg_gunship", NULL, 1.5 * 750 * 12, 0 ); // hit like a 1.5kg weight at 750 ft/s def.AddAmmoType("AirboatGun", DMG_AIRBOAT, TRACER_LINE, "sk_plr_dmg_airboat", "sk_npc_dmg_airboat", NULL, BULLET_IMPULSE(10, 600), 0 ); def.AddAmmoType("slam", DMG_BURN, TRACER_NONE, 0, 0, 5, 0, 0 ); def.AddAmmoType("AR2AltFire", DMG_DISSOLVE, TRACER_NONE, 0, 0, "sk_max_ar2_altfire", 0, 0 ); def.AddAmmoType("Grenade", DMG_BURN, TRACER_NONE, "sk_plr_dmg_grenade", "sk_npc_dmg_grenade", "sk_max_grenade", 0, 0); } return &def; }
void C_TEHL2MPFireBullets::CreateEffects( void ) { CAmmoDef* pAmmoDef = GetAmmoDef(); if ( pAmmoDef == NULL ) return; C_BaseEntity *pEnt = ClientEntityList().GetEnt( m_iPlayer ); if ( pEnt ) { C_BasePlayer *pPlayer = dynamic_cast<C_BasePlayer *>(pEnt); if ( pPlayer && pPlayer->GetActiveWeapon() ) { C_BaseCombatWeapon *pWpn = dynamic_cast<C_BaseCombatWeapon *>( pPlayer->GetActiveWeapon() ); if ( pWpn ) { int iSeed = m_iSeed; CShotManipulator Manipulator( m_vecDir ); for (int iShot = 0; iShot < m_iShots; iShot++) { RandomSeed( iSeed ); // init random system with this seed // Don't run the biasing code for the player at the moment. Vector vecDir = Manipulator.ApplySpread( Vector( m_flSpread, m_flSpread, m_flSpread ) ); Vector vecEnd = m_vecOrigin + vecDir * MAX_TRACE_LENGTH; trace_t tr; CTraceFilterSkipPlayerAndViewModelOnly traceFilter; if( m_iShots > 1 && iShot % 2 ) { // Half of the shotgun pellets are hulls that make it easier to hit targets with the shotgun. UTIL_TraceHull( m_vecOrigin, vecEnd, Vector( -3, -3, -3 ), Vector( 3, 3, 3 ), MASK_SHOT, &traceFilter, &tr ); } else { UTIL_TraceLine( m_vecOrigin, vecEnd, MASK_SHOT, &traceFilter, &tr); } if ( m_bDoTracers ) { const char *pTracerName = pWpn->GetTracerType(); CEffectData data; data.m_vStart = tr.startpos; data.m_vOrigin = tr.endpos; data.m_hEntity = pWpn->GetRefEHandle(); data.m_flScale = 0.0f; data.m_fFlags |= TRACER_FLAG_USEATTACHMENT; // Stomp the start, since it's not going to be used anyway data.m_nAttachmentIndex = 1; if ( pTracerName ) { DispatchEffect( pTracerName, data ); } else { DispatchEffect( "Tracer", data ); } } if ( m_bDoImpacts ) { pWpn->DoImpactEffect( tr, pAmmoDef->DamageType( m_iAmmoID ) ); } iSeed++; } } } } }
CAmmoDef *GetAmmoDef() { static CAmmoDef def; static bool bInitted = false; if ( !bInitted ) { bInitted = true; def.AddAmmoType("AR2", DMG_BULLET, TRACER_LINE_AND_WHIZ, 0, 0, 60, BULLET_IMPULSE(200, 1225), 0 ); def.AddAmmoType("AR2AltFire", DMG_DISSOLVE, TRACER_NONE, 0, 0, 3, 0, 0 ); def.AddAmmoType("Pistol", DMG_BULLET, TRACER_LINE_AND_WHIZ, 0, 0, 150, BULLET_IMPULSE(200, 1225), 0 ); def.AddAmmoType("SMG1", DMG_BULLET, TRACER_LINE_AND_WHIZ, 0, 0, 225, BULLET_IMPULSE(200, 1225), 0 ); def.AddAmmoType("357", DMG_BULLET, TRACER_LINE_AND_WHIZ, 0, 0, 12, BULLET_IMPULSE(800, 5000), 0 ); def.AddAmmoType("XBowBolt", DMG_BULLET, TRACER_LINE, 0, 0, 10, BULLET_IMPULSE(800, 8000), 0 ); def.AddAmmoType("Buckshot", DMG_BULLET | DMG_BUCKSHOT, TRACER_LINE, 0, 0, 30, BULLET_IMPULSE(400, 1200), 0 ); def.AddAmmoType("RPG_Round", DMG_BURN, TRACER_NONE, 0, 0, 3, 0, 0 ); def.AddAmmoType("SMG1_Grenade", DMG_BURN, TRACER_NONE, 0, 0, 3, 0, 0 ); def.AddAmmoType("Grenade", DMG_BURN, TRACER_NONE, 0, 0, 5, 0, 0 ); def.AddAmmoType("slam", DMG_BURN, TRACER_NONE, 0, 0, 5, 0, 0 ); } return &def; }
CAmmoDef *GetAmmoDef() { static CAmmoDef def; static bool bInitted = false; if ( !bInitted ) { bInitted = true; def.AddAmmoType("AR2", DMG_BULLET, TRACER_LINE_AND_WHIZ, 0, 0, 60, BULLET_IMPULSE(200, 1225), 0 ); def.AddAmmoType("AR2AltFire", DMG_DISSOLVE, TRACER_NONE, 0, 0, 3, 0, 0 ); def.AddAmmoType("Pistol", DMG_BULLET, TRACER_LINE_AND_WHIZ, 0, 0, 150, BULLET_IMPULSE(200, 1225), 0 ); def.AddAmmoType("SMG1", DMG_BULLET, TRACER_LINE_AND_WHIZ, 0, 0, 225, BULLET_IMPULSE(200, 1225), 0 ); def.AddAmmoType("357", DMG_BULLET, TRACER_LINE_AND_WHIZ, 0, 0, 12, BULLET_IMPULSE(800, 5000), 0 ); def.AddAmmoType("XBowBolt", DMG_BULLET, TRACER_LINE, 0, 0, 10, BULLET_IMPULSE(800, 8000), 0 ); def.AddAmmoType("Buckshot", DMG_BULLET | DMG_BUCKSHOT, TRACER_LINE, 0, 0, 30, BULLET_IMPULSE(400, 1200), 0 ); def.AddAmmoType("RPG_Round", DMG_BURN, TRACER_NONE, 0, 0, 3, 0, 0 ); def.AddAmmoType("SMG1_Grenade", DMG_BURN, TRACER_NONE, 0, 0, 3, 0, 0 ); def.AddAmmoType("Grenade", DMG_BURN, TRACER_NONE, 0, 0, 5, 0, 0 ); def.AddAmmoType("slam", DMG_BURN, TRACER_NONE, 0, 0, 5, 0, 0 ); #ifdef HL2MP_DEV_DLL def.AddAmmoType("GaussEnergy", DMG_SHOCK, TRACER_NONE, "sk_jeep_gauss_damage", "sk_jeep_gauss_damage", "sk_max_gauss_round", BULLET_IMPULSE(650, 8000), 0 ); // hit like a 10kg weight at 400 in/s def.AddAmmoType("AirboatGun", DMG_AIRBOAT, TRACER_LINE, "sk_plr_dmg_airboat", "sk_npc_dmg_airboat", NULL, BULLET_IMPULSE(10, 600), 0 ); #endif } return &def; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CUnitBase::FireBullets( const FireBulletsInfo_t &info ) { VPROF_BUDGET( "CUnitBase::FireBullets", VPROF_BUDGETGROUP_UNITS ); static int tracerCount; trace_t tr; CAmmoDef* pAmmoDef = GetAmmoDef(); int nDamageType = pAmmoDef->DamageType(info.m_iAmmoType); //int nAmmoFlags = pAmmoDef->Flags(info.m_iAmmoType); int iNumShots; float flActualDamage; // the default attacker is ourselves CBaseEntity *pAttacker = info.m_pAttacker ? info.m_pAttacker : this; ClearMultiDamage(); g_MultiDamage.SetDamageType( nDamageType | DMG_NEVERGIB ); Vector vecDir; Vector vecEnd; // Adjust spread to accuracy Vector vecSpread( info.m_vecSpread ); //vecSpread.x = sin( ( (asin( info.m_vecSpread.x ) * 2.0f) * m_fAccuracy ) / 2.0f ); //vecSpread.y = sin( ( (asin( info.m_vecSpread.y ) * 2.0f) * m_fAccuracy ) / 2.0f ); //vecSpread.z = sin( ( (asin( info.m_vecSpread.z ) * 2.0f) * m_fAccuracy ) / 2.0f ); // Skip multiple entities when tracing CWarsBulletsFilter traceFilter( this, COLLISION_GROUP_NONE ); traceFilter.SetPassEntity( this ); // Standard pass entity for THIS so that it can be easily removed from the list after passing through a portal traceFilter.AddEntityToIgnore( info.m_pAdditionalIgnoreEnt ); CShotManipulator Manipulator( info.m_vecDirShooting ); iNumShots = info.m_iShots; flActualDamage = info.m_flDamage; if ( flActualDamage == 0.0 ) { flActualDamage = g_pGameRules->GetAmmoDamage( pAttacker, tr.m_pEnt, info.m_iAmmoType ); } flActualDamage *= m_fAccuracy; // Pretty much a damage modifier for (int iShot = 0; iShot < iNumShots; iShot++) { //vecDir = info.m_vecDirShooting; vecDir = Manipulator.ApplySpread( vecSpread ); vecEnd = info.m_vecSrc + vecDir * info.m_flDistance; AI_TraceLine(info.m_vecSrc, vecEnd, MASK_SHOT, &traceFilter, &tr); if( unit_debugfirebullets.GetBool() ) { #ifdef CLIENT_DLL NDebugOverlay::Line(info.m_vecSrc, vecEnd, 255, 0, 0, 255, 0.1f); NDebugOverlay::Line(info.m_vecSrc, tr.endpos, 0, 255, 0, 255, 0.1f); #else NDebugOverlay::Line(info.m_vecSrc, vecEnd, 255, 255, 0, 255, 0.1f); NDebugOverlay::Line(info.m_vecSrc, tr.endpos, 0, 255, 255, 255, 0.1f); #endif // CLIENT_DLL } // Make sure given a valid bullet type if (info.m_iAmmoType == -1) { DevMsg("ERROR: Undefined ammo type!\n"); return; } Vector vecTracerDest = tr.endpos; // do damage, paint decals if (tr.fraction != 1.0) { CTakeDamageInfo dmgInfo( pAttacker, pAttacker, flActualDamage, nDamageType ); CalculateBulletDamageForce( &dmgInfo, info.m_iAmmoType, vecDir, tr.endpos ); dmgInfo.ScaleDamageForce( info.m_flDamageForceScale ); dmgInfo.SetAmmoType( info.m_iAmmoType ); (dynamic_cast<CBaseEntity *>(tr.m_pEnt))->DispatchTraceAttack( dmgInfo, vecDir, &tr ); // Effects only, FireBullets should be called on the client. // Dispatching on the server generates far too many events/data! #ifdef CLIENT_DLL DoImpactEffect( tr, nDamageType ); Vector vecTracerSrc = vec3_origin; ComputeTracerStartPosition( info.m_vecSrc, &vecTracerSrc ); trace_t Tracer; Tracer = tr; Tracer.endpos = vecTracerDest; MakeTracer( vecTracerSrc, Tracer, pAmmoDef->TracerType(info.m_iAmmoType) ); #endif // CLIENT_DLL } } #ifdef GAME_DLL ApplyMultiDamage(); #endif // GAME_DLL }