summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSergeanur <s.anureev@yandex.ua>2020-08-24 20:52:16 +0200
committerSergeanur <s.anureev@yandex.ua>2020-08-24 20:52:16 +0200
commitbbcf3fd7d2e699b0fb7e2cceda8e002dfa61ab3f (patch)
tree4d73bdb6237ce683c25354ebae4c3a093cd7f20c /src
parentfixes to zones and vehicle comp rules (diff)
downloadre3-bbcf3fd7d2e699b0fb7e2cceda8e002dfa61ab3f.tar
re3-bbcf3fd7d2e699b0fb7e2cceda8e002dfa61ab3f.tar.gz
re3-bbcf3fd7d2e699b0fb7e2cceda8e002dfa61ab3f.tar.bz2
re3-bbcf3fd7d2e699b0fb7e2cceda8e002dfa61ab3f.tar.lz
re3-bbcf3fd7d2e699b0fb7e2cceda8e002dfa61ab3f.tar.xz
re3-bbcf3fd7d2e699b0fb7e2cceda8e002dfa61ab3f.tar.zst
re3-bbcf3fd7d2e699b0fb7e2cceda8e002dfa61ab3f.zip
Diffstat (limited to 'src')
-rw-r--r--src/animation/AnimBlendClumpData.h1
-rw-r--r--src/animation/AnimBlendHierarchy.h1
-rw-r--r--src/animation/CutsceneMgr.cpp291
-rw-r--r--src/animation/CutsceneMgr.h9
-rw-r--r--src/control/CarCtrl.cpp4
-rw-r--r--src/control/Script.cpp12
-rw-r--r--src/core/Streaming.cpp5
7 files changed, 277 insertions, 46 deletions
diff --git a/src/animation/AnimBlendClumpData.h b/src/animation/AnimBlendClumpData.h
index 4043c778..af7e5df5 100644
--- a/src/animation/AnimBlendClumpData.h
+++ b/src/animation/AnimBlendClumpData.h
@@ -12,6 +12,7 @@ struct AnimBlendFrameData
VELOCITY_EXTRACTION = 8,
VELOCITY_EXTRACTION_3D = 0x10,
UPDATE_KEYFRAMES = 0x20,
+ UNK_COMPRESSED = 0x40,
};
uint8 flag;
diff --git a/src/animation/AnimBlendHierarchy.h b/src/animation/AnimBlendHierarchy.h
index 45c9217e..b34ae210 100644
--- a/src/animation/AnimBlendHierarchy.h
+++ b/src/animation/AnimBlendHierarchy.h
@@ -25,6 +25,7 @@ public:
void RemoveAnimSequences(void);
void Uncompress(void);
void RemoveUncompressedData(void);
+ bool IsCompressed() { return !!compressed; };
};
VALIDATE_SIZE(CAnimBlendHierarchy, 0x28); \ No newline at end of file
diff --git a/src/animation/CutsceneMgr.cpp b/src/animation/CutsceneMgr.cpp
index e720fccb..e6a072ff 100644
--- a/src/animation/CutsceneMgr.cpp
+++ b/src/animation/CutsceneMgr.cpp
@@ -19,6 +19,11 @@
#include "RpAnimBlend.h"
#include "ModelIndices.h"
#include "TempColModels.h"
+#include "ColStore.h"
+#include "Radar.h"
+#include "Pools.h"
+
+//--MIAMI: file done
const struct {
const char *szTrackName;
@@ -119,15 +124,22 @@ int32 CCutsceneMgr::ms_numCutsceneObjs;
bool CCutsceneMgr::ms_loaded;
bool CCutsceneMgr::ms_animLoaded;
bool CCutsceneMgr::ms_useLodMultiplier;
-bool CCutsceneMgr::ms_camLoaded;
char CCutsceneMgr::ms_cutsceneName[CUTSCENENAMESIZE];
-char CCutsceneMgr::ms_uncompressedAnims[8][32];
-uint32 CCutsceneMgr::ms_numUncompressedAnims;
CAnimBlendAssocGroup CCutsceneMgr::ms_cutsceneAssociations;
CVector CCutsceneMgr::ms_cutsceneOffset;
float CCutsceneMgr::ms_cutsceneTimer;
bool CCutsceneMgr::ms_wasCutsceneSkipped;
uint32 CCutsceneMgr::ms_cutsceneLoadStatus;
+bool CCutsceneMgr::ms_useCutsceneShadows = true;
+
+bool bCamLoaded;
+bool bIsEverythingRemovedFromTheWorldForTheBiggestFuckoffCutsceneEver; // pls don't shrink the name :P
+int32 NumberOfSavedWeapons;
+eWeaponType SavedWeaponIDs[TOTAL_WEAPON_SLOTS];
+int32 SavedWeaponAmmo[TOTAL_WEAPON_SLOTS];
+char uncompressedAnims[8][32];
+uint32 numUncompressedAnims;
+
RpAtomic *
CalculateBoundingSphereRadiusCB(RpAtomic *atomic, void *data)
@@ -151,15 +163,15 @@ CCutsceneMgr::Initialise(void)
ms_loaded = false;
ms_wasCutsceneSkipped = false;
ms_running = false;
+ ms_useLodMultiplier = false;
ms_animLoaded = false;
ms_cutsceneProcessing = false;
- ms_useLodMultiplier = false;
ms_pCutsceneDir = new CDirectory(CUTSCENEDIRSIZE);
ms_pCutsceneDir->ReadDirFile("ANIM\\CUTS.DIR");
- ms_numUncompressedAnims = 0;
- ms_uncompressedAnims[0][0] = '\0';
+ numUncompressedAnims = 0;
+ uncompressedAnims[0][0] = '\0';
}
void
@@ -178,9 +190,9 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName)
ms_cutsceneProcessing = true;
ms_wasCutsceneSkipped = false;
- if (!strcasecmp(szCutsceneName, "jb"))
- ms_useLodMultiplier = true;
CTimer::Suspend();
+ if (!bIsEverythingRemovedFromTheWorldForTheBiggestFuckoffCutsceneEver)
+ CStreaming::RemoveCurrentZonesModels();
ms_pCutsceneDir->numEntries = 0;
ms_pCutsceneDir->ReadDirFile("ANIM\\CUTS.DIR");
@@ -200,7 +212,7 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName)
CStreaming::MakeSpaceFor(size << 11);
CStreaming::ImGonnaUseStreamingMemory();
RwStreamSkip(stream, offset << 11);
- CAnimManager::LoadAnimFile(stream, true, ms_uncompressedAnims);
+ CAnimManager::LoadAnimFile(stream, true, uncompressedAnims);
ms_cutsceneAssociations.CreateAssociations(szCutsceneName);
CStreaming::IHaveUsedStreamingMemory();
ms_animLoaded = true;
@@ -217,9 +229,9 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName)
CFileMgr::Seek(file, offset << 11, SEEK_SET);
TheCamera.LoadPathSplines(file);
CStreaming::IHaveUsedStreamingMemory();
- ms_camLoaded = true;
+ bCamLoaded = true;
} else {
- ms_camLoaded = false;
+ bCamLoaded = false;
}
CFileMgr::CloseFile(file);
@@ -252,7 +264,7 @@ void
CCutsceneMgr::FinishCutscene()
{
ms_wasCutsceneSkipped = true;
- if (ms_camLoaded) {
+ if (bCamLoaded) {
CCutsceneMgr::ms_cutsceneTimer = TheCamera.GetCutSceneFinishTime() * 0.001f;
TheCamera.FinishCutscene();
}
@@ -264,7 +276,7 @@ CCutsceneMgr::FinishCutscene()
void
CCutsceneMgr::SetupCutsceneToStart(void)
{
- if (ms_camLoaded) {
+ if (bCamLoaded) {
TheCamera.SetCamCutSceneOffSet(ms_cutsceneOffset);
TheCamera.TakeControlWithSpline(JUMP_CUT);
TheCamera.SetWideScreenOn();
@@ -276,7 +288,16 @@ CCutsceneMgr::SetupCutsceneToStart(void)
assert(RwObjectGetType(ms_pCutsceneObjects[i]->m_rwObject) == rpCLUMP);
if (CAnimBlendAssociation *pAnimBlendAssoc = RpAnimBlendClumpGetFirstAssociation((RpClump*)ms_pCutsceneObjects[i]->m_rwObject)) {
assert(pAnimBlendAssoc->hierarchy->sequences[0].HasTranslation());
- ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset + ((KeyFrameTrans*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrame(0))->translation);
+ if (ms_pCutsceneObjects[i]->m_pAttachTo != nil) {
+ pAnimBlendAssoc->flags &= (~ASSOC_HAS_TRANSLATION);
+ } else {
+ KeyFrameTrans* keyFrames;
+ if (pAnimBlendAssoc->hierarchy->IsCompressed())
+ keyFrames = ((KeyFrameTrans*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrameCompressed(0));
+ else
+ keyFrames = ((KeyFrameTrans*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrame(0));
+ ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset + keyFrames->translation);
+ }
pAnimBlendAssoc->SetRun();
} else {
ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset);
@@ -300,19 +321,31 @@ CCutsceneMgr::SetCutsceneAnim(const char *animName, CObject *pObject)
CAnimBlendClumpData *pAnimBlendClumpData;
assert(RwObjectGetType(pObject->m_rwObject) == rpCLUMP);
+ debug("Give cutscene anim %s\n", animName);
RpAnimBlendClumpRemoveAllAssociations((RpClump*)pObject->m_rwObject);
- pNewAnim = ms_cutsceneAssociations.CopyAnimation(animName);
+ pNewAnim = ms_cutsceneAssociations.GetAnimation(animName);
if (!pNewAnim) {
debug("\n\nHaven't I told you I can't find the fucking animation %s\n\n\n", animName);
return;
}
+
+ if (pNewAnim->hierarchy->IsCompressed())
+ pNewAnim->hierarchy->compressed2 = true;
+
+ CStreaming::ImGonnaUseStreamingMemory();
+ pNewAnim = ms_cutsceneAssociations.CopyAnimation(animName);
+ CStreaming::IHaveUsedStreamingMemory();
+
pNewAnim->SetCurrentTime(0.0f);
pNewAnim->flags |= ASSOC_HAS_TRANSLATION;
pNewAnim->flags &= ~ASSOC_RUNNING;
pAnimBlendClumpData = *RPANIMBLENDCLUMPDATA(pObject->m_rwObject);
pAnimBlendClumpData->link.Prepend(&pNewAnim->link);
+
+ if (pNewAnim->hierarchy->compressed2)
+ pAnimBlendClumpData->frames->flag |= AnimBlendFrameData::UNK_COMPRESSED;
}
void
@@ -327,25 +360,42 @@ CCutsceneMgr::AddCutsceneHead(CObject *pObject, int modelId)
return nil;
}
+void UpdateCutsceneObjectBoundingBox(RpClump* clump, int modelId)
+{
+ if (modelId >= MI_CUTOBJ01 && modelId <= MI_CUTOBJ05) {
+ CColModel* pColModel = &CTempColModels::ms_colModelCutObj[modelId - MI_CUTOBJ01];
+ float radius = 0.0f;
+ RpClumpForAllAtomics(clump, CalculateBoundingSphereRadiusCB, &radius);
+ pColModel->boundingSphere.radius = radius;
+ pColModel->boundingBox.min = CVector(-radius, -radius, -radius);
+ pColModel->boundingBox.max = CVector(radius, radius, radius);
+ }
+}
+
CCutsceneObject *
CCutsceneMgr::CreateCutsceneObject(int modelId)
{
CBaseModelInfo *pModelInfo;
CColModel *pColModel;
- float radius;
- RpClump *clump;
CCutsceneObject *pCutsceneObject;
+ CStreaming::ImGonnaUseStreamingMemory();
+ debug("Created cutscene object %s\n", CModelInfo::GetModelInfo(modelId)->GetName());
if (modelId >= MI_CUTOBJ01 && modelId <= MI_CUTOBJ05) {
pModelInfo = CModelInfo::GetModelInfo(modelId);
pColModel = &CTempColModels::ms_colModelCutObj[modelId - MI_CUTOBJ01];
- radius = 0.0f;
-
pModelInfo->SetColModel(pColModel);
- clump = (RpClump*)pModelInfo->GetRwObject();
- assert(RwObjectGetType((RwObject*)clump) == rpCLUMP);
- RpClumpForAllAtomics(clump, CalculateBoundingSphereRadiusCB, &radius);
-
+ UpdateCutsceneObjectBoundingBox((RpClump*)pModelInfo->GetRwObject(), modelId);
+ } else if (modelId >= MI_SPECIAL01 && modelId <= MI_SPECIAL21) {
+ pModelInfo = CModelInfo::GetModelInfo(modelId);
+ if (pModelInfo->GetColModel() == &CTempColModels::ms_colModelPed1) {
+ CColModel *colModel = new CColModel();
+ colModel->boundingSphere.radius = 2.0f;
+ colModel->boundingSphere.center = CVector(0.0f, 0.0f, 0.0f);
+ pModelInfo->SetColModel(colModel, true);
+ }
+ pColModel = pModelInfo->GetColModel();
+ float radius = 2.0f;
pColModel->boundingSphere.radius = radius;
pColModel->boundingBox.min = CVector(-radius, -radius, -radius);
pColModel->boundingBox.max = CVector(radius, radius, radius);
@@ -353,7 +403,10 @@ CCutsceneMgr::CreateCutsceneObject(int modelId)
pCutsceneObject = new CCutsceneObject();
pCutsceneObject->SetModelIndex(modelId);
+ if (ms_useCutsceneShadows)
+ pCutsceneObject->CreateShadow();
ms_pCutsceneObjects[ms_numCutsceneObjs++] = pCutsceneObject;
+ CStreaming::IHaveUsedStreamingMemory();
return pCutsceneObject;
}
@@ -365,6 +418,7 @@ CCutsceneMgr::DeleteCutsceneData(void)
ms_cutsceneProcessing = false;
ms_useLodMultiplier = false;
+ ms_useCutsceneShadows = true;
for (--ms_numCutsceneObjs; ms_numCutsceneObjs >= 0; ms_numCutsceneObjs--) {
CWorld::Remove(ms_pCutsceneObjects[ms_numCutsceneObjs]);
@@ -374,14 +428,23 @@ CCutsceneMgr::DeleteCutsceneData(void)
}
ms_numCutsceneObjs = 0;
+ for (int i = MI_SPECIAL01; i < MI_SPECIAL21; i++) {
+ CBaseModelInfo *minfo = CModelInfo::GetModelInfo(i);
+ CColModel *colModel = minfo->GetColModel();
+ if (colModel != &CTempColModels::ms_colModelPed1) {
+ delete colModel;
+ minfo->SetColModel(&CTempColModels::ms_colModelPed1);
+ }
+ }
+
if (ms_animLoaded)
CAnimManager::RemoveLastAnimFile();
ms_animLoaded = false;
- ms_numUncompressedAnims = 0;
- ms_uncompressedAnims[0][0] = '\0';
+ numUncompressedAnims = 0;
+ uncompressedAnims[0][0] = '\0';
- if (ms_camLoaded) {
+ if (bCamLoaded) {
TheCamera.RestoreWithJumpCut();
TheCamera.SetWideScreenOff();
TheCamera.DeleteCutSceneCamDataMemory();
@@ -397,10 +460,37 @@ CCutsceneMgr::DeleteCutsceneData(void)
DMAudio.StopCutSceneMusic();
DMAudio.ChangeMusicMode(MUSICMODE_GAME);
}
+
+ CStreaming::ms_disableStreaming = false;
+ CWorld::bProcessCutsceneOnly = false;
+
+ if(bCamLoaded)
+ CGame::DrasticTidyUpMemory(TheCamera.GetScreenFadeStatus() == FADE_2);
- if(ms_camLoaded)
- CGame::DrasticTidyUpMemory(TheCamera.GetScreenFadeStatus() == 2);
-
+ CPad::GetPad(0)->Clear(false);
+ if (bIsEverythingRemovedFromTheWorldForTheBiggestFuckoffCutsceneEver) {
+ CStreaming::LoadInitialPeds();
+ CStreaming::LoadInitialWeapons();
+ CStreaming::LoadInitialVehicles();
+ bIsEverythingRemovedFromTheWorldForTheBiggestFuckoffCutsceneEver = false;
+
+ CPlayerPed *pPlayerPed = FindPlayerPed();
+ for (int i = 0; i < NumberOfSavedWeapons; i++) {
+ int32 weaponModelId = CWeaponInfo::GetWeaponInfo(SavedWeaponIDs[i])->m_nModelId;
+ uint8 flags = CStreaming::ms_aInfoForModel[weaponModelId].m_flags;
+ CStreaming::RequestModel(weaponModelId, STREAMFLAGS_DONT_REMOVE);
+ CStreaming::LoadAllRequestedModels(false);
+ if (CWeaponInfo::GetWeaponInfo(SavedWeaponIDs[i])->m_nModel2Id != -1) {
+ CStreaming::RequestModel(CWeaponInfo::GetWeaponInfo(SavedWeaponIDs[i])->m_nModel2Id, 0);
+ CStreaming::LoadAllRequestedModels(false);
+ }
+ if (!(flags & STREAMFLAGS_DONT_REMOVE))
+ CStreaming::SetModelIsDeletable(weaponModelId);
+ pPlayerPed->GiveWeapon(SavedWeaponIDs[i], SavedWeaponAmmo[i], true);
+ }
+ NumberOfSavedWeapons = 0;
+ }
+
CTimer::Resume();
}
@@ -437,26 +527,155 @@ CCutsceneMgr::Update(void)
ms_cutsceneTimer += CTimer::GetTimeStepNonClippedInSeconds();
- if (ms_camLoaded)
+ for (int i = 0; i < ms_numCutsceneObjs; i++) {
+ int modelId = ms_pCutsceneObjects[i]->GetModelIndex();
+ if (modelId >= MI_CUTOBJ01 && modelId <= MI_CUTOBJ05)
+ UpdateCutsceneObjectBoundingBox(ms_pCutsceneObjects[i]->GetClump(), modelId);
+
+ if (ms_pCutsceneObjects[i]->m_pAttachTo != nil && modelId >= MI_SPECIAL01 && modelId <= MI_SPECIAL21)
+ UpdateCutsceneObjectBoundingBox(ms_pCutsceneObjects[i]->GetClump(), modelId);
+ }
+
+ if (bCamLoaded)
if (CGeneral::faststricmp(ms_cutsceneName, "finale") && TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_FLYBY && ms_cutsceneLoadStatus == CUTSCENE_LOADING_0) {
if (CPad::GetPad(0)->GetCrossJustDown()
|| (CGame::playingIntro && CPad::GetPad(0)->GetStartJustDown())
|| CPad::GetPad(0)->GetLeftMouseJustDown()
|| CPad::GetPad(0)->GetEnterJustDown()
|| CPad::GetPad(0)->GetCharJustDown(' '))
- FinishCutscene();
+ FinishCutscene();
}
}
-bool CCutsceneMgr::HasCutsceneFinished(void) { return !ms_camLoaded || TheCamera.GetPositionAlongSpline() == 1.0f; }
+bool CCutsceneMgr::HasCutsceneFinished(void) { return !bCamLoaded || TheCamera.GetPositionAlongSpline() == 1.0f; }
void
CCutsceneMgr::LoadAnimationUncompressed(char const* name)
{
- strcpy(ms_uncompressedAnims[ms_numUncompressedAnims], name);
+ strcpy(uncompressedAnims[numUncompressedAnims], name);
// Because that's how CAnimManager knows the end of array
- ++ms_numUncompressedAnims;
- assert(ms_numUncompressedAnims < ARRAY_SIZE(ms_uncompressedAnims));
- ms_uncompressedAnims[ms_numUncompressedAnims][0] = '\0';
+ ++numUncompressedAnims;
+ assert(numUncompressedAnims < ARRAY_SIZE(uncompressedAnims));
+ uncompressedAnims[numUncompressedAnims][0] = '\0';
+}
+
+void
+CCutsceneMgr::AttachObjectToParent(CObject *pObject, CEntity *pAttachTo)
+{
+ ((CCutsceneObject*)pObject)->m_pAttachmentObject = nil;
+ ((CCutsceneObject*)pObject)->m_pAttachTo = RpClumpGetFrame(pAttachTo->GetClump());
+
+ debug("Attach %s to %s\n", CModelInfo::GetModelInfo(pObject->GetModelIndex())->GetName(), CModelInfo::GetModelInfo(pAttachTo->GetModelIndex())->GetName());
+}
+
+void
+CCutsceneMgr::AttachObjectToFrame(CObject *pObject, CEntity *pAttachTo, const char *frame)
+{
+ ((CCutsceneObject*)pObject)->m_pAttachmentObject = nil;
+ ((CCutsceneObject*)pObject)->m_pAttachTo = RpAnimBlendClumpFindFrame(pAttachTo->GetClump(), frame)->frame;
+ debug("Attach %s to component %s of %s\n",
+ CModelInfo::GetModelInfo(pObject->GetModelIndex())->GetName(),
+ frame,
+ CModelInfo::GetModelInfo(pAttachTo->GetModelIndex())->GetName());
+ RpClump* clump = pObject->GetClump();
+ if (RwObjectGetType(clump) == rpCLUMP)
+ if (IsClumpSkinned(clump))
+ RpAtomicGetBoundingSphere(GetFirstAtomic(clump))->radius *= 1.1f;
+}
+
+void
+CCutsceneMgr::AttachObjectToBone(CObject *pObject, CObject *pAttachTo, int bone)
+{
+ RpHAnimHierarchy *hanim = GetAnimHierarchyFromSkinClump(pAttachTo->GetClump());
+ RwInt32 id = RpHAnimIDGetIndex(hanim, bone);
+ RwMatrix *matrixArray = RpHAnimHierarchyGetMatrixArray(hanim);
+ ((CCutsceneObject*)pObject)->m_pAttachmentObject = pAttachTo;
+ ((CCutsceneObject*)pObject)->m_pAttachTo = &matrixArray[id];
+ debug("Attach %s to %s\n",
+ CModelInfo::GetModelInfo(pObject->GetModelIndex())->GetName(),
+ CModelInfo::GetModelInfo(pAttachTo->GetModelIndex())->GetName());
+}
+
+void
+CCutsceneMgr::RemoveEverythingFromTheWorldForTheBiggestFuckoffCutsceneEver()
+{
+ CStreaming::ms_disableStreaming = true;
+ CColStore::RemoveAllCollision();
+ CWorld::bProcessCutsceneOnly = true;
+ ms_cutsceneProcessing = true;
+
+ for (int i = CPools::GetPedPool()->GetSize() - 1; i >= 0; i--) {
+ CPed *pPed = CPools::GetPedPool()->GetSlot(i);
+ if (pPed) {
+ if (!pPed->IsPlayer() && pPed->CanBeDeleted()) {
+ CWorld::Remove(pPed);
+ delete pPed;
+ }
+ }
+ }
+
+ for (int i = CPools::GetVehiclePool()->GetSize() - 1; i >= 0; i--) {
+ CVehicle *pVehicle = CPools::GetVehiclePool()->GetSlot(i);
+ if (pVehicle) {
+ if (pVehicle->CanBeDeleted()) {
+ CWorld::Remove(pVehicle);
+ delete pVehicle;
+ }
+ }
+ }
+
+ bIsEverythingRemovedFromTheWorldForTheBiggestFuckoffCutsceneEver = true;
+ CStreaming::RemoveCurrentZonesModels();
+ CStreaming::SetModelIsDeletable(MI_MALE01);
+ CStreaming::SetModelTxdIsDeletable(MI_MALE01);
+ CStreaming::SetModelIsDeletable(MI_HMOCA);
+ CStreaming::SetModelTxdIsDeletable(MI_HMOCA);
+ CStreaming::SetModelIsDeletable(MI_NIGHTSTICK);
+ CStreaming::SetModelTxdIsDeletable(MI_NIGHTSTICK);
+ CStreaming::SetModelIsDeletable(MI_MISSILE);
+ CStreaming::SetModelTxdIsDeletable(MI_MISSILE);
+ CStreaming::SetModelIsDeletable(MI_POLICE);
+ CStreaming::SetModelTxdIsDeletable(MI_POLICE);
+
+ while (CStreaming::RemoveLoadedVehicle()) ;
+
+ CRadar::RemoveRadarSections();
+
+ for (int i = CPools::GetDummyPool()->GetSize() - 1; i >= 0; i--) {
+ CDummy* pDummy = CPools::GetDummyPool()->GetSlot(i);
+ if (pDummy)
+ pDummy->DeleteRwObject();
+ }
+
+ for (int i = CPools::GetObjectPool()->GetSize() - 1; i >= 0; i--) {
+ CObject* pObject = CPools::GetObjectPool()->GetSlot(i);
+ if (pObject)
+ pObject->DeleteRwObject();
+ }
+
+ for (int i = CPools::GetBuildingPool()->GetSize() - 1; i >= 0; i--) {
+ CBuilding* pBuilding = CPools::GetBuildingPool()->GetSlot(i);
+ if (pBuilding && pBuilding->GetClump() != nil && pBuilding->bIsBIGBuilding && pBuilding->bStreamBIGBuilding) {
+ if (pBuilding->bIsBIGBuilding)
+ CStreaming::RequestModel(pBuilding->GetModelIndex(), 0);
+ if (!pBuilding->bImBeingRendered)
+ pBuilding->DeleteRwObject();
+ }
+ }
+
+ CPlayerPed *pPlayerPed = FindPlayerPed();
+ pPlayerPed->RemoveWeaponAnims(0, -1000.0f);
+ NumberOfSavedWeapons = 0;
+
+ for (int i = 0; i < TOTAL_WEAPON_SLOTS; i++) {
+ if (pPlayerPed->m_weapons[i].m_eWeaponType != WEAPONTYPE_UNARMED) {
+ SavedWeaponIDs[NumberOfSavedWeapons] = pPlayerPed->m_weapons[i].m_eWeaponType;
+ SavedWeaponAmmo[NumberOfSavedWeapons] = pPlayerPed->m_weapons[i].m_nAmmoTotal;
+ NumberOfSavedWeapons++;
+ }
+ }
+
+ pPlayerPed->ClearWeapons();
+ CGame::DrasticTidyUpMemory(true);
} \ No newline at end of file
diff --git a/src/animation/CutsceneMgr.h b/src/animation/CutsceneMgr.h
index c3f86273..b4497b5b 100644
--- a/src/animation/CutsceneMgr.h
+++ b/src/animation/CutsceneMgr.h
@@ -17,15 +17,13 @@ class CCutsceneMgr
static bool ms_animLoaded;
static bool ms_useLodMultiplier;
- static bool ms_camLoaded;
static char ms_cutsceneName[CUTSCENENAMESIZE];
- static char ms_uncompressedAnims[8][32];
- static uint32 ms_numUncompressedAnims;
static CAnimBlendAssocGroup ms_cutsceneAssociations;
static CVector ms_cutsceneOffset;
static float ms_cutsceneTimer;
static bool ms_wasCutsceneSkipped;
static bool ms_cutsceneProcessing;
+ static bool ms_useCutsceneShadows;
public:
static CDirectory *ms_pCutsceneDir;
static uint32 ms_cutsceneLoadStatus;
@@ -54,4 +52,9 @@ public:
static void DeleteCutsceneData(void);
static void LoadAnimationUncompressed(char const*);
static void Update(void);
+
+ static void AttachObjectToParent(CObject *pObject, CEntity *pAttachTo);
+ static void AttachObjectToFrame(CObject *pObject, CEntity *pAttachTo, const char *frame);
+ static void AttachObjectToBone(CObject *pObject, CObject *pAttachTo, int frame);
+ static void RemoveEverythingFromTheWorldForTheBiggestFuckoffCutsceneEver();
};
diff --git a/src/control/CarCtrl.cpp b/src/control/CarCtrl.cpp
index 5b2454ac..74c4f006 100644
--- a/src/control/CarCtrl.cpp
+++ b/src/control/CarCtrl.cpp
@@ -2759,7 +2759,7 @@ void CCarCtrl::SteerAIPlaneTowardsTargetCoors(CAutomobile* pPlane)
float steer = difference > 0.0f ? 0.04f : -0.04f;
if (Abs(difference) < 0.2f)
steer *= 5.0f * Abs(difference);
- pPlane->m_fPlaneSteer *= Pow(0.96, CTimer::GetTimeStep());
+ pPlane->m_fPlaneSteer *= Pow(0.96f, CTimer::GetTimeStep());
float steerChange = steer - pPlane->m_fPlaneSteer;
float maxChange = 0.003f * CTimer::GetTimeStep();
if (Abs(steerChange) < maxChange)
@@ -2782,7 +2782,7 @@ void CCarCtrl::SteerAIPlaneTowardsTargetCoors(CAutomobile* pPlane)
pPlane->GetMatrix().GetRight() = right;
pPlane->GetMatrix().GetForward() = forward;
pPlane->GetMatrix().GetUp() = up;
- float newSplit = 1.0f - Pow(0.95, CTimer::GetTimeStep());
+ float newSplit = 1.0f - Pow(0.95f, CTimer::GetTimeStep());
float oldSplit = 1.0f - newSplit;
#ifdef FIX_BUGS
pPlane->m_vecMoveSpeed = pPlane->m_vecMoveSpeed * oldSplit + pPlane->AutoPilot.GetCruiseSpeed() * 0.01f * forward * newSplit;
diff --git a/src/control/Script.cpp b/src/control/Script.cpp
index ea94794b..bf761a3f 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -13017,14 +13017,20 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
case COMMAND_ATTACH_CUTSCENE_OBJECT_TO_BONE:
{
CollectParameters(&m_nIp, 3);
- debug("ATTACH_CUTSCENE_OBJECT_TO_BONE not implemented, skipping\n"); // TODO(MIAMI)
+ CCutsceneMgr::AttachObjectToBone(CPools::GetObjectPool()->GetAt(ScriptParams[0]), CPools::GetObjectPool()->GetAt(ScriptParams[1]), ScriptParams[2]);
return 0;
}
case COMMAND_ATTACH_CUTSCENE_OBJECT_TO_COMPONENT:
{
CollectParameters(&m_nIp, 2);
- debug("ATTACH_CUTSCENE_OBJECT_TO_COMPONENT not implemented, skipping\n"); // TODO(MIAMI)
+ CObject *obj1 = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ CObject *obj2 = CPools::GetObjectPool()->GetAt(ScriptParams[1]);
+
+ char key[KEY_LENGTH_IN_SCRIPT];
+ CTheScripts::ReadTextLabelFromScript(&m_nIp, key);
m_nIp += KEY_LENGTH_IN_SCRIPT;
+
+ CCutsceneMgr::AttachObjectToFrame(obj1, obj2, key);
return 0;
}
case COMMAND_SET_CHAR_STAY_IN_CAR_WHEN_JACKED:
@@ -13236,7 +13242,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command)
case COMMAND_ATTACH_CUTSCENE_OBJECT_TO_VEHICLE:
{
CollectParameters(&m_nIp, 2);
- debug("ATTACH_CUTSCENE_OBJECT_TO_VEHICLE not implemented\n"); // TODO(MIAMI)
+ CCutsceneMgr::AttachObjectToParent(CPools::GetObjectPool()->GetAt(ScriptParams[0]), CPools::GetVehiclePool()->GetAt(ScriptParams[1]));
return 0;
}
case COMMAND_LOAD_MISSION_TEXT:
diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp
index 74fec192..d296496e 100644
--- a/src/core/Streaming.cpp
+++ b/src/core/Streaming.cpp
@@ -1668,7 +1668,7 @@ CStreaming::StreamZoneModels(const CVector &pos)
while(ms_bIsPedFromPedGroupLoaded[j]);
ms_bIsPedFromPedGroupLoaded[j] = true;
if(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[j] != -1)
- RequestModel(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i], STREAMFLAGS_DEPENDENCY);
+ RequestModel(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[j], STREAMFLAGS_DEPENDENCY);
}
ms_numPedsLoaded = MAXZONEPEDSLOADED;
timeBeforeNextLoad = 300;
@@ -1692,7 +1692,7 @@ CStreaming::StreamZoneModels(const CVector &pos)
j = CGeneral::GetRandomNumberInRange(0, NUMMODELSPERPEDGROUP);
while(ms_bIsPedFromPedGroupLoaded[j]);
if(ms_numPedsLoaded == MAXZONEPEDSLOADED)
- ms_bIsPedFromPedGroupLoaded[i] = 0;
+ ms_bIsPedFromPedGroupLoaded[i] = false;
ms_bIsPedFromPedGroupLoaded[j] = true;
int newMI = CPopulation::ms_pPedGroups[ms_currentPedGrp].models[j];
if(newMI != oldMI){
@@ -1766,6 +1766,7 @@ CStreaming::RemoveCurrentZonesModels(void)
if (ms_currentPedGrp != -1)
for (i = 0; i < NUMMODELSPERPEDGROUP; i++) {
+ ms_bIsPedFromPedGroupLoaded[i] = false;
if (CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] != -1 &&
CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] != MI_MALE01) {
SetModelIsDeletable(CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i]);