#include "die.h" #include "gui.h" void SetZoneToIndexHook(AFortGameModeAthena* GameModeAthena, int OverridePhaseMaybeIDFK) { static auto ZoneDurationsOffset = Fortnite_Version >= 15 && Fortnite_Version < 18 ? 0x258 : std::floor(Fortnite_Version) >= 18 ? 0x248 : 0x1F8; // S13-S14 static auto GameMode_SafeZonePhaseOffset = GameModeAthena->GetOffset("SafeZonePhase"); auto GameState = Cast(GameModeAthena->GetGameState()); if (!GameState) return SetZoneToIndexOriginal(GameModeAthena, OverridePhaseMaybeIDFK); auto SafeZoneIndicator = GameModeAthena->GetSafeZoneIndicator(); static auto GameState_SafeZonePhaseOffset = GameState->GetOffset("SafeZonePhase"); static int NewLateGameSafeZonePhase = 2; LOG_INFO(LogDev, "NewLateGameSafeZonePhase: {}", NewLateGameSafeZonePhase); static bool bReversing = false; if (Fortnite_Version < 13) { if (Globals::bLateGame.load()) { GameModeAthena->Get(GameMode_SafeZonePhaseOffset) = NewLateGameSafeZonePhase; GameState->Get(GameState_SafeZonePhaseOffset) = NewLateGameSafeZonePhase; SetZoneToIndexOriginal(GameModeAthena, OverridePhaseMaybeIDFK); if (NewLateGameSafeZonePhase == EndReverseZonePhase) { bReversing = false; } if (NewLateGameSafeZonePhase == 2 || NewLateGameSafeZonePhase == 3) { if (SafeZoneIndicator) SafeZoneIndicator->SkipShrinkSafeZone(); else LOG_WARN(LogZone, "Invalid SafeZoneIndicator!"); } if (NewLateGameSafeZonePhase >= StartReverseZonePhase) // This means instead of going to the 8th phase its gonna go down. { bReversing = true; } if (bReversing && bEnableReverseZone) NewLateGameSafeZonePhase--; else NewLateGameSafeZonePhase++; return; } return SetZoneToIndexOriginal(GameModeAthena, OverridePhaseMaybeIDFK); } if (!SafeZoneIndicator) { LOG_WARN(LogZone, "Invalid SafeZoneIndicator!"); return SetZoneToIndexOriginal(GameModeAthena, OverridePhaseMaybeIDFK); } static auto SafeZoneFinishShrinkTimeOffset = SafeZoneIndicator->GetOffset("SafeZoneFinishShrinkTime"); static auto SafeZoneStartShrinkTimeOffset = SafeZoneIndicator->GetOffset("SafeZoneStartShrinkTime"); static auto RadiusOffset = SafeZoneIndicator->GetOffset("Radius"); static auto SafeZonePhaseOffset = GameModeAthena->GetOffset("SafeZonePhase"); static auto MapInfoOffset = GameState->GetOffset("MapInfo"); auto MapInfo = GameState->Get(MapInfoOffset); if (!MapInfo) { LOG_WARN(LogZone, "Invalid MapInfo!") return SetZoneToIndexOriginal(GameModeAthena, OverridePhaseMaybeIDFK); } static auto SafeZoneDefinitionOffset = MapInfo->GetOffset("SafeZoneDefinition"); auto SafeZoneDefinition = MapInfo->GetPtr<__int64>(SafeZoneDefinitionOffset); LOG_INFO(LogDev, "SafeZoneDefinitionOffset: 0x{:x}", SafeZoneDefinitionOffset); static auto ZoneHoldDurationsOffset = ZoneDurationsOffset - 0x10; // fr auto& ZoneDurations = *(TArray*)(__int64(SafeZoneDefinition) + ZoneDurationsOffset); auto& ZoneHoldDurations = *(TArray*)(__int64(SafeZoneDefinition) + ZoneHoldDurationsOffset); static bool bFilledDurations = false; if (!bFilledDurations) { bFilledDurations = true; auto CurrentPlaylist = GameState->GetCurrentPlaylist(); UCurveTable* FortGameData = nullptr; static auto GameDataOffset = CurrentPlaylist->GetOffset("GameData"); FortGameData = CurrentPlaylist ? CurrentPlaylist->Get>(GameDataOffset).Get() : nullptr; if (!FortGameData) FortGameData = FindObject(L"/Game/Balance/AthenaGameData.AthenaGameData"); auto ShrinkTimeFName = UKismetStringLibrary::Conv_StringToName(L"Default.SafeZone.ShrinkTime"); auto HoldTimeFName = UKismetStringLibrary::Conv_StringToName(L"Default.SafeZone.WaitTime"); for (int i = 0; i < ZoneDurations.Num(); i++) { ZoneDurations.at(i) = FortGameData->GetValueOfKey(FortGameData->GetKey(ShrinkTimeFName, i)); } for (int i = 0; i < ZoneHoldDurations.Num(); i++) { ZoneHoldDurations.at(i) = FortGameData->GetValueOfKey(FortGameData->GetKey(HoldTimeFName, i)); } } LOG_INFO(LogZone, "SafeZonePhase: {}", GameModeAthena->Get(SafeZonePhaseOffset)); LOG_INFO(LogZone, "OverridePhaseMaybeIDFK: {}", OverridePhaseMaybeIDFK); LOG_INFO(LogZone, "TimeSeconds: {}", UGameplayStatics::GetTimeSeconds(GetWorld())); if (Globals::bLateGame.load()) { GameModeAthena->Get(GameMode_SafeZonePhaseOffset) = NewLateGameSafeZonePhase; GameState->Get(GameState_SafeZonePhaseOffset) = NewLateGameSafeZonePhase; SetZoneToIndexOriginal(GameModeAthena, OverridePhaseMaybeIDFK); if (NewLateGameSafeZonePhase == EndReverseZonePhase) { bReversing = false; } if (NewLateGameSafeZonePhase >= StartReverseZonePhase) // This means instead of going to the 8th phase its gonna go down. { bReversing = true; } if (bReversing && bEnableReverseZone) NewLateGameSafeZonePhase--; else NewLateGameSafeZonePhase++; } else { SetZoneToIndexOriginal(GameModeAthena, OverridePhaseMaybeIDFK); } LOG_INFO(LogZone, "SafeZonePhase After: {}", GameModeAthena->Get(SafeZonePhaseOffset)); float ZoneHoldDuration = 0; if (GameModeAthena->Get(SafeZonePhaseOffset) >= 0 && GameModeAthena->Get(SafeZonePhaseOffset) < ZoneHoldDurations.Num()) ZoneHoldDuration = ZoneHoldDurations.at(GameModeAthena->Get(SafeZonePhaseOffset)); SafeZoneIndicator->Get(SafeZoneStartShrinkTimeOffset) = GameState->GetServerWorldTimeSeconds() + ZoneHoldDuration; float ZoneDuration = 0; if (GameModeAthena->Get(SafeZonePhaseOffset) >= 0 && GameModeAthena->Get(SafeZonePhaseOffset) < ZoneDurations.Num()) ZoneDuration = ZoneDurations.at(GameModeAthena->Get(SafeZonePhaseOffset)); LOG_INFO(LogZone, "ZoneDuration: {}", ZoneDuration); LOG_INFO(LogZone, "Duration: {}", SafeZoneIndicator->Get(RadiusOffset)); SafeZoneIndicator->Get(SafeZoneFinishShrinkTimeOffset) = SafeZoneIndicator->Get(SafeZoneStartShrinkTimeOffset) + ZoneDuration; if (NewLateGameSafeZonePhase == 3 || NewLateGameSafeZonePhase == 4) { if (SafeZoneIndicator) SafeZoneIndicator->SkipShrinkSafeZone(); else LOG_WARN(LogZone, "Invalid SafeZoneIndicator!"); } }