void CClientWeapon::DoGunShells ( CVector vecOrigin, CVector vecDirection ) { float fShellSize = 0.0f; switch( m_Type ) { case(WEAPONTYPE_MINIGUN): case(WEAPONTYPE_M4): case(WEAPONTYPE_AK47): { if ( m_ucCounter == 0) { fShellSize = 0.25f; m_ucCounter = 1; } else { m_ucCounter = 0; } break; } break; case(WEAPONTYPE_MICRO_UZI): case(WEAPONTYPE_MP5): case(WEAPONTYPE_TEC9): fShellSize = 0.3f; break; case(WEAPONTYPE_SNIPERRIFLE): case(WEAPONTYPE_PISTOL): case(WEAPONTYPE_PISTOL_SILENCED): case(WEAPONTYPE_DESERT_EAGLE): fShellSize = 0.25f; break; case(WEAPONTYPE_SHOTGUN): case(WEAPONTYPE_SAWNOFF_SHOTGUN): case(WEAPONTYPE_SPAS12_SHOTGUN): fShellSize = 0.45f; break; } if(fShellSize > 0.0f) { if ( !m_weaponConfig.bDisableWeaponModel ) { g_pGame->GetPointLights ()->AddLight ( PLTYPE_POINTLIGHT, vecOrigin, CVector (), 3.0f, 0.22f, 0.25f, 0, 0, 0, 0 ); } if ( GetAttachedTo () ) g_pGame->GetFx ()->TriggerGunshot ( NULL, vecOrigin, vecDirection, true ); else g_pGame->GetFx ()->TriggerGunshot ( NULL, vecOrigin, vecDirection, true ); m_pWeapon->AddGunshell ( m_pObject, &vecOrigin, &CVector2D ( 0, -1 ), fShellSize ); if ( m_Type != WEAPONTYPE_MINIGUN ) { g_pGame->GetAudioEngine ()->ReportWeaponEvent ( WEAPON_EVENT_FIRE, m_Type, m_pObject ); } } }
void CClientSound::Process3D ( CVector vecPosition ) { if ( !m_pSound || !m_b3D ) return; // Update our position and velocity if we're attached CClientEntity* pAttachedToEntity = GetAttachedTo (); if ( pAttachedToEntity ) { DoAttaching (); CVector vecVelocity; if ( CStaticFunctionDefinitions::GetElementVelocity ( *pAttachedToEntity, vecVelocity ) ) SetVelocity ( vecVelocity ); } // Volume float fDistance = DistanceBetweenPoints3D ( vecPosition, m_vecPosition ); float fDistDiff = m_fMaxDistance - m_fMinDistance; float fVolume = 1.0; //Transform e^-x to suit our sound if ( fDistance <= m_fMinDistance ) fVolume = 1.0f; else if ( fDistance >= m_fMaxDistance ) fVolume = 0.0f; else fVolume = exp ( - ( fDistance - m_fMinDistance ) * ( CUT_OFF / fDistDiff ) ); BASS_ChannelSetAttribute( m_pSound, BASS_ATTRIB_VOL, fVolume * m_fVolume ); }
//////////////////////////////////////////////////////////// // // CClientSound::Process3D // // Update position and velocity and pass on the BASS for processing. // m_pAudio->DoPulse needs to be called for non-3D sounds also. // //////////////////////////////////////////////////////////// void CClientSound::Process3D ( const CVector& vecPlayerPosition, const CVector& vecCameraPosition, const CVector& vecLookAt ) { // Update 3D things if required if ( m_b3D ) { // Update our position and velocity if we're attached CClientEntity* pAttachedToEntity = GetAttachedTo (); if ( pAttachedToEntity ) { GetPosition( m_vecPosition ); DoAttaching (); CVector vecVelocity; if ( CStaticFunctionDefinitions::GetElementVelocity ( *pAttachedToEntity, vecVelocity ) ) SetVelocity ( vecVelocity ); // Update our spatial data position UpdateSpatialData (); } } // If the sound isn't active, we don't need to process it // Moved after 3D updating as the streamer didn't know the position changed if a sound isn't streamed in when attached. if ( !m_pAudio ) return; m_pAudio->DoPulse ( vecPlayerPosition, vecCameraPosition, vecLookAt ); // Trigger script events for things SSoundEventInfo eventInfo; while ( m_pAudio->GetQueuedEvent ( eventInfo ) ) { if ( eventInfo.type == SOUND_EVENT_FINISHED_DOWNLOAD ) { CLuaArguments Arguments; Arguments.PushNumber ( eventInfo.dNumber ); CallEvent ( "onClientSoundFinishedDownload", Arguments, true ); OutputDebugLine ( SString ( "[ClientSound] onClientSoundFinishedDownload %f", eventInfo.dNumber ) ); } else if ( eventInfo.type == SOUND_EVENT_CHANGED_META ) { CLuaArguments Arguments; Arguments.PushString ( eventInfo.strString ); CallEvent ( "onClientSoundChangedMeta", Arguments, true ); OutputDebugLine ( SString ( "[ClientSound] onClientSoundChangedMeta %s", *eventInfo.strString ) ); } else if ( eventInfo.type == SOUND_EVENT_STREAM_RESULT ) { // Call onClientSoundStream LUA event CLuaArguments Arguments; Arguments.PushBoolean ( eventInfo.bBool ); Arguments.PushNumber ( eventInfo.dNumber ); if ( !eventInfo.strString.empty () ) Arguments.PushString ( eventInfo.strString ); CallEvent ( "onClientSoundStream", Arguments, true ); OutputDebugLine ( SString ( "[ClientSound] onClientSoundStream %d %f %s", eventInfo.bBool, eventInfo.dNumber, *eventInfo.strString ) ); } else if ( eventInfo.type == SOUND_EVENT_BEAT ) { CLuaArguments Arguments; Arguments.PushNumber ( eventInfo.dNumber ); CallEvent ( "onClientSoundBeat", Arguments, true ); } } }
void CClientWeapon::FireInstantHit ( CVector vecOrigin, CVector vecTarget, bool bServerFire, bool bRemote ) #endif { CVector vecDirection = vecTarget - vecOrigin; vecDirection.Normalize (); CClientEntity * pAttachedTo = GetAttachedTo (); CVector vecOriginalTarget = vecTarget; CEntity * pColEntity = NULL; CColPoint * pColPoint = NULL; SLineOfSightBuildingResult pBuildingResult; CEntitySAInterface * pEntity = NULL; if ( m_Type != WEAPONTYPE_SHOTGUN ) { CVector vecWeaponFirePosition; if ( !IsLocalEntity ( ) && m_pOwner ) { CClientPlayer * pPlayer = m_pOwner; CClientPed * pLocalPlayer = g_pClientGame->GetLocalPlayer(); if ( pLocalPlayer && pPlayer ) { CClientVehicle* pVehicle = pLocalPlayer->GetRealOccupiedVehicle (); // Move both players to where they should be for shot compensation if ( pPlayer && !pPlayer->IsLocalPlayer () ) { if ( !pVehicle || pLocalPlayer->GetOccupiedVehicleSeat() == 0 ) { // Warp back in time to where we were when this player shot (their latency) // We don't account for interpolation here, +250ms seems to work better // ** Changed ajustment to +125ms as the position of this clients player on the firers screen // has been changed. See CClientPed::UpdateTargetPosition() ** CVector vecPosition; unsigned short usLatency = ( pPlayer->GetLatency () + 125 ); g_pClientGame->GetNetAPI()->GetInterpolation ( vecPosition, usLatency ); // Move the entity back if ( pVehicle ) { pVehicle->GetPosition ( vecWeaponFirePosition ); pVehicle->SetPosition ( vecPosition, false, false ); } else { pLocalPlayer->GetPosition ( vecWeaponFirePosition ); pLocalPlayer->SetPosition ( vecPosition, false, false ); } } } } } //if ( pAttachedTo ) pAttachedTo->WorldIgnore ( true ); if ( m_pWeapon->ProcessLineOfSight ( &vecOrigin, &vecTarget, &pColPoint, &pColEntity, m_weaponConfig.flags, &pBuildingResult, m_Type, &pEntity ) ) { vecTarget = pColPoint->GetPosition (); } // Don't continue without a valid colpoint if ( !pColPoint ) return; //if ( pAttachedTo ) pAttachedTo->WorldIgnore ( false ); // return if shoot if target is blocked is false and we aren't pointing at our target if ( ( m_pTarget != NULL && m_pTarget->GetGameEntity ( ) != NULL && m_pTarget->GetGameEntity()->GetInterface ( ) != pEntity ) && m_weaponConfig.bShootIfTargetBlocked == false && bRemote == false ) { if ( pColPoint ) pColPoint->Destroy (); return; } // Execute our weapon fire event CClientEntity * pClientEntity = m_pManager->FindEntitySafe ( pColEntity ); CLuaArguments Arguments; if ( pClientEntity ) Arguments.PushElement ( pClientEntity ); // entity that got hit else Arguments.PushNil ( ); // Probably a building. Arguments.PushNumber ( pColPoint->GetPosition ( ).fX ); // pos x Arguments.PushNumber ( pColPoint->GetPosition ( ).fY ); // pos y Arguments.PushNumber ( pColPoint->GetPosition ( ).fZ ); // pos z Arguments.PushNumber ( pColPoint->GetNormal ( ).fX ); // Normal x Arguments.PushNumber ( pColPoint->GetNormal ( ).fY ); // Normal y Arguments.PushNumber ( pColPoint->GetNormal ( ).fZ ); // Normal z Arguments.PushNumber ( pColPoint->GetSurfaceTypeB ( ) ); // Surface type "B" Arguments.PushNumber ( pColPoint->GetLightingForTimeOfDay ( ) ); // Lighting Arguments.PushNumber ( pColPoint->GetPieceTypeB ( ) ); // Piece if ( !CallEvent ( "onClientWeaponFire", Arguments, true ) ) { if ( pColPoint ) pColPoint->Destroy (); return; } DoGunShells ( vecOrigin, vecDirection ); CVector vecCollision; if ( g_pGame->GetWaterManager ()->TestLineAgainstWater ( vecOrigin, vecTarget, &vecCollision ) ) { g_pGame->GetFx ()->TriggerBulletSplash ( vecCollision ); g_pGame->GetAudioEngine ()->ReportBulletHit ( NULL, SURFACE_TYPE_WATER_SHALLOW, &vecCollision, 0.0f ); } #ifdef MARKER_DEBUG m_pMarker2->SetPosition ( vecTarget ); #endif m_pWeapon->DoBulletImpact ( m_pObject, pEntity, &vecOrigin, &vecTarget, pColPoint, 0 ); if ( !IsLocalEntity ( ) && m_pOwner ) { CClientPed * pPed = m_pOwner; CClientPed * pLocalPlayer = g_pClientGame->GetLocalPlayer(); if ( pPed->GetType () == CCLIENTPLAYER ) { // Restore compensated positions if ( !pPed->IsLocalPlayer () ) { CClientVehicle* pVehicle = pLocalPlayer->GetRealOccupiedVehicle (); if ( !pVehicle ) { pLocalPlayer->SetPosition ( vecWeaponFirePosition, false, false ); } else if ( pLocalPlayer->GetOccupiedVehicleSeat() == 0 ) { pVehicle->SetPosition ( vecWeaponFirePosition, false, false ); } } } } if ( !IsLocalEntity ( ) && GetOwner ( ) == g_pClientGame->GetLocalPlayer ( ) && bServerFire == false ) { g_pClientGame->GetNetAPI ( )->SendBulletSyncCustomWeaponFire ( this, vecOrigin, vecOriginalTarget ); } } #ifdef SHOTGUN_TEST else { //if ( pAttachedTo ) pAttachedTo->WorldIgnore ( true ); //if ( pAttachedTo ) pAttachedTo->WorldIgnore ( false ); // Fire instant hit is off by a few degrees FireShotgun ( m_pObject, vecOrigin, vecTarget, vecRotation ); } #endif if ( pColPoint ) pColPoint->Destroy (); }
void CClientWeapon::FireInstantHit ( CVector & vecOrigin, CVector & vecTarget ) #endif { CVector vecDirection = vecTarget - vecOrigin; vecDirection.Normalize (); CClientEntity * pAttachedTo = GetAttachedTo (); CEntity * pColEntity = NULL; CColPoint * pColPoint = NULL; SLineOfSightBuildingResult pBuildingResult; CEntitySAInterface * pEntity = NULL; if ( m_Type != WEAPONTYPE_SHOTGUN ) { //if ( pAttachedTo ) pAttachedTo->WorldIgnore ( true ); if ( m_pWeapon->ProcessLineOfSight ( &vecOrigin, &vecTarget, &pColPoint, &pColEntity, m_weaponConfig.flags, &pBuildingResult, m_Type, &pEntity ) ) { vecTarget = pColPoint->GetPosition (); } // Don't continue without a valid colpoint if ( !pColPoint ) return; //if ( pAttachedTo ) pAttachedTo->WorldIgnore ( false ); // return if shoot if target is blocked is false and we aren't pointing at our target if ( ( m_pTarget != NULL && m_pTarget->GetGameEntity ( ) != NULL && m_pTarget->GetGameEntity()->GetInterface ( ) != pEntity ) && m_weaponConfig.bShootIfTargetBlocked == false ) { return; } // Execute our weapon fire event CClientEntity * pClientEntity = m_pManager->FindEntitySafe ( pColEntity ); CLuaArguments Arguments; if ( pClientEntity ) Arguments.PushElement ( pClientEntity ); // entity that got hit else Arguments.PushNil ( ); // Probably a building. Arguments.PushNumber ( pColPoint->GetPosition ( ).fX ); // pos x Arguments.PushNumber ( pColPoint->GetPosition ( ).fY ); // pos y Arguments.PushNumber ( pColPoint->GetPosition ( ).fZ ); // pos z Arguments.PushNumber ( pColPoint->GetNormal ( ).fX ); // Normal x Arguments.PushNumber ( pColPoint->GetNormal ( ).fY ); // Normal y Arguments.PushNumber ( pColPoint->GetNormal ( ).fZ ); // Normal z Arguments.PushNumber ( pColPoint->GetSurfaceTypeB ( ) ); // Surface type "B" Arguments.PushNumber ( pColPoint->GetLightingForTimeOfDay ( ) ); // Lighting Arguments.PushNumber ( pColPoint->GetPieceTypeB ( ) ); // Piece if ( !CallEvent ( "onClientWeaponFire", Arguments, true ) ) { return; } DoGunShells ( vecOrigin, vecDirection ); CVector vecCollision; if ( g_pGame->GetWaterManager ()->TestLineAgainstWater ( vecOrigin, vecTarget, &vecCollision ) ) { g_pGame->GetFx ()->TriggerBulletSplash ( vecCollision ); g_pGame->GetAudioEngine ()->ReportBulletHit ( NULL, SURFACE_TYPE_WATER_SHALLOW, &vecCollision, 0.0f ); } #ifdef MARKER_DEBUG m_pMarker2->SetPosition ( vecTarget ); #endif m_pWeapon->DoBulletImpact ( m_pObject, pEntity, &vecOrigin, &vecTarget, pColPoint, 0 ); if ( pColEntity && pColEntity->GetEntityType () == ENTITY_TYPE_PED ) { ePedPieceTypes hitZone = ( ePedPieceTypes ) pColPoint->GetPieceTypeB (); short sDamage = m_pWeaponInfo->GetDamagePerHit (); m_pWeapon->GenerateDamageEvent ( dynamic_cast < CPed * > ( pColEntity ), m_pObject, m_Type, sDamage, hitZone, 0 ); } } #ifdef SHOTGUN_TEST else { //if ( pAttachedTo ) pAttachedTo->WorldIgnore ( true ); //if ( pAttachedTo ) pAttachedTo->WorldIgnore ( false ); // Fire instant hit is off by a few degrees FireShotgun ( m_pObject, vecOrigin, vecTarget, vecRotation ); } #endif if ( pColPoint ) pColPoint->Destroy (); }