CClientWeapon::CClientWeapon ( CClientManager * pManager, ElementID ID, eWeaponType type ) : ClassInit ( this ) , CClientObject ( pManager, ID, CClientPickupManager::GetWeaponModel ( type ), false ) { // Ensure m_pTarget and m_pOwner get NULLed when they are destroyed CClientEntityRefManager::AddEntityRefs ( ENTITY_REF_DEBUG ( this, "CClientWeapon" ), &m_pTarget, &m_pOwner, NULL ); m_pManager = pManager; m_pManager->GetWeaponManager ()->AddToList ( this ); m_Type = type; m_State = WEAPONSTATE_READY; m_pWeapon = NULL; m_pWeaponInfo = g_pGame->GetWeaponInfo ( m_Type ); m_bHasTargetDirection = false; m_pOwner = NULL; SetTypeName ( "weapon" ); SetStatic ( true ); Create (); #ifdef MARKER_DEBUG m_pMarker = new CClientMarker ( pManager, INVALID_ELEMENT_ID, 4 ); m_pMarker->SetColor( SColor( 0xFF00FF00 ) ); m_pMarker->SetSize ( 0.5f ); m_pMarker2 = new CClientMarker ( pManager, INVALID_ELEMENT_ID, 4 ); m_pMarker2->SetColor( SColor( 0xFFFF0000 ) ); m_pMarker2->SetSize ( 0.5f ); #endif m_sDamage = m_pWeaponInfo->GetDamagePerHit ( ); m_pWeaponStat = g_pGame->CreateWeaponStat ( type, WEAPONSKILL_STD ); ResetWeaponTarget ( ); // Setup weapon config. m_weaponConfig.bDisableWeaponModel = false; m_weaponConfig.bShootIfTargetBlocked = false; m_weaponConfig.bShootIfTargetOutOfRange = false; m_weaponConfig.flags.bShootThroughStuff = false; m_weaponConfig.flags.bIgnoreSomeObjectsForCamera = false; m_weaponConfig.flags.bSeeThroughStuff = false; m_weaponConfig.flags.bCheckDummies = true; m_weaponConfig.flags.bCheckObjects = true; m_weaponConfig.flags.bCheckPeds = true; m_weaponConfig.flags.bCheckVehicles = true; m_weaponConfig.flags.bCheckBuildings = true; m_weaponConfig.flags.bCheckCarTires = true; m_itargetWheel = MAX_WHEELS + 1; m_nAmmoInClip = m_pWeaponStat->GetMaximumClipAmmo(); m_ucCounter = 0; m_nAmmoTotal = 9999; m_iWeaponFireRate = GetWeaponFireTime ( m_pWeaponStat ); }
void CClientWeapon::DoPulse ( void ) { /*if ( m_bHasTargetDirection ) { CVector vecDirection = m_vecLastDirection; CVector vecOffset = m_vecTargetDirection - vecDirection; vecOffset /= CVector ( 10, 10, 10 ); vecDirection += vecOffset; vecDirection.Normalize (); m_vecLastDirection = vecDirection; SetDirection ( vecDirection ); }*/ if ( m_targetType != TARGET_TYPE_FIXED ) { CVector vecTargetPos; if ( m_targetType == TARGET_TYPE_ENTITY ) { if ( m_pTarget ) { if ( m_pTarget->GetType ( ) == CCLIENTPED || m_pTarget->GetType ( ) == CCLIENTPLAYER ) { CClientPed * pPed = (CClientPed *) (CClientEntity *)(m_pTarget); pPed->GetBonePosition( m_targetBone, vecTargetPos ); } else { m_pTarget->GetPosition( vecTargetPos ); } } else { ResetWeaponTarget ( ); } } else if ( m_targetType == TARGET_TYPE_VECTOR ) { vecTargetPos = m_vecTarget; } if ( !m_pAttachedToEntity ) { // Calculate direction to target CVector vecPosition; GetPosition ( vecPosition ); CVector vecDirection = vecTargetPos - vecPosition; // Convert direction to rotation CVector vecRotation = vecDirection.ToRotation (); SetRotationRadians ( vecRotation ); } else { // Transform target position into local (AttachedToEntity) space CMatrix attachedToMatrix; m_pAttachedToEntity->GetMatrix ( attachedToMatrix ); CVector vecLocalTargetPos = attachedToMatrix.Inverse ().TransformVector ( vecTargetPos ); // Calculate local direction CVector vecDirection = vecLocalTargetPos - m_vecAttachedPosition; // Convert local direction to local rotation CVector vecRotation = vecDirection.ToRotation (); // Apply local rotation SetAttachedOffsets ( m_vecAttachedPosition, vecRotation ); } } if ( m_nAmmoInClip <= 0 ) { if ( m_weaponConfig.bInstantReload == false ) { if ( m_nAmmoTotal >= m_pWeaponStat->GetMaximumClipAmmo() && m_State != WEAPONSTATE_RELOADING ) { m_PreviousState = m_State; m_State = WEAPONSTATE_RELOADING; m_reloadTimer.Reset(); } else if ( m_State == WEAPONSTATE_RELOADING && m_reloadTimer.Get() >= m_pWeapon->GetWeaponReloadTime ( m_pWeaponStat ) ) { m_State = m_PreviousState; m_nAmmoInClip = m_pWeaponStat->GetMaximumClipAmmo(); m_nAmmoTotal -= m_pWeaponStat->GetMaximumClipAmmo(); } else return; } else { if ( m_nAmmoTotal >= m_pWeaponStat->GetMaximumClipAmmo() && m_State != WEAPONSTATE_RELOADING ) { m_nAmmoInClip = m_pWeaponStat->GetMaximumClipAmmo(); m_nAmmoTotal -= m_pWeaponStat->GetMaximumClipAmmo(); } } } if ( m_nAmmoInClip > 0 && ( IsLocalEntity ( ) || m_pOwner == g_pClientGame->GetLocalPlayer ( ) ) ) { if ( m_State == WEAPONSTATE_FIRING && m_fireTimer.Get() >= m_iWeaponFireRate ) { Fire (); } } }
void CClientWeapon::Fire ( bool bServerFire ) { if ( !m_pWeapon || !m_pObject || ( !IsLocalEntity ( ) && m_pOwner != g_pClientGame->GetLocalPlayer ( ) && bServerFire == false ) ) return; switch ( m_Type ) { case WEAPONTYPE_PISTOL: case WEAPONTYPE_PISTOL_SILENCED: case WEAPONTYPE_DESERT_EAGLE: #ifdef SHOTGUN_TEST case WEAPONTYPE_SHOTGUN: case WEAPONTYPE_SAWNOFF_SHOTGUN: case WEAPONTYPE_SPAS12_SHOTGUN: #endif case WEAPONTYPE_MICRO_UZI: case WEAPONTYPE_MP5: case WEAPONTYPE_AK47: case WEAPONTYPE_M4: case WEAPONTYPE_TEC9: case WEAPONTYPE_COUNTRYRIFLE: case WEAPONTYPE_SNIPERRIFLE: case WEAPONTYPE_MINIGUN: { CMatrix matOrigin; GetMatrix ( matOrigin ); CVector vecTarget; float fDistance = m_pWeaponInfo->GetWeaponRange (); if ( m_targetType == TARGET_TYPE_ENTITY ) { if ( m_pTarget ) { if ( m_pTarget->GetType ( ) == CCLIENTPED || m_pTarget->GetType ( ) == CCLIENTPLAYER ) { CClientPed * pPed = (CClientPed *) (CClientEntity *) m_pTarget; pPed->GetBonePosition( m_targetBone, vecTarget ); } else { if ( m_pTarget->GetType() == CCLIENTVEHICLE ) { if ( m_itargetWheel <= MAX_WHEELS ) { CClientVehicle * pTarget = (CClientVehicle*)(CClientEntity *)m_pTarget; vecTarget = pTarget->GetGameVehicle()->GetWheelPosition ( (eWheels)m_itargetWheel ); } else m_pTarget->GetPosition( vecTarget ); } else m_pTarget->GetPosition( vecTarget ); } if ( m_weaponConfig.bShootIfTargetOutOfRange == false && (matOrigin.GetPosition() - vecTarget).Length() >= fDistance ) { return; } } else { ResetWeaponTarget ( ); } } else if ( m_targetType == TARGET_TYPE_VECTOR ) { vecTarget = m_vecTarget; if ( m_weaponConfig.bShootIfTargetOutOfRange == false && (matOrigin.GetPosition() - vecTarget).Length() >= fDistance ) { return; } } else { #ifndef SHOTGUN_TEST CVector vecFireOffset = *m_pWeaponInfo->GetFireOffset (); matOrigin = CMatrix( vecFireOffset, m_vecFireRotationNoTarget ) * matOrigin; #endif CVector vecDirection ( 1, 0, 0 ); vecDirection *= fDistance; vecTarget = matOrigin.TransformVector( vecDirection ); } // Save short sDamage = m_pWeaponInfo->GetDamagePerHit ( ); float fAccuracy = m_pWeaponInfo->GetAccuracy ( ); float fTargetRange = m_pWeaponInfo->GetTargetRange ( ); float fRange = m_pWeaponInfo->GetWeaponRange ( ); // Set new m_pWeaponInfo->SetDamagePerHit ( m_pWeaponStat->GetDamagePerHit ( ) ); m_pWeaponInfo->SetAccuracy ( m_pWeaponStat->GetAccuracy ( ) ); m_pWeaponInfo->SetTargetRange ( m_pWeaponStat->GetTargetRange ( ) ); m_pWeaponInfo->SetWeaponRange ( m_pWeaponStat->GetWeaponRange ( ) ); #ifdef SHOTGUN_TEST CVector vecFireOffset = *m_pWeaponInfo->GetFireOffset (); CMatrix matTemp = CMatrix( vecFireOffset ) * matOrigin; #ifdef MARKER_DEBUG // Process m_pMarker->SetPosition ( matOrigin.GetPosition() ); #endif CVector vecTemp2; GetRotationDegrees(vecTemp2); vecTemp2.fZ -= 84.6f; SetRotationDegrees(vecTemp2); FireInstantHit ( matOrigin.GetPosition(), vecTarget-matOrigin.GetPosition(), matTemp.GetPosition() ); vecTemp2.fZ += 84.6f; SetRotationDegrees(vecTemp2); #else FireInstantHit ( matOrigin.GetPosition(), vecTarget, bServerFire ); #endif // Restore m_pWeaponInfo->SetDamagePerHit ( sDamage ); m_pWeaponInfo->SetAccuracy ( fAccuracy ); m_pWeaponInfo->SetTargetRange ( fTargetRange ); m_pWeaponInfo->SetWeaponRange ( fRange ); m_nAmmoInClip--; m_fireTimer.Reset(); break; } default: break; } }
void CClientWeapon::Fire ( void ) { if ( !m_pWeapon || !m_pObject ) return; switch ( m_Type ) { case WEAPONTYPE_PISTOL: case WEAPONTYPE_PISTOL_SILENCED: case WEAPONTYPE_DESERT_EAGLE: #ifdef SHOTGUN_TEST case WEAPONTYPE_SHOTGUN: case WEAPONTYPE_SAWNOFF_SHOTGUN: case WEAPONTYPE_SPAS12_SHOTGUN: #endif case WEAPONTYPE_MICRO_UZI: case WEAPONTYPE_MP5: case WEAPONTYPE_AK47: case WEAPONTYPE_M4: case WEAPONTYPE_TEC9: case WEAPONTYPE_COUNTRYRIFLE: case WEAPONTYPE_SNIPERRIFLE: case WEAPONTYPE_MINIGUN: { CVector vecOrigin, vecRotation; GetPosition ( vecOrigin ); if ( m_pAttachedToEntity ) { GetRotationRadians ( vecRotation ); } else { GetRotationRadians ( vecRotation ); vecRotation = -vecRotation; } CVector vecTarget; float fDistance = m_pWeaponInfo->GetWeaponRange (); if ( m_targetType == TARGET_TYPE_ENTITY ) { if ( m_pTarget ) { if ( m_pTarget->GetType ( ) == CCLIENTPED || m_pTarget->GetType ( ) == CCLIENTPLAYER ) { CClientPed * pPed = (CClientPed *) (CClientEntity *) m_pTarget; pPed->GetBonePosition( m_targetBone, vecTarget ); } else { if ( m_pTarget->GetType() == CCLIENTVEHICLE ) { if ( m_itargetWheel <= MAX_WHEELS ) { CClientVehicle * pTarget = (CClientVehicle*)(CClientEntity *)m_pTarget; vecTarget = pTarget->GetGameVehicle()->GetWheelPosition ( (eWheels)m_itargetWheel ); } else m_pTarget->GetPosition( vecTarget ); } else m_pTarget->GetPosition( vecTarget ); } if ( m_weaponConfig.bShootIfTargetOutOfRange == false && (vecOrigin - vecTarget).Length() >= fDistance ) { return; } } else { ResetWeaponTarget ( ); } } else if ( m_targetType == TARGET_TYPE_VECTOR ) { vecTarget = m_vecTarget; if ( m_weaponConfig.bShootIfTargetOutOfRange == false && (vecOrigin - vecTarget).Length() >= fDistance ) { return; } } else { CVector vecFireOffset = *m_pWeaponInfo->GetFireOffset (); RotateVector ( vecFireOffset, vecRotation ); #ifndef SHOTGUN_TEST vecOrigin += vecFireOffset; #endif CVector vecDirection ( 1, 0, 0 ); vecDirection *= fDistance; RotateVector ( vecDirection, vecRotation ); vecTarget = vecOrigin + vecDirection; } // Save short sDamage = m_pWeaponInfo->GetDamagePerHit ( ); float fAccuracy = m_pWeaponInfo->GetAccuracy ( ); float fTargetRange = m_pWeaponInfo->GetTargetRange ( ); float fRange = m_pWeaponInfo->GetWeaponRange ( ); // Set new m_pWeaponInfo->SetDamagePerHit ( m_pWeaponStat->GetDamagePerHit ( ) ); m_pWeaponInfo->SetAccuracy ( m_pWeaponStat->GetAccuracy ( ) ); m_pWeaponInfo->SetTargetRange ( m_pWeaponStat->GetTargetRange ( ) ); m_pWeaponInfo->SetWeaponRange ( m_pWeaponStat->GetWeaponRange ( ) ); // Begin our lag compensation CPlayerPed* pOwnerPed = NULL; if ( m_pOwner && !m_pTarget && g_pClientGame->GetPlayerManager()->Exists(m_pOwner) ) // No need for compensation if we're hitting a target directly { pOwnerPed = m_pOwner->GetGamePlayer(); //if ( g_pGame->m_pPreWeaponFireHandler && pOwnerPed ) //g_pGame->m_pPreWeaponFireHandler ( pOwnerPed, false ); } #ifdef SHOTGUN_TEST CVector vecTemp; CVector vecFireOffset = *m_pWeaponInfo->GetFireOffset (); RotateVector ( vecFireOffset, vecRotation ); vecTemp = vecFireOffset; vecTemp += vecOrigin; #ifdef MARKER_DEBUG // Process m_pMarker->SetPosition ( vecOrigin ); #endif CVector vecTemp2; GetRotationDegrees(vecTemp2); vecTemp2.fZ -= 84.6f; SetRotationDegrees(vecTemp2); FireInstantHit ( vecOrigin, vecTarget-vecOrigin, vecTemp ); vecTemp2.fZ += 84.6f; SetRotationDegrees(vecTemp2); #else FireInstantHit ( vecOrigin, vecTarget ); #endif // Restore m_pWeaponInfo->SetDamagePerHit ( sDamage ); m_pWeaponInfo->SetAccuracy ( fAccuracy ); m_pWeaponInfo->SetTargetRange ( fTargetRange ); m_pWeaponInfo->SetWeaponRange ( fRange ); // End our lag compensation //if ( g_pGame->m_pPostWeaponFireHandler && pOwnerPed ) //g_pGame->m_pPostWeaponFireHandler (); m_nAmmoInClip--; m_fireTimer.Reset(); break; } default: break; } }