[III] add timecyc editor, fixes

This commit is contained in:
Grinch_ 2021-10-26 13:10:53 +06:00
parent 2a18a72b9e
commit 6ac842a607
4 changed files with 125 additions and 93 deletions

View File

@ -63,11 +63,11 @@ Teleport::Teleport()
if (pVeh && BY_GAME(player->m_nPedFlags.bInVehicle, player->m_pVehicle, player->m_pVehicle)) if (pVeh && BY_GAME(player->m_nPedFlags.bInVehicle, player->m_pVehicle, player->m_pVehicle))
{ {
BY_GAME(pVeh->Teleport(m_Teleport::m_fPos, false, false), pVeh->Teleport(m_Teleport::m_fPos)); BY_GAME(pVeh->Teleport(m_Teleport::m_fPos, false, false), pVeh->Teleport(m_Teleport::m_fPos), player->Teleport(m_Teleport::m_fPos));
} }
else else
{ {
BY_GAME(player->Teleport(m_Teleport::m_fPos, false, false), player->Teleport(m_Teleport::m_fPos)); BY_GAME(player->Teleport(m_Teleport::m_fPos, false, false), player->Teleport(m_Teleport::m_fPos), player->Teleport(m_Teleport::m_fPos));
} }
m_Teleport::m_bEnabled = false; m_Teleport::m_bEnabled = false;

View File

@ -132,54 +132,54 @@ uchar *m_nBlurBlue = (uchar *)0x945728;
#else // GTA3 #else // GTA3
uchar *m_nAmbientRed = (uchar *)0x86AF78; int *m_nAmbientRed = (int *)0x86AF78;
uchar *m_nAmbientGreen = (uchar *)0x665308; int *m_nAmbientGreen = (int *)0x665308;
uchar *m_nAmbientBlue = (uchar *)0x72CF88; int *m_nAmbientBlue = (int *)0x72CF88;
uchar *m_nDirRed = (uchar *)0x6FAB78; int *m_nDirRed = (int *)0x6FAB78;
uchar *m_nDirGreen = (uchar *)0x6F4528; int *m_nDirGreen = (int *)0x6F4528;
uchar *m_nDirBlue = (uchar *)0x83CE58; int *m_nDirBlue = (int *)0x83CE58;
uchar *m_nSkyTopRed = (uchar *)0x87FB90; int *m_nSkyTopRed = (int *)0x87FB90;
uchar *m_nSkyTopGreen = (uchar *)0x8460A8; int *m_nSkyTopGreen = (int *)0x8460A8;
uchar *m_nSkyTopBlue = (uchar *)0x87B158; int *m_nSkyTopBlue = (int *)0x87B158;
uchar *m_nSkyBottomRed = (uchar *)0x6FA960; int *m_nSkyBottomRed = (int *)0x6FA960;
uchar *m_nSkyBottomGreen = (uchar *)0x70D6A8; int *m_nSkyBottomGreen = (int *)0x70D6A8;
uchar *m_nSkyBottomBlue = (uchar *)0x83D288; int *m_nSkyBottomBlue = (int *)0x83D288;
uchar *m_nSunCoreRed = (uchar *)0x878360; int *m_nSunCoreRed = (int *)0x878360;
uchar *m_nSunCoreGreen = (uchar *)0x6EE088; int *m_nSunCoreGreen = (int *)0x6EE088;
uchar *m_nSunCoreBlue = (uchar *)0x773A68; int *m_nSunCoreBlue = (int *)0x773A68;
uchar *m_nSunCoronaRed = (uchar *)0x664B60; int *m_nSunCoronaRed = (int *)0x664B60;
uchar *m_nSunCoronaGreen = (uchar *)0x6F01E0; int *m_nSunCoronaGreen = (int *)0x6F01E0;
uchar *m_nSunCoronaBlue = (uchar *)0x6E6340; int *m_nSunCoronaBlue = (int *)0x6E6340;
uchar *m_nShadowStrength = (uchar *)0x83CFD8; short *m_nShadowStrength = (short *)0x83CFD8;
uchar *m_nLightShadowStrength = (uchar *)0x72B0F8; short *m_nLightShadowStrength = (short *)0x72B0F8;
uchar *m_nTreeShadowStrength = (uchar *)0x733450; short *m_nTreeShadowStrength = (short *)0x733450;
uchar *m_fSunSize = (uchar *)0x733510; float *m_fSunSize = (float *)0x733510;
uchar *m_fSpriteSize = (uchar *)0x87F820; float *m_fSpriteSize = (float *)0x87F820;
uchar *m_fSpriteBrightness = (uchar *)0x6E96F0; float *m_fSpriteBrightness = (float *)0x6E96F0;
short *m_fFarClip = (short *)0x8804E0; float *m_fFarClip = (float *)0x8804E0;
short *m_fFogStart = (short *)0x8806C8; float *m_fFogStart = (float *)0x8806C8;
uchar *m_fLightsOnGroundBrightness = (uchar *)0x83D108; float *m_fLightsOnGroundBrightness = (float *)0x83D108;
uchar *m_nLowCloudsRed = (uchar *)0x726770; int *m_nLowCloudsRed = (int *)0x726770;
uchar *m_nLowCloudsGreen = (uchar *)0x87BF08; int *m_nLowCloudsGreen = (int *)0x87BF08;
uchar *m_nLowCloudsBlue = (uchar *)0x87FA10; int *m_nLowCloudsBlue = (int *)0x87FA10;
uchar *m_nTopCloudsRed = (uchar *)0x70F2B0; int *m_nTopCloudsRed = (int *)0x70F2B0;
uchar *m_nTopCloudsGreen = (uchar *)0x72D288; int *m_nTopCloudsGreen = (int *)0x72D288;
uchar *m_nTopCloudsBlue = (uchar *)0x86B108; int *m_nTopCloudsBlue = (int *)0x86B108;
uchar *m_nBottomCloudsRed = (uchar *)0x6E8DA8; int *m_nBottomCloudsRed = (int *)0x6E8DA8;
uchar *m_nBottomCloudsGreen = (uchar *)0x715AA8; int *m_nBottomCloudsGreen = (int *)0x715AA8;
uchar *m_nBottomCloudsBlue = (uchar *)0x6EE2D0; int *m_nBottomCloudsBlue = (int *)0x6EE2D0;
uchar *m_fWaterRed = (uchar *)0x87C7E0; float *m_fPostFxRed = (float *)0x87C7E0;
uchar *m_fWaterGreen = (uchar *)0x774C10; float *m_fPostFxGreen = (float *)0x774C10;
uchar *m_fWaterBlue = (uchar *)0x8784E0; float *m_fPostFxBlue = (float *)0x8784E0;
uchar *m_fWaterAlpha = (uchar *)0x733690; float *m_fPostFxAlpha = (float *)0x733690;
#endif #endif

