Add new car, ped & weapon directly from the menu

This commit is contained in:
Grinch_ 2022-08-04 02:15:42 +06:00
parent 7b66de03c3
commit 4b9ab8890c
17 changed files with 450 additions and 236 deletions

View File

@ -1,93 +1,91 @@
############################################################################## [Explosion]
# Particle Names 'Barrel explosion' = 'explosion_barrel'
# Example, 'Crate explosion' = 'explosion_crate'
# [Category Name] 'Door explosion' = 'explosion_door'
# particle_name = "" 'Fuel car explosion' = 'explosion_fuel_car'
############################################################################## 'Large explosion' = 'explosion_large'
'Medium explosion' = 'explosion_medium'
'Molotov explosion' = 'explosion_molotov'
'Small explosion' = 'explosion_small'
'Tiny explosion' = 'explosion_tiny'
[Custom] [Fire]
Extinguisher = 'extinguisher'
Fire = 'fire'
'Fire bike' = 'fire_bike'
'Fire car' = 'fire_car'
'Fire large' = 'fire_large'
'Fire med' = 'fire_med'
Flame = 'flame'
Flamethrower = 'flamethrower'
'Molotov flame' = 'molotov_flame'
'Prt spark' = 'prt_spark'
'Prt spark2' = 'prt_spark2'
[Main] [Smoke]
prt_blood = "" 'Cigarette smoke' = 'cigarette_smoke'
prt_boatsplash = "" 'Collision smoke' = 'prt_collisionsmoke'
prt_bubbles = "" 'Factory smoke' = 'ws_factorysmoke'
prt_cardebris = "" Gunsmoke = 'gunsmoke'
prt_collisionsmoke = "" 'Riot smoke' = 'riot_smoke'
prt_glass = "" 'Smoke 1' = 'smoke30lit'
prt_gunshell = "" 'Smoke 2' = 'smoke30m'
prt_sand = "" 'Smoke 3' = 'smoke50lit'
prt_sand2 = "" 'Smoke 4' = 'prt_smokeII_3_expand'
prt_smokeII_3_expand = "" 'Smoke huge' = 'prt_smoke_huge'
prt_smoke_huge = "" 'Smoke flare' = 'smoke_flare'
prt_spark = ""
prt_spark2 = ""
prt_splash = ""
prt_wake = ""
prt_watersplash = ""
prt_wheeldirt = ""
boat_prop = ""
camflash = ""
exhale = ""
explosion_fuel_car = ""
explosion_large = ""
explosion_medium = ""
explosion_molotov = ""
explosion_small = ""
explosion_tiny = ""
extinguisher = ""
fire = ""
fire_bike = ""
fire_car = ""
fire_large = ""
fire_med = ""
flamethrower = ""
gunflash = ""
gunsmoke = ""
heli_dust = ""
jetpack = ""
jetthrust = ""
molotov_flame = ""
nitro = ""
overheat_car = ""
overheat_car_electric = ""
riot_smoke = ""
spraycan = ""
tank_fire = ""
teargas = ""
teargasAD = ""
water_hydrant = ""
water_ripples = ""
water_speed = ""
water_splash = ""
water_splsh_big = ""
water_splsh_sml = ""
water_swim = ""
cigarette_smoke = ""
flame = ""
insects = ""
smoke30lit = ""
smoke30m = ""
smoke50lit = ""
vent = ""
vent2 = ""
waterfall_end = ""
water_fnt_tme = ""
water_fountain = ""
tree_hit_fir = ""
tree_hit_palm = ""
blood_heli = ""
carwashspray = ""
cement = ""
cloudfast = ""
coke_puff = ""
coke_trail = ""
explosion_barrel = ""
explosion_crate = ""
explosion_door = ""
petrolcan = ""
puke = ""
shootlight = ""
smoke_flare = ""
wallbust = ""
ws_factorysmoke = ""
[Water]
'Prt boatsplash' = 'prt_boatsplash'
'Prt splash' = 'prt_splash'
'Prt watersplash' = 'prt_watersplash'
'Water big splsh' = 'water_splsh_big'
'Water fnt tme' = 'water_fnt_tme'
'Water fountain' = 'water_fountain'
'Water hydrant' = 'water_hydrant'
'Water ripples' = 'water_ripples'
'Water sml splsh' = 'water_splsh_sml'
'Water speed' = 'water_speed'
'Water splash' = 'water_splash'
'Water swim' = 'water_swim'
'Waterfall end' = 'waterfall_end'
[Misc]
'Blood heli' = 'blood_heli'
'Boat prop' = 'boat_prop'
Camflash = 'camflash'
'Carwash spray' = 'carwashspray'
Cement = 'cement'
Cloudfast = 'cloudfast'
'Coke puff' = 'coke_puff'
'Coke trail' = 'coke_trail'
Exhale = 'exhale'
Gunflash = 'gunflash'
'Heli dust' = 'heli_dust'
Insects = 'insects'
Jetpack = 'jetpack'
Jetthrust = 'jetthrust'
Nitro = 'nitro'
'Overheat car' = 'overheat_car'
'Overheat electric car' = 'overheat_car_electric'
Petrolcan = 'petrolcan'
'Prt blood' = 'prt_blood'
'Prt bubbles' = 'prt_bubbles'
'Prt cardebris' = 'prt_cardebris'
'Prt glass' = 'prt_glass'
'Prt gunshell' = 'prt_gunshell'
'Prt sand' = 'prt_sand'
'Prt sand2' = 'prt_sand2'
'Prt wake' = 'prt_wake'
'Prt wheeldirt' = 'prt_wheeldirt'
Puke = 'puke'
Shootlight = 'shootlight'
Spraycan = 'spraycan'
'Tank fire' = 'tank_fire'
Teargas = 'teargas'
Teargasad = 'teargasAD'
'Tree hit fir' = 'tree_hit_fir'
'Tree hit palm' = 'tree_hit_palm'
Vent = 'vent'
Vent2 = 'vent2'
Wallbust = 'wallbust'

View File

