From aa4e7ad5eb554b1219f7eaae53e5ddc0d4478dd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?eray=20or=C3=A7unus?= Date: Sat, 5 Oct 2019 16:44:03 +0300 Subject: [PATCH] CDarkel, walkaround fix --- src/control/Darkel.cpp | 298 +++++++++++++++++++---------------- src/control/Darkel.h | 10 +- src/core/Streaming.cpp | 8 +- src/core/config.h | 19 ++- src/modelinfo/ModelIndices.h | 2 - src/peds/Ped.cpp | 63 ++++---- 6 files changed, 227 insertions(+), 173 deletions(-) diff --git a/src/control/Darkel.cpp b/src/control/Darkel.cpp index 670c10fb..da28faa7 100644 --- a/src/control/Darkel.cpp +++ b/src/control/Darkel.cpp @@ -2,12 +2,12 @@ #include "patcher.h" #include "main.h" #include "Darkel.h" +#include "PlayerPed.h" #include "Timer.h" #include "DMAudio.h" #include "Population.h" #include "Weapon.h" #include "World.h" -#include "PlayerPed.h" #include "Stats.h" #include "Font.h" #include "Text.h" @@ -19,105 +19,140 @@ int32 &CDarkel::WeaponType = *(int32*)0x9430F0; int32 &CDarkel::AmmoInterruptedWeapon = *(int32*)0x8E29C8; int32 &CDarkel::KillsNeeded = *(int32*)0x8F1AB8; int8 &CDarkel::InterruptedWeapon = *(int8*)0x95CD60; + +/* + * bStandardSoundAndMessages is a completely beta thing, + * makes game handle sounds & messages instead of SCM (just like in GTA2) + * but it's never been used in the game. Has unused sliding text when frenzy completed etc. + */ int8 &CDarkel::bStandardSoundAndMessages = *(int8*)0x95CDB6; int8 &CDarkel::bNeedHeadShot = *(int8*)0x95CDCA; int8 &CDarkel::bProperKillFrenzy = *(int8*)0x95CD98; eKillFrenzyStatus &CDarkel::Status = *(eKillFrenzyStatus*)0x95CCB4; -int16 *CDarkel::RegisteredKills = (int16*)0x6EDBE0; +uint16 (&CDarkel::RegisteredKills)[NUMDEFAULTMODELS] = *(uint16(*)[NUMDEFAULTMODELS]) * (uintptr*)0x6EDBE0; int32 &CDarkel::ModelToKill = *(int32*)0x8F2C78; int32 &CDarkel::ModelToKill2 = *(int32*)0x885B40; int32 &CDarkel::ModelToKill3 = *(int32*)0x885B3C; int32 &CDarkel::ModelToKill4 = *(int32*)0x885B34; wchar *CDarkel::pStartMessage = (wchar*)0x8F2C08; -int32 CDarkel::CalcFade(uint32 time, int32 start, uint32 end) { +uint8 +CDarkel::CalcFade(uint32 time, uint32 start, uint32 end) +{ if (time >= start && time <= end) { if (time >= start + 500) { if (time <= end - 500) return 255; else return 255 * (end - time) / 500; - } - else + } else return 255 * (time - start) / 500; - } - else + } else return 0; } -// This function has been cleaned up from unused stuff. -#if 0 -WRAPPER void CDarkel::DrawMessages(void) { EAXJMP(0x420920); } -#else -void CDarkel::DrawMessages() +// Screen positions taken from VC +void +CDarkel::DrawMessages() { - bool DisplayTimers = false; - switch (Status) { - case KILLFRENZY_ONGOING: - assert(pStartMessage != nil); - DisplayTimers = true; - break; - case KILLFRENZY_PASSED: - case KILLFRENZY_FAILED: - DisplayTimers = false; - break; - }; - - if (DisplayTimers) { - CFont::SetPropOn(); - CFont::SetBackgroundOff(); - CFont::SetBackGroundOnlyTextOn(); - CFont::SetAlignment(ALIGN_RIGHT); - CFont::SetRightJustifyWrap(-SCREEN_WIDTH); - CFont::SetFontStyle(FONT_HEADING); - CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f)); - - float AlignToHUD = SCREEN_SCALE_X(-10.0f); - int32 a = (TimeLimit - (CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart)); - if (CTimer::GetFrameCounter() & 8 || a > 4000) { - sprintf(gString, "%d:%02d", a / 60000, a % 60000 / 1000); + case KILLFRENZY_ONGOING: + { + CFont::SetJustifyOff(); + CFont::SetBackgroundOff(); + CFont::SetCentreSize(SCREEN_SCALE_FROM_RIGHT(30.0f)); + CFont::SetCentreOn(); + CFont::SetPropOn(); + uint32 timePassedSinceStart = CTimer::GetTimeInMilliseconds() - CDarkel::TimeOfFrenzyStart; + if (CDarkel::bStandardSoundAndMessages) { + if (timePassedSinceStart >= 3000 && timePassedSinceStart < 11000) { + CFont::SetScale(SCREEN_SCALE_X(1.3f), SCREEN_SCALE_Y(1.3f)); + CFont::SetJustifyOff(); + CFont::SetColor(CRGBA(255, 255, 128, CalcFade(timePassedSinceStart, 3000, 11000))); + CFont::SetFontStyle(FONT_BANK); + if (pStartMessage) { + CFont::PrintString(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, pStartMessage); + } + } + } else { + if (timePassedSinceStart < 8000) { + CFont::SetScale(SCREEN_SCALE_X(1.3f), SCREEN_SCALE_Y(1.3f)); + CFont::SetJustifyOff(); + CFont::SetColor(CRGBA(255, 255, 128, CalcFade(timePassedSinceStart, 0, 8000))); + CFont::SetFontStyle(FONT_BANK); + if (pStartMessage) { + CFont::PrintString(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, pStartMessage); + } + } + } + CFont::SetScale(SCREEN_SCALE_X(0.75f), SCREEN_SCALE_Y(1.5f)); + CFont::SetCentreOff(); + CFont::SetRightJustifyOn(); + CFont::SetFontStyle(FONT_HEADING); + if (CDarkel::TimeLimit >= 0) { + uint32 timeLeft = CDarkel::TimeLimit - (CTimer::GetTimeInMilliseconds() - CDarkel::TimeOfFrenzyStart); + sprintf(gString, "%d:%02d", timeLeft / 60000, timeLeft % 60000 / 1000); + AsciiToUnicode(gString, gUString); + if (timeLeft > 4000 || CTimer::GetFrameCounter() & 1) { + CFont::SetColor(CRGBA(0, 0, 0, 255)); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(35.0f), SCREEN_SCALE_Y(109.0f), gUString); + CFont::SetColor(CRGBA(150, 100, 255, 255)); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(34.0f), SCREEN_SCALE_Y(108.0f), gUString); + } + } + sprintf(gString, "%d", (CDarkel::KillsNeeded >= 0 ? CDarkel::KillsNeeded : 0)); AsciiToUnicode(gString, gUString); CFont::SetColor(CRGBA(0, 0, 0, 255)); - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(25.0f) + AlignToHUD, SCREEN_SCALE_Y(112.0f), gUString); - - CFont::SetColor(CRGBA(150, 100, 255, 255)); - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(27.0f) + AlignToHUD, SCREEN_SCALE_Y(110.0f), gUString); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(35.0f), SCREEN_SCALE_Y(144.0f), gUString); + CFont::SetColor(CRGBA(255, 128, 128, 255)); + CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(34.0f), SCREEN_SCALE_Y(143.0f), gUString); + break; } - - if (KillsNeeded <= 0) - KillsNeeded = 0; - - sprintf((char *)gString, "%d", KillsNeeded); - AsciiToUnicode(gString, gUString); - - CFont::SetColor(CRGBA(0, 0, 0, 255)); - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(25.0f) + AlignToHUD, SCREEN_SCALE_Y(134.0f), gUString); - - CFont::SetColor(CRGBA(255, 128, 128, 255)); - CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(27.0f) + AlignToHUD, SCREEN_SCALE_Y(132.0f), gUString); + case KILLFRENZY_PASSED: + { + if (CDarkel::bStandardSoundAndMessages) { + uint32 timePassedSinceStart = CTimer::GetTimeInMilliseconds() - CDarkel::TimeOfFrenzyStart; + if (CTimer::GetTimeInMilliseconds() - CDarkel::TimeOfFrenzyStart < 5000) { + CFont::SetBackgroundOff(); + CFont::SetCentreSize(SCREEN_SCALE_FROM_RIGHT(20.0f)); + CFont::SetCentreOn(); + CFont::SetScale(SCREEN_SCALE_X(1.5f), SCREEN_SCALE_Y(1.5f)); + CFont::SetJustifyOff(); + CFont::SetColor(CRGBA(128, 255, 128, CalcFade(timePassedSinceStart, 0, 5000))); + CFont::SetFontStyle(FONT_BANK); + int y = SCREEN_HEIGHT / 2 + SCREEN_SCALE_Y(25.0f - timePassedSinceStart * 0.01f); + CFont::PrintString(SCREEN_WIDTH / 2, y, TheText.Get("KF_3")); + } + } + break; + } + default: + break; } } -#endif -void CDarkel::Init() +void +CDarkel::Init() { Status = KILLFRENZY_NONE; } -int16 CDarkel::QueryModelsKilledByPlayer(int32 modelId) +uint16 +CDarkel::QueryModelsKilledByPlayer(int32 modelId) { return RegisteredKills[modelId]; } -bool CDarkel::FrenzyOnGoing() +bool +CDarkel::FrenzyOnGoing() { return Status == KILLFRENZY_ONGOING; } -eKillFrenzyStatus CDarkel::ReadStatus() +uint16 +CDarkel::ReadStatus() { return Status; } @@ -141,21 +176,24 @@ void CDarkel::RegisterKillByPlayer(CPed *victim, eWeaponType weapontype, bool he } #endif -void CDarkel::RegisterKillNotByPlayer(CPed* victim, eWeaponType weapontype) +void +CDarkel::RegisterKillNotByPlayer(CPed* victim, eWeaponType weapontype) { - ++CStats::NumberKillFrenziesPassed; + ++CStats::PeopleKilledByOthers; } -void CDarkel::ResetModelsKilledByPlayer() +void +CDarkel::ResetModelsKilledByPlayer() { - for (int i = 0; i < 200; i++) + for (int i = 0; i < NUMDEFAULTMODELS; i++) RegisteredKills[i] = 0; } #if 0 WRAPPER void CDarkel::ResetOnPlayerDeath() { EAXJMP(0x420E70); } #else -void CDarkel::ResetOnPlayerDeath() +void +CDarkel::ResetOnPlayerDeath() { if (Status != KILLFRENZY_ONGOING) return; @@ -164,48 +202,37 @@ void CDarkel::ResetOnPlayerDeath() Status = KILLFRENZY_FAILED; TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds(); + eWeaponType fixedWeapon; if (WeaponType == WEAPONTYPE_UZI_DRIVEBY) - WeaponType = WEAPONTYPE_UZI; + fixedWeapon = WEAPONTYPE_UZI; + else + fixedWeapon = (eWeaponType)WeaponType; - if (WeaponType < WEAPONTYPE_TOTALWEAPONS) { - FindPlayerPed()->m_nSelectedWepSlot = InterruptedWeapon; - CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal = AmmoInterruptedWeapon; + CPlayerPed *player = FindPlayerPed(); + if (fixedWeapon < WEAPONTYPE_TOTALWEAPONS) { + player->m_nSelectedWepSlot = InterruptedWeapon; + player->GetWeapon(player->GetWeaponSlot(fixedWeapon)).m_nAmmoTotal = CDarkel::AmmoInterruptedWeapon; } if (FindPlayerVehicle()) { - FindPlayerPed()->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(FindPlayerPed()->GetWeapon()->m_eWeaponType)->m_nModelId); - FindPlayerPed()->m_currentWeapon = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType; - FindPlayerPed()->MakeChangesForNewWeapon(FindPlayerPed()->m_currentWeapon); - } - - - CPopulation::m_AllRandomPedsThisType = -1; - Status = KILLFRENZY_FAILED; - TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds(); - - if (WeaponType == WEAPONTYPE_UZI_DRIVEBY) - WeaponType = WEAPONTYPE_UZI; - - if (WeaponType < WEAPONTYPE_TOTALWEAPONS) { - FindPlayerPed()->m_nSelectedWepSlot = InterruptedWeapon; - CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal = AmmoInterruptedWeapon; - } - - if (FindPlayerVehicle()) { - FindPlayerPed()->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(FindPlayerPed()->GetWeapon()->m_eWeaponType)->m_nModelId); - FindPlayerPed()->m_currentWeapon = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType; - FindPlayerPed()->MakeChangesForNewWeapon(FindPlayerPed()->m_currentWeapon); + player->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(player->GetWeapon()->m_eWeaponType)->m_nModelId); + player->m_currentWeapon = player->m_nSelectedWepSlot; + player->MakeChangesForNewWeapon(player->m_currentWeapon); } } #endif #if 0 -WRAPPER void CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, int16 kill, int32 modelId0, wchar *text, int32 modelId2, int32 modelId3, int32 modelId4, bool standardSound, bool needHeadShot) { EAXJMP(0x4210E0); } +WRAPPER void CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, uint16 kill, int32 modelId0, wchar *text, int32 modelId2, int32 modelId3, int32 modelId4, bool standardSound, bool needHeadShot) { EAXJMP(0x4210E0); } #else -void CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, int16 kill, int32 modelId0, wchar *text, int32 modelId2, int32 modelId3, int32 modelId4, bool standardSound, bool needHeadShot) +void +CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, uint16 kill, int32 modelId0, wchar *text, int32 modelId2, int32 modelId3, int32 modelId4, bool standardSound, bool needHeadShot) { + eWeaponType fixedWeapon; if (weaponType == WEAPONTYPE_UZI_DRIVEBY) - weaponType = WEAPONTYPE_UZI; + fixedWeapon = WEAPONTYPE_UZI; + else + fixedWeapon = weaponType; WeaponType = weaponType; Status = KILLFRENZY_ONGOING; @@ -219,8 +246,7 @@ void CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, int16 kill, int32 if (text == TheText.Get("PAGE_00")) { CDarkel::bProperKillFrenzy = 1; CDarkel::pStartMessage = 0; - } - else + } else bProperKillFrenzy = 0; bStandardSoundAndMessages = standardSound; @@ -229,20 +255,19 @@ void CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, int16 kill, int32 TimeLimit = time; PreviousTime = time / 1000; - if (weaponType < WEAPONTYPE_TOTALWEAPONS) { - InterruptedWeapon = FindPlayerPed()->m_currentWeapon; - FindPlayerPed()->GiveWeapon(weaponType, 0); - AmmoInterruptedWeapon = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal; - FindPlayerPed()->GiveWeapon(weaponType, 30000); - FindPlayerPed()->m_nSelectedWepSlot = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType; - FindPlayerPed()->MakeChangesForNewWeapon(FindPlayerPed()->m_nSelectedWepSlot); + CPlayerPed *player = FindPlayerPed(); + if (fixedWeapon < WEAPONTYPE_TOTALWEAPONS) { + InterruptedWeapon = player->m_currentWeapon; + player->GiveWeapon(fixedWeapon, 0); + AmmoInterruptedWeapon = player->GetWeapon(player->GetWeaponSlot(fixedWeapon)).m_nAmmoTotal; + player->GiveWeapon(fixedWeapon, 30000); + player->m_nSelectedWepSlot = player->GetWeaponSlot(fixedWeapon); + player->MakeChangesForNewWeapon(player->m_nSelectedWepSlot); if (FindPlayerVehicle()) { - FindPlayerPed()->m_currentWeapon = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType; - if (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal <= CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoInClip) - CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoInClip = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal; - - FindPlayerPed()->ClearWeaponTarget(); + player->m_currentWeapon = player->m_nSelectedWepSlot; + player->GetWeapon()->m_nAmmoInClip = min(player->GetWeapon()->m_nAmmoTotal, CWeaponInfo::GetWeaponInfo(player->GetWeapon()->m_eWeaponType)->m_nAmountofAmmunition); + player->ClearWeaponTarget(); } } if (CDarkel::bStandardSoundAndMessages) @@ -250,13 +275,15 @@ void CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, int16 kill, int32 } #endif -void CDarkel::Update() +void +CDarkel::Update() { if (Status != KILLFRENZY_ONGOING) return; int32 FrameTime = TimeLimit - (CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart); if ((TimeLimit - (CTimer::GetTimeInMilliseconds() - TimeOfFrenzyStart)) > 0 || TimeLimit < 0) { + DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_ONGOING, FrameTime); int32 PrevTime = FrameTime / 1000; @@ -267,24 +294,27 @@ void CDarkel::Update() PreviousTime = PrevTime; } - } - else { + } else { CPopulation::m_AllRandomPedsThisType = -1; Status = KILLFRENZY_FAILED; TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds(); + eWeaponType fixedWeapon; if (WeaponType == WEAPONTYPE_UZI_DRIVEBY) - WeaponType = WEAPONTYPE_UZI; + fixedWeapon = WEAPONTYPE_UZI; + else + fixedWeapon = (eWeaponType)WeaponType; - if (WeaponType < WEAPONTYPE_TOTALWEAPONS) { - FindPlayerPed()->m_nSelectedWepSlot = InterruptedWeapon; - CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal = AmmoInterruptedWeapon; + CPlayerPed *player = FindPlayerPed(); + if (fixedWeapon < WEAPONTYPE_TOTALWEAPONS) { + player->m_nSelectedWepSlot = InterruptedWeapon; + player->GetWeapon(player->GetWeaponSlot(fixedWeapon)).m_nAmmoTotal = CDarkel::AmmoInterruptedWeapon; } if (FindPlayerVehicle()) { - FindPlayerPed()->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(FindPlayerPed()->GetWeapon()->m_eWeaponType)->m_nModelId); - FindPlayerPed()->m_currentWeapon = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType; - FindPlayerPed()->MakeChangesForNewWeapon(FindPlayerPed()->m_currentWeapon); + player->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(player->GetWeapon()->m_eWeaponType)->m_nModelId); + player->m_currentWeapon = player->m_nSelectedWepSlot; + player->MakeChangesForNewWeapon(player->m_currentWeapon); } if (bStandardSoundAndMessages) @@ -302,18 +332,22 @@ void CDarkel::Update() FindPlayerPed()->m_pWanted->SetWantedLevel(0); + eWeaponType fixedWeapon; if (WeaponType == WEAPONTYPE_UZI_DRIVEBY) - WeaponType = WEAPONTYPE_UZI; + fixedWeapon = WEAPONTYPE_UZI; + else + fixedWeapon = (eWeaponType)WeaponType; - if (WeaponType < WEAPONTYPE_TOTALWEAPONS) { - FindPlayerPed()->m_nSelectedWepSlot = InterruptedWeapon; - CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_nAmmoTotal = AmmoInterruptedWeapon; + CPlayerPed* player = FindPlayerPed(); + if (fixedWeapon < WEAPONTYPE_TOTALWEAPONS) { + player->m_nSelectedWepSlot = InterruptedWeapon; + player->GetWeapon(player->GetWeaponSlot(fixedWeapon)).m_nAmmoTotal = CDarkel::AmmoInterruptedWeapon; } if (FindPlayerVehicle()) { - FindPlayerPed()->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(FindPlayerPed()->GetWeapon()->m_eWeaponType)->m_nModelId); - FindPlayerPed()->m_currentWeapon = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType; - FindPlayerPed()->MakeChangesForNewWeapon(FindPlayerPed()->m_currentWeapon); + player->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(player->GetWeapon()->m_eWeaponType)->m_nModelId); + player->m_currentWeapon = player->m_nSelectedWepSlot; + player->MakeChangesForNewWeapon(player->m_currentWeapon); } if (bStandardSoundAndMessages) @@ -322,17 +356,17 @@ void CDarkel::Update() } STARTPATCHES - /*InjectHook(0x421380, CDarkel::CalcFade, PATCH_JUMP); - InjectHook(0x420920, CDarkel::DrawMessages, PATCH_JUMP); - InjectHook(0x420E60, CDarkel::FrenzyOnGoing, PATCH_JUMP); + InjectHook(0x421380, CDarkel::CalcFade, PATCH_JUMP); InjectHook(0x420650, CDarkel::Init, PATCH_JUMP); - InjectHook(0x421370, CDarkel::QueryModelsKilledByPlayer, PATCH_JUMP); + InjectHook(0x420660, CDarkel::Update, PATCH_JUMP); + InjectHook(0x420E60, CDarkel::FrenzyOnGoing, PATCH_JUMP); InjectHook(0x420E50, CDarkel::ReadStatus, PATCH_JUMP); - InjectHook(0x421070, CDarkel::RegisterCarBlownUpByPlayer, PATCH_JUMP); - InjectHook(0x420F60, CDarkel::RegisterKillByPlayer, PATCH_JUMP); - InjectHook(0x421060, CDarkel::RegisterKillNotByPlayer, PATCH_JUMP); - InjectHook(0x421310, CDarkel::ResetModelsKilledByPlayer, PATCH_JUMP); InjectHook(0x420E70, CDarkel::ResetOnPlayerDeath, PATCH_JUMP); InjectHook(0x4210E0, CDarkel::StartFrenzy, PATCH_JUMP); - InjectHook(0x420660, CDarkel::Update, PATCH_JUMP);*/ + InjectHook(0x421370, CDarkel::QueryModelsKilledByPlayer, PATCH_JUMP); + InjectHook(0x421060, CDarkel::RegisterKillNotByPlayer, PATCH_JUMP); + InjectHook(0x421310, CDarkel::ResetModelsKilledByPlayer, PATCH_JUMP); + InjectHook(0x420920, CDarkel::DrawMessages, PATCH_JUMP); + //InjectHook(0x421070, CDarkel::RegisterCarBlownUpByPlayer, PATCH_JUMP); + //InjectHook(0x420F60, CDarkel::RegisterKillByPlayer, PATCH_JUMP); ENDPATCHES \ No newline at end of file diff --git a/src/control/Darkel.h b/src/control/Darkel.h index 77a14bb8..0171cd2c 100644 --- a/src/control/Darkel.h +++ b/src/control/Darkel.h @@ -26,7 +26,7 @@ private: static int8 &bNeedHeadShot; static int8 &bProperKillFrenzy; static eKillFrenzyStatus &Status; - static int16 *RegisteredKills; + static uint16 (&RegisteredKills)[NUMDEFAULTMODELS]; static int32 &ModelToKill; static int32 &ModelToKill2; static int32 &ModelToKill3; @@ -34,18 +34,18 @@ private: static wchar *pStartMessage; public: - static int32 CalcFade(uint32 time, int32 min, uint32 max); + static uint8 CalcFade(uint32 time, uint32 min, uint32 max); static void DrawMessages(void); static bool FrenzyOnGoing(); static void Init(); - static int16 QueryModelsKilledByPlayer(int32 modelId); - static eKillFrenzyStatus ReadStatus(); + static uint16 QueryModelsKilledByPlayer(int32 modelId); + static uint16 ReadStatus(); static void RegisterCarBlownUpByPlayer(CVehicle *vehicle); static void RegisterKillByPlayer(CPed *victim, eWeaponType weapontype, bool headshot = false); static void RegisterKillNotByPlayer(CPed* victim, eWeaponType weapontype); static void ResetModelsKilledByPlayer(); static void ResetOnPlayerDeath(); - static void StartFrenzy(eWeaponType weaponType, int32 time, int16 kill, int32 modelId0, wchar *text, int32 modelId2, int32 modelId3, int32 modelId4, bool standardSound, bool needHeadShot); + static void StartFrenzy(eWeaponType weaponType, int32 time, uint16 kill, int32 modelId0, wchar *text, int32 modelId2, int32 modelId3, int32 modelId4, bool standardSound, bool needHeadShot); static void Update(); }; diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp index a7bde91e..d15415ea 100644 --- a/src/core/Streaming.cpp +++ b/src/core/Streaming.cpp @@ -1021,7 +1021,7 @@ CStreaming::RemoveAllUnusedModels(void) for(i = 0; i < MAXVEHICLESLOADED; i++) RemoveLoadedVehicle(); - for(i = NUM_DEFAULT_MODELS; i < MODELINFOSIZE; i++){ + for(i = NUMDEFAULTMODELS; i < MODELINFOSIZE; i++){ if(ms_aInfoForModel[i].m_loadState == STREAMSTATE_LOADED && ms_aInfoForModel[i].m_flags & STREAMFLAGS_DONT_REMOVE && CModelInfo::GetModelInfo(i)->m_refCount == 0){ @@ -2408,8 +2408,8 @@ CStreaming::MemoryCardSave(uint8 *buffer, uint32 *length) { int i; - *length = NUM_DEFAULT_MODELS; - for(i = 0; i < NUM_DEFAULT_MODELS; i++) + *length = NUMDEFAULTMODELS; + for(i = 0; i < NUMDEFAULTMODELS; i++) if(ms_aInfoForModel[i].m_loadState == STREAMSTATE_LOADED) buffer[i] = ms_aInfoForModel[i].m_flags; else @@ -2421,7 +2421,7 @@ CStreaming::MemoryCardLoad(uint8 *buffer, uint32 length) { uint32 i; - assert(length == NUM_DEFAULT_MODELS); + assert(length == NUMDEFAULTMODELS); for(i = 0; i < length; i++) if(ms_aInfoForModel[i].m_loadState == STREAMSTATE_LOADED) if(buffer[i] != 0xFF) diff --git a/src/core/config.h b/src/core/config.h index 49bef3fa..520bcc72 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -32,6 +32,7 @@ enum Config { NUMDUMMIES = 2802, // 2368 on PS2 NUMAUDIOSCRIPTOBJECTS = 256, NUMCUTSCENEOBJECTS = 50, + NUMDEFAULTMODELS = 200, NUMTEMPOBJECTS = 30, @@ -138,11 +139,25 @@ enum Config { #endif #define FIX_BUGS // fix bugs in the game, TODO: use this more + +// Pad #define KANGAROO_CHEAT + +// Hud #define ASPECT_RATIO_SCALE + +// Script #define USE_DEBUG_SCRIPT_LOADER + +// Vehicles #define EXPLODING_AIRTRAIN // can blow up jumbo jet with rocket launcher -#define ANIMATE_PED_COL_MODEL //#define REMOVE_TREADABLE_PATHFIND + +// Pickups +//#define MONEY_MESSAGES + +// Peds +#define ANIMATE_PED_COL_MODEL #define VC_PED_PORTS -//#define MONEY_MESSAGES \ No newline at end of file +#define NEW_WALK_AROUND_ALGORITHM +#define CANCELLABLE_CAR_ENTER \ No newline at end of file diff --git a/src/modelinfo/ModelIndices.h b/src/modelinfo/ModelIndices.h index a0d3f70c..8f6d0e48 100644 --- a/src/modelinfo/ModelIndices.h +++ b/src/modelinfo/ModelIndices.h @@ -352,8 +352,6 @@ enum MI_AIRTRAIN_VLO = 198, MI_LOPOLYGUY, - - NUM_DEFAULT_MODELS, }; enum{ diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index 33b31066..44148f14 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -69,9 +69,6 @@ WRAPPER void CPed::SetExitCar(CVehicle*, uint32) { EAXJMP(0x4E1010); } #define FEET_OFFSET 1.04f -#define NEW_WALK_AROUND_ALGORITHM -#define CANCELLABLE_CAR_ENTER - CPed *gapTempPedList[50]; uint16 gnNumTempPedList; @@ -13506,19 +13503,29 @@ CPed::SetExitTrain(CVehicle* train) #ifdef NEW_WALK_AROUND_ALGORITHM CVector -LocalPosForWalkAround(CVector2D colMin, CVector2D colMax, int walkAround) { +LocalPosForWalkAround(CVector2D colMin, CVector2D colMax, int walkAround, uint32 enterDoorNode, bool itsVan) { switch (walkAround) { case 0: + if (enterDoorNode == CAR_DOOR_LF) + return CVector(colMin.x, colMax.y - 1.0f, 0.0f); case 1: return CVector(colMin.x, colMax.y, 0.0f); case 2: case 3: + if (walkAround == 3 && enterDoorNode == CAR_DOOR_RF) + return CVector(colMax.x, colMax.y - 1.0f, 0.0f); + return CVector(colMax.x, colMax.y, 0.0f); case 4: + if (enterDoorNode == CAR_DOOR_RR && !itsVan) + return CVector(colMax.x, colMin.y + 1.0f, 0.0f); case 5: return CVector(colMax.x, colMin.y, 0.0f); case 6: case 7: + if (walkAround == 7 && enterDoorNode == CAR_DOOR_LR && !itsVan) + return CVector(colMin.x, colMin.y + 1.0f, 0.0f); + return CVector(colMin.x, colMin.y, 0.0f); default: return CVector(0.0f, 0.0f, 0.0f); @@ -13537,8 +13544,8 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj) CVector objColCenter = (objColMin + objColMax) / 2.0f; CMatrix objMat(obj->GetMatrix()); float dirToSet = obj->GetForward().Heading(); - bool objIsSeekTargetAndVan = false; - bool objIsSeekTarget = false; + bool goingToEnterCarAndItsVan = false; + bool goingToEnterCar = false; bool objUpsideDown = false; float checkIntervalInDist = (objColMax.y - objColMin.y) * 0.1f; @@ -13620,12 +13627,12 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj) if (m_pSeekTarget == obj && obj->IsVehicle()) { if (m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER || m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER || m_objective == OBJECTIVE_SOLICIT) { - objIsSeekTarget = true; + goingToEnterCar = true; if (IsPlayer()) checkIntervalInTime = 0.0f; if (((CVehicle*)obj)->bIsVan) - objIsSeekTargetAndVan = true; + goingToEnterCarAndItsVan = true; } } @@ -13671,7 +13678,7 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj) else { CVector tl = obj->GetMatrix() * CVector(adjustedColMin.x, adjustedColMax.y, 0.0f) - GetPosition(); cornerToGo = tl; - if (objIsSeekTarget && (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR)) { + if (goingToEnterCar && (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR)) { m_walkAroundType = 1; } else { dirToGo = GetLocalDirection(tl); @@ -13705,7 +13712,7 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj) CVector tr = obj->GetMatrix() * CVector(adjustedColMax.x, adjustedColMax.y, 0.0f) - GetPosition(); if (tr.Magnitude2D() < cornerToGo.Magnitude2D()) { cornerToGo = tr; - if (objIsSeekTarget && (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR)) { + if (goingToEnterCar && (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR)) { m_walkAroundType = 2; } else { dirToGo = GetLocalDirection(tr); @@ -13740,7 +13747,7 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj) CVector br = obj->GetMatrix() * CVector(adjustedColMax.x, adjustedColMin.y, 0.0f) - GetPosition(); if (br.Magnitude2D() < cornerToGo.Magnitude2D()) { cornerToGo = br; - if (objIsSeekTarget && (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR)) { + if (goingToEnterCar && (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR)) { m_walkAroundType = 5; } else { dirToGo = GetLocalDirection(br); @@ -13775,7 +13782,7 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj) CVector bl = obj->GetMatrix() * CVector(adjustedColMin.x, adjustedColMin.y, 0.0f) - GetPosition(); if (bl.Magnitude2D() < cornerToGo.Magnitude2D()) { cornerToGo = bl; - if (objIsSeekTarget && (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR)) { + if (goingToEnterCar && (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR)) { m_walkAroundType = 6; } else { dirToGo = GetLocalDirection(bl); @@ -13803,7 +13810,7 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj) if (Abs(angleDiffBtwObjCenterAndForward) >= objTopRightHeading) { if (PI - objTopRightHeading >= Abs(angleDiffBtwObjCenterAndForward)) { if ((angleDiffBtwObjCenterAndForward <= 0.0f || objUpsideDown) && (angleDiffBtwObjCenterAndForward < 0.0f || !objUpsideDown)) { - if (objIsSeekTarget && (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR)) { + if (goingToEnterCar && (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR)) { m_walkAroundType = 0; } else { if (CGeneral::LimitRadianAngle(m_fRotationDest - angleToFaceObjCenter) >= 0.0f) { @@ -13821,7 +13828,7 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj) } } } else { - if (objIsSeekTarget && (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR)) { + if (goingToEnterCar && (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR)) { m_walkAroundType = 0; } else { if (CGeneral::LimitRadianAngle(m_fRotationDest - angleToFaceObjCenter) <= 0.0f) { @@ -13839,7 +13846,7 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj) } } } - } else if (objIsSeekTarget && (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR) + } else if (goingToEnterCar && (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR) || CGeneral::LimitRadianAngle(m_fRotationDest - angleToFaceObjCenter) < 0.0f) { if (entityOnTopLeftOfObj == 1 || entityOnTopLeftOfObj && !entityOnTopRightOfObj && !entityOnBottomRightOfObj) { m_walkAroundType = 3; @@ -13847,7 +13854,7 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj) } else if (entityOnTopRightOfObj == 1 || entityOnTopRightOfObj && !entityOnTopLeftOfObj && !entityOnBottomLeftOfObj) { m_walkAroundType = 4; } - } else if (objIsSeekTarget && (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR) + } else if (goingToEnterCar && (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR) || CGeneral::LimitRadianAngle(m_fRotationDest - angleToFaceObjCenter) > 0.0f) { if (entityOnBottomLeftOfObj == 1 || entityOnBottomLeftOfObj && !entityOnTopRightOfObj && !entityOnBottomRightOfObj) { m_walkAroundType = 2; @@ -13880,13 +13887,13 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj) nextWalkAround = 7; } - CVector nextPosToHead = objMat * LocalPosForWalkAround(adjustedColMin, adjustedColMax, nextWalkAround); + CVector nextPosToHead = objMat * LocalPosForWalkAround(adjustedColMin, adjustedColMax, nextWalkAround, goingToEnterCar ? m_vehEnterType : 0, goingToEnterCarAndItsVan); bool nextRouteIsClear = CWorld::GetIsLineOfSightClear(GetPosition(), nextPosToHead, true, true, true, true, true, true, false); if(nextRouteIsClear) m_walkAroundType = nextWalkAround; else { - CVector posToHead = objMat * LocalPosForWalkAround(adjustedColMin, adjustedColMax, m_walkAroundType); + CVector posToHead = objMat * LocalPosForWalkAround(adjustedColMin, adjustedColMax, m_walkAroundType, goingToEnterCar ? m_vehEnterType : 0, goingToEnterCarAndItsVan); bool currentRouteIsClear = CWorld::GetIsLineOfSightClear(GetPosition(), posToHead, true, true, true, true, true, true, false); @@ -13916,11 +13923,11 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj) } } - localPosToHead = LocalPosForWalkAround(adjustedColMin, adjustedColMax, m_walkAroundType); + localPosToHead = LocalPosForWalkAround(adjustedColMin, adjustedColMax, m_walkAroundType, goingToEnterCar ? m_vehEnterType : 0, goingToEnterCarAndItsVan); #else if (Abs(angleDiffBtwObjCenterAndForward) < objTopRightHeading) { - if (objIsSeekTarget) { - if (objIsSeekTargetAndVan) { + if (goingToEnterCar) { + if (goingToEnterCarAndItsVan) { if (m_vehEnterType == CAR_DOOR_LR || m_vehEnterType == CAR_DOOR_RR) return; } @@ -13953,9 +13960,9 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj) } else { if (PI - objTopRightHeading >= Abs(angleDiffBtwObjCenterAndForward)) { if (angleDiffBtwObjCenterAndForward <= 0.0f) { - if (!objIsSeekTarget || !objIsSeekTargetAndVan || m_vehEnterType != CAR_DOOR_LR && m_vehEnterType != CAR_DOOR_RR) { - if (objIsSeekTarget) { - if (m_vehEnterType == CAR_DOOR_RF || (m_vehEnterType == CAR_DOOR_RR && !objIsSeekTargetAndVan)) + if (!goingToEnterCar || !goingToEnterCarAndItsVan || m_vehEnterType != CAR_DOOR_LR && m_vehEnterType != CAR_DOOR_RR) { + if (goingToEnterCar) { + if (m_vehEnterType == CAR_DOOR_RF || (m_vehEnterType == CAR_DOOR_RR && !goingToEnterCarAndItsVan)) return; } if (m_walkAroundType == 4 || m_walkAroundType == 3 @@ -13977,14 +13984,14 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj) localPosToHead.z = 0.0f; localPosToHead.y = adjustedColMin.y; } - } else if (objIsSeekTarget && objIsSeekTargetAndVan && (m_vehEnterType == CAR_DOOR_LR || m_vehEnterType == CAR_DOOR_RR)) { + } else if (goingToEnterCar && goingToEnterCarAndItsVan && (m_vehEnterType == CAR_DOOR_LR || m_vehEnterType == CAR_DOOR_RR)) { m_fRotationDest = CGeneral::LimitRadianAngle(PI + dirToSet); localPosToHead.x = adjustedColMin.x; localPosToHead.z = 0.0f; localPosToHead.y = adjustedColMin.y; } else { - if (objIsSeekTarget) { - if (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR && !objIsSeekTargetAndVan) + if (goingToEnterCar) { + if (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR && !goingToEnterCarAndItsVan) return; } if (m_walkAroundType == 1 || m_walkAroundType == 2 @@ -14002,7 +14009,7 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj) } } } else { - if (objIsSeekTarget && (!objIsSeekTargetAndVan || m_vehEnterType != CAR_DOOR_LR && m_vehEnterType != CAR_DOOR_RR)) { + if (goingToEnterCar && (!goingToEnterCarAndItsVan || m_vehEnterType != CAR_DOOR_LR && m_vehEnterType != CAR_DOOR_RR)) { if (m_vehEnterType != CAR_DOOR_LF && m_vehEnterType != CAR_DOOR_LR && (!entityOnTopRightOfObj || entityOnTopLeftOfObj)) { m_fRotationDest = CGeneral::LimitRadianAngle(dirToSet - HALFPI);