View File

@ -98,7 +98,7 @@ void Visual::GenerateTimecycFile()
if (j == 7) buffer = "// 10 PM\n"; if (j == 7) buffer = "// 10 PM\n";
} }
int val = 23 * j + i; int val = TOTAL_WEATHERS * j + i;
buffer += std::format("{} {} {}\t{} {} {}\t255 255 255\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {} {}\t{} {} {} {}\t{} {} {} {}\t{} {} {} {}", buffer += std::format("{} {} {}\t{} {} {}\t255 255 255\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {} {}\t{} {} {} {}\t{} {} {} {}\t{} {} {} {}",
GetTCVal(m_nAmbientRed, val), GetTCVal(m_nAmbientGreen, val), GetTCVal(m_nAmbientBlue, val), GetTCVal(m_nAmbientRed, val), GetTCVal(m_nAmbientGreen, val), GetTCVal(m_nAmbientBlue, val),
@ -120,7 +120,7 @@ void Visual::GenerateTimecycFile()
file << buffer << std::endl; file << buffer << std::endl;
} }
} }
#elif GTAVC #else // GTA3 & GTAVC
std::ofstream file = std::ofstream("timecyc.dat"); std::ofstream file = std::ofstream("timecyc.dat");
for (uint i = 0; i < 4; ++i) for (uint i = 0; i < 4; ++i)
@ -141,8 +141,11 @@ void Visual::GenerateTimecycFile()
buffer = "\n// FOGGY\n"; buffer = "\n// FOGGY\n";
} }
#ifdef GTA3
buffer += "// Amb Dir Sky top Sky bot SunCore SunCorona SunSz SprSz SprBght Shdw LightShd TreeShd FarClp FogSt LightOnGround LowCloudsRGB TopCloudRGB BottomCloudRGB PostFx";
#else // GTAVC
buffer += "// Amb Amb_Obj Amb_bl Amb_Obj_bl Dir Sky top Sky bot SunCore SunCorona SunSz SprSz SprBght Shdw LightShd PoleShd FarClp FogSt LightOnGround LowCloudsRGB TopCloudRGB BottomCloudRGB BlurRGB WaterRGBA"; buffer += "// Amb Amb_Obj Amb_bl Amb_Obj_bl Dir Sky top Sky bot SunCore SunCorona SunSz SprSz SprBght Shdw LightShd PoleShd FarClp FogSt LightOnGround LowCloudsRGB TopCloudRGB BottomCloudRGB BlurRGB WaterRGBA";
#endif
file << buffer << std::endl; file << buffer << std::endl;
for (size_t j = 0; j < 24; ++j) for (size_t j = 0; j < 24; ++j)
@ -157,8 +160,25 @@ void Visual::GenerateTimecycFile()
buffer += "PM\n"; buffer += "PM\n";
} }
size_t val = 7 * i + j; size_t val = TOTAL_WEATHERS * i + j;
#ifdef GTA3
buffer += std::format("{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {} {}",
GetTCVal(m_nAmbientRed, val), GetTCVal(m_nAmbientGreen, val), GetTCVal(m_nAmbientBlue, val),
GetTCVal(m_nDirRed, val), GetTCVal(m_nDirGreen, val), GetTCVal(m_nDirBlue, val),
GetTCVal(m_nSkyTopRed, val), GetTCVal(m_nSkyTopGreen, val), GetTCVal(m_nSkyTopBlue, val),
GetTCVal(m_nSkyBottomRed, val), GetTCVal(m_nSkyBottomGreen, val), GetTCVal(m_nSkyBottomBlue, val),
GetTCVal(m_nSunCoreRed, val), GetTCVal(m_nSunCoreGreen, val), GetTCVal(m_nSunCoreBlue, val),
GetTCVal(m_nSunCoronaRed, val), GetTCVal(m_nSunCoronaGreen, val), GetTCVal(m_nSunCoronaBlue, val),
GetTCVal(m_fSunSize, val), GetTCVal(m_fSpriteSize, val), GetTCVal(m_fSpriteBrightness, val),
GetTCVal(m_nShadowStrength, val), GetTCVal(m_nLightShadowStrength, val), GetTCVal(m_nTreeShadowStrength, val),
GetTCVal(m_fFarClip, val), GetTCVal(m_fFogStart, val), GetTCVal(m_fLightsOnGroundBrightness, val),
GetTCVal(m_nLowCloudsRed, val), GetTCVal(m_nLowCloudsGreen, val), GetTCVal(m_nLowCloudsBlue, val),
GetTCVal(m_nTopCloudsRed, val), GetTCVal(m_nTopCloudsGreen, val), GetTCVal(m_nTopCloudsBlue, val),
GetTCVal(m_nBottomCloudsRed, val), GetTCVal(m_nBottomCloudsGreen, val), GetTCVal(m_nBottomCloudsBlue, val),
GetTCVal(m_fPostFxRed, val), GetTCVal(m_fPostFxGreen, val), GetTCVal(m_fPostFxBlue, val), GetTCVal(m_fPostFxAlpha, val)
);
#elif GTAVC
buffer += std::format("{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {} {}", buffer += std::format("{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {}\t{} {} {} {}",
GetTCVal(m_nAmbientRed, val), GetTCVal(m_nAmbientGreen, val), GetTCVal(m_nAmbientBlue, val), GetTCVal(m_nAmbientRed, val), GetTCVal(m_nAmbientGreen, val), GetTCVal(m_nAmbientBlue, val),
GetTCVal(m_nAmbientRed_Obj, val), GetTCVal(m_nAmbientGreen_Obj, val), GetTCVal(m_nAmbientBlue_Obj, val), GetTCVal(m_nAmbientRed_Obj, val), GetTCVal(m_nAmbientGreen_Obj, val), GetTCVal(m_nAmbientBlue_Obj, val),
@ -178,6 +198,7 @@ void Visual::GenerateTimecycFile()
GetTCVal(m_nBlurRed, val), GetTCVal(m_nBlurGreen, val), GetTCVal(m_nBlurBlue, val), GetTCVal(m_nBlurRed, val), GetTCVal(m_nBlurGreen, val), GetTCVal(m_nBlurBlue, val),
GetTCVal(m_fWaterRed, val), GetTCVal(m_fWaterGreen, val), GetTCVal(m_fWaterBlue, val), GetTCVal(m_fWaterAlpha, val) GetTCVal(m_fWaterRed, val), GetTCVal(m_fWaterGreen, val), GetTCVal(m_fWaterBlue, val), GetTCVal(m_fWaterAlpha, val)
); );
#endif
file << buffer << std::endl; file << buffer << std::endl;
} }
} }
@ -217,19 +238,21 @@ int Visual::CalcArrayIndex()
return TOTAL_WEATHERS * hour + CWeather::OldWeatherType; return TOTAL_WEATHERS * hour + CWeather::OldWeatherType;
} }
bool Visual::TimeCycColorEdit3(const char* label, uchar* r, uchar* g, uchar* b, ImGuiColorEditFlags flags)
template<typename T>
bool Visual::TimeCycColorEdit3(const char* label, T* r, T* g, T* b, ImGuiColorEditFlags flags)
{ {
bool rtn = false; bool rtn = false;
int val = CalcArrayIndex(); int val = CalcArrayIndex();
#ifdef GTASA #ifdef GTASA
auto red = static_cast<uchar*>(patch::GetPointer(int(r))); auto red = static_cast<T*>(patch::GetPointer(int(r)));
auto green = static_cast<uchar*>(patch::GetPointer(int(g))); auto green = static_cast<T*>(patch::GetPointer(int(g)));
auto blue = static_cast<uchar*>(patch::GetPointer(int(b))); auto blue = static_cast<T*>(patch::GetPointer(int(b)));
#else // GTA3 & GTAVC #else // GTA3 & GTAVC
auto red = static_cast<uchar*>(r); auto red = static_cast<T*>(r);
auto green = static_cast<uchar*>(g); auto green = static_cast<T*>(g);
auto blue = static_cast<uchar*>(b); auto blue = static_cast<T*>(b);
#endif #endif
float col[3]{ red[val] / 255.0f, green[val] / 255.0f, blue[val] / 255.0f }; float col[3]{ red[val] / 255.0f, green[val] / 255.0f, blue[val] / 255.0f };
@ -245,21 +268,38 @@ bool Visual::TimeCycColorEdit3(const char* label, uchar* r, uchar* g, uchar* b,
return rtn; return rtn;
} }
bool Visual::TimeCycColorEdit4(const char* label, uchar* r, uchar* g, uchar* b, uchar* a, ImGuiColorEditFlags flags) template <typename T>
void Visual::TimecycSlider(const char* label, T* ptr, int min, int max)
{
int val = CalcArrayIndex();
#ifdef GTASA
// Compatable with 24h TimeCyc
T* arr = static_cast<T*>(patch::GetPointer(int(ptr)));
#else // GTA3 & GTAVC
T* arr = static_cast<T*>(ptr);
#endif
int a = arr[val];
if (ImGui::SliderInt(label, &a, min, max))
arr[val] = static_cast<T>(a);
}
template <typename T>
bool Visual::TimeCycColorEdit4(const char* label, T* r, T* g, T* b, T* a, ImGuiColorEditFlags flags)
{ {
bool rtn = false; bool rtn = false;
int val = CalcArrayIndex(); int val = CalcArrayIndex();
#ifdef GTASA #ifdef GTASA
auto red = static_cast<uchar*>(patch::GetPointer(int(r))); auto red = static_cast<T*>(patch::GetPointer(int(r)));
auto green = static_cast<uchar*>(patch::GetPointer(int(g))); auto green = static_cast<T*>(patch::GetPointer(int(g)));
auto blue = static_cast<uchar*>(patch::GetPointer(int(b))); auto blue = static_cast<T*>(patch::GetPointer(int(b)));
auto alpha = static_cast<uchar*>(patch::GetPointer(int(a))); auto alpha = static_cast<T*>(patch::GetPointer(int(a)));
#else // GTA3 & GTAVC #else // GTA3 & GTAVC
auto red = static_cast<uchar*>(r); auto red = static_cast<T*>(r);
auto green = static_cast<uchar*>(g); auto green = static_cast<T*>(g);
auto blue = static_cast<uchar*>(b); auto blue = static_cast<T*>(b);
auto alpha = static_cast<uchar*>(a); auto alpha = static_cast<T*>(a);
#endif #endif
float col[4]{ red[val] / 255.0f, green[val] / 255.0f, blue[val] / 255.0f, alpha[val] / 255.0f }; float col[4]{ red[val] / 255.0f, green[val] / 255.0f, blue[val] / 255.0f, alpha[val] / 255.0f };
@ -378,11 +418,10 @@ void Visual::Draw()
Ui::CheckboxAddress("Green scanlines", 0xA10B69); Ui::CheckboxAddress("Green scanlines", 0xA10B69);
Ui::CheckboxAddress("White scanlines", 0xA10B68); Ui::CheckboxAddress("White scanlines", 0xA10B68);
#else // GTA3 #else // GTA3
Ui::CheckboxWithHint("Lock weather", &m_bLockWeather); static bool hideHud, hideRadar;
static bool showHud, showRadar; if (Ui::CheckboxWithHint("Hide hud", &hideHud))
if (Ui::CheckboxWithHint("Show hud", &showHud))
{ {
if (showHud) if (hideHud)
{ {
patch::Nop(0x48E420, 5); // CHud::Draw patch::Nop(0x48E420, 5); // CHud::Draw
} }
@ -391,9 +430,9 @@ void Visual::Draw()
patch::SetRaw(0x48E420, (char*)"\xE8\x7B\x6E\x07\x00", 5); patch::SetRaw(0x48E420, (char*)"\xE8\x7B\x6E\x07\x00", 5);
} }
} }
if (Ui::CheckboxWithHint("Show radar", &showRadar)) if (Ui::CheckboxWithHint("Hide radar", &hideRadar))
{ {
if (showHud) if (hideHud)
{ {
patch::Nop(0x50838D, 5); // CRadar::Draw patch::Nop(0x50838D, 5); // CRadar::Draw
} }
@ -402,6 +441,7 @@ void Visual::Draw()
patch::SetRaw(0x50838D, (char*)"\xE8\x6E\xBE\xF9\xFF", 5); patch::SetRaw(0x50838D, (char*)"\xE8\x6E\xBE\xF9\xFF", 5);
} }
} }
Ui::CheckboxWithHint("Lock weather", &m_bLockWeather);
#endif #endif
ImGui::Columns(1); ImGui::Columns(1);
ImGui::EndTabItem(); ImGui::EndTabItem();
@ -566,7 +606,10 @@ void Visual::Draw()
int hour = CClock::ms_nGameClockHours; int hour = CClock::ms_nGameClockHours;
int minute = CClock::ms_nGameClockMinutes; int minute = CClock::ms_nGameClockMinutes;
ImGui::BeginDisabled(Game::m_bSyncTime); if (Game::m_bSyncTime)
{
ImGui::BeginDisabled(Game::m_bSyncTime);
}
if (ImGui::InputInt("Hour", &hour) & !Game::m_bSyncTime) if (ImGui::InputInt("Hour", &hour) & !Game::m_bSyncTime)
{ {
@ -631,8 +674,10 @@ void Visual::Draw()
#endif #endif
#ifdef GTASA #ifdef GTASA
TimeCycColorEdit4("Postfx 1", m_fPostFx1Red, m_fPostFx1Green, m_fPostFx1Blue, m_fPostFx1Alpha); TimeCycColorEdit4("PostFx 1", m_fPostFx1Red, m_fPostFx1Green, m_fPostFx1Blue, m_fPostFx1Alpha);
TimeCycColorEdit4("Postfx 2", m_fPostFx2Red, m_fPostFx2Green, m_fPostFx2Blue, m_fPostFx1Alpha); TimeCycColorEdit4("PostFx 2", m_fPostFx2Red, m_fPostFx2Green, m_fPostFx2Blue, m_fPostFx1Alpha);
#elif GTA3
TimeCycColorEdit4("PostFx", m_fPostFxRed, m_fPostFxGreen, m_fPostFxBlue, m_fPostFxAlpha);
#endif #endif
TimeCycColorEdit3("Sky bottom", m_nSkyBottomRed, m_nSkyBottomGreen, m_nSkyBottomBlue); TimeCycColorEdit3("Sky bottom", m_nSkyBottomRed, m_nSkyBottomGreen, m_nSkyBottomBlue);
@ -640,8 +685,9 @@ void Visual::Draw()
TimeCycColorEdit3("Sun corona", m_nSunCoronaRed, m_nSunCoronaGreen, m_nSunCoronaBlue); TimeCycColorEdit3("Sun corona", m_nSunCoronaRed, m_nSunCoronaGreen, m_nSunCoronaBlue);
TimeCycColorEdit3("Sky top", m_nSkyTopRed, m_nSkyTopGreen, m_nSkyTopBlue); TimeCycColorEdit3("Sky top", m_nSkyTopRed, m_nSkyTopGreen, m_nSkyTopBlue);
#ifndef GTA3
TimeCycColorEdit4("Water", m_fWaterRed, m_fWaterGreen, m_fWaterBlue, m_fWaterAlpha); TimeCycColorEdit4("Water", m_fWaterRed, m_fWaterGreen, m_fWaterBlue, m_fWaterAlpha);
#endif
ImGui::EndChild(); ImGui::EndChild();
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
@ -654,8 +700,8 @@ void Visual::Draw()
TimecycSlider("Cloud alpha", m_fCloudAlpha, 0, 255); TimecycSlider("Cloud alpha", m_fCloudAlpha, 0, 255);
TimecycSlider("Directional mult", m_nDirectionalMult, 0, 255); TimecycSlider("Directional mult", m_nDirectionalMult, 0, 255);
#endif #endif
TimecycSlider("Far clip", m_fFarClip, 0, 2000); TimecycSlider("Far clip", m_fFarClip, 0, 5000);
TimecycSlider("Fog start", m_fFogStart, 0, 1500); TimecycSlider("Fog start", m_fFogStart, 0, 5000);
#ifdef GTASA #ifdef GTASA
TimecycSlider("High light min intensity", m_nHighLightMinIntensity, 0, 255); TimecycSlider("High light min intensity", m_nHighLightMinIntensity, 0, 255);
#endif #endif

View File

@ -25,27 +25,13 @@ private:
static void GenerateTimecycFile(); static void GenerateTimecycFile();
static int CalcArrayIndex(); static int CalcArrayIndex();
static bool TimeCycColorEdit3(const char* label, uchar* r, uchar* g, uchar* b, ImGuiColorEditFlags flags = 0); template<typename T>
static bool TimeCycColorEdit4(const char* label, uchar* r, uchar* g, uchar* b, uchar* a, ImGuiColorEditFlags flags = 0); static bool TimeCycColorEdit3(const char* label, T* r, T* g, T* b, ImGuiColorEditFlags flags = 0);
template <typename T>
static bool TimeCycColorEdit4(const char* label, T* r, T* g, T* b, T* a, ImGuiColorEditFlags flags = 0);
template <typename T> template <typename T>
static void TimecycSlider(const char* label, T* data, int min, int max); static void TimecycSlider(const char* label, T* data, int min, int max);
public: public:
Visual(); Visual();
static void Draw(); static void Draw();
}; };
template <typename T>
void Visual::TimecycSlider(const char* label, T* ptr, int min, int max)
{
int val = CalcArrayIndex();
#ifdef GTASA
// Compatable with 24h TimeCyc
T* arr = static_cast<T*>(patch::GetPointer(int(ptr)));
#else // GTA3 & GTAVC
T* arr = static_cast<T*>(ptr);
#endif
int a = arr[val];
if (ImGui::SliderInt(label, &a, min, max))
arr[val] = static_cast<T>(a);
}