@ -5,9 +5,6 @@
###################################################################### ######################################################################
[Animation] [Animation]
AddAnimation = "Add animation"
AddParticle = "Add particle"
AnimationRemoved = "Animation removed"
AnimationTab = "Animation##TABBAR" AnimationTab = "Animation##TABBAR"
AnimName = "Anim name" AnimName = "Anim name"
CustomAnimsOnly = "You can only remove custom animations" CustomAnimsOnly = "You can only remove custom animations"
@ -22,6 +19,8 @@ LoopCheckbox = "Loop"
LoopCheckboxText = "Keep playing the animation on repeat" LoopCheckboxText = "Keep playing the animation on repeat"
NoTarget = "No player target found. Aim a ped with a weapon to select it for animation player." NoTarget = "No player target found. Aim a ped with a weapon to select it for animation player."
ParticleName = "Particle name" ParticleName = "Particle name"
ParticleID = "Particle id"
ParticleAdded = "Particle added"
ParticleRemoved = "Particle removed" ParticleRemoved = "Particle removed"
ParticleTab = "Particle##TABBAR" ParticleTab = "Particle##TABBAR"
PedAnim = "Ped anim" PedAnim = "Ped anim"
@ -260,6 +259,8 @@ WelcomeMSG = "Welcome to Cheat Menu"
[Ped] [Ped]
Accuracy = "Accuracy" Accuracy = "Accuracy"
AddPed = "Add ped"
AddPedMSG = "Ped added"
BigHead = "Big head effect" BigHead = "Big head effect"
ConfigTab = "Config" ConfigTab = "Config"
DownloadExGangWars = "Download ExGangWars" DownloadExGangWars = "Download ExGangWars"
@ -272,8 +273,10 @@ GangsControl = "Gangs control streets"
GangsEverywhere = "Gangs everywhere" GangsEverywhere = "Gangs everywhere"
Gangs = "Gangs" Gangs = "Gangs"
GangWars = "Gang wars" GangWars = "Gang wars"
GetPlayerModel = "Insert player model"
Health = "Health" Health = "Health"
MaxLimit = "Max limit reached" MaxLimit = "Max limit reached"
Model = "Model"
NastyLimbs = "Nasty limbs" NastyLimbs = "Nasty limbs"
NoMove = "Don't move" NoMove = "Don't move"
NoProstitutes = "No prostitutes" NoProstitutes = "No prostitutes"
@ -403,9 +406,7 @@ Walking = "Walking"
Wasted = "Wasted!" Wasted = "Wasted!"
[Teleport] [Teleport]
AddLocation = "Add location"
Coordinates = "Coordinates" Coordinates = "Coordinates"
CustomLocationRemoveOnly = "You can only remove custom location"
CustomMapSize = "Custom map size" CustomMapSize = "Custom map size"
CustomMapSizeHint = "Custom game map size for quick teleport. Only needed for Total Conversion mods (SAxVCxLC)" CustomMapSizeHint = "Custom game map size for quick teleport. Only needed for Total Conversion mods (SAxVCxLC)"
Height = "Height" Height = "Height"
@ -434,6 +435,7 @@ NotFound = "No update found"
[Vehicle] [Vehicle]
Abs = "Abs" Abs = "Abs"
ADM = "Anti dive multiplier" ADM = "Anti dive multiplier"
AddVehicle = "Add vehicle"
AggroDriver = "Aggressive driver" AggroDriver = "Aggressive driver"
AimDrive = "Aim while driving" AimDrive = "Aim while driving"
All = "All" All = "All"
@ -502,6 +504,7 @@ ForCurVeh = "For current vehicle,"
FourWheelDrive = "Four wheel drive" FourWheelDrive = "Four wheel drive"
FrontLights = "Front lights" FrontLights = "Front lights"
FrontWheelDrive = "Front wheel drive" FrontWheelDrive = "Front wheel drive"
GetCurrentVehInfo = "Current vehicle info"
GreenLights = "Green traffic lights" GreenLights = "Green traffic lights"
HandlingFlags = "Handling flags" HandlingFlags = "Handling flags"
HandlingTab = "Handling" HandlingTab = "Handling"
@ -511,12 +514,11 @@ HSTargetTip = "Heat Seaker missile can target this"
IDSpawnText = "Spawn with ID (Enter)" IDSpawnText = "Spawn with ID (Enter)"
InfNitro = "Unlimited nitro" InfNitro = "Unlimited nitro"
InfNitroTip = """ InfNitroTip = """
Nitro will activate when left clicked Enabling this would disable,
Enabling this would disable
All cars have nitro All cars have nitro
All taxis have nitro""" All taxis have nitro
(Activate nitro with left click)"""
InstantStop = "Instant stop" InstantStop = "Instant stop"
InvalidID = "Invalid model ID" InvalidID = "Invalid model ID"
InvisCar = "Invisible car" InvisCar = "Invisible car"
@ -531,14 +533,16 @@ Mass = "Mass"
MatFilter = "Material filter" MatFilter = "Material filter"
MaxVelocity = "Max velocity" MaxVelocity = "Max velocity"
MeleeProof = "Melee proof" MeleeProof = "Melee proof"
Model = "Model"
ModelFlags = "Model flags" ModelFlags = "Model flags"
MonValue = "Monetary value" MonValue = "Monetary value"
LockTrainCam = "Lock train cam" LockTrainCam = "Lock train cam"
NeonsTab = "Neons" NeonsTab = "Neons"
NoColl = "Disable collisions" NoColl = "Disable collisions"
NoDerail = "No train derail"
NotInVehicle = "Not inside vehicle!"
NoNearVeh = "No nearby vehicles!" NoNearVeh = "No nearby vehicles!"
NoParticles = "Disable particles" NoParticles = "Disable particles"
NoDerail = "No train derail"
NumGears = "Number of gears" NumGears = "Number of gears"
Off = "Off" Off = "Off"
On = "On" On = "On"
@ -783,13 +787,27 @@ Weapon3 = "Weapon 3"
WeaponTweaksText = """ WeaponTweaksText = """
Weapon tweaks apply globally Weapon tweaks apply globally
to every ped weapon type""" to every ped weapon type"""
WeaponType = "Weapon type"
[Window] [Window]
AddEntry = "Add entry"
AddEntryMSG = "Entry added"
AddNew = "Add new" AddNew = "Add new"
AddNewCustomImg = "How to add custom images for entries?"
AddNewTip = "Providing wrong values might crash your game"
AddNewTip2 = """
Custom entry images can be added inside texture file.
1. Open up the 'CheatMenuSA/{}.txd' file using Magic.TXD program.
2. Add your images to that file (Follow aspect ratio & naming format)
3. Save & try in game
"""
AnimationPage = "Animation" AnimationPage = "Animation"
CheckboxTab = "Checkboxes" CheckboxTab = "Checkboxes"
CopiedToClipboard = "Copied to clipboard" CopiedToClipboard = "Copied to clipboard"
CustomRemoveOnly = "You can only remove added entries"
Default = "Def" Default = "Def"
DownloadMagicTxd = "Download Magic.TXD"
Enabled = "Enabled" Enabled = "Enabled"
GamePage = "Game" GamePage = "Game"
Info = "Info" Info = "Info"

View File

