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;
    }
}
예제 #4
0
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;
    }
}