CPedSA::CPedSA( CPedSAInterface * pPedInterface ) : m_pPedIntelligence ( NULL ), m_pPedInterface ( pPedInterface ), m_pPedSound ( NULL ), m_iCustomMoveAnim( 0 ) { DEBUG_TRACE("CPedSA::CPedSA( CPedSAInterface * pedInterface )"); MemSetFast ( this->m_pWeapons, 0, sizeof ( CWeaponSA* ) * WEAPONSLOT_MAX ); }
BOOL HookInstall( DWORD dwInstallAddress, DWORD dwHookHandler, int iJmpCodeSize ) { BYTE JumpBytes[MAX_JUMPCODE_SIZE]; MemSetFast ( JumpBytes, 0x90, MAX_JUMPCODE_SIZE ); if ( CreateJump ( dwInstallAddress, dwHookHandler, JumpBytes ) ) { MemCpy ( (PVOID)dwInstallAddress, JumpBytes, iJmpCodeSize ); return TRUE; } else { return FALSE; } }
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 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 (); MemCpyFast ( &data->m_pad, pLocalPadInterface, sizeof ( CPadSAInterface ) ); } } pGameInterface->GetPad()->Restore(); MemPutFast < 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(); MemPutFast < DWORD > ( 0xB7CD98, (DWORD)ped ); } PostContextSwitch(); pGameInterface->OnPedContextChange ( NULL ); if ( m_pPostContextSwitchHandler ) { m_pPostContextSwitchHandler (); } } else { // Store any changes to the local-players stats? if ( !bLocalStatsStatic ) { assert ( 0 ); // bLocalStatsStatic is always true MemCpyFast ( &localStatsData.StatTypesFloat, (void *)0xb79380, sizeof(float) * MAX_FLOAT_STATS ); MemCpyFast ( &localStatsData.StatTypesInt, (void *)0xb79000, sizeof(int) * MAX_INT_STATS ); MemCpyFast ( &localStatsData.StatReactionValue, (void *)0xb78f10, sizeof(float) * MAX_REACTION_STATS ); } } // radio change on startup hack //0050237C 90 NOP MemSetFast ((void *)0x50237C, 0x90, 5); MemSetFast ((void *)0x5023A3, 0x90, 5); // We need to set this back, even if its the local player pGameInterface->SetGravity ( fGlobalGravity ); }
CObjectSA::CObjectSA(DWORD dwModel, bool bBreakingDisabled) { DEBUG_TRACE("CObjectSA::CObjectSA( DWORD dwModel )"); CWorldSA* world = (CWorldSA*)pGame->GetWorld(); DWORD dwThis = 0; #ifdef MTA_USE_BUILDINGS_AS_OBJECTS DWORD dwFunc = 0x538090; // CFileLoader__LoadObjectInstance CFileObjectInstance fileLoader; MemSetFast(&fileLoader, 0, sizeof(CFileObjectInstance)); fileLoader.modelId = dwModel; fileLoader.rr = 1; fileLoader.areaNumber = 0; fileLoader.flags = -1; _asm { push 0 lea ecx, fileLoader push ecx call dwFunc add esp, 8 mov dwThis, eax } this->SetInterface((CEntitySAInterface*)dwThis); MemPutFast<DWORD>(0xBCC0E0, dwThis); MemPutFast<DWORD>(0xBCC0D8, 1); dwFunc = 0x404DE0; // CIplStore__SetupRelatedIpls DWORD dwTemp = 0; char szTemp[255]; strcpy(szTemp, "moo"); _asm { push 0xBCC0E0 push -1 lea eax, szTemp push eax call dwFunc add esp, 0xC mov dwTemp, eax } dwFunc = 0x5B51E0; // AddBuildingInstancesToWorld _asm { push dwTemp call dwFunc add esp, 4 } dwFunc = 0x405110; // CIplStore__RemoveRelatedIpls _asm { push -1 call dwFunc add esp, 4 } // VITAL to get colmodels to appear // this gets the level for a colmodel (colmodel+40) dwFunc = 0x4107A0; _asm { mov eax, dwModel mov eax, 0xA9B0C8[eax*4] mov eax, [eax+20] movzx eax, byte ptr [eax+40] push eax call dwFunc add esp, 4 } #else DWORD CObjectCreate = FUNC_CObject_Create; DWORD dwObjectPtr = 0; _asm { push 1 push dwModel call CObjectCreate add esp, 8 mov dwObjectPtr, eax } if (dwObjectPtr) { this->SetInterface((CEntitySAInterface*)dwObjectPtr); world->Add(m_pInterface, CObject_Constructor); // Setup some flags this->BeingDeleted = FALSE; this->DoNotRemoveFromGame = FALSE; MemPutFast<BYTE>(dwObjectPtr + 316, 6); if (bBreakingDisabled) { // Set our immunities // Sum of all flags checked @ CPhysical__CanPhysicalBeDamaged CObjectSAInterface* pObjectSAInterface = GetObjectInterface(); pObjectSAInterface->bBulletProof = true; pObjectSAInterface->bFireProof = true; pObjectSAInterface->bCollisionProof = true; pObjectSAInterface->bMeeleProof = true; pObjectSAInterface->bExplosionProof = true; } m_pInterface->bStreamingDontDelete = true; } else { // The exception handler doesn't work for some reason, so do this this->SetInterface(NULL); } #endif this->internalID = pGame->GetPools()->GetObjectRef((DWORD*)this->GetInterface()); m_ucAlpha = 255; if (m_pInterface) { ResetScale(); CheckForGangTag(); } }