@ -55,7 +55,7 @@ void Cutscene::Play(std::string& rootKey, std::string& cutsceneId, std::string&
} }
} }
void Particle::Play(std::string& rootKey, std::string& particle, std::string& dummy) void Particle::Play(std::string& cat, std::string& name, std::string& particle)
{ {
CPlayerPed* pPlayer = FindPlayerPed(); CPlayerPed* pPlayer = FindPlayerPed();
if (pPlayer) if (pPlayer)
@ -69,9 +69,9 @@ void Particle::Play(std::string& rootKey, std::string& particle, std::string& du
} }
void Particle::Remove(std::string& ifp, std::string& particle, std::string& dummy) void Particle::Remove(std::string& cat, std::string& name, std::string& particle)
{ {
if (ifp == "Custom") if (cat == "Custom")
{ {
Particle::m_Data.m_pData->RemoveKey("Custom", particle.c_str()); Particle::m_Data.m_pData->RemoveKey("Custom", particle.c_str());
Particle::m_Data.m_pData->Save(); Particle::m_Data.m_pData->Save();
@ -340,27 +340,27 @@ void Animation::ShowPage()
} }
else else
{ {
if (ImGui::CollapsingHeader(TEXT("Window.AddNew")))
{
static char animBuf[INPUT_BUFFER_SIZE];
static char ifpBuf[INPUT_BUFFER_SIZE];
ImGui::InputTextWithHint(TEXT("Animation.IFPName"), "ped", ifpBuf, INPUT_BUFFER_SIZE);
ImGui::InputTextWithHint(TEXT("Animation.AnimName"), "cower", animBuf, INPUT_BUFFER_SIZE);
ImGui::Spacing();
if (ImGui::Button(TEXT("Animation.AddAnimation"), Widget::CalcSize()))
{
std::string key = std::string("Custom.") + animBuf;
m_AnimData.m_pData->Set(key.c_str(), std::string(ifpBuf));
m_AnimData.m_pData->Save();
}
}
ImGui::Spacing(); ImGui::Spacing();
if (ImGui::BeginChild("Anims Child")) if (ImGui::BeginChild("Anims Child"))
{ {
ImGui::Spacing(); ImGui::Spacing();
Widget::DataList(m_AnimData, Play, Remove); Widget::DataList(m_AnimData, Play, Remove,
[](){
static char animBuf[INPUT_BUFFER_SIZE];
static char ifpBuf[INPUT_BUFFER_SIZE];
ImGui::InputTextWithHint(TEXT("Animation.IFPName"), "ped", ifpBuf, INPUT_BUFFER_SIZE);
ImGui::InputTextWithHint(TEXT("Animation.AnimName"), "cower", animBuf, INPUT_BUFFER_SIZE);
ImGui::Spacing();
if (ImGui::Button(TEXT("Window.AddEntry"), Widget::CalcSize()))
{
std::string key = std::string("Custom.") + animBuf;
m_AnimData.m_pData->Set(key.c_str(), std::string(ifpBuf));
m_AnimData.m_pData->Save();
Util::SetMessage("Window.AddEntryMSG");
}
});
ImGui::EndChild(); ImGui::EndChild();
} }
} }
@ -474,23 +474,24 @@ void Animation::ShowPage()
pPlayer->m_nPedFlags.bDontRender = (pPlayer->m_nPedFlags.bDontRender == 1) ? 0 : 1; pPlayer->m_nPedFlags.bDontRender = (pPlayer->m_nPedFlags.bDontRender == 1) ? 0 : 1;
} }
ImGui::Spacing(); ImGui::Spacing();
if (ImGui::CollapsingHeader(TEXT("Window.AddNew")))
{
static char buf[INPUT_BUFFER_SIZE];
ImGui::InputTextWithHint(TEXT("Animation.ParticleName"), "kkjj_on_fire", buf, INPUT_BUFFER_SIZE);
ImGui::Spacing();
if (ImGui::Button(TEXT("Animation.AddParticle"), Widget::CalcSize()))
{
std::string key = std::string("Custom.") + buf;
m_AnimData.m_pData->Set(key.c_str(), std::string("Dummy"));
Particle::m_Data.m_pData->Save();
}
}
ImGui::Spacing(); ImGui::Spacing();
if (ImGui::BeginChild("Anims Child")) if (ImGui::BeginChild("Anims Child"))
{ {
ImGui::Spacing(); ImGui::Spacing();
Widget::DataList(Particle::m_Data, Particle::Play, Particle::Remove); Widget::DataList(Particle::m_Data, Particle::Play, Particle::Remove,
[](){
static char name[INPUT_BUFFER_SIZE], particle[INPUT_BUFFER_SIZE];
ImGui::InputTextWithHint(TEXT("Animation.ParticleName"), "KKJJ fire particle", name, INPUT_BUFFER_SIZE);
ImGui::InputTextWithHint(TEXT("Animation.ParticleID"), "kkjj_on_fire", particle, INPUT_BUFFER_SIZE);
ImGui::Spacing();
if (ImGui::Button(TEXT("Window.AddEntry"), Widget::CalcSize()))
{
std::string key = std::string("Custom.") + name;
Particle::m_Data.m_pData->Set(key.c_str(), std::string(particle));
Particle::m_Data.m_pData->Save();
Util::SetMessage(TEXT("Window.AddEntryMSG"));
}
});
ImGui::EndChild(); ImGui::EndChild();
} }
ImGui::EndTabItem(); ImGui::EndTabItem();

View File

@ -312,12 +312,12 @@ void CheatMenu::ShowAnniversaryPage()
if (ImGui::Button(TEXT("Menu.DiscordServer"), ImVec2(Widget::CalcSize(3)))) if (ImGui::Button(TEXT("Menu.DiscordServer"), ImVec2(Widget::CalcSize(3))))
{ {
ShellExecute(nullptr, "open", DISCORD_INVITE, nullptr, nullptr, SW_SHOWNORMAL); OPEN_LINK(DISCORD_INVITE);
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button(TEXT("Menu.GitHubRepo"), ImVec2(Widget::CalcSize(3)))) if (ImGui::Button(TEXT("Menu.GitHubRepo"), ImVec2(Widget::CalcSize(3))))
{ {
ShellExecute(nullptr, "open", GITHUB_LINK, nullptr, nullptr, SW_SHOWNORMAL); OPEN_LINK(GITHUB_LINK);
} }
} }
@ -333,12 +333,12 @@ void CheatMenu::ShowWelcomePage()
ImGui::NewLine(); ImGui::NewLine();
if (ImGui::Button(TEXT("Menu.DiscordServer"), ImVec2(Widget::CalcSize(2)))) if (ImGui::Button(TEXT("Menu.DiscordServer"), ImVec2(Widget::CalcSize(2))))
{ {
ShellExecute(nullptr, "open", DISCORD_INVITE, nullptr, nullptr, SW_SHOWNORMAL); OPEN_LINK(DISCORD_INVITE);
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button(TEXT("Menu.GitHubRepo"), ImVec2(Widget::CalcSize(2)))) if (ImGui::Button(TEXT("Menu.GitHubRepo"), ImVec2(Widget::CalcSize(2))))
{ {
ShellExecute(nullptr, "open", GITHUB_LINK, nullptr, nullptr, SW_SHOWNORMAL); OPEN_LINK(GITHUB_LINK);
} }
ImGui::NewLine(); ImGui::NewLine();
ImGui::TextWrapped(TEXT("Menu.BugDisclaimer")); ImGui::TextWrapped(TEXT("Menu.BugDisclaimer"));
@ -361,7 +361,7 @@ void CheatMenu::ShowUpdatePage()
ImGui::Dummy(ImVec2(0, 5)); ImGui::Dummy(ImVec2(0, 5));
if (ImGui::Button(TEXT("Menu.DiscordServer"), ImVec2(Widget::CalcSize(2)))) if (ImGui::Button(TEXT("Menu.DiscordServer"), ImVec2(Widget::CalcSize(2))))
{ {
ShellExecute(nullptr, "open", DISCORD_INVITE, nullptr, nullptr, SW_SHOWNORMAL); OPEN_LINK(DISCORD_INVITE);
} }
ImGui::SameLine(); ImGui::SameLine();

View File

@ -23,6 +23,7 @@
#define FILE_NAME BY_GAME("CheatMenuSA" , "CheatMenuVC", "CheatMenuIII") #define FILE_NAME BY_GAME("CheatMenuSA" , "CheatMenuVC", "CheatMenuIII")
#define MENU_DATA_PATH(x) (PLUGIN_PATH((char*)FILE_NAME##"/"##x)) #define MENU_DATA_PATH(x) (PLUGIN_PATH((char*)FILE_NAME##"/"##x))
#define MENU_DATA_EXISTS(x) (std::filesystem::exists(MENU_DATA_PATH(x))) #define MENU_DATA_EXISTS(x) (std::filesystem::exists(MENU_DATA_PATH(x)))
#define OPEN_LINK(x) ShellExecute(nullptr, "open", x, nullptr, nullptr, SW_SHOWNORMAL)

View File

@ -45,7 +45,7 @@ void MenuThread(void* param)
if (msgID == IDOK) if (msgID == IDOK)
{ {
ShellExecute(nullptr, "open", "https://gtaforums.com/topic/669045-silentpatch/", nullptr, nullptr, SW_SHOWNORMAL); OPEN_LINK("https://gtaforums.com/topic/669045-silentpatch/");
}; };
return; return;
} }

