diff options
Diffstat (limited to 'src/control')
-rw-r--r-- | src/control/Darkel.cpp | 332 | ||||
-rw-r--r-- | src/control/Darkel.h | 39 |
2 files changed, 367 insertions, 4 deletions
diff --git a/src/control/Darkel.cpp b/src/control/Darkel.cpp index 32d975e0..f050a540 100644 --- a/src/control/Darkel.cpp +++ b/src/control/Darkel.cpp @@ -1,12 +1,338 @@ #include "common.h" #include "patcher.h" +#include "main.h" #include "Darkel.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" +int32 &CDarkel::TimeLimit = *(int32*)0x885BAC; +int32 &CDarkel::PreviousTime = *(int32*)0x885B00; +int32 &CDarkel::TimeOfFrenzyStart = *(int32*)0x9430D8; +int32 &CDarkel::WeaponType = *(int32*)0x9430F0; +int32 &CDarkel::AmmoInterruptedWeapon = *(int32*)0x8E29C8; +int32 &CDarkel::KillsNeeded = *(int32*)0x8F1AB8; +int8 &CDarkel::InterruptedWeapon = *(int8*)0x95CD60; +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; +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) { + if (time >= start && time <= end) { + if (time >= start + 500) { + if (time <= end - 500) + return 255; + else + return 255 * (end - time) / 500; + } + else + return 255 * (time - start) / 500; + } + 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() +{ + 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); + 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); + } + + 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); + } +} +#endif + +void CDarkel::Init() +{ + Status = KILLFRENZY_NONE; +} + +int16 CDarkel::QueryModelsKilledByPlayer(int32 modelId) +{ + return RegisteredKills[modelId]; +} -bool CDarkel::Status = *(bool*)0x95CCB4; bool CDarkel::FrenzyOnGoing() { - return Status == 1; -}
\ No newline at end of file + return Status == KILLFRENZY_ONGOING; +} + + +eKillFrenzyStatus CDarkel::ReadStatus() +{ + return Status; +} + +#if 1 +WRAPPER int32 CDarkel::RegisterCarBlownUpByPlayer(eKillFrenzyStatus status) { EAXJMP(0x421070); } +#else +int32 CDarkel::RegisterCarBlownUpByPlayer(eKillFrenzyStatus status) +{ + return 0; +} +#endif + +#if 1 +WRAPPER void CDarkel::RegisterKillByPlayer(int32 modelid, eWeaponType weapontype, bool flag) { EAXJMP(0x420F60); } +#else +void CDarkel::RegisterKillByPlayer(int32 modelid, eWeaponType weapontype, bool flag) +{ + + +} +#endif + +void CDarkel::RegisterKillNotByPlayer() +{ + ++CStats::NumberKillFrenziesPassed; +} + +void CDarkel::ResetModelsKilledByPlayer() +{ + for (int i = 0; i < 200; i++) + RegisteredKills[i] = 0; +} + +#if 0 +WRAPPER void CDarkel::ResetOnPlayerDeath() { EAXJMP(0x420E70); } +#else +void CDarkel::ResetOnPlayerDeath() +{ + if (Status != KILLFRENZY_ONGOING) + return; + + CPopulation::m_AllRandomPedsThisType = -1; + Status = KILLFRENZY_FAILED; + TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds(); + + if (WeaponType == WEAPONTYPE_UZI_DRIVEBY) + WeaponType = WEAPONTYPE_UZI; + + if (WeaponType < WEAPONTYPE_TOTALWEAPONS) { + FindPlayerPed()->m_bWeaponSlot = 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); + } + + + CPopulation::m_AllRandomPedsThisType = -1; + Status = KILLFRENZY_FAILED; + TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds(); + + if (WeaponType == WEAPONTYPE_UZI_DRIVEBY) + WeaponType = WEAPONTYPE_UZI; + + if (WeaponType < WEAPONTYPE_TOTALWEAPONS) { + FindPlayerPed()->m_bWeaponSlot = 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); + } +} +#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); } +#else +void CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, int16 kill, int32 modelId0, wchar *text, int32 modelId2, int32 modelId3, int32 modelId4, bool standardSound, bool needHeadShot) +{ + if (weaponType == WEAPONTYPE_UZI_DRIVEBY) + weaponType = WEAPONTYPE_UZI; + + WeaponType = weaponType; + Status = KILLFRENZY_ONGOING; + KillsNeeded = kill; + ModelToKill = modelId0; + ModelToKill2 = modelId2; + ModelToKill3 = modelId3; + ModelToKill4 = modelId4; + pStartMessage = text; + + if (text == TheText.Get("PAGE_00")) { + CDarkel::bProperKillFrenzy = 1; + CDarkel::pStartMessage = 0; + } + else + bProperKillFrenzy = 0; + + bStandardSoundAndMessages = standardSound; + bNeedHeadShot = needHeadShot; + TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds(); + 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_bWeaponSlot = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_weapons[CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_currentWeapon].m_eWeaponType; + FindPlayerPed()->MakeChangesForNewWeapon(FindPlayerPed()->m_bWeaponSlot); + + 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(); + } + } + if (CDarkel::bStandardSoundAndMessages) + DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_START, 0); +} +#endif + +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; + + if (PrevTime != PreviousTime) { + if (PreviousTime < 12) + DMAudio.PlayFrontEndSound(SOUND_CLOCK_TICK, PrevTime); + PreviousTime = PrevTime; + } + + } + else { + CPopulation::m_AllRandomPedsThisType = -1; + Status = KILLFRENZY_FAILED; + TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds(); + + if (WeaponType == WEAPONTYPE_UZI_DRIVEBY) + WeaponType = WEAPONTYPE_UZI; + + if (WeaponType < WEAPONTYPE_TOTALWEAPONS) { + FindPlayerPed()->m_bWeaponSlot = 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); + } + + if (bStandardSoundAndMessages) + DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_FAILED, 0); + } + + if (KillsNeeded <= 0) { + CPopulation::m_AllRandomPedsThisType = -1; + Status = KILLFRENZY_PASSED; + + if (bProperKillFrenzy) + CStats::AnotherKillFrenzyPassed(); + + TimeOfFrenzyStart = CTimer::GetTimeInMilliseconds(); + + FindPlayerPed()->m_pWanted->SetWantedLevel(NOTWANTED); + + if (WeaponType == WEAPONTYPE_UZI_DRIVEBY) + WeaponType = WEAPONTYPE_UZI; + + if (WeaponType < WEAPONTYPE_TOTALWEAPONS) { + FindPlayerPed()->m_bWeaponSlot = 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); + } + + if (bStandardSoundAndMessages) + DMAudio.PlayFrontEndSound(SOUND_RAMPAGE_PASSED, 0); + } +} + +STARTPATCHES + /*InjectHook(0x421380, CDarkel::CalcFade, PATCH_JUMP); + InjectHook(0x420920, CDarkel::DrawMessages, PATCH_JUMP); + InjectHook(0x420E60, CDarkel::FrenzyOnGoing, PATCH_JUMP); + InjectHook(0x420650, CDarkel::Init, PATCH_JUMP); + InjectHook(0x421370, CDarkel::QueryModelsKilledByPlayer, 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);*/ +ENDPATCHES
\ No newline at end of file diff --git a/src/control/Darkel.h b/src/control/Darkel.h index ed78d4e1..da1df24a 100644 --- a/src/control/Darkel.h +++ b/src/control/Darkel.h @@ -1,11 +1,48 @@ #pragma once +#include "Weapon.h" + +enum eKillFrenzyStatus +{ + KILLFRENZY_NONE, + KILLFRENZY_ONGOING, + KILLFRENZY_PASSED, + KILLFRENZY_FAILED, +}; class CDarkel { private: - static bool Status; + static int32 &TimeLimit; + static int32 &PreviousTime; + static int32 &TimeOfFrenzyStart; + static int32 &WeaponType; + static int32 &AmmoInterruptedWeapon; + static int32 &KillsNeeded; + static int8 &InterruptedWeapon; + static int8 &bStandardSoundAndMessages; + static int8 &bNeedHeadShot; + static int8 &bProperKillFrenzy; + static eKillFrenzyStatus &Status; + static int16 *RegisteredKills; + static int32 &ModelToKill; + static int32 &ModelToKill2; + static int32 &ModelToKill3; + static int32 &ModelToKill4; + static wchar *pStartMessage; public: + static int32 CalcFade(uint32 time, int32 min, uint32 max); static void DrawMessages(void); static bool FrenzyOnGoing(); + static void Init(); + static int16 QueryModelsKilledByPlayer(int32 modelId); + static eKillFrenzyStatus ReadStatus(); + static int32 RegisterCarBlownUpByPlayer(eKillFrenzyStatus status); + static void RegisterKillByPlayer(int32 modelid, eWeaponType weapontype, bool flag); + static void RegisterKillNotByPlayer(); + 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 Update(); + }; |