From eafa9cc10797db529e74b0480f51d7b8ade12cfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eray=20or=C3=A7unus?= Date: Thu, 30 Jul 2020 15:11:06 +0300 Subject: [PATCH] new opcodes, buyable properties, minor fixes --- src/animation/AnimManager.cpp | 22 ++++++- src/animation/CutsceneMgr.cpp | 81 ++++++++++++++++++-------- src/animation/CutsceneMgr.h | 4 ++ src/control/Pickups.cpp | 106 +++++++++++++++++++++++++++++++++- src/control/Pickups.h | 16 +++-- src/control/Script.cpp | 53 ++++++++++++----- src/core/Frontend.cpp | 4 +- src/core/Pad.cpp | 32 ++++++++++ src/core/Pad.h | 1 + src/render/Hud.cpp | 6 ++ src/render/Hud.h | 1 + src/vehicles/Automobile.cpp | 2 +- 12 files changed, 275 insertions(+), 53 deletions(-) diff --git a/src/animation/AnimManager.cpp b/src/animation/AnimManager.cpp index f682964f..a85149e6 100644 --- a/src/animation/AnimManager.cpp +++ b/src/animation/AnimManager.cpp @@ -12,7 +12,7 @@ #include "AnimManager.h" #include "Streaming.h" -//--MIAMI: code done (except for pointless TODO) +//--MIAMI: file done CAnimBlock CAnimManager::ms_aAnimBlocks[NUMANIMBLOCKS]; CAnimBlendHierarchy CAnimManager::ms_aAnimations[NUMANIMATIONS]; @@ -1276,7 +1276,7 @@ CAnimManager::LoadAnimFile(const char *filename) RwStreamClose(stream, nil); } -//--MIAMI: done (except maybe implement some unimplemented compression?) +//--MIAMI: done void CAnimManager::LoadAnimFile(RwStream *stream, bool compress, char (*somename)[32]) { @@ -1323,7 +1323,14 @@ CAnimManager::LoadAnimFile(RwStream *stream, bool compress, char (*somename)[32] RwStreamRead(stream, buf, name.size); hier->SetName(buf); - // TODO(MIAMI)? some unused crap here + // Unimplemented uncompressed anim thing + if (somename) { + for (int i = 0; somename[i][0]; i++) { + if (!CGeneral::faststricmp(somename[i], hier->name)) + debug("Loading %s uncompressed\n", hier->name); + } + } + hier->compressed = false; hier->compressed2 = false; @@ -1357,6 +1364,9 @@ CAnimManager::LoadAnimFile(RwStream *stream, bool compress, char (*somename)[32] if(strncmp(info.ident, "KR00", 4) == 0){ seq->SetNumFrames(numFrames, false, false); KeyFrame *kf = seq->GetKeyFrame(0); + if (strstr(seq->name, "L Toe")) + debug("anim %s has toe keyframes\n", hier->name); // , seq->name); + for(l = 0; l < numFrames; l++, kf++){ RwStreamRead(stream, buf, 0x14); kf->rotation.x = -fbuf[0]; @@ -1368,6 +1378,9 @@ CAnimManager::LoadAnimFile(RwStream *stream, bool compress, char (*somename)[32] }else if(strncmp(info.ident, "KRT0", 4) == 0){ seq->SetNumFrames(numFrames, true, false); KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(0); + if (strstr(seq->name, "L Toe")) + debug("anim %s has toe keyframes\n", hier->name); // , seq->name); + for(l = 0; l < numFrames; l++, kf++){ RwStreamRead(stream, buf, 0x20); kf->rotation.x = -fbuf[0]; @@ -1382,6 +1395,9 @@ CAnimManager::LoadAnimFile(RwStream *stream, bool compress, char (*somename)[32] }else if(strncmp(info.ident, "KRTS", 4) == 0){ seq->SetNumFrames(numFrames, true, false); KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(0); + if (strstr(seq->name, "L Toe")) + debug("anim %s has toe keyframes\n", hier->name); // , seq->name); + for(l = 0; l < numFrames; l++, kf++){ RwStreamRead(stream, buf, 0x2C); kf->rotation.x = -fbuf[0]; diff --git a/src/animation/CutsceneMgr.cpp b/src/animation/CutsceneMgr.cpp index b4f226e8..e720fccb 100644 --- a/src/animation/CutsceneMgr.cpp +++ b/src/animation/CutsceneMgr.cpp @@ -119,7 +119,10 @@ 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; @@ -154,6 +157,9 @@ CCutsceneMgr::Initialise(void) ms_pCutsceneDir = new CDirectory(CUTSCENEDIRSIZE); ms_pCutsceneDir->ReadDirFile("ANIM\\CUTS.DIR"); + + ms_numUncompressedAnims = 0; + ms_uncompressedAnims[0][0] = '\0'; } void @@ -194,7 +200,7 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName) CStreaming::MakeSpaceFor(size << 11); CStreaming::ImGonnaUseStreamingMemory(); RwStreamSkip(stream, offset << 11); - CAnimManager::LoadAnimFile(stream, false); + CAnimManager::LoadAnimFile(stream, true, ms_uncompressedAnims); ms_cutsceneAssociations.CreateAssociations(szCutsceneName); CStreaming::IHaveUsedStreamingMemory(); ms_animLoaded = true; @@ -207,13 +213,18 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName) file = CFileMgr::OpenFile("ANIM\\CUTS.IMG", "rb"); sprintf(gString, "%s.DAT", szCutsceneName); if (ms_pCutsceneDir->FindItem(gString, offset, size)) { + CStreaming::ImGonnaUseStreamingMemory(); CFileMgr::Seek(file, offset << 11, SEEK_SET); TheCamera.LoadPathSplines(file); + CStreaming::IHaveUsedStreamingMemory(); + ms_camLoaded = true; + } else { + ms_camLoaded = false; } CFileMgr::CloseFile(file); - if (CGeneral::faststricmp(ms_cutsceneName, "end")) { + if (CGeneral::faststricmp(ms_cutsceneName, "finale")) { DMAudio.ChangeMusicMode(MUSICMODE_CUTSCENE); int trackId = FindCutsceneAudioTrackId(szCutsceneName); if (trackId != -1) { @@ -241,8 +252,10 @@ void CCutsceneMgr::FinishCutscene() { ms_wasCutsceneSkipped = true; - CCutsceneMgr::ms_cutsceneTimer = TheCamera.GetCutSceneFinishTime() * 0.001f; - TheCamera.FinishCutscene(); + if (ms_camLoaded) { + CCutsceneMgr::ms_cutsceneTimer = TheCamera.GetCutSceneFinishTime() * 0.001f; + TheCamera.FinishCutscene(); + } FindPlayerPed()->bIsVisible = true; CWorld::Players[CWorld::PlayerInFocus].MakePlayerSafe(false); @@ -251,9 +264,11 @@ CCutsceneMgr::FinishCutscene() void CCutsceneMgr::SetupCutsceneToStart(void) { - TheCamera.SetCamCutSceneOffSet(ms_cutsceneOffset); - TheCamera.TakeControlWithSpline(JUMP_CUT); - TheCamera.SetWideScreenOn(); + if (ms_camLoaded) { + TheCamera.SetCamCutSceneOffSet(ms_cutsceneOffset); + TheCamera.TakeControlWithSpline(JUMP_CUT); + TheCamera.SetWideScreenOn(); + } ms_cutsceneOffset.z++; @@ -363,8 +378,14 @@ CCutsceneMgr::DeleteCutsceneData(void) CAnimManager::RemoveLastAnimFile(); ms_animLoaded = false; - TheCamera.RestoreWithJumpCut(); - TheCamera.SetWideScreenOff(); + ms_numUncompressedAnims = 0; + ms_uncompressedAnims[0][0] = '\0'; + + if (ms_camLoaded) { + TheCamera.RestoreWithJumpCut(); + TheCamera.SetWideScreenOff(); + TheCamera.DeleteCutSceneCamDataMemory(); + } ms_running = false; ms_loaded = false; @@ -372,12 +393,14 @@ CCutsceneMgr::DeleteCutsceneData(void) CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_CUTSCENE); CWorld::Players[CWorld::PlayerInFocus].MakePlayerSafe(false); - if (CGeneral::faststricmp(ms_cutsceneName, "end")) { + if (CGeneral::faststricmp(ms_cutsceneName, "finale")) { DMAudio.StopCutSceneMusic(); - if (CGeneral::faststricmp(ms_cutsceneName, "bet")) - DMAudio.ChangeMusicMode(MUSICMODE_GAME); + DMAudio.ChangeMusicMode(MUSICMODE_GAME); } - CGame::DrasticTidyUpMemory(TheCamera.GetScreenFadeStatus() == 2); + + if(ms_camLoaded) + CGame::DrasticTidyUpMemory(TheCamera.GetScreenFadeStatus() == 2); + CTimer::Resume(); } @@ -395,7 +418,7 @@ CCutsceneMgr::Update(void) switch (ms_cutsceneLoadStatus) { case CUTSCENE_LOADING_AUDIO: SetupCutsceneToStart(); - if (CGeneral::faststricmp(ms_cutsceneName, "end")) + if (CGeneral::faststricmp(ms_cutsceneName, "finale")) DMAudio.PlayPreloadedCutSceneMusic(); ms_cutsceneLoadStatus++; break; @@ -413,15 +436,27 @@ CCutsceneMgr::Update(void) if (!ms_running) return; ms_cutsceneTimer += CTimer::GetTimeStepNonClippedInSeconds(); - if (CGeneral::faststricmp(ms_cutsceneName, "end") && 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(); - } + + if (ms_camLoaded) + 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(); + } } -bool CCutsceneMgr::HasCutsceneFinished(void) { return TheCamera.GetPositionAlongSpline() == 1.0f; } +bool CCutsceneMgr::HasCutsceneFinished(void) { return !ms_camLoaded || TheCamera.GetPositionAlongSpline() == 1.0f; } +void +CCutsceneMgr::LoadAnimationUncompressed(char const* name) +{ + strcpy(ms_uncompressedAnims[ms_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'; +} \ No newline at end of file diff --git a/src/animation/CutsceneMgr.h b/src/animation/CutsceneMgr.h index 97093fb1..c3f86273 100644 --- a/src/animation/CutsceneMgr.h +++ b/src/animation/CutsceneMgr.h @@ -17,7 +17,10 @@ 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; @@ -49,5 +52,6 @@ public: static CCutsceneHead *AddCutsceneHead(CObject *pObject, int modelId); static CCutsceneObject *CreateCutsceneObject(int modelId); static void DeleteCutsceneData(void); + static void LoadAnimationUncompressed(char const*); static void Update(void); }; diff --git a/src/control/Pickups.cpp b/src/control/Pickups.cpp index 3a7b3a90..7a9808f6 100644 --- a/src/control/Pickups.cpp +++ b/src/control/Pickups.cpp @@ -30,6 +30,8 @@ #include "Timer.h" #include "WaterLevel.h" #include "World.h" +#include "Hud.h" +#include "Messages.h" CPickup CPickups::aPickUps[NUMPICKUPS]; int16 CPickups::NumMessages; @@ -37,6 +39,7 @@ int32 CPickups::aPickUpsCollected[NUMCOLLECTEDPICKUPS]; int16 CPickups::CollectedPickUpIndex; int32 CPickups::PlayerOnWeaponPickup; +int32 CPickups::CollectPickupBuffer; // unused bool CPickups::bPickUpcamActivated; @@ -71,6 +74,32 @@ uint8 aWeaponBlues[] = { 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 128, 255, 0, 0 }; +void +ModifyStringLabelForControlSetting(char *str) +{ + int len = (int)strlen(str); + if (len <= 2) + return; + + if (str[len - 2] != '_') + return; + + switch (CPad::GetPad(0)->Mode) { + case 0: + case 1: + str[len - 1] = 'L'; + break; + case 2: + str[len - 1] = 'T'; + break; + case 3: + str[len - 1] = 'C'; + break; + default: + return; + } +} + void CPickup::RemoveKeepType() { @@ -163,6 +192,31 @@ CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId) { float waterLevel; + if (m_pObject) { + m_pObject->SetPosition(m_vecPos); + // TODO(Miami): Extra object + } + if (m_eType == PICKUP_ASSET_REVENUE) { + uint32 oldTimer = m_nTimer; + m_nTimer = CTimer::GetTimeInMilliseconds(); + float calculatedRevenue; + if ((FindPlayerCoors() - m_vecPos).Magnitude() > 10.0) { + uint32 timePassed = CTimer::GetTimeInMilliseconds() - oldTimer; + calculatedRevenue = m_nRevenue + (timePassed * m_nMoneySpeed) * sq(1.f / 1200.f); + } else { + calculatedRevenue = m_nRevenue; + } + m_nRevenue = Min(calculatedRevenue, m_nQuantity); + // TODO(Miami): For pickup glow effect? + /* + if (calculatedRevenue < 10.0) { + m_pObject->m_nCostValue = 0; + } else { + m_pObject->m_nCostValue = calculatedRevenue; + } + */ + } + if (m_bRemoved) { if (CTimer::GetTimeInMilliseconds() > m_nTimer) { // respawn pickup if we're far enough @@ -290,6 +344,32 @@ CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId) Remove(); DMAudio.PlayFrontEndSound(SOUND_PICKUP_MONEY, 0); return true; + case PICKUP_ASSET_REVENUE: + CWorld::Players[CWorld::PlayerInFocus].m_nMoney += m_nRevenue; + m_nRevenue = 0; + DMAudio.PlayFrontEndSound(SOUND_PICKUP_MONEY, 0); + return false; + // TODO(Miami): Control flow + case PICKUP_PROPERTY_FORSALE: + ModifyStringLabelForControlSetting(m_sTextKey); + CMessages::InsertNumberInString(TheText.Get(m_sTextKey), m_nQuantity, + 0, 0, 0, 0, 0, gUString); + if (!CHud::IsHelpMessageBeingDisplayed()) + CHud::SetHelpMessage(gUString, false); // 0, 0, 0); + if (CPickups::CollectPickupBuffer == 0) + return false; + if (CTheScripts::IsPlayerOnAMission()) { + CHud::SetHelpMessage(TheText.Get("PROP_2"), true); // , false); + } else { + if (CWorld::Players[CWorld::PlayerInFocus].m_nMoney >= m_nQuantity) { + CWorld::Players[CWorld::PlayerInFocus].m_nMoney -= m_nQuantity; + CHud::SetHelpMessage(nil, true); //, false); + Remove(); + return true; + } + CHud::SetHelpMessage(TheText.Get("PROP_1"), true); //, false); + } + return false; default: break; } @@ -528,12 +608,12 @@ CPickups::RemovePickUp(int32 pickupIndex) } int32 -CPickups::GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quantity, uint32 rate, bool highPriority, wchar* pText) +CPickups::GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quantity, uint32 rate, bool highPriority, char* pText) { bool bFreeFound = false; int32 slot = 0; - if (type == PICKUP_FLOATINGPACKAGE || type == PICKUP_NAUTICAL_MINE_INACTIVE) { + if (type == PICKUP_FLOATINGPACKAGE || type == PICKUP_NAUTICAL_MINE_INACTIVE || highPriority) { for (slot = NUMPICKUPS-1; slot >= 0; slot--) { if (aPickUps[slot].m_eType == PICKUP_NONE) { bFreeFound = true; @@ -556,7 +636,7 @@ CPickups::GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quan if (slot >= NUMGENERALPICKUPS) { for (slot = 0; slot < NUMGENERALPICKUPS; slot++) { - if (aPickUps[slot].m_eType == PICKUP_ONCE_TIMEOUT) break; + if (aPickUps[slot].m_eType == PICKUP_ONCE_TIMEOUT || aPickUps[slot].m_eType == PICKUP_ONCE_TIMEOUT_SLOW) break; } if (slot >= NUMGENERALPICKUPS) return -1; @@ -568,8 +648,13 @@ CPickups::GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quan aPickUps[slot].m_eType = (ePickupType)type; aPickUps[slot].m_bRemoved = false; aPickUps[slot].m_nQuantity = quantity; + aPickUps[slot].m_nMoneySpeed = rate; + aPickUps[slot].m_nRevenue = 0; + aPickUps[slot].m_nTimer = CTimer::GetTimeInMilliseconds(); if (type == PICKUP_ONCE_TIMEOUT) aPickUps[slot].m_nTimer = CTimer::GetTimeInMilliseconds() + 20000; + else if (type == PICKUP_ONCE_TIMEOUT_SLOW) + aPickUps[slot].m_nTimer = CTimer::GetTimeInMilliseconds() + 120000; else if (type == PICKUP_MONEY) aPickUps[slot].m_nTimer = CTimer::GetTimeInMilliseconds() + 30000; else if (type == PICKUP_MINE_INACTIVE || type == PICKUP_MINE_ARMED) { @@ -580,6 +665,11 @@ CPickups::GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quan aPickUps[slot].m_nTimer = CTimer::GetTimeInMilliseconds() + 1500; } aPickUps[slot].m_eModelIndex = modelIndex; + if (pText) + strncpy(aPickUps[slot].m_sTextKey, pText, 8); + else + aPickUps[slot].m_sTextKey[0] = '\0'; + aPickUps[slot].m_vecPos = pos; aPickUps[slot].m_pObject = aPickUps[slot].GiveUsAPickUpObject(-1); if (aPickUps[slot].m_pObject) @@ -664,6 +754,16 @@ CPickups::Update() } } #endif + if (CPad::GetPad(0)->CollectPickupJustDown()) { + CollectPickupBuffer = 6; + } else { + CollectPickupBuffer = Max(0, CollectPickupBuffer - 1); + } + + if (PlayerOnWeaponPickup) { + PlayerOnWeaponPickup = Max(0, PlayerOnWeaponPickup - 1); + } + #define PICKUPS_FRAME_SPAN (6) #ifdef FIX_BUGS for (uint32 i = NUMGENERALPICKUPS * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN) / PICKUPS_FRAME_SPAN; i < NUMGENERALPICKUPS * (CTimer::GetFrameCounter() % PICKUPS_FRAME_SPAN + 1) / PICKUPS_FRAME_SPAN; i++) { diff --git a/src/control/Pickups.h b/src/control/Pickups.h index 423f864b..8f6ef4c3 100644 --- a/src/control/Pickups.h +++ b/src/control/Pickups.h @@ -33,14 +33,19 @@ class CPlayerPed; class CPickup { public: - ePickupType m_eType; - bool m_bRemoved; - uint16 m_nQuantity; + CVector m_vecPos; + uint32 m_nRevenue; CObject *m_pObject; + CObject *m_pExtraObject; + uint16 m_nQuantity; uint32 m_nTimer; + int16 m_nMoneySpeed; int16 m_eModelIndex; uint16 m_nIndex; - CVector m_vecPos; + char m_sTextKey[8]; + ePickupType m_eType; + bool m_bRemoved; + uint8 m_effects; CObject *GiveUsAPickUpObject(int32 handle); bool Update(CPlayerPed *player, CVehicle *vehicle, int playerId); @@ -71,6 +76,7 @@ class CPickups static tPickupMessage aMessages[NUMPICKUPMESSAGES]; public: static int32 PlayerOnWeaponPickup; + static int32 CollectPickupBuffer; static void Init(); static void Update(); @@ -79,7 +85,7 @@ public: static void DoMoneyEffects(CEntity *ent); static void DoMineEffects(CEntity *ent); static void DoPickUpEffects(CEntity *ent); - static int32 GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quantity, uint32 rate = 0, bool highPriority = false, wchar* pText = nil); + static int32 GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quantity, uint32 rate = 0, bool highPriority = false, char* pText = nil); static int32 GenerateNewOne_WeaponType(CVector pos, eWeaponType weaponType, uint8 type, uint32 quantity); static void RemovePickUp(int32 pickupIndex); static void RemoveAllFloatingPickups(); diff --git a/src/control/Script.cpp b/src/control/Script.cpp index 88a62f4e..eb950464 100644 --- a/src/control/Script.cpp +++ b/src/control/Script.cpp @@ -80,6 +80,8 @@ #include "World.h" #include "Zones.h" #include "main.h" +#include "Ropes.h" +#include "MBlur.h" #ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT #include #endif @@ -12110,6 +12112,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command) CVector pos = *(CVector*)&ScriptParams[0]; if (pos.z <= MAP_Z_LOW_LIMIT) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y) + PICKUP_PLACEMENT_OFFSET; + CPickups::GetActualPickupIndex(CollectNextParameterWithoutIncreasingPC(m_nIp)); ScriptParams[0] = CPickups::GenerateNewOne(pos, MI_PICKUP_REVENUE, PICKUP_ASSET_REVENUE, ScriptParams[3], ScriptParams[4]); StoreParameters(&m_nIp, 1); return 0; @@ -12790,7 +12793,7 @@ int8 CRunningScript::ProcessCommands1200To1299(int32 command) case COMMAND_CREATE_SWAT_ROPE: { CollectParameters(&m_nIp, 3); - debug("CREATE_SWAT_ROPE is not implemented\n"); + CRopes::CreateRopeWithSwatComingDown(*(CVector*)&ScriptParams[0]); return 0; } //case COMMAND_SET_FIRST_PERSON_CONTROL_CAMERA: @@ -12902,10 +12905,12 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) CVector pos = *(CVector*)&ScriptParams[0]; if (pos.z <= MAP_Z_LOW_LIMIT) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y) + PICKUP_PLACEMENT_OFFSET; - wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); - // TODO(MIAMI) - add text + char key[KEY_LENGTH_IN_SCRIPT]; + CTheScripts::ReadTextLabelFromScript(&m_nIp, key); + m_nIp += KEY_LENGTH_IN_SCRIPT; + // TheText.Get(key); CPickups::GetActualPickupIndex(CollectNextParameterWithoutIncreasingPC(m_nIp)); - ScriptParams[0] = CPickups::GenerateNewOne(pos, MI_PICKUP_PROPERTY, PICKUP_PROPERTY_LOCKED, 0, 0, false, text); + ScriptParams[0] = CPickups::GenerateNewOne(pos, MI_PICKUP_PROPERTY, PICKUP_PROPERTY_LOCKED, 0, 0, false, key); StoreParameters(&m_nIp, 1); return 0; } @@ -12915,10 +12920,12 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) CVector pos = *(CVector*)&ScriptParams[0]; if (pos.z <= MAP_Z_LOW_LIMIT) pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y) + PICKUP_PLACEMENT_OFFSET; - wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp); - // TODO(MIAMI) - add text + char key[KEY_LENGTH_IN_SCRIPT]; + CTheScripts::ReadTextLabelFromScript(&m_nIp, key); + m_nIp += KEY_LENGTH_IN_SCRIPT; + // TheText.Get(key); CPickups::GetActualPickupIndex(CollectNextParameterWithoutIncreasingPC(m_nIp)); - ScriptParams[0] = CPickups::GenerateNewOne(pos, MI_PICKUP_PROPERTY_FORSALE, PICKUP_PROPERTY_FORSALE, ScriptParams[3], 0, false, text); + ScriptParams[0] = CPickups::GenerateNewOne(pos, MI_PICKUP_PROPERTY_FORSALE, PICKUP_PROPERTY_FORSALE, ScriptParams[3], 0, false, key); StoreParameters(&m_nIp, 1); return 0; } @@ -13021,7 +13028,11 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) case COMMAND_SET_PLAYER_DRUNKENNESS: { CollectParameters(&m_nIp, 2); - debug("SET_PLAYER_DRUNKENNESS not implemented\n"); // TODO(MIAMI) + CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]]; + pPlayerInfo->m_pPed->m_nDrunkenness = ScriptParams[1]; + pPlayerInfo->m_pPed->m_nFadeDrunkenness = 0; + if (pPlayerInfo->m_pPed->m_nDrunkenness == 0) + CMBlur::ClearDrunkBlur(); return 0; } //case COMMAND_GET_PLAYER_DRUNKENNESS: @@ -13421,7 +13432,7 @@ int8 CRunningScript::ProcessCommands1300To1399(int32 command) char key[KEY_LENGTH_IN_SCRIPT]; CTheScripts::ReadTextLabelFromScript(&m_nIp, key); m_nIp += KEY_LENGTH_IN_SCRIPT; - debug("LOAD_UNCOMPRESSED_ANIM not implemented\n"); // TODO(MIAMI) + CCutsceneMgr::LoadAnimationUncompressed(key); return 0; } case COMMAND_WAS_CUTSCENE_SKIPPED: @@ -13624,15 +13635,13 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command) case COMMAND_IS_PLAYER_IN_INFO_ZONE: { CollectParameters(&m_nIp, 1); + CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]]; char key[KEY_LENGTH_IN_SCRIPT]; CTheScripts::ReadTextLabelFromScript(&m_nIp, key); m_nIp += KEY_LENGTH_IN_SCRIPT; - static bool bShowed = false; - if (!bShowed) { - debug("IS_PLAYER_IN_INFO_ZONE not implemented, default to FALSE\n"); - bShowed = true; - } - UpdateCompareFlag(false); + CVector pos = pPlayerInfo->GetPos(); + CZone *infoZone = CTheZones::FindInformationZoneForPosition(&pos); + UpdateCompareFlag(strncmp(key, infoZone->name, 8) == 0); return 0; } case COMMAND_CLEAR_CHAR_ICE_CREAM_PURCHASE: @@ -13828,7 +13837,19 @@ int8 CRunningScript::ProcessCommands1400To1499(int32 command) case COMMAND_CREATE_DUST_EFFECT_FOR_CUTSCENE_HELI: { CollectParameters(&m_nIp, 3); - debug("CREATE_DUST_EFFECT_FOR_CUTSCENE_HELI not implemented\n"); // TODO(MIAMI) + CObject *pHeli = CPools::GetObjectPool()->GetAt(ScriptParams[0]); + bool found = false; + float waterLevel = -1000.0f; + CVector pos = pHeli->GetPosition(); + float radius = *(float*)&ScriptParams[1]; + float ground = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z, &found); + if (!CWaterLevel::GetWaterLevel(pos.x, pos.y, pos.z, &waterLevel, false)) + waterLevel = 0.0f; + if (waterLevel > ground) + ground = waterLevel; + if (ScriptParams[2] > 8) + ScriptParams[2] = 8; + CVehicle::HeliDustGenerate(pHeli, (pos.z - ground - 1.0f - radius) * 0.3 + radius, ground, ScriptParams[2]); return 0; } case COMMAND_REGISTER_FIRE_LEVEL: diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index 06744ac2..ccb89fbd 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -3409,9 +3409,9 @@ CMenuManager::SmallMessageScreen(const char* text) CFont::SetPropOn(); CFont::SetJustifyOn(); CFont::SetBackGroundOnlyTextOn(); - CSprite2d::DrawRect(CRect(SCREEN_SCALE_X(95.0f), SCREEN_SCALE_FROM_BOTTOM(165.0f), SCREEN_SCALE_FROM_RIGHT(95.0f), SCREEN_SCALE_Y(115.0f)), CRGBA(50, 50, 50, FadeIn(210))); + CSprite2d::DrawRect(CRect(SCREEN_STRETCH_X(95.0f), SCREEN_SCALE_FROM_BOTTOM(165.0f), SCREEN_STRETCH_FROM_RIGHT(95.0f), SCREEN_SCALE_Y(115.0f)), CRGBA(50, 50, 50, FadeIn(210))); CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); - CFont::SetCentreSize(SCREEN_SCALE_X(430.0f)); + CFont::SetCentreSize(SCREEN_STRETCH_X(430.0f)); CFont::SetCentreOn(); CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, FadeIn(255))); CFont::SetDropShadowPosition(2); diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp index cfe79dcc..c1016bdd 100644 --- a/src/core/Pad.cpp +++ b/src/core/Pad.cpp @@ -2644,6 +2644,38 @@ bool CPad::TargetJustDown(void) return false; } +bool CPad::CollectPickupJustDown(void) +{ + if ( ArePlayerControlsDisabled() ) + return false; + + switch (CURMODE) + { + case 0: + case 1: + { + return !!(NewState.LeftShoulder1 && !OldState.LeftShoulder1); + + break; + } + case 2: + { + return !!(NewState.Triangle && !OldState.Triangle); + + break; + } + + case 3: + { + return !!(NewState.Circle && !OldState.Circle); + + break; + } + } + + return false; +} + bool CPad::DuckJustDown(void) { if (ArePlayerControlsDisabled()) diff --git a/src/core/Pad.h b/src/core/Pad.h index f76d7b5d..2a0bb7d3 100644 --- a/src/core/Pad.h +++ b/src/core/Pad.h @@ -238,6 +238,7 @@ public: bool GetTarget(void); bool TargetJustDown(void); bool DuckJustDown(void); + bool CollectPickupJustDown(void); bool JumpJustDown(void); bool GetSprint(void); bool ShiftTargetLeftJustDown(void); diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp index daafd27b..10408355 100644 --- a/src/render/Hud.cpp +++ b/src/render/Hud.cpp @@ -1708,6 +1708,12 @@ void CHud::SetHelpMessage(wchar *message, bool quick) } } +bool CHud::IsHelpMessageBeingDisplayed(void) +{ + return m_HelpMessageState != 0; +} + + void CHud::SetMessage(wchar *message) { int i = 0; diff --git a/src/render/Hud.h b/src/render/Hud.h index 9106f6fa..4dd52aa8 100644 --- a/src/render/Hud.h +++ b/src/render/Hud.h @@ -133,6 +133,7 @@ public: static void ReInitialise(); static void SetBigMessage(wchar *message, int16 style); static void SetHelpMessage(wchar *message, bool quick); + static bool IsHelpMessageBeingDisplayed(void); static void SetMessage(wchar *message); static void SetPagerMessage(wchar *message); static void SetVehicleName(wchar *name); diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp index b0dc98ad..3f329251 100644 --- a/src/vehicles/Automobile.cpp +++ b/src/vehicles/Automobile.cpp @@ -5577,7 +5577,7 @@ CAutomobile::TellHeliToGoToCoors(float x, float y, float z, uint8 speed) void CAutomobile::TellPlaneToGoToCoors(float x, float y, float z, uint8 speed) { - AutoPilot.m_nCarMission = MISSION_HELI_FLYTOCOORS; + AutoPilot.m_nCarMission = MISSION_PLANE_FLYTOCOORS; AutoPilot.m_vecDestinationCoors.x = x; AutoPilot.m_vecDestinationCoors.y = y; AutoPilot.m_vecDestinationCoors.z = z;