From 2a07dce860053752ef079ad5608da6c7b6d33ed1 Mon Sep 17 00:00:00 2001 From: Youssef Maged Date: Fri, 11 Sep 2026 05:40:09 +0300 Subject: [PATCH] Making the code easier to read (code formatting only) --- Client/game_sa/CBuildingRemovalSA.cpp | 17 ++++++++++++++ Client/game_sa/CBuildingSA.cpp | 3 +++ Client/game_sa/CBuildingsPoolSA.cpp | 3 +++ Client/game_sa/CFileLoaderSA.cpp | 8 +++++++ Client/game_sa/TaskAttackSA.h | 1 + Client/mods/deathmatch/logic/CBassAudio.cpp | 5 +++++ .../mods/deathmatch/logic/CClientBuilding.cpp | 10 +++++++++ .../logic/CClientBuildingManager.cpp | 2 ++ Client/mods/deathmatch/logic/CClientModel.cpp | 4 ++++ Client/mods/deathmatch/logic/CClientPed.cpp | 2 ++ .../deathmatch/logic/CClientPlayerVoice.cpp | 6 +++++ Client/mods/deathmatch/logic/CClientSound.cpp | 5 +++++ .../deathmatch/logic/CClientSoundManager.cpp | 14 ++++++++++++ .../mods/deathmatch/logic/CClientVehicle.cpp | 4 ++++ .../deathmatch/logic/CDeathmatchObject.cpp | 4 ++++ .../deathmatch/logic/CObjectRespawner.cpp | 1 + Client/mods/deathmatch/logic/CObjectSync.cpp | 6 +++++ .../mods/deathmatch/logic/CPacketHandler.cpp | 2 ++ .../logic/luadefs/CLuaAudioDefs.cpp | 22 +++++++++++++++++++ .../logic/luadefs/CLuaBuildingDefs.cpp | 1 + .../logic/luadefs/CLuaWorldDefs.cpp | 1 + .../deathmatch/logic/rpc/CElementRPCs.cpp | 3 +++ .../mods/deathmatch/logic/rpc/CObjectRPCs.cpp | 6 +++++ 23 files changed, 130 insertions(+) diff --git a/Client/game_sa/CBuildingRemovalSA.cpp b/Client/game_sa/CBuildingRemovalSA.cpp index 910cbbdd169..ee87a915839 100644 --- a/Client/game_sa/CBuildingRemovalSA.cpp +++ b/Client/game_sa/CBuildingRemovalSA.cpp @@ -256,9 +256,12 @@ bool CBuildingRemovalSA::RestoreBuilding(uint16_t usModelToRestore, float fRange } } } + // Remove the building from the list m_pBuildingRemovals->erase(iter++); + delete pFind; + // Success! don't return incase there are any others to delete bSuccess = true; } @@ -268,6 +271,7 @@ bool CBuildingRemovalSA::RestoreBuilding(uint16_t usModelToRestore, float fRange else iter++; } + std::pair::iterator, std::multimap::iterator> dataBuildingIterators = m_pDataBuildings->equal_range(usModelToRestore); std::multimap::const_iterator iterator = dataBuildingIterators.first; @@ -367,6 +371,7 @@ bool CBuildingRemovalSA::IsRemovedModelInRadius(SIPLInst* pInst) } } } + return false; } @@ -400,6 +405,7 @@ bool CBuildingRemovalSA::IsObjectRemoved(CEntitySAInterface* pInterface) } float fDistance = sqrt(fDistanceX * fDistanceX + fDistanceY * fDistanceY + fDistanceZ * fDistanceZ); + // is it in the removal spheres radius if so return else keep looking if (fDistance <= pFind->m_fRadius) { @@ -408,6 +414,7 @@ bool CBuildingRemovalSA::IsObjectRemoved(CEntitySAInterface* pInterface) } } } + return false; } @@ -500,6 +507,7 @@ void CBuildingRemovalSA::ClearRemovedBuildingLists(uint* pOutAmount) else iter++; } + // Init some variables std::multimap::const_iterator iterator = m_pDataBuildings->begin(); // Loop through the data building list @@ -512,6 +520,7 @@ void CBuildingRemovalSA::ClearRemovedBuildingLists(uint* pOutAmount) pFound->m_iCount = 0; } } + // Init some variables std::multimap::const_iterator iteratorBinary = m_pBinaryBuildings->begin(); // Loop through the data building list @@ -524,10 +533,13 @@ void CBuildingRemovalSA::ClearRemovedBuildingLists(uint* pOutAmount) pFoundBinary->m_iCount = 0; } } + // Delete old building lists delete m_pBuildingRemovals; + // Create new m_pBuildingRemovals = new std::multimap; + m_pRemovedEntities.clear(); m_pAddedEntities.clear(); @@ -579,10 +591,13 @@ sDataBuildingRemovalItem* CBuildingRemovalSA::AddDataBuilding(CEntitySAInterface // Create a new building removal sDataBuildingRemovalItem* pBuildingRemoval = new sDataBuildingRemovalItem(pInterface, true); + // Insert it with the model index so we can fast lookup m_pDataBuildings->insert(std::pair((uint16_t)pInterface->m_nModelIndex, pBuildingRemoval)); + m_pAddedEntities[(DWORD)pInterface] = true; m_pRemovedEntities[(DWORD)pInterface] = false; + return pBuildingRemoval; } @@ -618,8 +633,10 @@ void CBuildingRemovalSA::AddBinaryBuilding(CEntitySAInterface* pInterface) { // Create a new building removal sBuildingRemovalItem* pBuildingRemoval = new sBuildingRemovalItem(pInterface, false); + // Insert it with the model index so we can fast lookup m_pBinaryBuildings->insert(std::pair((uint16_t)pInterface->m_nModelIndex, pBuildingRemoval)); + m_pAddedEntities[(DWORD)pInterface] = true; m_pRemovedEntities[(DWORD)pInterface] = false; } diff --git a/Client/game_sa/CBuildingSA.cpp b/Client/game_sa/CBuildingSA.cpp index 28164b59fe5..06f17448601 100644 --- a/Client/game_sa/CBuildingSA.cpp +++ b/Client/game_sa/CBuildingSA.cpp @@ -57,6 +57,7 @@ void CBuildingSA::SetLod(CBuilding* pLod) else { CEntitySAInterface* pCurrentLod = m_pInterface->m_pLod; + if (pCurrentLod) { pGame->GetWorld()->Remove(pCurrentLod, CBuilding_SetLod); @@ -91,6 +92,7 @@ void CBuildingSA::ReallocateMatrix() newMatrix->m_pNext = nullptr; m_pInterface->RemoveMatrix(); + m_pInterface->matrix = reinterpret_cast(newMatrix); } @@ -106,5 +108,6 @@ void CBuildingSA::RemoveAllocatedMatrix() g_matrixPool.RemoveItem(reinterpret_cast(m_pInterface->matrix)); g_matrixPool.SetCapacity(0); + m_pInterface->matrix = nullptr; } diff --git a/Client/game_sa/CBuildingsPoolSA.cpp b/Client/game_sa/CBuildingsPoolSA.cpp index 352126dae57..4a2738ed657 100644 --- a/Client/game_sa/CBuildingsPoolSA.cpp +++ b/Client/game_sa/CBuildingsPoolSA.cpp @@ -42,6 +42,7 @@ inline bool CBuildingsPoolSA::AddBuildingToPool(CClientBuilding* pClientBuilding return false; std::int32_t iElementIndexInPool = (*m_ppBuildingPoolInterface)->GetObjectIndexSafe(pInterface); + if (iElementIndexInPool == -1) return false; @@ -82,6 +83,7 @@ CBuilding* CBuildingsPoolSA::AddBuilding(CClientBuilding* pClientBuilding, uint1 // Change the properties group to force dynamic models to be created as buildings instead of dummies auto prevGroup = modelInfo->GetObjectPropertiesGroup(); + if (prevGroup != MODEL_PROPERTIES_GROUP_STATIC) modelInfo->SetObjectPropertiesGroup(MODEL_PROPERTIES_GROUP_STATIC); @@ -140,6 +142,7 @@ void CBuildingsPoolSA::RemoveBuilding(CBuilding* pBuilding) CBuildingSAInterface* pInterface = pBuilding->GetBuildingInterface(); std::int32_t iElementIndexInPool = (*m_ppBuildingPoolInterface)->GetObjectIndexSafe(pInterface); + if (iElementIndexInPool == -1) return; diff --git a/Client/game_sa/CFileLoaderSA.cpp b/Client/game_sa/CFileLoaderSA.cpp index d5ce6c911ee..e71222dfd03 100644 --- a/Client/game_sa/CFileLoaderSA.cpp +++ b/Client/game_sa/CFileLoaderSA.cpp @@ -149,6 +149,7 @@ bool CFileLoader_LoadAtomicFile(RwStream* stream, unsigned int modelId) auto pAtomicModelInfo = reinterpret_cast(pBaseModelInfo); bool bUseCommonVehicleTexDictionary = false; + if (pAtomicModelInfo && pBaseModelInfo->bWetRoadReflection) { bUseCommonVehicleTexDictionary = true; @@ -156,9 +157,11 @@ bool CFileLoader_LoadAtomicFile(RwStream* stream, unsigned int modelId) } const unsigned int rwID_CLUMP = 16; + if (RwStreamFindChunk(stream, rwID_CLUMP, nullptr, nullptr)) { RpClump* pReadClump = RpClumpStreamRead(stream); + if (!pReadClump) { if (bUseCommonVehicleTexDictionary) @@ -169,6 +172,7 @@ bool CFileLoader_LoadAtomicFile(RwStream* stream, unsigned int modelId) } gAtomicModelId = modelId; + SRelatedModelInfo relatedModelInfo = {0}; relatedModelInfo.pClump = pReadClump; relatedModelInfo.bDeleteOldRwObject = false; @@ -186,6 +190,7 @@ bool CFileLoader_LoadAtomicFile(RwStream* stream, unsigned int modelId) { CVehicleModelInfo_StopUsingCommonVehicleTexDicationary(); } + return true; } @@ -213,6 +218,7 @@ RpAtomic* CFileLoader_SetRelatedModelInfoCB(RpAtomic* atomic, SRelatedModelInfo* CVisibilityPlugins_SetAtomicRenderCallback(atomic, 0); RpAtomic* pOldAtomic = reinterpret_cast(pBaseModelInfo->pRwObject); + if (bDamage) { auto pDamagableModelInfo = reinterpret_cast(pAtomicModelInfo); @@ -224,6 +230,7 @@ RpAtomic* CFileLoader_SetRelatedModelInfoCB(RpAtomic* atomic, SRelatedModelInfo* } RpClumpRemoveAtomic(pRelatedModelInfo->pClump, atomic); + RwFrame* newFrame = RwFrameCreate(); RpAtomicSetFrame(atomic, newFrame); CVisibilityPlugins_SetAtomicId(atomic, gAtomicModelId); @@ -265,6 +272,7 @@ CEntitySAInterface* CFileLoader_LoadObjectInstance(const char* szLine) but custom exporters might not contain the normalization. And we must do it instead. */ const float fLenSq = inst.rotation.LengthSquared(); + if (fLenSq > 0.0f && std::fabs(fLenSq - 1.0f) > std::numeric_limits::epsilon()) { const float fLength = std::sqrt(fLenSq); diff --git a/Client/game_sa/TaskAttackSA.h b/Client/game_sa/TaskAttackSA.h index 994e8cd25a3..60f5c24a520 100644 --- a/Client/game_sa/TaskAttackSA.h +++ b/Client/game_sa/TaskAttackSA.h @@ -203,4 +203,5 @@ class CTaskSimpleStealthKillSAInterface : public CTaskSimpleSAInterface CAnimBlendAssociation* m_anim; unsigned int m_spentWaitingMs; }; + static_assert(sizeof(CTaskSimpleStealthKillSAInterface) == 0x20, "Invalid CTaskSimpleStealthKillSAInterface size"); diff --git a/Client/mods/deathmatch/logic/CBassAudio.cpp b/Client/mods/deathmatch/logic/CBassAudio.cpp index 48b37f2ad3b..54773305ee8 100644 --- a/Client/mods/deathmatch/logic/CBassAudio.cpp +++ b/Client/mods/deathmatch/logic/CBassAudio.cpp @@ -244,6 +244,7 @@ bool CBassAudio::BeginLoadingMedia() if (it == ms_FailedAudioFiles.end() || (dwCurrentTime - it->second) >= FAILED_LOAD_RETRY_DELAY) { bShouldTry = true; + // Mark as failed/in-progress immediately // and to ensure failure is cached if ConvertFileToMono fails ms_FailedAudioFiles[m_strPath] = dwCurrentTime; @@ -331,12 +332,15 @@ bool CBassAudio::BeginLoadingMedia() g_pCore->GetConsole()->Printf("BASS ERROR %d in BASS_FX_BPM_BeatCallbackSet path:%s 3d:%d loop:%d", BASS_ErrorGetCode(), *m_strPath, m_b3D, m_bLoop); } + m_pSound = BASS_FX_TempoCreate(m_pSound, lFlags | BASS_FX_FREESOURCE); + if (!m_pSound) { g_pCore->GetConsole()->Printf("BASS ERROR %d in CreateTempo path:%s 3d:%d loop:%d", BASS_ErrorGetCode(), *m_strPath, m_b3D, m_bLoop); return false; } + BASS_ChannelGetAttribute(m_pSound, BASS_ATTRIB_TEMPO, &m_fTempo); BASS_ChannelGetAttribute(m_pSound, BASS_ATTRIB_TEMPO_PITCH, &m_fPitch); BASS_ChannelGetAttribute(m_pSound, BASS_ATTRIB_TEMPO_FREQ, &m_fSampleRate); @@ -1077,6 +1081,7 @@ float* CBassAudio::GetWaveData(int iLength) } return NULL; } + DWORD CBassAudio::GetLevelData() { if (m_pSound) diff --git a/Client/mods/deathmatch/logic/CClientBuilding.cpp b/Client/mods/deathmatch/logic/CClientBuilding.cpp index a8306e9bb8b..5b356cbc219 100644 --- a/Client/mods/deathmatch/logic/CClientBuilding.cpp +++ b/Client/mods/deathmatch/logic/CClientBuilding.cpp @@ -43,10 +43,12 @@ void CClientBuilding::Unlink() { m_pHighBuilding->SetLowLodBuilding(); } + if (m_pLowBuilding) { SetLowLodBuilding(); } + Destroy(); } @@ -57,6 +59,7 @@ void CClientBuilding::SetPosition(const CVector& vecPosition) if (m_vPos == vecPosition) return; + m_vPos = vecPosition; Recreate(); UpdateSpatialData(); @@ -66,6 +69,7 @@ void CClientBuilding::SetRotationRadians(const CVector& vecRadians) { if (m_vRot == vecRadians) return; + m_vRot = vecRadians; Recreate(); } @@ -94,6 +98,7 @@ void CClientBuilding::SetInterior(uint8_t ucInterior) { if (m_interior == ucInterior) return; + m_interior = ucInterior; Recreate(); } @@ -172,8 +177,10 @@ void CClientBuilding::Create() { m_pBuilding->SetUsesCollision(m_usesCollision); } + if (m_ucAlpha != 255) m_pBuilding->SetAlpha(m_ucAlpha); + if (m_pHighBuilding) { m_pHighBuilding->GetBuildingEntity()->SetLod(m_pBuilding); @@ -189,6 +196,7 @@ void CClientBuilding::Destroy() { m_pHighBuilding->GetBuildingEntity()->SetLod(nullptr); } + g_pGame->GetPools()->GetBuildingsPool().RemoveBuilding(m_pBuilding); m_pBuilding = nullptr; } @@ -202,6 +210,7 @@ bool CClientBuilding::SetLowLodBuilding(CClientBuilding* pLod) // Unlink old high lod element CClientBuilding* pOveridedBuilding = pLod->GetHighLodBuilding(); + if (pOveridedBuilding && pOveridedBuilding != this) { pOveridedBuilding->SetLowLodBuilding(); @@ -220,6 +229,7 @@ bool CClientBuilding::SetLowLodBuilding(CClientBuilding* pLod) { m_pLowBuilding->SetHighLodBuilding(); } + m_pBuilding->SetLod(nullptr); m_pLowBuilding = nullptr; } diff --git a/Client/mods/deathmatch/logic/CClientBuildingManager.cpp b/Client/mods/deathmatch/logic/CClientBuildingManager.cpp index fbfda5b8364..19671d3c131 100644 --- a/Client/mods/deathmatch/logic/CClientBuildingManager.cpp +++ b/Client/mods/deathmatch/logic/CClientBuildingManager.cpp @@ -75,6 +75,7 @@ bool CClientBuildingManager::IsValidModel(uint16_t modelId) return false; CModelInfo* pModelInfo = g_pGame->GetModelInfo(modelId); + if (!pModelInfo || !pModelInfo->GetInterface()) return false; @@ -82,6 +83,7 @@ bool CClientBuildingManager::IsValidModel(uint16_t modelId) return false; eModelInfoType eType = pModelInfo->GetModelType(); + return (eType == eModelInfoType::CLUMP || eType == eModelInfoType::ATOMIC || eType == eModelInfoType::WEAPON || eType == eModelInfoType::TIME); } diff --git a/Client/mods/deathmatch/logic/CClientModel.cpp b/Client/mods/deathmatch/logic/CClientModel.cpp index 8565ef76dbf..753f214779d 100644 --- a/Client/mods/deathmatch/logic/CClientModel.cpp +++ b/Client/mods/deathmatch/logic/CClientModel.cpp @@ -55,6 +55,7 @@ bool CClientModel::Allocate(ushort usParentID) { bool isValidModel = g_pClientGame->GetObjectManager()->IsValidModel(usParentID); bool isDamagable = pParentModelInfo->IsDamageableAtomic(); + if (isValidModel && isDamagable) { pModelInfo->MakeObjectDamageableModel(usParentID); @@ -204,6 +205,7 @@ void CClientModel::RestoreDFF(CModelInfo* pModelInfo) // Restore buildings CClientBuildingManager* pBuildingsManager = g_pClientGame->GetManager()->GetBuildingManager(); auto& buildingsList = pBuildingsManager->GetBuildings(); + unloadModelsAndCallEventsNonStreamed(buildingsList.begin(), buildingsList.end(), usParentID, [=](auto& element) { element.SetModel(usParentID); }); // Restore COL @@ -228,11 +230,13 @@ void CClientModel::RestoreDFF(CModelInfo* pModelInfo) bool CClientModel::AllocateTXD(std::string& strTxdName) { std::uint32_t uiSlotID = g_pGame->GetPools()->GetTxdPool().AllocateTextureDictonarySlot(m_iModelID - MAX_MODEL_DFF_ID, strTxdName); + if (uiSlotID != -1) { m_bAllocatedByUs = true; return true; } + return false; } diff --git a/Client/mods/deathmatch/logic/CClientPed.cpp b/Client/mods/deathmatch/logic/CClientPed.cpp index d8a8528aefc..28f13dc90fd 100644 --- a/Client/mods/deathmatch/logic/CClientPed.cpp +++ b/Client/mods/deathmatch/logic/CClientPed.cpp @@ -5485,8 +5485,10 @@ void CClientPed::SetTargetPosition(const CVector& vecPosition, unsigned long ulD { if (m_interp.pTargetOriginSource) m_interp.pTargetOriginSource->RemoveOriginSourceUser(this); + if (pTargetOriginSource) pTargetOriginSource->AddOriginSourceUser(this); + m_interp.pTargetOriginSource = pTargetOriginSource; } diff --git a/Client/mods/deathmatch/logic/CClientPlayerVoice.cpp b/Client/mods/deathmatch/logic/CClientPlayerVoice.cpp index 465540fa413..8a35dea36f2 100644 --- a/Client/mods/deathmatch/logic/CClientPlayerVoice.cpp +++ b/Client/mods/deathmatch/logic/CClientPlayerVoice.cpp @@ -57,6 +57,7 @@ CClientPlayerVoice::CClientPlayerVoice(CClientPlayer* pPlayer, CVoiceRecorder* p m_fPlaybackSpeed = 1.0f; Init(); } + CClientPlayerVoice::~CClientPlayerVoice() { DeInit(); @@ -430,16 +431,19 @@ void CClientPlayerVoice::ApplyFXModifications(float fSampleRate, float fTempo, f m_fSampleRate = fSampleRate; m_fTempo = fTempo; m_fPitch = fPitch; + if (m_pBassPlaybackStream) { if (fTempo != m_fTempo) { m_fTempo = fTempo; } + if (fPitch != m_fPitch) { m_fPitch = fPitch; } + if (fSampleRate != m_fSampleRate) { m_fSampleRate = fSampleRate; @@ -604,6 +608,7 @@ bool CClientPlayerVoice::SetFxEffectParameters(std::uint32_t uiFxEffect, void* p { if (IsFxEffectEnabled(uiFxEffect)) return BASS_FXSetParameters(m_FxEffects[uiFxEffect], params); + return false; } @@ -611,6 +616,7 @@ bool CClientPlayerVoice::GetFxEffectParameters(std::uint32_t uiFxEffect, void* p { if (IsFxEffectEnabled(uiFxEffect)) return BASS_FXGetParameters(m_FxEffects[uiFxEffect], params); + return false; } diff --git a/Client/mods/deathmatch/logic/CClientSound.cpp b/Client/mods/deathmatch/logic/CClientSound.cpp index 1c4fd702d07..a2a6d99e799 100644 --- a/Client/mods/deathmatch/logic/CClientSound.cpp +++ b/Client/mods/deathmatch/logic/CClientSound.cpp @@ -597,6 +597,7 @@ float* CClientSound::GetWaveData(int iLength) } return NULL; } + bool CClientSound::SetPanEnabled(bool bPan) { if (m_b3D) @@ -737,13 +738,17 @@ void CClientSound::Process3D(const CVector& vecPlayerPosition, const CVector& ve { // Update our position and velocity if we're attached CClientEntity* pAttachedToEntity = GetAttachedTo(); + if (pAttachedToEntity) { GetPosition(m_vecPosition); DoAttaching(); + CVector vecVelocity; + if (CStaticFunctionDefinitions::GetElementVelocity(*pAttachedToEntity, vecVelocity)) SetVelocity(vecVelocity); + // Update our spatial data position UpdateSpatialData(); } diff --git a/Client/mods/deathmatch/logic/CClientSoundManager.cpp b/Client/mods/deathmatch/logic/CClientSoundManager.cpp index 3f8c42d8a0c..ba93e592ce5 100644 --- a/Client/mods/deathmatch/logic/CClientSoundManager.cpp +++ b/Client/mods/deathmatch/logic/CClientSoundManager.cpp @@ -128,6 +128,7 @@ void CClientSoundManager::DoPulse() g_pClientGame->GetElementDeleter()->Delete(pSound); } } + UpdateDistanceStreaming(vecCameraPosition); ProcessStopQueues(); } @@ -149,9 +150,12 @@ CClientSound* CClientSoundManager::PlaySound2D(const SString& strSound, bool bIs { size_t size = strSound.size(); void* pMemory = new char[size]; + memcpy(pMemory, strSound.data(), size); + if (pSound->Play((void*)pMemory, size, bLoop)) return pSound; + // Note: pMemory is already owned by pSound via AdoptBuffer, don't delete it here } else if (pSound->Play(strSound, bLoop)) @@ -186,12 +190,15 @@ CClientSound* CClientSoundManager::PlaySound3D(const SString& strSound, bool bIs { size_t size = strSound.size(); void* pMemory = new char[size]; + memcpy(pMemory, strSound.data(), size); + if (pSound->Play3D((void*)pMemory, size, bLoop)) { pSound->SetPosition(vecPosition); return pSound; } + // Note: pMemory is already owned by pSound via AdoptBuffer, don't delete it here } else if (pSound->Play3D(strSound, bLoop)) @@ -238,11 +245,13 @@ CClientSound* CClientSoundManager::PlayGTASFX(eAudioLookupIndex containerIndex, } CClientSound* pSound = PlaySound2D(pAudioData, uiAudioLength, bLoop); + if (pSound) { CGameSettings* gameSettings = g_pGame->GetSettings(); pSound->SetVolume(gameSettings->GetSFXVolume() / 255.0f); } + return pSound; } @@ -266,11 +275,13 @@ CClientSound* CClientSoundManager::PlayGTASFX3D(eAudioLookupIndex containerIndex } CClientSound* pSound = PlaySound3D(pAudioData, uiAudioLength, vecPosition, bLoop); + if (pSound) { CGameSettings* gameSettings = g_pGame->GetSettings(); pSound->SetVolume(gameSettings->GetSFXVolume() / 255.0f); } + return pSound; } @@ -288,6 +299,7 @@ int CClientSoundManager::GetFxEffectFromName(const std::string& strEffectName) { return it->second; } + return -1; } @@ -408,6 +420,7 @@ void CClientSoundManager::QueueChannelStop(DWORD pSound) { // Always not main thread dassert(!IsMainThread()); + m_CS.Lock(); m_ChannelStopQueue.push_back(pSound); m_CS.Unlock(); @@ -434,6 +447,7 @@ void CClientSoundManager::ProcessStopQueues(bool bFlush) std::vector channelStopList = m_ChannelStopQueue; m_ChannelStopQueue.clear(); m_CS.Unlock(); + for (unsigned int i = 0; i < channelStopList.size(); i++) { BASS_ChannelStop(channelStopList[i]); diff --git a/Client/mods/deathmatch/logic/CClientVehicle.cpp b/Client/mods/deathmatch/logic/CClientVehicle.cpp index 392aa118eae..78479f0dfc8 100644 --- a/Client/mods/deathmatch/logic/CClientVehicle.cpp +++ b/Client/mods/deathmatch/logic/CClientVehicle.cpp @@ -384,6 +384,7 @@ void CClientVehicle::GetPosition(CVector& vecPosition) const static bool CanMoveOccupantWithVehicle(CClientPed* pOccupant) { const int iState = pOccupant->GetVehicleInOutState(); + return (iState != VEHICLE_INOUT_GETTING_OUT && iState != VEHICLE_INOUT_GETTING_JACKED) || pOccupant->GetRealOccupiedVehicle(); } @@ -394,6 +395,7 @@ void CClientVehicle::SetPosition(const CVector& vecPosition, bool bResetInterpol { // If move is big enough, do ground checks float DistanceMoved = (m_Matrix.vPos - vecPosition).Length(); + if (DistanceMoved > 50 && !IsFrozen() && bAllowGroundLoadFreeze) SetFrozenWaitingForGroundToLoad(true, true); } @@ -408,6 +410,7 @@ void CClientVehicle::SetPosition(const CVector& vecPosition, bool bResetInterpol { CVector vecMoveSpeed; m_pVehicle->GetMoveSpeed(&vecMoveSpeed); + if (vecMoveSpeed.fX == 0.0f && vecMoveSpeed.fY == 0.0f && vecMoveSpeed.fZ == 0.0f) { vecMoveSpeed.fZ -= 0.01f; @@ -415,6 +418,7 @@ void CClientVehicle::SetPosition(const CVector& vecPosition, bool bResetInterpol } } } + // Have we moved to a different position? if (m_Matrix.vPos != vecPosition) { diff --git a/Client/mods/deathmatch/logic/CDeathmatchObject.cpp b/Client/mods/deathmatch/logic/CDeathmatchObject.cpp index cd950285a85..43d567d76f2 100644 --- a/Client/mods/deathmatch/logic/CDeathmatchObject.cpp +++ b/Client/mods/deathmatch/logic/CDeathmatchObject.cpp @@ -69,6 +69,7 @@ void CDeathmatchObject::StartMovement(const CPositionRotationAnimation& a_rMoveA a_rMoveAnimation.GetFinalValue(positionRotation); SetOrientation(positionRotation.m_vecPosition, positionRotation.m_vecRotation); } + CLuaArguments Arguments; this->CallEvent("onClientObjectMoveStart", Arguments, true); } @@ -88,6 +89,7 @@ void CDeathmatchObject::_StopMovement(bool a_bUnregister) } delete m_pMoveAnimation; m_pMoveAnimation = NULL; + CLuaArguments Arguments; this->CallEvent("onClientObjectMoveStop", Arguments, true); } @@ -210,6 +212,7 @@ void CDeathmatchObject::UpdateContacting(const CVector& vecCenterOfRotation, con if (vecFrameRotation.fZ != 0) { float fRotationZ = pPed->GetCurrentRotation(); + pPed->SetCurrentRotation(fRotationZ + vecFrameRotation.fZ); } } @@ -218,6 +221,7 @@ void CDeathmatchObject::UpdateContacting(const CVector& vecCenterOfRotation, con for (uint i = 0; i < m_AttachedEntities.size(); ++i) { CClientEntity* pEntity = m_AttachedEntities[i]; + if (IS_OBJECT(pEntity)) { CDeathmatchObject* pObject = static_cast(pEntity); diff --git a/Client/mods/deathmatch/logic/CObjectRespawner.cpp b/Client/mods/deathmatch/logic/CObjectRespawner.cpp index acb6a315f3b..f8fdcd9710d 100644 --- a/Client/mods/deathmatch/logic/CObjectRespawner.cpp +++ b/Client/mods/deathmatch/logic/CObjectRespawner.cpp @@ -57,6 +57,7 @@ bool CObjectRespawner::IsBeingRespawned(CClientObject* pObject) void CObjectRespawner::Unreference(CClientObject* pObject) { std::vector::iterator it = std::find(m_List.begin(), m_List.end(), pObject); + if (it != m_List.end()) m_List.erase(it); } diff --git a/Client/mods/deathmatch/logic/CObjectSync.cpp b/Client/mods/deathmatch/logic/CObjectSync.cpp index f580376cddb..0aad193aedd 100644 --- a/Client/mods/deathmatch/logic/CObjectSync.cpp +++ b/Client/mods/deathmatch/logic/CObjectSync.cpp @@ -106,6 +106,7 @@ void CObjectSync::Packet_ObjectStartSync(NetBitStreamInterface& BitStream) // Read out the health SObjectHealthSync health; + if (BitStream.Read(&health)) { pObject->SetHealth(health.data.fValue); @@ -177,13 +178,16 @@ void CObjectSync::Packet_ObjectSync(NetBitStreamInterface& BitStream) // Grab the object CDeathmatchObject* pObject = static_cast(m_pObjectManager->Get(ID)); + // Only update the sync if this packet is from the same context if (pObject && pObject->CanUpdateSync(ucSyncTimeContext)) { if (flags & 0x1) pObject->SetPosition(position.data.vecPosition); + if (flags & 0x2) pObject->SetRotationRadians(rotation.data.vecRotation); + if (flags & 0x4) pObject->SetHealth(health.data.fValue); } @@ -219,8 +223,10 @@ void CObjectSync::WriteObjectInformation(NetBitStreamInterface* pBitStream, CDea if (vecPosition != pObject->m_LastSyncedData.vecPosition) ucFlags |= 0x1; + if (vecRotation != pObject->m_LastSyncedData.vecRotation) ucFlags |= 0x2; + if (pObject->GetHealth() != pObject->m_LastSyncedData.fHealth) ucFlags |= 0x4; diff --git a/Client/mods/deathmatch/logic/CPacketHandler.cpp b/Client/mods/deathmatch/logic/CPacketHandler.cpp index 7cdeb13dc5f..e6a08146871 100644 --- a/Client/mods/deathmatch/logic/CPacketHandler.cpp +++ b/Client/mods/deathmatch/logic/CPacketHandler.cpp @@ -1923,6 +1923,7 @@ void CPacketHandler::Packet_Vehicle_InOut(NetBitStreamInterface& bitStream) // A jack victim also leaves through here when the jacker aborts, and his drag // animation may still be playing on clients watching it; let it finish. bool bDontWarpIfGettingDraggedOut = pPed->IsLocalPlayer() || pPed->IsSyncing() || pPed->IsGettingJacked(); + pPed->RemoveFromVehicle(bDontWarpIfGettingDraggedOut); if (ucSeat == 0) @@ -2078,6 +2079,7 @@ void CPacketHandler::Packet_Vehicle_InOut(NetBitStreamInterface& bitStream) // The confirmation only waits for the jacker's own enter animation, so it can arrive while // the jacked ped's drag animation still plays on clients watching it; let it finish. bool bDontWarpIfGettingDraggedOut = pOutsidePed->IsLocalPlayer() || pOutsidePed->IsSyncing() || pOutsidePed->IsGettingJacked(); + pOutsidePed->RemoveFromVehicle(bDontWarpIfGettingDraggedOut); // Reset interpolation so he won't appear on the roof of the vehicle until next sync diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaAudioDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaAudioDefs.cpp index 78276c0ecd4..c2c4f050124 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaAudioDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaAudioDefs.cpp @@ -94,6 +94,7 @@ std::variant CLuaAudioDefs::PlaySound(lua_State* luaVM, con if (resource) { CClientSound* sound = m_pManager->GetSoundManager()->PlaySound2D(soundPath, isURL, isRawData, loop.value_or(false), throttle.value_or(true)); + if (sound) { sound->SetParent(resource->GetResourceDynamicEntity()); @@ -135,6 +136,7 @@ std::variant CLuaAudioDefs::PlaySound3D(lua_State* luaVM, c if (resource) { CClientSound* sound = m_pManager->GetSoundManager()->PlaySound3D(soundPath, isURL, isRawData, position, loop.value_or(false), throttle.value_or(true)); + if (sound) { sound->SetParent(resource->GetResourceDynamicEntity()); @@ -626,6 +628,7 @@ bool CLuaAudioDefs::SetSoundEffectParameter(std::variantGetFxEffectParameters((std::uint32_t)effectType, ¶ms); Chorus effectParameterType; + if (!StringToEnum(effectParameter, effectParameterType)) return false; + switch (effectParameterType) { case Chorus::WET_DRY_MIX: @@ -690,8 +695,10 @@ bool CLuaAudioDefs::SetSoundEffectParameter(std::variantGetFxEffectParameters((std::uint32_t)effectType, ¶ms); Compressor effectParameterType; + if (!StringToEnum(effectParameter, effectParameterType)) return false; + switch (effectParameterType) { case Compressor::GAIN: @@ -740,8 +747,10 @@ bool CLuaAudioDefs::SetSoundEffectParameter(std::variantGetFxEffectParameters((std::uint32_t)effectType, ¶ms); Distortion effectParameterType; + if (!StringToEnum(effectParameter, effectParameterType)) return false; + switch (effectParameterType) { case Distortion::GAIN: @@ -784,8 +793,10 @@ bool CLuaAudioDefs::SetSoundEffectParameter(std::variantGetFxEffectParameters((std::uint32_t)effectType, ¶ms); Echo effectParameterType; + if (!StringToEnum(effectParameter, effectParameterType)) return false; + switch (effectParameterType) { case Echo::WET_DRY_MIX: @@ -830,8 +841,10 @@ bool CLuaAudioDefs::SetSoundEffectParameter(std::variantGetFxEffectParameters((std::uint32_t)effectType, ¶ms); Flanger effectParameterType; + if (!StringToEnum(effectParameter, effectParameterType)) return false; + switch (effectParameterType) { case Flanger::WET_DRY_MIX: @@ -886,8 +899,10 @@ bool CLuaAudioDefs::SetSoundEffectParameter(std::variantGetFxEffectParameters((std::uint32_t)effectType, ¶ms); Gargle effectParameterType; + if (!StringToEnum(effectParameter, effectParameterType)) return false; + switch (effectParameterType) { case Gargle::RATE_HZ: @@ -912,8 +927,10 @@ bool CLuaAudioDefs::SetSoundEffectParameter(std::variantGetFxEffectParameters((std::uint32_t)effectType, ¶ms); I3DL2Reverb effectParameterType; + if (!StringToEnum(effectParameter, effectParameterType)) return false; + switch (effectParameterType) { case I3DL2Reverb::ROOM: @@ -998,8 +1015,10 @@ bool CLuaAudioDefs::SetSoundEffectParameter(std::variantGetFxEffectParameters((std::uint32_t)effectType, ¶ms); ParamEq effectParameterType; + if (!StringToEnum(effectParameter, effectParameterType)) return false; + switch (effectParameterType) { case ParamEq::CENTER: @@ -1030,8 +1049,10 @@ bool CLuaAudioDefs::SetSoundEffectParameter(std::variantGetFxEffectParameters((std::uint32_t)effectType, ¶ms); Reverb effectParameterType; + if (!StringToEnum(effectParameter, effectParameterType)) return false; + switch (effectParameterType) { case Reverb::IN_GAIN: @@ -1080,6 +1101,7 @@ auto CLuaAudioDefs::GetSoundEffectParameters(std::variant(&sound)) soundElement = *soundPtr; else if (auto* playerPtr = std::get_if(&sound)) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.cpp index 732b821cbea..6041d4768ef 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaBuildingDefs.cpp @@ -40,6 +40,7 @@ CClientBuilding* CLuaBuildingDefs::CreateBuilding(lua_State* const luaVM, std::u // Get the resource we belong to CResource* pResource = pLuaMain->GetResource(); + if (!pResource) return nullptr; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp index 57c1d04d85e..d3c8296fbdd 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp @@ -2373,6 +2373,7 @@ CLuaMultiReturnGetWorld()->TestSphereAgainstWorld( sphereCenter, radius, ignoredEntity.has_value() ? ignoredEntity.value()->GetGameEntity() : nullptr, checkBuildings.value_or(true), checkVehicles.value_or(true), checkPeds.value_or(true), checkObjects.value_or(true), checkDummies.value_or(true), cameraIgnore.value_or(false), result); + if (entity) collidedEntity = reinterpret_cast(entity->GetStoredPointer()); diff --git a/Client/mods/deathmatch/logic/rpc/CElementRPCs.cpp b/Client/mods/deathmatch/logic/rpc/CElementRPCs.cpp index edd799fe60b..71d809161ce 100644 --- a/Client/mods/deathmatch/logic/rpc/CElementRPCs.cpp +++ b/Client/mods/deathmatch/logic/rpc/CElementRPCs.cpp @@ -94,8 +94,10 @@ void CElementRPCs::SetElementData(CClientEntity* pSource, NetBitStreamInterface& CLogger::ErrorPrintf("RPC SetElementData name length > MAX_CUSTOMDATA_NAME_LENGTH"); return; } + SString strName; CLuaArgument Argument; + if (bitStream.ReadStringCharacters(strName, usNameLength) && Argument.ReadFromBitStream(bitStream)) { pSource->SetCustomData(CStringName{strName}, Argument); @@ -113,6 +115,7 @@ void CElementRPCs::RemoveElementData(CClientEntity* pSource, NetBitStreamInterfa SString strName; // Read out the name plus whether it's recursive or not + if (bitStream.ReadStringCharacters(strName, usNameLength) && bitStream.ReadBit(bRecursive)) { // Remove that name diff --git a/Client/mods/deathmatch/logic/rpc/CObjectRPCs.cpp b/Client/mods/deathmatch/logic/rpc/CObjectRPCs.cpp index 6800075e6a3..44f24c6a872 100644 --- a/Client/mods/deathmatch/logic/rpc/CObjectRPCs.cpp +++ b/Client/mods/deathmatch/logic/rpc/CObjectRPCs.cpp @@ -46,6 +46,7 @@ void CObjectRPCs::SetObjectRotation(CClientEntity* pSource, NetBitStreamInterfac // Grab the object CDeathmatchObject* pObject = static_cast(m_pObjectManager->Get(pSource->GetID())); + if (pObject) { if (bitStream.Read(vecRotation.fX) && bitStream.Read(vecRotation.fY) && bitStream.Read(vecRotation.fZ)) @@ -78,11 +79,13 @@ void CObjectRPCs::StopObject(CClientEntity* pSource, NetBitStreamInterface& bitS { // Grab the object CDeathmatchObject* pObject = static_cast(m_pObjectManager->Get(pSource->GetID())); + if (pObject) { // Read out the position and rotation CVector vecSourcePosition; CVector vecSourceRotation; + if (bitStream.Read(vecSourcePosition.fX) && bitStream.Read(vecSourcePosition.fY) && bitStream.Read(vecSourcePosition.fZ) && bitStream.Read(vecSourceRotation.fX) && bitStream.Read(vecSourceRotation.fY) && bitStream.Read(vecSourceRotation.fZ)) { @@ -97,6 +100,7 @@ void CObjectRPCs::StopObject(CClientEntity* pSource, NetBitStreamInterface& bitS void CObjectRPCs::SetObjectScale(CClientEntity* pSource, NetBitStreamInterface& bitStream) { CDeathmatchObject* pObject = static_cast(m_pObjectManager->Get(pSource->GetID())); + if (pObject) { CVector vecScale; @@ -104,8 +108,10 @@ void CObjectRPCs::SetObjectScale(CClientEntity* pSource, NetBitStreamInterface& bitStream.Read(vecScale.fX); vecScale.fY = vecScale.fX; vecScale.fZ = vecScale.fX; + bitStream.Read(vecScale.fY); bitStream.Read(vecScale.fZ); + pObject->SetScale(vecScale); } }