void C3DMarkerSA::SetMatrix ( CMatrix * pMatrix ) { CMatrix_Padded * mat = &GetInterface ()->m_mat; MemCpyFast ( &mat->vPos, &pMatrix->vPos, sizeof ( CVector ) ); MemCpyFast ( &mat->vFront, &pMatrix->vFront, sizeof ( CVector ) ); MemCpyFast ( &mat->vRight, &pMatrix->vRight, sizeof ( CVector ) ); MemCpyFast ( &mat->vUp, &pMatrix->vUp, sizeof ( CVector ) ); }
bool FreePoolHunk(MemPool * Pool,void * Hunk) { if ( Pool->NumFreedHunks >= Pool->MaxNumFreedHunks ) { void ** NewFreedHunks; if ( (NewFreedHunks = malloc((Pool->MaxNumFreedHunks<<1)*sizeof(void *))) == NULL ) return(0); MemCpyFast(NewFreedHunks,Pool->FreedHunks,Pool->MaxNumFreedHunks); free(Pool->FreedHunks); Pool->FreedHunks = NewFreedHunks; Pool->MaxNumFreedHunks <<= 1; } Pool->FreedHunks[Pool->NumFreedHunks] = Hunk; Pool->NumFreedHunks++; Pool->NumItemsActive--; return(1); }
void PostContextSwitch ( void ) { // Prevent the game making remote player's weapons get switched by the local player's MemPutFast < BYTE > ( 0x60D850, 0x56 ); MemPutFast < BYTE > ( 0x60D851, 0x57 ); MemPutFast < BYTE > ( 0x60D852, 0x8B ); // Prevent it calling ClearWeaponTarget for remote players MemPutFast < BYTE > ( 0x609C80, 0x57 ); // Prevent CCamera::SetNewPlayerWeaponMode being called MemPutFast < BYTE > ( 0x50BFB0, 0x66 ); MemPutFast < BYTE > ( 0x50BFB1, 0x8B ); MemPutFast < BYTE > ( 0x50BFB2, 0x44 ); // This is so weapon clicks and similar don't play for us when done remotly MemPutFast < BYTE > ( 0x60F273, 0x75 ); MemPutFast < BYTE > ( 0x60F260, 0x74 ); MemPutFast < BYTE > ( 0x60F261, 0x13 ); // Prevent it calling CCamera::ClearPlayerWeaponMode for remote players MemPutFast < BYTE > ( 0x50AB10, 0x33 ); // this is to prevent shooting players following the local camera MemPutFast < BYTE > ( 0x687099, 0x75 ); // Prevent rockets firing oddly //*(BYTE *)0x73811C = 0x0F; //*(BYTE *)0x73811D = 0x84; // Prevent it marking targets of remote players MemPutFast < BYTE > ( 0x742BF0, 0x8B ); // Restore the mouse look state back to the default MemPutFast < bool > ( 0xB6EC2E, bMouseLookEnabled ); // Restore the visual goggle mode back MemPutFast < bool > ( 0xC402B9, bInfraredVisionEnabled ); MemPutFast < bool > ( 0xC402B8, bNightVisionEnabled ); // Make players cough on fire extinguisher and teargas again MemPutFast < unsigned char > ( 0x4C03F0, 0x83 ); MemPutFast < unsigned char > ( 0x4C03F1, 0xF8 ); MemPutFast < unsigned char > ( 0x4C03F2, 0x29 ); MemPutFast < unsigned char > ( 0x4C03F8, 0x74 ); MemPutFast < unsigned char > ( 0x4C03F9, 0x09 ); MemPutFast < unsigned char > ( 0x4C03FA, 0x83 ); MemPutFast < unsigned char > ( 0x4C03FB, 0xF8 ); MemPutFast < unsigned char > ( 0x4C03FC, 0x2A ); MemPutFast < unsigned char > ( 0x4C03FD, 0x74 ); MemPutFast < unsigned char > ( 0x4C03FE, 0x04 ); // make the CCamera::Using1stPersonWeaponMode function return true if ( b1stPersonWeaponModeHackInPlace) { b1stPersonWeaponModeHackInPlace = false; MemPutFast < BYTE > ( 0x50BFF0, 0x66 ); MemPutFast < BYTE > ( 0x50BFF1, 0x8B ); MemPutFast < BYTE > ( 0x50BFF2, 0x81 ); } if ( bRadioHackInstalled ) { // For tanks, to prevent our mouse movement affecting remote tanks // 006AEA25 0F85 60010000 JNZ gta_sa.006AEB8B // ^ // 006AEA25 90 NOP // 006AEA26 E9 60010000 JMP gta_sa.006AEB8B MemPutFast < BYTE > ( 0x6AEA25, 0x0F ); MemPutFast < BYTE > ( 0x6AEA26, 0x85 ); // Same for firetrucks and SWATs // 00729B96 0F85 75010000 JNZ gta_sa.00729D11 // ^ // 00729B96 90 NOP // 00729B97 E9 75010000 JMP gta_sa.00729D11 MemPutFast < BYTE > ( 0x729B96, 0x0F ); MemPutFast < BYTE > ( 0x729B97, 0x85 ); // Prevent the game making remote players vehicle's audio behave like locals (and deleting // radio etc when they are removed) - issue #95 MemPutFast < BYTE > ( 0x50230C, 0x1 ); bRadioHackInstalled = FALSE; } /* // 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. localStatsData.StatTypesFloat [ 69 ] = 500.0f; localStatsData.StatTypesFloat [ 70 ] = 999.0f; localStatsData.StatTypesFloat [ 71 ] = 999.0f; localStatsData.StatTypesFloat [ 72 ] = 999.0f; localStatsData.StatTypesFloat [ 73 ] = 500.0f; localStatsData.StatTypesFloat [ 74 ] = 999.0f; localStatsData.StatTypesFloat [ 75 ] = 500.0f; localStatsData.StatTypesFloat [ 76 ] = 999.0f; localStatsData.StatTypesFloat [ 77 ] = 999.0f; localStatsData.StatTypesFloat [ 78 ] = 999.0f; localStatsData.StatTypesFloat [ 79 ] = 999.0f; */ // ChrML: This causes the aiming issues // Restore the local player stats MemCpyFast ( (void *)0xb79380, &localStatsData.StatTypesFloat, sizeof(float) * MAX_FLOAT_STATS ); MemCpyFast ( (void *)0xb79000, &localStatsData.StatTypesInt, sizeof(int) * MAX_INT_STATS ); MemCpyFast ( (void *)0xb78f10, &localStatsData.StatReactionValue, sizeof(float) * MAX_REACTION_STATS ); }
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 ); }
CPlayerPedSA::CPlayerPedSA( ePedModel pedType ) { DEBUG_TRACE("CPlayerPedSA::CPlayerPedSA( ePedModel pedType )"); // based on CPlayerPed::SetupPlayerPed (R*) DWORD CPedOperatorNew = FUNC_CPedOperatorNew; DWORD CPlayerPedConstructor = FUNC_CPlayerPedConstructor; DWORD dwPedPointer = 0; _asm { push SIZEOF_CPLAYERPED call CPedOperatorNew add esp, 4 mov dwPedPointer, eax mov ecx, eax push 0 // set to 0 and they'll behave like AI peds push 1 call CPlayerPedConstructor } this->SetInterface((CEntitySAInterface *)dwPedPointer); this->Init(); // init our interfaces CPoolsSA * pools = (CPoolsSA *)pGame->GetPools ( ); this->internalID = pools->GetPedRef ( (DWORD *)this->GetInterface () ); CWorldSA * world = (CWorldSA *)pGame->GetWorld(); this->SetModelIndex(pedType); this->BeingDeleted = FALSE; this->DoNotRemoveFromGame = FALSE; this->SetType ( PLAYER_PED ); // Allocate a player data struct and set it as the players m_bIsLocal = false; m_pData = new CPlayerPedDataSAInterface; // Copy the local player data so we're defaulted to something good CPlayerPedSA* pLocalPlayerSA = dynamic_cast < CPlayerPedSA* > ( pools->GetPedFromRef ( (DWORD)1 ) ); if ( pLocalPlayerSA ) MemCpyFast ( m_pData, ((CPlayerPedSAInterface*)pLocalPlayerSA->GetInterface ())->pPlayerData, sizeof ( CPlayerPedDataSAInterface ) ); // Replace the player ped data in our ped interface with the one we just created GetPlayerPedInterface ()->pPlayerData = m_pData; // Set default stuff m_pData->m_bRenderWeapon = true; m_pData->m_Wanted = pLocalWanted; m_pData->m_fSprintEnergy = 1000.0f; // Clothes pointers or we'll crash later (TODO: Wrap up with some cloth classes and make it unique per player) m_pData->m_pClothes = pLocalClothes; // Not sure why was this here (svn blame reports that this line came from the old SVN), // but it's causing a bug in what the just streamed-in players that are in the air are // processed as if they would be standing on some surface, screwing velocity calculations // for players floating in air (using superman script, for example) because GTA:SA will // try to apply the floor friction to their velocity. //SetIsStanding ( true ); GetPlayerPedInterface ()->pedFlags.bCanBeShotInVehicle = true; GetPlayerPedInterface ()->pedFlags.bTestForShotInVehicle = true; // Stop remote players targeting eachother, this also stops the local player targeting them (needs to be fixed) GetPlayerPedInterface ()->pedFlags.bNeverEverTargetThisPed = true; GetPlayerPedInterface ()->pedFlags.bIsLanding = false; GetPlayerPedInterface ()->fRotationSpeed = 7.5; m_pInterface->bStreamingDontDelete = true; m_pInterface->bDontStream = true; world->Add ( m_pInterface, CPlayerPed_Constructor ); }
//////////////////////////////////////////////////////////////// // // CRenderWareSA::ModelInfoTXDAddTextures // // Adds texture into the TXD of a model. // Returns true if model was affected. // //////////////////////////////////////////////////////////////// bool CRenderWareSA::ModelInfoTXDAddTextures ( SReplacementTextures* pReplacementTextures, ushort usModelId ) { // Already done for this modelid? if ( ListContains ( pReplacementTextures->usedInModelIds, usModelId ) ) return false; // Get valid textures info for this model CModelTexturesInfo* pInfo = GetModelTexturesInfo ( usModelId ); if ( !pInfo ) return false; // Remember which models this set has been applied to pReplacementTextures->usedInModelIds.push_back ( usModelId ); // Already done for this txd? if ( ListContains ( pReplacementTextures->usedInTxdIds, pInfo->usTxdId ) ) return true; // Return true as model may need restreaming // // Add section for this txd // pReplacementTextures->perTxdList.push_back ( SReplacementTextures::SPerTxd () ); SReplacementTextures::SPerTxd& perTxdInfo = pReplacementTextures->perTxdList.back (); perTxdInfo.usTxdId = pInfo->usTxdId; perTxdInfo.bTexturesAreCopies = ( pReplacementTextures->usedInTxdIds.size () > 0 ); // Copy / clone textures for ( std::vector < RwTexture* >::iterator iter = pReplacementTextures->textures.begin () ; iter != pReplacementTextures->textures.end () ; iter++ ) { RwTexture* pNewTexture = *iter; // Use a copy if not first txd if ( perTxdInfo.bTexturesAreCopies ) { // Reuse the given texture's raster RwTexture* pCopyTex = RwTextureCreate ( pNewTexture->raster ); // Copy over additional properties MemCpyFast ( &pCopyTex->name, &pNewTexture->name, RW_TEXTURE_NAME_LENGTH ); MemCpyFast ( &pCopyTex->mask, &pNewTexture->mask, RW_TEXTURE_NAME_LENGTH ); pCopyTex->flags = pNewTexture->flags; pNewTexture = pCopyTex; } perTxdInfo.usingTextures.push_back ( pNewTexture ); } // // Add each texture to the target txd // for ( std::vector < RwTexture* >::iterator iter = perTxdInfo.usingTextures.begin () ; iter != perTxdInfo.usingTextures.end () ; iter++ ) { RwTexture* pNewTexture = *iter; // If there is a name clash with an existing texture, replace it RwTexture* pExistingTexture = RwTexDictionaryFindNamedTexture ( pInfo->pTxd, pNewTexture->name ); if ( pExistingTexture ) { RwTexDictionaryRemoveTexture ( pInfo->pTxd, pExistingTexture ); } // Add the texture dassert ( !RwTexDictionaryContainsTexture ( pInfo->pTxd, pNewTexture ) ); RwTexDictionaryAddTexture ( pInfo->pTxd, pNewTexture ); } // Remember which txds this set has been applied to pReplacementTextures->usedInTxdIds.push_back ( pInfo->usTxdId ); dassert ( !ListContains ( pInfo->usedByReplacements, pReplacementTextures ) ); pInfo->usedByReplacements.push_back ( pReplacementTextures ); return true; }
VOID CMarkerSA::SetPosition(CVector* vecPosition) { DEBUG_TRACE("VOID CMarkerSA::SetPosition ( CVector * vecPosition )"); MemCpyFast(&internalInterface->position, vecPosition, sizeof(CVector)); }