/** * \todo Handle pEvent correctly to convert it */ bool CTaskSA::MakeAbortable(CPed* pPed, const int iPriority, const CEvent* pEvent) { DEBUG_TRACE("bool CTaskSA::MakeAbortable(CPed* pPed, const int iPriority, const CEvent* pEvent)"); CPedSA* pPedSA = dynamic_cast<CPedSA*>(pPed); if (!pPedSA) return false; DWORD dwPedInterface = (DWORD)pPedSA->GetInterface(); DWORD dwThisInterface = (DWORD)this->GetInterface(); DWORD dwFunc = this->GetInterface()->VTBL->MakeAbortable; bool bReturn = 0; if (dwFunc != 0x82263A && dwFunc) // 82263A = purecall { _asm { mov ecx, dwThisInterface push pEvent push iPriority push dwPedInterface call dwFunc mov bReturn, al } } return bReturn; }
VOID ReturnContextToLocalPlayer() { if ( bNotInLocalContext ) { // Grab the remote data storage for the player we context switched to CPlayerPed* pContextSwitchedPlayerPed = dynamic_cast < CPlayerPed* > ( pContextSwitchedPed ); if ( pContextSwitchedPlayerPed ) { CRemoteDataStorageSA * data = CRemoteDataSA::GetRemoteDataStorage ( pContextSwitchedPlayerPed ); if ( data ) { // Store any changes the game has made to the pad CPad* pLocalPad = pGameInterface->GetPad (); CPadSAInterface* pLocalPadInterface = ( (CPadSA*) pLocalPad )->GetInterface (); memcpy ( &data->m_pad, pLocalPadInterface, sizeof ( CPadSAInterface ) ); } } pGameInterface->GetPad()->Restore(); *(float *)VAR_CameraRotation = fLocalPlayerCameraRotation; bNotInLocalContext = false; CPed* pLocalPlayerPed = pGameInterface->GetPools ()->GetPedFromRef ( (DWORD)1 ); // the player CPedSA* pLocalPlayerPedSA = dynamic_cast < CPedSA* > ( pLocalPlayerPed ); if ( pLocalPlayerPedSA ) { CEntitySAInterface * ped = pLocalPlayerPedSA->GetInterface(); *(DWORD *)0xB7CD98 = (DWORD)ped; } PostContextSwitch(); if ( m_pPostContextSwitchHandler ) { m_pPostContextSwitchHandler (); } } else { // Store any changes to the local-players stats? if ( !bLocalStatsStatic ) { memcpy ( &localStatsData.StatTypesFloat, (void *)0xb79380, sizeof(float) * MAX_FLOAT_STATS ); memcpy ( &localStatsData.StatTypesInt, (void *)0xb79000, sizeof(int) * MAX_INT_STATS ); memcpy ( &localStatsData.StatReactionValue, (void *)0xb78f10, sizeof(float) * MAX_REACTION_STATS ); } } // radio change on startup hack //0050237C 90 NOP memset((void *)0x50237C, 0x90, 5); memset((void *)0x5023A3, 0x90, 5); // We need to set this back, even if its the local player pGameInterface->SetGravity ( fGlobalGravity ); }
CTask* CTaskComplexSA::ControlSubTask(CPed* pPed) { DEBUG_TRACE("CTask * CTaskComplexSA::ControlSubTask(CPed* pPed)"); CPedSA* pPedSA = dynamic_cast<CPedSA*>(pPed); if (!pPedSA) return NULL; DWORD dwPedInterface = (DWORD)pPedSA->GetInterface(); DWORD dwThisInterface = (DWORD)this->GetInterface(); DWORD dwFunc = ((TaskComplexVTBL*)this->GetInterface()->VTBL)->ControlSubTask; DWORD dwReturn = 0; if (dwFunc != 0x82263A && dwFunc) { _asm { mov ecx, dwThisInterface push dwPedInterface call dwFunc mov dwReturn, eax } } return ((CTaskManagementSystemSA*)pGame->GetTaskManagementSystem())->GetTask((CTaskSAInterface*)dwReturn); }
bool CTaskSimpleSA::SetPedPosition(CPed* pPed) { DEBUG_TRACE("bool CTaskSimpleSA::SetPedPosition(CPed* pPed)"); CPedSA* pPedSA = dynamic_cast<CPedSA*>(pPed); if (!pPedSA) return false; DWORD dwPedInterface = (DWORD)pPedSA->GetInterface(); DWORD dwThisInterface = (DWORD)this->GetInterface(); DWORD dwFunc = ((TaskSimpleVTBL*)this->GetInterface()->VTBL)->SetPedPosition; bool bReturn = 0; if (dwFunc != 0x82263A && dwFunc) { _asm { mov ecx, dwThisInterface push dwPedInterface call dwFunc mov bReturn, al } } return bReturn; }
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 eWeaponType currentWeapon = thePed->GetWeapon(thePed->GetCurrentWeaponSlot())->GetType(); CControllerState * cs = data->CurrentControllerState(); if ( cs->RightShoulder1 != 0 && ( currentWeapon == WEAPONTYPE_SNIPERRIFLE || currentWeapon == WEAPONTYPE_ROCKETLAUNCHER || currentWeapon == WEAPONTYPE_ROCKETLAUNCHER_HS || currentWeapon == WEAPONTYPE_CAMERA ) ) { b1stPersonWeaponModeHackInPlace = true; // make the CCamera::Using1stPersonWeaponMode function return true *(BYTE *)0x50BFF0 = 0xB0; // MOV AL, 1 *(BYTE *)0x50BFF1 = 0x01; *(BYTE *)0x50BFF2 = 0xC3; // RETN } // Change the local player's pad to the remote player's memcpy ( 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; *(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; CWeapon* pWeapon = thePed->GetWeapon ( thePed->GetCurrentWeaponSlot () ); if ( pWeapon ) { eWeaponType weaponType = pWeapon->GetType (); switch ( weaponType ) { case WEAPONTYPE_SNIPERRIFLE: case WEAPONTYPE_ROCKETLAUNCHER: case WEAPONTYPE_ROCKETLAUNCHER_HS: bDisableMouseLook = false; } } bMouseLookEnabled = *(bool *)0xB6EC2E; if ( bDisableMouseLook ) *(bool *)0xB6EC2E = false; // Disable the goggles bInfraredVisionEnabled = *(bool *)0xC402B9; *(bool *)0xC402B9 = false; bNightVisionEnabled = *(bool *)0xC402B8; *(bool *)0xC402B8 = false; // Remove the code making players cough on fire extinguisher and teargas memset ( (void*) 0x4C03F0, 0x90, 3 ); memset ( (void*) 0x4C03F8, 0x90, 7 ); // Prevent it calling ClearWeaponTarget for remote players *(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 *(BYTE *)0x60F273 = 0xEB; *(BYTE *)0x60F260 = 0x90; *(BYTE *)0x60F261 = 0x90; // Prevent CCamera::SetNewPlayerWeaponMode being called *(BYTE *)0x50BFB0 = 0xC2; // RETN 0xC *(BYTE *)0x50BFB1 = 0x0C; *(BYTE *)0x50BFB2 = 0x00; // Prevent it calling CCamera::ClearPlayerWeaponMode for remote players *(BYTE *)0x50AB10 = 0xC3; // Prevent it marking targets of remote players *(BYTE *)0x742BF0 = 0xC3; // this is to prevent shooting players following the local camera *(BYTE *)0x687099 = 0xEB; // Prevent the game making remote player's weapons get switched by the local player's *(BYTE *)0x60D850 = 0xC2; *(BYTE *)0x60D851 = 0x04; *(BYTE *)0x60D852 = 0x00; // Change the local player's stats to the remote player's if ( data ) { memcpy ( (void *)0xb79380, data->m_stats.StatTypesFloat, sizeof(float) * MAX_FLOAT_STATS ); memcpy ( (void *)0xb79000, data->m_stats.StatTypesInt, sizeof(int) * MAX_INT_STATS ); memcpy ( (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(); *(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 ) *(float *)VAR_CameraRotation = fLocalPlayerCameraRotation; } } }