View File

@ -32,7 +32,8 @@ void Menu::ShowPage()
&& !FontMgr::IsSupportPackageInstalled()) && !FontMgr::IsSupportPackageInstalled())
{ {
ImGui::Spacing(); ImGui::Spacing();
ImGui::TextWrapped("Font support package is required to display this language! This may take a while depending on your connection."); ImGui::TextWrapped("Font support package is required to display this language!"
" This may take a while depending on your internet connection.\n\nIt's recommended NOT to install unless you want to use this language! (Affects game loading time)");
ImGui::Spacing(); ImGui::Spacing();
if (ImGui::Button("Install package", ImVec2(Widget::CalcSize(2)))) if (ImGui::Button("Install package", ImVec2(Widget::CalcSize(2))))
{ {
@ -288,14 +289,14 @@ void Menu::ShowPage()
if (ImGui::Button(TEXT("Menu.DiscordServer"), ImVec2(Widget::CalcSize(3)))) if (ImGui::Button(TEXT("Menu.DiscordServer"), ImVec2(Widget::CalcSize(3))))
{ {
ShellExecute(nullptr, "open", DISCORD_INVITE, nullptr, nullptr, SW_SHOWNORMAL); OPEN_LINK(DISCORD_INVITE);
} }
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::Button(TEXT("Menu.GitHubRepo"), ImVec2(Widget::CalcSize(3)))) if (ImGui::Button(TEXT("Menu.GitHubRepo"), ImVec2(Widget::CalcSize(3))))
{ {
ShellExecute(nullptr, "open", GITHUB_LINK, nullptr, nullptr, SW_SHOWNORMAL); OPEN_LINK(GITHUB_LINK);
} }
ImGui::Spacing(); ImGui::Spacing();

View File

@ -80,6 +80,7 @@ extern DataStore gConfig;
typedef void(*ArgCallback3)(std::string&, std::string&, std::string&); typedef void(*ArgCallback3)(std::string&, std::string&, std::string&);
typedef void(*ArgCallback)(std::string&); typedef void(*ArgCallback)(std::string&);
typedef void(*ArgCallbackNone)();
typedef std::string(*ArgCallbackRtn)(std::string&); typedef std::string(*ArgCallbackRtn)(std::string&);
typedef bool(*ArgCallbackRtnBool)(std::string&); typedef bool(*ArgCallbackRtnBool)(std::string&);

View File

@ -306,9 +306,38 @@ void Ped::ShowPage()
ImGui::Spacing(); ImGui::Spacing();
#ifdef GTASA #ifdef GTASA
Widget::ImageList(m_PedData, SpawnPed, Widget::ImageList(m_PedData, SpawnPed,
[](std::string& str) [](std::string& str){
{
return m_PedData.m_pData->Get(str.c_str(), "Unknown"); return m_PedData.m_pData->Get(str.c_str(), "Unknown");
}, nullptr,
[](){
static char name[8];
static int model = 0;
ImGui::InputTextWithHint(TEXT("Menu.Name"), "PEDNAME", name, 7);
Widget::InputInt(TEXT("Ped.Model"), &model, 1, 0, 999999);
ImGui::Spacing();
ImVec2 sz = Widget::CalcSize(2);
if (ImGui::Button(TEXT("Ped.AddPed"), sz))
{
Command<Commands::REQUEST_MODEL>(model);
Command<Commands::LOAD_ALL_MODELS_NOW>();
if (Command<Commands::IS_MODEL_AVAILABLE>(model))
{
std::string key = std::format("Custom.{} (Added)", name);
m_PedData.m_pData->Set(key.c_str(), std::to_string(model));
m_PedData.m_pData->Save();
Util::SetMessage(TEXT("Ped.AddPedMSG"));
Command<Commands::MARK_MODEL_AS_NO_LONGER_NEEDED>(model);
}
else
{
Util::SetMessage(TEXT("Vehicle.InvalidID"));
}
}
ImGui::SameLine();
if (ImGui::Button(TEXT("Ped.GetPlayerModel"), sz))
{
model = FindPlayerPed()->m_nModelIndex;
}
}); });
#else #else
Widget::DataList(m_PedData, SpawnPed, nullptr); Widget::DataList(m_PedData, SpawnPed, nullptr);

View File

@ -2,7 +2,7 @@
#include "pch.h" #include "pch.h"
ResourceStore::ResourceStore(const char* text, eResourceType type, ImVec2 imageSize) ResourceStore::ResourceStore(const char* text, eResourceType type, ImVec2 imageSize)
: m_ImageSize(imageSize), m_Type(type) : m_ImageSize(imageSize), m_Type(type), m_FileName(text)
{ {
if (m_Type != eResourceType::TYPE_IMAGE) if (m_Type != eResourceType::TYPE_IMAGE)
{ {
@ -50,7 +50,7 @@ RwTexDictionary* LoadTexDictionary(char const* filename) {
return plugin::CallAndReturnDynGlobal<RwTexDictionary*, char const*>(0x5B3860, filename); return plugin::CallAndReturnDynGlobal<RwTexDictionary*, char const*>(0x5B3860, filename);
} }
RwTexture* ResourceStore::FindTextureByName(std::string&& name) RwTexture* ResourceStore::FindRwTextureByName(const std::string& name)
{ {
for (auto& item: m_ImagesList) for (auto& item: m_ImagesList)
{ {
@ -62,6 +62,16 @@ RwTexture* ResourceStore::FindTextureByName(std::string&& name)
return nullptr; return nullptr;
} }
IDirect3DTexture9** ResourceStore::FindTextureByName(const std::string& name)
{
RwTexture *pTex = FindRwTextureByName(name);
if (pTex)
{
return GetTextureFromRaster(pTex);
}
return nullptr;
}
void ResourceStore::LoadTextureResource(std::string&& name) void ResourceStore::LoadTextureResource(std::string&& name)
{ {
std::string fullPath = PLUGIN_PATH((char*)FILE_NAME "\\") + name + ".txd"; std::string fullPath = PLUGIN_PATH((char*)FILE_NAME "\\") + name + ".txd";
@ -78,7 +88,7 @@ void ResourceStore::LoadTextureResource(std::string&& name)
{ {
RwLinkList *pRLL = (RwLinkList*)pRwTexDictionary->texturesInDict.link.next; RwLinkList *pRLL = (RwLinkList*)pRwTexDictionary->texturesInDict.link.next;
RwTexDictionary *pEndDic; RwTexDictionary *pEndDic;
bool addCategories = (m_Categories.size() < 2); // "All" bool addCategories = (m_Categories.size() < 3); // "All", "Custom"
do do
{ {
pEndDic = (RwTexDictionary*)pRLL->link.next; pEndDic = (RwTexDictionary*)pRLL->link.next;

View File

@ -57,8 +57,9 @@ private:
public: public:
ImGuiTextFilter m_Filter = ""; ImGuiTextFilter m_Filter = "";
std::vector<std::string> m_Categories = {"All"}; std::vector<std::string> m_Categories = {"All", "Custom"};
std::string m_Selected = "All"; std::string m_Selected = "All";
std::string m_FileName;
std::unique_ptr<DataStore> m_pData; std::unique_ptr<DataStore> m_pData;
std::vector<std::unique_ptr<TextureResource>> m_ImagesList; std::vector<std::unique_ptr<TextureResource>> m_ImagesList;
ImVec2 m_ImageSize; ImVec2 m_ImageSize;
@ -67,5 +68,6 @@ public:
ResourceStore(const char* text, eResourceType type = TYPE_IMAGE, ImVec2 imageSize = ImVec2(64, 64)); ResourceStore(const char* text, eResourceType type = TYPE_IMAGE, ImVec2 imageSize = ImVec2(64, 64));
RwTexture* FindTextureByName(std::string&& name); RwTexture* FindRwTextureByName(const std::string& name);
IDirect3DTexture9** FindTextureByName(const std::string& name);
}; };

View File

@ -59,7 +59,7 @@ void Teleport::Init()
static CSprite2d map; static CSprite2d map;
if (!map.m_pTexture) if (!map.m_pTexture)
{ {
map.m_pTexture = gTextureList.FindTextureByName("map"); map.m_pTexture = gTextureList.FindRwTextureByName("map");
} }
float height = screen::GetScreenHeight(); float height = screen::GetScreenHeight();
float width = screen::GetScreenWidth(); float width = screen::GetScreenWidth();
@ -309,27 +309,6 @@ void Teleport::ShowPage()
#ifdef GTASA #ifdef GTASA
FetchRadarSpriteData(); FetchRadarSpriteData();
#endif #endif
ImGui::Spacing();
if (ImGui::CollapsingHeader(TEXT("Window.AddNew")))
{
ImGui::Spacing();
ImGui::InputTextWithHint(TEXT("Teleport.Location"), TEXT("Teleport.LocationHint"), locBuf, INPUT_BUFFER_SIZE);
ImGui::InputTextWithHint(TEXT("Teleport.Coordinates"), "x, y, z", inBuf, INPUT_BUFFER_SIZE);
ImGui::Spacing();
if (ImGui::Button(TEXT("Teleport.AddLocation"), Widget::CalcSize()))
{
std::string key = std::string("Custom.") + locBuf;
m_locData.m_pData->Set(key.c_str(), ("0, " + std::string(inBuf)));
#ifdef GTASA
// Clear the Radar coordinates
m_locData.m_pData->RemoveTable("Radar");
#endif
m_locData.m_pData->Save();
}
}
ImGui::Spacing(); ImGui::Spacing();
Widget::DataList(m_locData, Widget::DataList(m_locData,
[](std::string& unk1, std::string& unk2, std::string& loc){ [](std::string& unk1, std::string& unk2, std::string& loc){
@ -353,7 +332,24 @@ void Teleport::ShowPage()
} }
else else
{ {
Util::SetMessage(TEXT("Teleport.CustomLocationRemoveOnly")); Util::SetMessage(TEXT("Window.CustomRemoveOnly"));
}
},
[](){
ImGui::InputTextWithHint(TEXT("Teleport.Location"), TEXT("Teleport.LocationHint"), locBuf, INPUT_BUFFER_SIZE);
ImGui::InputTextWithHint(TEXT("Teleport.Coordinates"), "x, y, z", inBuf, INPUT_BUFFER_SIZE);
ImGui::Spacing();
if (ImGui::Button(TEXT("Window.AddEntry"), Widget::CalcSize()))
{
std::string key = std::string("Custom.") + locBuf;
m_locData.m_pData->Set(key.c_str(), ("0, " + std::string(inBuf)));
#ifdef GTASA
// Clear the Radar coordinates
m_locData.m_pData->RemoveTable("Radar");
#endif
m_locData.m_pData->Save();
Util::SetMessage(TEXT("Window.AddEntryMSG"));
} }
}); });
ImGui::EndTabItem(); ImGui::EndTabItem();

View File

@ -1139,9 +1139,46 @@ void Vehicle::ShowPage()
ImGui::InputTextWithHint("##LicenseText", TEXT("Vehicle.PlateText"), Spawner::m_nLicenseText, 9); ImGui::InputTextWithHint("##LicenseText", TEXT("Vehicle.PlateText"), Spawner::m_nLicenseText, 9);
Widget::ImageList(Spawner::m_VehData, SpawnVehicle, Widget::ImageList(Spawner::m_VehData, SpawnVehicle,
[](std::string& str) [](std::string& str){
{
return GetNameFromModel(std::stoi(str)); return GetNameFromModel(std::stoi(str));
}, nullptr,
[](){
static char name[INPUT_BUFFER_SIZE];
static int model = 0;
ImGui::InputTextWithHint(TEXT("Menu.Name"), "Cheetah", name, INPUT_BUFFER_SIZE);
Widget::InputInt(TEXT("Vehicle.Model"), &model, 1, 0, 999999);
ImGui::Spacing();
ImVec2 sz = Widget::CalcSize(2);
if (ImGui::Button(TEXT("Window.AddEntry"), sz))
{
if (Command<Commands::IS_THIS_MODEL_A_CAR>(model))
{
std::string key = std::format("Custom.{} (Added)", name);
Spawner::m_VehData.m_pData->Set(key.c_str(), std::to_string(model));
Spawner::m_VehData.m_pData->Save();
Util::SetMessage(TEXT("Window.AddEntryMSG"));
}
else
{
Util::SetMessage(TEXT("Vehicle.InvalidID"));
}
}
ImGui::SameLine();
if (ImGui::Button(TEXT("Vehicle.GetCurrentVehInfo"), sz))
{
CPlayerPed *pPlayer = FindPlayerPed();
int hPlayer = CPools::GetPedRef(pPlayer);
if (Command<Commands::IS_CHAR_IN_ANY_CAR>(hPlayer))
{
model = pPlayer->m_pVehicle->m_nModelIndex;
std::string str = Vehicle::GetNameFromModel(model);
strcpy(name, str.c_str());
}
else
{
Util::SetMessage(TEXT("Vehicle.NotInVehicle"));
}
}
}); });
#else #else
Widget::DataList(Spawner::m_VehData, SpawnVehicle, nullptr); Widget::DataList(Spawner::m_VehData, SpawnVehicle, nullptr);
@ -1399,7 +1436,7 @@ void Vehicle::ShowPage()
[](std::string& str) [](std::string& str)
{ {
return str; return str;
}); }, nullptr, [](){});
ImGui::EndTabItem(); ImGui::EndTabItem();
} }

View File

@ -716,7 +716,7 @@ void Visual::ShowPage()
{ {
static float var = 0.000001f; static float var = 0.000001f;
static CSprite2d sprite; static CSprite2d sprite;
sprite.m_pTexture = gTextureList.FindTextureByName("radardisc"); sprite.m_pTexture = gTextureList.FindRwTextureByName("radardisc");
// rediect to our texture // rediect to our texture
patch::Set(0x58A8C9, &sprite); patch::Set(0x58A8C9, &sprite);

View File

@ -367,6 +367,21 @@ void Weapon::ShowPage()
[](std::string& str) [](std::string& str)
{ {
return str != "0"; /*Unarmed*/ return str != "0"; /*Unarmed*/
},
[](){
static char name[INPUT_BUFFER_SIZE];
static int model = 0;
ImGui::InputTextWithHint(TEXT("Menu.Name"), "Minigun", name, INPUT_BUFFER_SIZE);
Widget::InputInt(TEXT("Weapon.WeaponType"), &model, 1, 0, 999999);
ImGui::Spacing();
ImVec2 sz = Widget::CalcSize(1);
if (ImGui::Button(TEXT("Window.AddEntry"), sz))
{
std::string key = std::format("Custom.{} (Added)", name);
m_WeaponData.m_pData->Set(key.c_str(), std::to_string(model));
m_WeaponData.m_pData->Save();
Util::SetMessage(TEXT("Window.AddEntryMSG"));
}
}); });
#else #else
Widget::DataList(m_WeaponData, GiveWeaponToPlayer, nullptr); Widget::DataList(m_WeaponData, GiveWeaponToPlayer, nullptr);
@ -390,12 +405,10 @@ void Weapon::ShowPage()
ImGui::Text(TEXT("Weapon.CurrentWeapon"), m_WeaponData.m_pData->Get(key.c_str(), "Unknown").c_str()); ImGui::Text(TEXT("Weapon.CurrentWeapon"), m_WeaponData.m_pData->Get(key.c_str(), "Unknown").c_str());
ImGui::Spacing(); ImGui::Spacing();
Widget::ImageList(m_WeaponData, SetGangWeapon, Widget::ImageList(m_WeaponData, SetGangWeapon,
[](std::string& str) [](std::string& str){
{
return m_WeaponData.m_pData->Get(str.c_str(), "Unknown"); return m_WeaponData.m_pData->Get(str.c_str(), "Unknown");
}, },
[](std::string& str) [](std::string& str){
{
return str != "-1"; /*Jetpack*/ return str != "-1"; /*Jetpack*/
}); });
ImGui::EndTabItem(); ImGui::EndTabItem();

View File

@ -7,6 +7,7 @@ static struct
std::string root, key, val; std::string root, key, val;
void* func = nullptr; void* func = nullptr;
bool show = false; bool show = false;
bool added = false;
} contextMenu; } contextMenu;
ImVec2 Widget::CalcSize(short count, bool spacing) ImVec2 Widget::CalcSize(short count, bool spacing)
@ -75,7 +76,7 @@ void Widget::Filter(const char* label, ImGuiTextFilter& filter, const char* hint
} }
} }
void Widget::DataList(ResourceStore& data, ArgCallback3 clickFunc, ArgCallback3 removeFunc) void Widget::DataList(ResourceStore& data, ArgCallback3 clickFunc, ArgCallback3 removeFunc, ArgCallbackNone addFunc)
{ {
if (ImGui::IsMouseClicked(1)) if (ImGui::IsMouseClicked(1))
{ {
@ -207,37 +208,54 @@ void Widget::DataList(ResourceStore& data, ArgCallback3 clickFunc, ArgCallback3
ImGui::EndChild(); ImGui::EndChild();
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
if (addFunc)
{
if (ImGui::BeginTabItem(TEXT("Window.AddNew")))
{
ImGui::Spacing();
ImGui::BeginChild("AddNew2");
ImGui::TextWrapped(TEXT("Window.AddNewTip"));
ImGui::Dummy(ImVec2(0, 5));
addFunc();
ImGui::EndChild();
ImGui::EndTabItem();
}
}
ImGui::EndTabBar(); ImGui::EndTabBar();
} }
} }
static bool RoundedImageButton(ImTextureID user_texture_id, ImVec2& size, const char* hover_text) static bool RoundedImageButton(ImTextureID textureID, ImVec2& size, const char* hoverText, bool alwaysHovered = false)
{ {
// Default to using texture ID as ID. User can still push string/integer prefixes. // Default to using texture ID as ID. User can still push string/integer prefixes.
// Creating a invisible button as placeholder // Creating a invisible button as placeholder
ImGui::InvisibleButton(hover_text, size); ImGui::InvisibleButton(hoverText, size);
ImVec2 min = ImGui::GetItemRectMin(); ImVec2 min = ImGui::GetItemRectMin();
ImVec2 max = ImGui::GetItemRectMax(); ImVec2 max = ImGui::GetItemRectMax();
ImDrawList *drawList = ImGui::GetWindowDrawList(); ImDrawList *drawList = ImGui::GetWindowDrawList();
drawList->AddImageRounded(user_texture_id, min, max, ImVec2(0, 0), ImVec2(1, 1), ImGui::GetColorU32(ImVec4(1, 1, 1, 1)), 5.0f); drawList->AddImageRounded(textureID, min, max, ImVec2(0, 0), ImVec2(1, 1), ImGui::GetColorU32(ImVec4(1, 1, 1, 1)), 5.0f);
// Add selection overlay and stuff on hover // Add selection overlay and stuff on hover
if (ImGui::IsItemHovered()) bool isHovered = ImGui::IsItemHovered();
if (isHovered || alwaysHovered)
{ {
drawList->AddRectFilled(min, max, ImGui::GetColorU32(ImGuiCol_ModalWindowDimBg), 5.6f); if (isHovered)
{
drawList->AddRectFilled(min, max, ImGui::GetColorU32(ImGuiCol_ModalWindowDimBg), 5.6f);
}
// Calculating and drawing text over the image // Calculating and drawing text over the image
ImVec2 textSize = ImGui::CalcTextSize(hover_text); ImVec2 textSize = ImGui::CalcTextSize(hoverText);
if (textSize.x < size.x) if (textSize.x < size.x)
{ {
float offsetX = (ImGui::GetItemRectSize().x - textSize.x) / 2; float offsetX = (ImGui::GetItemRectSize().x - textSize.x) / 2;
drawList->AddText(ImVec2(min.x + offsetX, min.y + 10), ImGui::GetColorU32(ImGuiCol_Text), hover_text); drawList->AddText(ImVec2(min.x + offsetX, min.y + 10), ImGui::GetColorU32(ImGuiCol_Text), hoverText);
} }
else else
{ {
std::string buf = ""; std::string buf = "";
std::stringstream ss(hover_text); std::stringstream ss(hoverText);
short count = 1; short count = 1;
while (ss >> buf) while (ss >> buf)
@ -254,8 +272,14 @@ static bool RoundedImageButton(ImTextureID user_texture_id, ImVec2& size, const
return ImGui::IsItemClicked(0); return ImGui::IsItemClicked(0);
} }
void Widget::ImageList(ResourceStore &store, ArgCallback clickFunc, ArgCallbackRtn getNameFunc, ArgCallbackRtnBool verifyFunc) /*
Here we go again...
This direly needs a refactor oof
*/
void Widget::ImageList(ResourceStore &store, ArgCallback clickFunc, ArgCallbackRtn getNameFunc,
ArgCallbackRtnBool verifyFunc, ArgCallbackNone addFunc)
{ {
static IDirect3DTexture9 **pDefaultTex = nullptr;
ImGuiStyle& style = ImGui::GetStyle(); ImGuiStyle& style = ImGui::GetStyle();
/* /*
Trying to scale images based on resolutions Trying to scale images based on resolutions
@ -316,30 +340,55 @@ void Widget::ImageList(ResourceStore &store, ArgCallback clickFunc, ArgCallbackR
&& (verifyFunc == nullptr || verifyFunc(text)) && (verifyFunc == nullptr || verifyFunc(text))
) )
{ {
/* if (showImages ? RoundedImageButton(store.m_ImagesList[i]->m_pTexture, m_ImageSize, modelName.c_str())
Couldn't figure out how to laod images for Dx11 : ImGui::MenuItem(modelName.c_str())
Using texts for now )
*/
if (showImages)
{ {
if (RoundedImageButton(store.m_ImagesList[i]->m_pTexture, m_ImageSize, modelName.c_str())) clickFunc(text);
{
clickFunc(text);
}
}
else
{
if (ImGui::MenuItem(modelName.c_str()))
{
clickFunc(text);
}
} }
// Right click popup // Right click popup
if (ImGui::IsItemClicked(1)) if (ImGui::IsItemClicked(1))
{ {
contextMenu.show = true; contextMenu.show = true;
contextMenu.added = false;
contextMenu.val = text;
contextMenu.key = modelName;
}
if (showImages)
{
if (imageCount % imagesInRow != 0)
{
ImGui::SameLine(0.0, style.ItemInnerSpacing.x);
}
}
imageCount++;
}
}
for (auto [k, v] : *store.m_pData->GetTable("Custom"))
{
if (!pDefaultTex)
{
pDefaultTex = gTextureList.FindTextureByName("placeholder");
}
std::string modelName = std::string(k.str());
std::string text = v.as_string()->value_or("0");
if (store.m_Filter.PassFilter(modelName.c_str())
&& (store.m_Selected == "Custom" || store.m_Selected == "All"))
{
if (showImages ? RoundedImageButton(pDefaultTex, m_ImageSize, modelName.c_str(), true)
: ImGui::MenuItem(modelName.c_str())
)
{
clickFunc(text);
}
// Right click popup
if (ImGui::IsItemClicked(1))
{
contextMenu.show = true;
contextMenu.added = (addFunc != nullptr);
contextMenu.val = text; contextMenu.val = text;
contextMenu.key = modelName; contextMenu.key = modelName;
} }
@ -362,10 +411,16 @@ void Widget::ImageList(ResourceStore &store, ArgCallback clickFunc, ArgCallbackR
ImGui::Separator(); ImGui::Separator();
if (ImGui::MenuItem(TEXT("Menu.Favourites"))) if (ImGui::MenuItem(TEXT("Menu.Favourites")))
{ {
store.m_pData->Set(std::format("Favourites.{}", contextMenu.val).c_str(), contextMenu.key); store.m_pData->Set(std::format("Favourites.{}", contextMenu.key).c_str(), contextMenu.val);
store.m_pData->Save(); store.m_pData->Save();
Util::SetMessage(TEXT("Menu.FavouritesText")); Util::SetMessage(TEXT("Menu.FavouritesText"));
} }
if (contextMenu.added && ImGui::MenuItem(TEXT("Menu.Remove")))
{
store.m_pData->RemoveKey("Custom", contextMenu.key.c_str());
store.m_pData->RemoveKey("Favourites", contextMenu.key.c_str());
store.m_pData->Save();
}
if (ImGui::MenuItem(TEXT("Menu.Close"))) if (ImGui::MenuItem(TEXT("Menu.Close")))
{ {
contextMenu.show = false; contextMenu.show = false;
@ -388,39 +443,26 @@ void Widget::ImageList(ResourceStore &store, ArgCallback clickFunc, ArgCallbackR
for (auto [k, v] : *store.m_pData->GetTable("Favourites")) for (auto [k, v] : *store.m_pData->GetTable("Favourites"))
{ {
std::string val = std::string(k.str()); auto str = k.str();
bool state = str.find("Added") != std::string::npos;
for (uint i = 0; i < store.m_ImagesList.size(); ++i) if (state)
{ {
std::string text = store.m_ImagesList[i]->m_FileName; std::string modelName = std::string(k.str());
std::string modelName = getNameFunc(text); std::string text = v.as_string()->value_or("0");
if (store.m_Filter.PassFilter(modelName.c_str()))
if (text == val && store.m_Filter.PassFilter(modelName.c_str()) && (verifyFunc == nullptr || verifyFunc(text)))
{ {
/* if (showImages ? RoundedImageButton(pDefaultTex, m_ImageSize, modelName.c_str(), true)
Couldn't figure out how to laod images for Dx11 : ImGui::MenuItem(modelName.c_str())
Using texts for now )
*/
if (showImages)
{ {
if (RoundedImageButton(store.m_ImagesList[i]->m_pTexture, m_ImageSize, modelName.c_str())) clickFunc(text);
{
clickFunc(text);
}
}
else
{
if (ImGui::MenuItem(modelName.c_str()))
{
clickFunc(text);
}
} }
// Right click popup // Right click popup
if (ImGui::IsItemClicked(1)) if (ImGui::IsItemClicked(1))
{ {
contextMenu.show = true; contextMenu.show = true;
contextMenu.added = false;
contextMenu.val = text; contextMenu.val = text;
contextMenu.key = modelName; contextMenu.key = modelName;
} }
@ -435,6 +477,42 @@ void Widget::ImageList(ResourceStore &store, ArgCallback clickFunc, ArgCallbackR
imageCount++; imageCount++;
} }
} }
else
{
for (uint i = 0; i < store.m_ImagesList.size(); ++i)
{
std::string text = store.m_ImagesList[i]->m_FileName;
std::string modelName = getNameFunc(text);
if (modelName == k.str() && store.m_Filter.PassFilter(modelName.c_str()) && (verifyFunc == nullptr || verifyFunc(text)))
{
if (showImages ? RoundedImageButton(store.m_ImagesList[i]->m_pTexture, m_ImageSize, modelName.c_str())
: ImGui::MenuItem(modelName.c_str())
)
{
clickFunc(text);
}
// Right click popup
if (ImGui::IsItemClicked(1))
{
contextMenu.show = true;
contextMenu.added = false;
contextMenu.val = text;
contextMenu.key = modelName;
}
if (showImages)
{
if (imageCount % imagesInRow != 0)
{
ImGui::SameLine(0.0, style.ItemInnerSpacing.x);
}
}
imageCount++;
}
}
}
} }
if (store.m_pData->GetTable("Favourites")->size() == 0) if (store.m_pData->GetTable("Favourites")->size() == 0)
{ {
@ -448,13 +526,14 @@ void Widget::ImageList(ResourceStore &store, ArgCallback clickFunc, ArgCallbackR
ImGui::Separator(); ImGui::Separator();
if (ImGui::MenuItem(TEXT("Menu.FavouritesRemove"))) if (ImGui::MenuItem(TEXT("Menu.FavouritesRemove")))
{ {
store.m_pData->RemoveKey("Favourites", contextMenu.val.c_str()); store.m_pData->RemoveKey("Favourites", contextMenu.key.c_str());
store.m_pData->Save(); store.m_pData->Save();
Util::SetMessage(TEXT("Menu.FavouritesRemoveText")); Util::SetMessage(TEXT("Menu.FavouritesRemoveText"));
} }
if (ImGui::MenuItem(TEXT("Menu.Close"))) if (ImGui::MenuItem(TEXT("Menu.Close")))
{ {
contextMenu.show = false; contextMenu.show = false;
contextMenu.added = false;
} }
ImGui::EndPopup(); ImGui::EndPopup();
@ -463,9 +542,36 @@ void Widget::ImageList(ResourceStore &store, ArgCallback clickFunc, ArgCallbackR
ImGui::EndChild(); ImGui::EndChild();
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
if (addFunc)
{
if (ImGui::BeginTabItem(TEXT("Window.AddNew")))
{
ImGui::Spacing();
ImGui::TextWrapped(TEXT("Window.AddNewTip"));
ImGui::Dummy(ImVec2(0, 5));
ImGui::BeginChild("AddNew2");
addFunc();
ImGui::Dummy(ImVec2(0.0f, 10.0f));
if (ImGui::CollapsingHeader(TEXT("Window.AddNewCustomImg")))
{
ImGui::Spacing();
ImGui::TextWrapped(std::vformat(TEXT("Window.AddNewTip2"), std::make_format_args(store.m_FileName)).c_str());
ImGui::Spacing();
if (ImGui::Button(TEXT("Window.DownloadMagicTxd"), Widget::CalcSize()))
{
OPEN_LINK("https://gtaforums.com/topic/851436-relopensrc-magictxd/");
}
ImGui::Spacing();
ImGui::Separator();
}
ImGui::EndChild();
ImGui::EndTabItem();
}
}
ImGui::EndTabBar(); ImGui::EndTabBar();
} }
if (showImages) if (showImages)
{ {

View File

@ -41,7 +41,8 @@ public:
static bool ColorBtn(int colorId, std::vector<float>& color, ImVec2 size); static bool ColorBtn(int colorId, std::vector<float>& color, ImVec2 size);
// Draws DataStore data in the interface // Draws DataStore data in the interface
static void DataList(ResourceStore& data, ArgCallback3 clickFunc, ArgCallback3 removeFunc); static void DataList(ResourceStore& data, ArgCallback3 clickFunc, ArgCallback3 removeFunc,
ArgCallbackNone addFunc = nullptr);
// Draws a dropdown editor for memory address // Draws a dropdown editor for memory address
template <typename T> template <typename T>
@ -70,7 +71,7 @@ public:
// Draws ResourceStore images in the interface // Draws ResourceStore images in the interface
static void ImageList(ResourceStore &store, ArgCallback clickFunc, ArgCallbackRtn getNameFunc, static void ImageList(ResourceStore &store, ArgCallback clickFunc, ArgCallbackRtn getNameFunc,
ArgCallbackRtnBool verifyFunc = nullptr); ArgCallbackRtnBool verifyFunc = nullptr, ArgCallbackNone addFunc = nullptr);
// Draws a dropdown listbox // Draws a dropdown listbox
static bool ListBox(const char* label, VecStr& allItems, int& selected); static bool ListBox(const char* label, VecStr& allItems, int& selected);