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 ); }
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; } } } }