void SwitchContext ( CPed* thePed )
{
    if ( thePed == NULL ) return;

    pContextSwitchedPed = thePed;
    // Are we not already in another context?
    if ( !bNotInLocalContext )
    {
        // Grab the local ped and the local pad
        CPed* pLocalPlayerPed = pGameInterface->GetPools ()->GetPedFromRef ( (DWORD)1 ); // the player
        CPad* pLocalPad = pGameInterface->GetPad ();
        CPadSAInterface* pLocalPadInterface = ( (CPadSA*) pLocalPad )->GetInterface ();

        // We're not switching to local player
        if ( thePed != pLocalPlayerPed )
        {
            // Store the local pad
            pLocalPad->Store (); // store a copy of the local pad internally

            // Grab the remote data storage for the player we're context switching to
            CPlayerPed* thePlayerPed = dynamic_cast < CPlayerPed* > ( thePed );
            if ( thePlayerPed )
            {
                CRemoteDataStorageSA * data = CRemoteDataSA::GetRemoteDataStorage ( thePlayerPed );
                if ( data )
                {
                    // We want the player to be seen as in targeting mode if they are right clicking and with weapons 
                    CWeapon* pWeapon = thePed->GetWeapon(thePed->GetCurrentWeaponSlot());
                    eWeaponType currentWeapon = pWeapon->GetType();
                    CControllerState * cs = data->CurrentControllerState();
                    CWeaponStat * pWeaponStat = NULL;
                    if ( currentWeapon >= WEAPONTYPE_PISTOL && currentWeapon <= WEAPONTYPE_TEC9 )
                    {
                        float fValue = data->m_stats.StatTypesFloat [ pGameInterface->GetStats ()->GetSkillStatIndex ( currentWeapon ) ];
                        pWeaponStat = pGameInterface->GetWeaponStatManager ( )->GetWeaponStatsFromSkillLevel ( currentWeapon, fValue );
                    }
                    else
                        pWeaponStat = pGameInterface->GetWeaponStatManager ( )->GetWeaponStats ( currentWeapon );

                    if ( cs->RightShoulder1 != 0 
                        && ( pWeaponStat && pWeaponStat->IsFlagSet ( WEAPONTYPE_FIRSTPERSON ) ) )
                    {
                        b1stPersonWeaponModeHackInPlace = true;
                        
                        // make the CCamera::Using1stPersonWeaponMode function return true
                        MemPutFast < BYTE > ( 0x50BFF0, 0xB0 );
                        MemPutFast < BYTE > ( 0x50BFF1, 0x01 );
                        MemPutFast < BYTE > ( 0x50BFF2, 0xC3 );
                    }

                    // Change the local player's pad to the remote player's
                    MemCpyFast ( pLocalPadInterface, &data->m_pad, sizeof ( CPadSAInterface ) );

                    // this is to fix the horn/siren
                    pLocalPad->SetHornHistoryValue ( ( cs->ShockButtonL == 255 ) );
                    // disables the impatient actions on remote players (which cause desync)
                    pLocalPad->SetLastTimeTouched ( pGameInterface->GetSystemTime () );

                    // this is to make movement work correctly
                    fLocalPlayerCameraRotation = *(float *)VAR_CameraRotation;
                    MemPutFast < float > ( VAR_CameraRotation, data->m_fCameraRotation );

                    // Change the gravity to the remote player's
                    pGameInterface->SetGravity ( data->m_fGravity );

                    // Disable mouselook for remote players (so the mouse doesn't affect them)
                    // Only disable mouselook if they're not holding a 1st-person weapon
                    // And if they're not under-water
                    bool bDisableMouseLook = true;
                    if ( pWeapon )
                    {
                        eWeaponType weaponType = pWeapon->GetType ();
                        if ( pWeaponStat->IsFlagSet ( WEAPONTYPE_FIRSTPERSON ) )
                        {
                            bDisableMouseLook = false;
                        }
                    }
                    bMouseLookEnabled = *(bool *)0xB6EC2E;
                    if ( bDisableMouseLook ) *(bool *)0xB6EC2E = false;

                    // Disable the goggles
                    bInfraredVisionEnabled = *(bool *)0xC402B9;
                    MemPutFast < bool > ( 0xC402B9, false );
                    bNightVisionEnabled = *(bool *)0xC402B8;
                    MemPutFast < bool > ( 0xC402B8, false );

                    // Remove the code making players cough on fire extinguisher and teargas
                    MemSetFast ( (void*) 0x4C03F0, 0x90, 3 );
                    MemSetFast ( (void*) 0x4C03F8, 0x90, 7 );

                    // Prevent it calling ClearWeaponTarget for remote players
                    MemPutFast < BYTE > ( 0x609C80, 0xC3 );

                    // Prevent rockets firing oddly
                    //*(BYTE *)0x73811C = 0x90;
                    //*(BYTE *)0x73811D = 0xE9;

                    
                    // This is so weapon clicks and similar don't play for us when done remotly
                    MemPutFast < BYTE > ( 0x60F273, 0xEB );
                    MemPutFast < BYTE > ( 0x60F260, 0x90 );
                    MemPutFast < BYTE > ( 0x60F261, 0x90 );
                    

                    // Prevent CCamera::SetNewPlayerWeaponMode being called
                    MemPutFast < BYTE > ( 0x50BFB0, 0xC2 );
                    MemPutFast < BYTE > ( 0x50BFB1, 0x0C );
                    MemPutFast < BYTE > ( 0x50BFB2, 0x00 );

                    // Prevent it calling CCamera::ClearPlayerWeaponMode for remote players
                    MemPutFast < BYTE > ( 0x50AB10, 0xC3 );

                    // Prevent it marking targets of remote players
                    MemPutFast < BYTE > ( 0x742BF0, 0xC3 );

                    // this is to prevent shooting players following the local camera
                    MemPutFast < BYTE > ( 0x687099, 0xEB );

                    // Prevent the game making remote player's weapons get switched by the local player's
                    MemPutFast < BYTE > ( 0x60D850, 0xC2 );
                    MemPutFast < BYTE > ( 0x60D851, 0x04 );
                    MemPutFast < BYTE > ( 0x60D852, 0x00 );

                    // Change the local player's stats to the remote player's
                    if ( data )
                    {
                        MemCpyFast ( (void *)0xb79380, data->m_stats.StatTypesFloat, sizeof(float) * MAX_FLOAT_STATS );
                        MemCpyFast ( (void *)0xb79000, data->m_stats.StatTypesInt, sizeof(int) * MAX_INT_STATS );
                        MemCpyFast ( (void *)0xb78f10, data->m_stats.StatReactionValue, sizeof(float) * MAX_REACTION_STATS );
                    }                 

                    /*
                    // ChrML: Force as high stats as we can go before screwing up. Players can't have different
                    //        stats or guns don't work. We can't have dual guns either due to some screwups.
                    //        Dual gun screwup: Sync code needs update and the gun pointing up needs to.
                    float* pfStats = (float*) 0xb79380;
                    pfStats [ 69 ] = 500.0f;
                    pfStats [ 70 ] = 999.0f;
                    pfStats [ 71 ] = 999.0f;
                    pfStats [ 72 ] = 999.0f;
                    pfStats [ 73 ] = 500.0f;
                    pfStats [ 74 ] = 999.0f;
                    pfStats [ 75 ] = 500.0f;
                    pfStats [ 76 ] = 999.0f;
                    pfStats [ 77 ] = 999.0f;
                    pfStats [ 78 ] = 999.0f;
                    pfStats [ 79 ] = 999.0f;
                    */

                    CPedSA* thePedSA = dynamic_cast < CPedSA* > ( thePed );
                    if ( thePedSA )
                    {
                        CEntitySAInterface * ped = thePedSA->GetInterface();
                        MemPutFast < DWORD > ( 0xB7CD98, (DWORD)ped );
                    }

                    // Remember that we're not in the local player's context any more (for switching back)
                    bNotInLocalContext = true;

                    // Call the pre-context switch handler we might have
                    if ( m_pPreContextSwitchHandler )
                    {
                        CPlayerPed* pPlayerPed = dynamic_cast < CPlayerPed* > ( thePed );
                        if ( pPlayerPed )
                            m_pPreContextSwitchHandler ( pPlayerPed );
                    }
                }
            }
        }
        else
        {
            // Set the local players gravity
            pGameInterface->SetGravity ( fLocalPlayerGravity );

            if ( bCustomCameraRotation )
                MemPutFast < float > ( VAR_CameraRotation, fLocalPlayerCameraRotation );
        }
    }
    pGameInterface->OnPedContextChange ( thePed );
}
Example #2
0
void CWorldRPCs::SetWeaponProperty ( NetBitStreamInterface& bitStream )
{
    unsigned char ucWeapon = 0;
    unsigned char ucProperty = 0;
    unsigned char ucWeaponSkill = 0;
    float fData = 0.0f;
    short sData = 0;
    if ( bitStream.Read ( ucWeapon ) && bitStream.Read ( ucProperty ) && bitStream.Read ( ucWeaponSkill ) )
    {
        CWeaponStat* pWeaponInfo = g_pGame->GetWeaponStatManager()->GetWeaponStats( static_cast < eWeaponType > ( ucWeapon ), static_cast < eWeaponSkill > ( ucWeaponSkill ) );
        CWeaponStat* pOriginalWeaponInfo = g_pGame->GetWeaponStatManager()->GetOriginalWeaponStats( static_cast < eWeaponType > ( ucWeapon ), static_cast < eWeaponSkill > ( ucWeaponSkill ) );
        switch ( ucProperty )
        {
        case WEAPON_WEAPON_RANGE:
        {
            bitStream.Read ( fData );
            pWeaponInfo->SetWeaponRange ( fData );
            break;
        }
        case WEAPON_TARGET_RANGE:
        {
            bitStream.Read ( fData );
            pWeaponInfo->SetTargetRange ( fData );
            break;
        }
        case WEAPON_ACCURACY:
        {
            bitStream.Read ( fData );
            pWeaponInfo->SetAccuracy ( fData );
            break;
        }
        case WEAPON_LIFE_SPAN:
        {
            bitStream.Read ( fData );
            pWeaponInfo->SetLifeSpan ( fData );
            break;
        }
        case WEAPON_FIRING_SPEED:
        {
            bitStream.Read ( fData );
            pWeaponInfo->SetFiringSpeed ( fData );
            break;
        }
        case WEAPON_MOVE_SPEED:
        {
            bitStream.Read ( fData );
            pWeaponInfo->SetMoveSpeed ( fData );
            break;
        }
        case WEAPON_ANIM_LOOP_START:
        {
            bitStream.Read ( fData );
            pWeaponInfo->SetWeaponAnimLoopStart ( fData );
            break;
        }
        case WEAPON_ANIM_LOOP_STOP:
        {
            bitStream.Read ( fData );
            pWeaponInfo->SetWeaponAnimLoopStop ( fData );
            break;
        }
        case WEAPON_ANIM_LOOP_RELEASE_BULLET_TIME:
        {
            bitStream.Read ( fData );
            pWeaponInfo->SetWeaponAnimLoopFireTime ( fData );
            break;
        }

        case WEAPON_ANIM2_LOOP_START:
        {
            bitStream.Read ( fData );
            pWeaponInfo->SetWeaponAnim2LoopStart ( fData );
            break;
        }
        case WEAPON_ANIM2_LOOP_STOP:
        {
            bitStream.Read ( fData );
            pWeaponInfo->SetWeaponAnim2LoopStop ( fData );
            break;
        }
        case WEAPON_ANIM2_LOOP_RELEASE_BULLET_TIME:
        {
            bitStream.Read ( fData );
            pWeaponInfo->SetWeaponAnim2LoopFireTime ( fData );
            break;
        }

        case WEAPON_ANIM_BREAKOUT_TIME:
        {
            bitStream.Read ( fData );
            pWeaponInfo->SetWeaponAnimBreakoutTime ( fData );
            break;
        }
        case WEAPON_DAMAGE:
        {
            bitStream.Read ( sData );
            pWeaponInfo->SetDamagePerHit ( sData );
            break;
        }
        case WEAPON_MAX_CLIP_AMMO:
        {
            bitStream.Read ( sData );
            pWeaponInfo->SetMaximumClipAmmo ( sData );
            break;
        }
        case WEAPON_FLAGS:
        {
            bitStream.Read ( sData );
            if ( pWeaponInfo->IsFlagSet ( sData ) )
            {
                if ( sData == 0x800 )
                {
                    // if it can support this anim group
                    if ( ( ucWeapon >= WEAPONTYPE_PISTOL && ucWeapon <= WEAPONTYPE_SNIPERRIFLE ) || ucWeapon == WEAPONTYPE_MINIGUN )
                    {
                        // Revert anim group to default
                        pWeaponInfo->SetAnimGroup ( pOriginalWeaponInfo->GetAnimGroup ( ) );
                    }
                }
                pWeaponInfo->ClearFlag ( sData );
            }
            else
            {
                if ( sData == 0x800 )
                {
                    // if it can support this anim group
                    if ( ( ucWeapon >= WEAPONTYPE_PISTOL && ucWeapon <= WEAPONTYPE_SNIPERRIFLE ) || ucWeapon == WEAPONTYPE_MINIGUN )
                    {
                        // sawn off shotgun anim group
                        pWeaponInfo->SetAnimGroup ( 17 );
                    }
                }
                pWeaponInfo->SetFlag ( sData );
            }

            break;
        }
        case WEAPON_ANIM_GROUP:
        {
            bitStream.Read ( sData );
            pWeaponInfo->SetAnimGroup ( sData );
            break;
        }
        }
    }
}