diff --git a/src/xrGame/ImUtils/ImUtils.cpp b/src/xrGame/ImUtils/ImUtils.cpp index 16d6716026..c75d690dfe 100644 --- a/src/xrGame/ImUtils/ImUtils.cpp +++ b/src/xrGame/ImUtils/ImUtils.cpp @@ -1,12 +1,8 @@ #include "stdafx.h" -void InitImGuiCLSIDInGame(); -void InitImGuiSearchInGame(); +#include "ImUtils.h" -void RenderTimeManagerWindow(); -void RenderSpawnManagerWindow(); -void RenderWeaponManagerWindow(); -void RenderSearchManagerWindow(); +clsid_manager* g_pClsidManager; void RegisterImGuiInGame() { @@ -19,5 +15,6 @@ void RegisterImGuiInGame() InitImGuiCLSIDInGame(); InitImGuiSearchInGame(); + InitSections(); } } \ No newline at end of file diff --git a/src/xrGame/ImUtils/ImUtils.h b/src/xrGame/ImUtils/ImUtils.h new file mode 100644 index 0000000000..e6a7ac141e --- /dev/null +++ b/src/xrGame/ImUtils/ImUtils.h @@ -0,0 +1,533 @@ +#pragma once + +#include "../xrCore/clsid.h" + +#include "../xrEngine/XR_IOConsole.h" +#include "../xrEngine/string_table.h" +#include + +struct clsid_manager; +extern clsid_manager* g_pClsidManager; + +struct clsid_manager +{ + void add_mp_stuff(CLASS_ID id) { + if (!is_item(id)) + mp_stuffs.insert(id); + } + bool is_mp_stuff(CLASS_ID id) { + return mp_stuffs.find(id) != mp_stuffs.end(); + } + + void add_item(CLASS_ID id) { + if (!is_item(id)) + items.insert(id); + } + bool is_item(CLASS_ID id) { + return items.find(id) != items.end(); + } + + void add_outfit(CLASS_ID id) { + if (!is_outfit(id)) + outfits.insert(id); + } + bool is_outfit(CLASS_ID id) { + return outfits.find(id) != outfits.end(); + } + + void add_ammo(CLASS_ID id) { + if (!is_ammo(id)) + ammo.insert(id); + } + bool is_ammo(CLASS_ID id) { + return ammo.find(id) != ammo.end(); + } + + void add_weapon(CLASS_ID id) { + if (!is_weapon(id)) + weapons.insert(id); + } + + bool is_weapon(CLASS_ID id) { + return weapons.find(id) != weapons.end(); + } + + void add_monster(CLASS_ID id) { + if (!is_monster(id)) + monsters.insert(id); + } + + bool is_monster(CLASS_ID id) { + return monsters.find(id) != monsters.end(); + } + + void add_addon(CLASS_ID id) { + if (!is_addon(id)) + addons.insert(id); + } + + bool is_addon(CLASS_ID id) { + return addons.find(id) != addons.end(); + } + + void add_artefact(CLASS_ID id) { + if (!is_artefact(id)) + artefacts.insert(id); + } + + bool is_artefact(CLASS_ID id) { + return artefacts.find(id) != artefacts.end(); + } + + void add_vehicle(CLASS_ID id) { + if (!is_vehicle(id)) + vehicles.insert(id); + } + + bool is_vehicle(CLASS_ID id) { + return vehicles.find(id) != vehicles.end(); + } + + const xr_set& get_items(void) const { return items; } + const xr_set& get_outfits(void) const { return outfits; } + const xr_set& get_ammo(void) const { return ammo; } + const xr_set& get_monsters(void) const { return monsters; } + const xr_set& get_weapons(void) const { return weapons; } + const xr_set& get_addons(void) const { return addons; } + const xr_set& get_artefacts(void) const { return artefacts; } + const xr_set& get_vehicles(void) const { return vehicles; } + const xr_set& get_mp_stuffs(void) const { return mp_stuffs; } + + const char* translateCLSID(CLASS_ID id) { + char name[16]{}; + CLSID2TEXT(id, name); + + for (int i = 0; i < 16; ++i) + { + if (name[i] == 32) + { + name[i] = '\0'; + } + } + return g_pStringTable ? g_pStringTable->translate(name).c_str() : name; + } + + // reminder: information took from class_registrator.script because it overloads existed classes (clsids) + CLASS_ID artefact_s = TEXT2CLSID("SCRPTART"); + CLASS_ID artefact = TEXT2CLSID("ARTEFACT"); + + //CLASS_ID car = TEXT2CLSID("SCRPTCAR"); + CLASS_ID car = TEXT2CLSID("C_NIVA"); + CLASS_ID stalker = TEXT2CLSID("AI_STL_S"); + CLASS_ID smart_terrain = TEXT2CLSID("SMRTTRRN"); + CLASS_ID smart_cover = TEXT2CLSID("SMRT_C_S"); + CLASS_ID level_changer = TEXT2CLSID("LVL_CHNG"); + CLASS_ID sim_squad_scripted = TEXT2CLSID("ON_OFF_S"); + + CLASS_ID outfit = TEXT2CLSID("E_STLK"); + CLASS_ID helmet = TEXT2CLSID("E_HLMET"); + + CLASS_ID monster_bloodsucker = TEXT2CLSID("SM_BLOOD"); + CLASS_ID monster_boar = TEXT2CLSID("SM_BOARW"); + CLASS_ID monster_dog = TEXT2CLSID("SM_DOG_S"); + CLASS_ID monster_flesh = TEXT2CLSID("SM_FLESH"); + CLASS_ID monster_pseudodog = TEXT2CLSID("SM_P_DOG"); + CLASS_ID monster_burer = TEXT2CLSID("SM_BURER"); + CLASS_ID monster_cat = TEXT2CLSID("SM_CAT_S"); + CLASS_ID monster_chimera = TEXT2CLSID("SM_CHIMS"); + CLASS_ID monster_controller = TEXT2CLSID("SM_CONTR"); + CLASS_ID monster_izlom = TEXT2CLSID("SM_IZLOM"); + CLASS_ID monster_poltergeist = TEXT2CLSID("SM_POLTR"); + CLASS_ID monster_pseudogigant = TEXT2CLSID("SM_GIANT"); + CLASS_ID monster_zombie = TEXT2CLSID("SM_ZOMBI"); + CLASS_ID monster_snork = TEXT2CLSID("SM_SNORK"); + CLASS_ID monster_tushkano = TEXT2CLSID("SM_TUSHK"); + CLASS_ID monster_psydog = TEXT2CLSID("SM_DOG_P"); + CLASS_ID monster_psydogphantom = TEXT2CLSID("SM_DOG_F"); + + CLASS_ID weapon_binocular = TEXT2CLSID("WP_BINOC"); + CLASS_ID weapon_knife = TEXT2CLSID("WP_KNIFE"); + CLASS_ID weapon_bm16 = TEXT2CLSID("WP_BM16"); + CLASS_ID weapon_groza = TEXT2CLSID("WP_GROZA"); + CLASS_ID weapon_svd = TEXT2CLSID("WP_SVD"); + CLASS_ID weapon_ak74 = TEXT2CLSID("WP_AK74"); + CLASS_ID weapon_lr300 = TEXT2CLSID("WP_LR300"); + CLASS_ID weapon_hpsa = TEXT2CLSID("WP_HPSA"); + CLASS_ID weapon_pm = TEXT2CLSID("WP_PM"); + CLASS_ID weapon_rg6 = TEXT2CLSID("WP_RG6"); + CLASS_ID weapon_rpg7 = TEXT2CLSID("WP_RPG7"); + CLASS_ID weapon_shotgun = TEXT2CLSID("WP_SHOTG"); + CLASS_ID weapon_autoshotgun = TEXT2CLSID("WP_ASHTG"); + CLASS_ID weapon_svu = TEXT2CLSID("WP_SVU"); + CLASS_ID weapon_usp45 = TEXT2CLSID("WP_USP45"); + CLASS_ID weapon_val = TEXT2CLSID("WP_VAL"); + CLASS_ID weapon_vintorez = TEXT2CLSID("WP_VINT"); + CLASS_ID weapon_walther = TEXT2CLSID("WP_WALTH"); + CLASS_ID weapon_magazine = TEXT2CLSID("WP_MAGAZ"); + CLASS_ID weapon_stationary_machine_gun = TEXT2CLSID("W_STMGUN"); + + CLASS_ID ammo_base = TEXT2CLSID("AMMO_S"); + CLASS_ID ammo_vog25 = TEXT2CLSID("S_VOG25"); + CLASS_ID ammo_og7b = TEXT2CLSID("S_OG7B"); + CLASS_ID ammo_m209 = TEXT2CLSID("S_M209"); + CLASS_ID ammo_f1 = TEXT2CLSID("G_F1_S"); + CLASS_ID ammo_rgd5 = TEXT2CLSID("G_RGD5_S"); + + CLASS_ID addon_scope = TEXT2CLSID("WP_SCOPE"); + CLASS_ID addon_silen = TEXT2CLSID("WP_SILEN"); + CLASS_ID addon_glaun = TEXT2CLSID("WP_GLAUN"); + + CLASS_ID item_torch = TEXT2CLSID("TORCH_S"); + CLASS_ID item_detector_scientific = TEXT2CLSID("DET_SCIE"); + CLASS_ID item_detector_elite = TEXT2CLSID("DET_ELIT"); + CLASS_ID item_detector_advanced = TEXT2CLSID("DET_ADVA"); + CLASS_ID item_detector_simple = TEXT2CLSID("DET_SIMP"); + CLASS_ID item_pda = TEXT2CLSID("S_PDA"); + CLASS_ID item_d_pda = TEXT2CLSID("D_PDA"); + CLASS_ID item_ii_attch = TEXT2CLSID("II_ATTCH"); + CLASS_ID item_medkit = TEXT2CLSID("S_MEDKI"); + CLASS_ID item_bandage = TEXT2CLSID("S_BANDG"); + CLASS_ID item_antirad = TEXT2CLSID("S_ANTIR"); + CLASS_ID item_food = TEXT2CLSID("S_FOOD"); + CLASS_ID item_bottle = TEXT2CLSID("S_BOTTL"); + + CLASS_ID mp_out_scientific = CLSID_EQUIPMENT_SCIENTIFIC; + CLASS_ID mp_out_stalker = CLSID_EQUIPMENT_STALKER; + CLASS_ID mp_out_military = CLSID_EQUIPMENT_MILITARY; + CLASS_ID mp_out_exo = CLSID_EQUIPMENT_EXO; + CLASS_ID mp_helmet = CLSID_EQUIPMENT_HELMET; + CLASS_ID mp_weapon_fn2000 = CLSID_OBJECT_W_FN2000; + CLASS_ID mp_weapon_binocular = CLSID_OBJECT_W_BINOCULAR; + CLASS_ID mp_weapon_knife = CLSID_OBJECT_W_KNIFE; + CLASS_ID mp_weapon_bm16 = CLSID_OBJECT_W_BM16; + CLASS_ID mp_weapon_groza = CLSID_OBJECT_W_GROZA; + CLASS_ID mp_weapon_svd = CLSID_OBJECT_W_SVD; + CLASS_ID mp_weapon_ak74 = CLSID_OBJECT_W_AK74; + CLASS_ID mp_weapon_lr300 = CLSID_OBJECT_W_LR300; + CLASS_ID mp_weapon_hpsa = CLSID_OBJECT_W_HPSA; + CLASS_ID mp_weapon_pm = CLSID_OBJECT_W_PM; + CLASS_ID mp_weapon_fort = CLSID_OBJECT_W_FORT; + CLASS_ID mp_weapon_rg6 = CLSID_OBJECT_W_RG6; + CLASS_ID mp_weapon_rpg7 = CLSID_OBJECT_W_RPG7; + CLASS_ID mp_weapon_shotgun = CLSID_OBJECT_W_SHOTGUN; + CLASS_ID mp_weapon_svu = CLSID_OBJECT_W_SVU; + CLASS_ID mp_weapon_usp45 = CLSID_OBJECT_W_USP45; + CLASS_ID mp_weapon_val = CLSID_OBJECT_W_VAL; + CLASS_ID mp_weapon_vintorez = CLSID_OBJECT_W_VINTOREZ; + CLASS_ID mp_weapon_walther = CLSID_OBJECT_W_WALTHER; + CLASS_ID mp_weapon_magazine = CLSID_OBJECT_W_MAGAZINED; + CLASS_ID mp_weapon_magazine_gl = CLSID_OBJECT_W_MAGAZWGL; + + CLASS_ID mp_ammo_base = CLSID_OBJECT_AMMO; + CLASS_ID mp_ammo_og7b = CLSID_OBJECT_A_OG7B; + CLASS_ID mp_ammo_m209 = CLSID_OBJECT_A_M209; + CLASS_ID mp_ammo_vog25 = CLSID_OBJECT_A_VOG25; + CLASS_ID mp_f1 = CLSID_GRENADE_F1; + CLASS_ID mp_rgd5 = CLSID_GRENADE_RGD5; + //CLASS_ID mp_rpg7 = CLSID_OBJECT_G_RPG7; + CLASS_ID mp_addon_scope = CLSID_OBJECT_W_SCOPE; + CLASS_ID mp_addon_silen = CLSID_OBJECT_W_SILENCER; + CLASS_ID mp_addon_glaun = CLSID_OBJECT_W_GLAUNCHER; + + CLASS_ID mp_art_mercury_ball = CLSID_AF_MERCURY_BALL; + CLASS_ID mp_art_black_drops = CLSID_AF_BLACKDROPS; + CLASS_ID mp_art_needles = CLSID_AF_NEEDLES; + CLASS_ID mp_art_bast_artefact = CLSID_AF_BAST; + CLASS_ID mp_art_gravi_black = CLSID_AF_BLACK_GRAVI; + CLASS_ID mp_art_dummy = CLSID_AF_DUMMY; + CLASS_ID mp_art_zuda = CLSID_AF_ZUDA; + CLASS_ID mp_art_thorn = CLSID_AF_THORN; + CLASS_ID mp_art_faded_ball = CLSID_AF_FADED_BALL; + CLASS_ID mp_art_electric_ball = CLSID_AF_ELECTRIC_BALL; + CLASS_ID mp_art_rusty_hair = CLSID_AF_RUSTY_HAIR; + CLASS_ID mp_art_galantine = CLSID_AF_GALANTINE; + CLASS_ID mp_art_gravi = CLSID_AF_GRAVI; + CLASS_ID mp_art_cta = CLSID_AF_CTA; + +private: + xr_set weapons; + xr_set monsters; + xr_set zones; + xr_set items; + xr_set outfits; + xr_set ammo; + xr_set addons; + xr_set artefacts; + xr_set vehicles; + xr_set mp_stuffs; +}; + +enum eSelectedType { + kSelectedType_All, + kSelectedType_SmartTerrain, + kSelectedType_SmartCover, + kSelectedType_LevelChanger, + kSelectedType_Artefact, + kSelectedType_Stalker, + kSelectedType_Car, + kSelectedType_Monster_All, + kSelectedType_Monster_BloodSucker, + kSelectedType_Monster_Boar, + kSelectedType_Monster_Dog, + kSelectedType_Monster_Flesh, + kSelectedType_Monster_PseudoDog, + kSelectedType_Monster_Burer, + kSelectedType_Monster_Cat, + kSelectedType_Monster_Chimera, + kSelectedType_Monster_Controller, + kSelectedType_Monster_Izlom, + kSelectedType_Monster_Poltergeist, + kSelectedType_Monster_PseudoGigant, + kSelectedType_Monster_Zombie, + kSelectedType_Monster_Snork, + kSelectedType_Monster_Tushkano, + kSelectedType_Monster_PsyDog, + kSelectedType_Monster_PsyDogPhantom, + kSelectedType_Weapon_All, + kSelectedType_Weapon_Binocular, + kSelectedType_Weapon_Knife, + kSelectedType_Weapon_BM16, + kSelectedType_Weapon_Groza, + kSelectedType_Weapon_SVD, + kSelectedType_Weapon_AK74, + kSelectedType_Weapon_LR300, + kSelectedType_Weapon_HPSA, + kSelectedType_Weapon_PM, + kSelectedType_Weapon_RG6, + kSelectedType_Weapon_RPG7, + kSelectedType_Weapon_Shotgun, + kSelectedType_Weapon_AutoShotgun, + kSelectedType_Weapon_SVU, + kSelectedType_Weapon_USP45, + kSelectedType_Weapon_VAL, + kSelectedType_Weapon_VINTOREZ, + kSelectedType_Weapon_WALTHER, + kSelectedType_Weapon_Magazine, + kSelectedType_Weapon_StationaryMachineGun, + kSelectedType_Count +}; + +struct { + + bool show_alive_creatures = {}; + int selected_type = {}; + char search_string[256] = {}; + char category_names[(eSelectedType::kSelectedType_Count)][32] = {}; + const char* combo_items[(eSelectedType::kSelectedType_Count)] = {}; + int counts[(eSelectedType::kSelectedType_Count)]{}; + + xr_hash_map type_to_class; + xr_hash_map class_to_type; + + eSelectedType convertCLSIDToType(CLASS_ID id) { + eSelectedType result = eSelectedType::kSelectedType_Count; + + if (class_to_type.find(id) != class_to_type.end()) + result = class_to_type.at(id); + + return result; + } + + const char* convertTypeToString(int type) { + switch (static_cast(type)) + { + case eSelectedType::kSelectedType_All: + { + return "All"; + } + case eSelectedType::kSelectedType_Monster_All: + { + return "Monster - All"; + } + case eSelectedType::kSelectedType_Weapon_All: + { + return "Weapon - All"; + } + } + + + if (type_to_class.find(eSelectedType(type)) != type_to_class.end()) + { + char name[16]{}; + CLASS_ID id = type_to_class.at(eSelectedType(type)); + CLSID2TEXT(id, name); + + for (int i = 0; i < 16; ++i) + { + if (name[i] == 32) + { + name[i] = '\0'; + } + } + const char* pTranslatedName = g_pStringTable ? g_pStringTable->translate(name).c_str() : name; + char result[32]{}; + + + if (g_pClsidManager && g_pClsidManager->is_monster(id)) + { + memcpy_s(result, sizeof(result), "Monster - ", sizeof("Monster - ")); + memcpy_s(&result[0] + sizeof("Monster -"), sizeof(result), pTranslatedName, strlen(pTranslatedName)); + } + else if (g_pClsidManager && g_pClsidManager->is_weapon(id)) + { + memcpy_s(result, sizeof(result), "Weapon - ", sizeof("Weapon - ")); + memcpy_s(&result[0] + sizeof("Weapon -"), sizeof(result), pTranslatedName, strlen(pTranslatedName)); + } + else + { + memcpy_s(result, sizeof(result), pTranslatedName, strlen(pTranslatedName)); + } + + return result; + } + + return "unknown"; + } + + bool filter(CLASS_ID id) { + + bool result{}; + + if (selected_type == eSelectedType::kSelectedType_All) + { + result = true; + return result; + } + + if (selected_type == eSelectedType::kSelectedType_Monster_All) + { + if (g_pClsidManager && g_pClsidManager->is_monster(id)) + { + result = true; + return result; + } + } + + if (selected_type == eSelectedType::kSelectedType_Weapon_All) + { + if (g_pClsidManager && g_pClsidManager->is_weapon(id)) + { + result = true; + return result; + } + } + + if (class_to_type.find(id) != class_to_type.end()) + { + result = selected_type == class_to_type.at(id); + } + + return result; + } + + void count(CLASS_ID id) { + counts[(eSelectedType::kSelectedType_All)] += 1; + + if (g_pClsidManager == nullptr) + { + return; + } + + if (g_pClsidManager->is_monster(id)) + { + counts[eSelectedType::kSelectedType_Monster_All] += 1; + + if (class_to_type.find(id) != class_to_type.end()) + counts[class_to_type.at(id)] += 1; + + } + else if (g_pClsidManager->is_weapon(id)) + { + counts[eSelectedType::kSelectedType_Weapon_All] += 1; + + if (class_to_type.find(id) != class_to_type.end()) + counts[class_to_type.at(id)] += 1; + } + else + { + if (class_to_type.find(id) != class_to_type.end()) + { + counts[class_to_type.at(id)] += 1; + } + } + } + + void init() + { + if (g_pClsidManager == nullptr) + return; + + type_to_class[eSelectedType::kSelectedType_SmartTerrain] = g_pClsidManager->smart_terrain; + type_to_class[eSelectedType::kSelectedType_SmartCover] = g_pClsidManager->smart_cover; + type_to_class[eSelectedType::kSelectedType_LevelChanger] = g_pClsidManager->level_changer; + type_to_class[eSelectedType::kSelectedType_Artefact] = g_pClsidManager->artefact; + type_to_class[eSelectedType::kSelectedType_Stalker] = g_pClsidManager->stalker; + type_to_class[eSelectedType::kSelectedType_Car] = g_pClsidManager->car; + + type_to_class[eSelectedType::kSelectedType_Monster_BloodSucker] = g_pClsidManager->monster_bloodsucker; + type_to_class[eSelectedType::kSelectedType_Monster_Boar] = g_pClsidManager->monster_boar; + type_to_class[eSelectedType::kSelectedType_Monster_Dog] = g_pClsidManager->monster_dog; + type_to_class[eSelectedType::kSelectedType_Monster_Flesh] = g_pClsidManager->monster_flesh; + type_to_class[eSelectedType::kSelectedType_Monster_PseudoDog] = g_pClsidManager->monster_pseudodog; + type_to_class[eSelectedType::kSelectedType_Monster_Burer] = g_pClsidManager->monster_burer; + type_to_class[eSelectedType::kSelectedType_Monster_Cat] = g_pClsidManager->monster_cat; + type_to_class[eSelectedType::kSelectedType_Monster_Chimera] = g_pClsidManager->monster_chimera; + type_to_class[eSelectedType::kSelectedType_Monster_Controller] = g_pClsidManager->monster_controller; + type_to_class[eSelectedType::kSelectedType_Monster_Izlom] = g_pClsidManager->monster_izlom; + type_to_class[eSelectedType::kSelectedType_Monster_Poltergeist] = g_pClsidManager->monster_poltergeist; + type_to_class[eSelectedType::kSelectedType_Monster_PseudoGigant] = g_pClsidManager->monster_pseudogigant; + type_to_class[eSelectedType::kSelectedType_Monster_Zombie] = g_pClsidManager->monster_zombie; + type_to_class[eSelectedType::kSelectedType_Monster_Snork] = g_pClsidManager->monster_snork; + type_to_class[eSelectedType::kSelectedType_Monster_Tushkano] = g_pClsidManager->monster_tushkano; + type_to_class[eSelectedType::kSelectedType_Monster_PsyDog] = g_pClsidManager->monster_psydog; + type_to_class[eSelectedType::kSelectedType_Monster_PsyDogPhantom] = g_pClsidManager->monster_psydogphantom; + + type_to_class[eSelectedType::kSelectedType_Weapon_Binocular] = g_pClsidManager->weapon_binocular; + type_to_class[eSelectedType::kSelectedType_Weapon_Knife] = g_pClsidManager->weapon_knife; + type_to_class[eSelectedType::kSelectedType_Weapon_BM16] = g_pClsidManager->weapon_bm16; + type_to_class[eSelectedType::kSelectedType_Weapon_Groza] = g_pClsidManager->weapon_groza; + type_to_class[eSelectedType::kSelectedType_Weapon_SVD] = g_pClsidManager->weapon_svd; + type_to_class[eSelectedType::kSelectedType_Weapon_AK74] = g_pClsidManager->weapon_ak74; + type_to_class[eSelectedType::kSelectedType_Weapon_LR300] = g_pClsidManager->weapon_lr300; + type_to_class[eSelectedType::kSelectedType_Weapon_HPSA] = g_pClsidManager->weapon_hpsa; + type_to_class[eSelectedType::kSelectedType_Weapon_PM] = g_pClsidManager->weapon_pm; + type_to_class[eSelectedType::kSelectedType_Weapon_RG6] = g_pClsidManager->weapon_rg6; + type_to_class[eSelectedType::kSelectedType_Weapon_RPG7] = g_pClsidManager->weapon_rpg7; + type_to_class[eSelectedType::kSelectedType_Weapon_Shotgun] = g_pClsidManager->weapon_shotgun; + type_to_class[eSelectedType::kSelectedType_Weapon_AutoShotgun] = g_pClsidManager->weapon_autoshotgun; + type_to_class[eSelectedType::kSelectedType_Weapon_SVU] = g_pClsidManager->weapon_svu; + type_to_class[eSelectedType::kSelectedType_Weapon_USP45] = g_pClsidManager->weapon_usp45; + type_to_class[eSelectedType::kSelectedType_Weapon_VAL] = g_pClsidManager->weapon_val; + type_to_class[eSelectedType::kSelectedType_Weapon_VINTOREZ] = g_pClsidManager->weapon_vintorez; + type_to_class[eSelectedType::kSelectedType_Weapon_WALTHER] = g_pClsidManager->weapon_walther; + type_to_class[eSelectedType::kSelectedType_Weapon_Magazine] = g_pClsidManager->weapon_magazine; + type_to_class[eSelectedType::kSelectedType_Weapon_StationaryMachineGun] = g_pClsidManager->weapon_stationary_machine_gun; + + for (const std::pair& pair : type_to_class) + { + class_to_type[pair.second] = pair.first; + } + + for (int i = 0; i < (eSelectedType::kSelectedType_Count); ++i) + { + char* pPtr = &category_names[i][0]; + const char* pStr = convertTypeToString(i); + + memcpy_s(pPtr, sizeof(category_names[i]), pStr, strlen(pStr)); + + combo_items[i] = pPtr; + } + } +} imgui_search_manager; + +void InitSections(); +void InitImGuiCLSIDInGame(); +void InitImGuiSearchInGame(); + +void RenderTimeManagerWindow(); +void RenderSpawnManagerWindow(); +void RenderWeaponManagerWindow(); +void RenderSearchManagerWindow(); + +void RegisterImGuiInGame(); +void execute_console_command_deferred(CConsole* c, LPCSTR string_to_execute); \ No newline at end of file diff --git a/src/xrGame/ImUtils/SearchManager.cpp b/src/xrGame/ImUtils/SearchManager.cpp index 64a2526ec4..ce436c00bc 100644 --- a/src/xrGame/ImUtils/SearchManager.cpp +++ b/src/xrGame/ImUtils/SearchManager.cpp @@ -9,371 +9,7 @@ #include "ai_space.h" -void execute_console_command_deferred(CConsole* c, LPCSTR string_to_execute); - -struct -{ - void add_weapon(CLASS_ID id) - { - if (weapons.find(id) == weapons.end()) - weapons.insert(id); - } - - void add_monster(CLASS_ID id) - { - if (monsters.find(id) == monsters.end()) - monsters.insert(id); - } - - bool is_weapon(CLASS_ID id) - { - return weapons.find(id) != weapons.end(); - } - - bool is_monster(CLASS_ID id) - { - return monsters.find(id) != monsters.end(); - } - - const xr_set& get_monsters(void) const { return monsters; } - const xr_set& get_weapons(void) const { return weapons; } - - const char* translateCLSID(CLASS_ID id) - { - char name[16]{}; - CLSID2TEXT(id, name); - - for (int i = 0; i < 16; ++i) - { - if (name[i] == 32) - { - name[i] = '\0'; - } - } - return g_pStringTable ? g_pStringTable->translate(name).c_str() : name; - } - - // reminder: information took from class_registrator.script because it overloads existed classes (clsids) - CLASS_ID artefact = TEXT2CLSID("SCRPTART"); - CLASS_ID car = TEXT2CLSID("SCRPTCAR"); - CLASS_ID stalker = TEXT2CLSID("AI_STL_S"); - CLASS_ID smart_terrain = TEXT2CLSID("SMRTTRRN"); - CLASS_ID smart_cover = TEXT2CLSID("SMRT_C_S"); - CLASS_ID level_changer = TEXT2CLSID("LVL_CHNG"); - CLASS_ID sim_squad_scripted = TEXT2CLSID("ON_OFF_S"); - CLASS_ID outfit = TEXT2CLSID("E_STLK"); - CLASS_ID pda = TEXT2CLSID("S_PDA"); - CLASS_ID food = TEXT2CLSID("S_FOOD"); - - CLASS_ID monster_bloodsucker = TEXT2CLSID("SM_BLOOD"); - CLASS_ID monster_boar = TEXT2CLSID("SM_BOARW"); - CLASS_ID monster_dog = TEXT2CLSID("SM_DOG_S"); - CLASS_ID monster_flesh = TEXT2CLSID("SM_FLESH"); - CLASS_ID monster_pseudodog = TEXT2CLSID("SM_P_DOG"); - CLASS_ID monster_burer = TEXT2CLSID("SM_BURER"); - CLASS_ID monster_cat = TEXT2CLSID("SM_CAT_S"); - CLASS_ID monster_chimera = TEXT2CLSID("SM_CHIMS"); - CLASS_ID monster_controller = TEXT2CLSID("SM_CONTR"); - CLASS_ID monster_izlom = TEXT2CLSID("SM_IZLOM"); - CLASS_ID monster_poltergeist = TEXT2CLSID("SM_POLTR"); - CLASS_ID monster_pseudogigant = TEXT2CLSID("SM_GIANT"); - CLASS_ID monster_zombie = TEXT2CLSID("SM_ZOMBI"); - CLASS_ID monster_snork = TEXT2CLSID("SM_SNORK"); - CLASS_ID monster_tushkano = TEXT2CLSID("SM_TUSHK"); - CLASS_ID monster_psydog = TEXT2CLSID("SM_DOG_P"); - CLASS_ID monster_psydogphantom = TEXT2CLSID("SM_DOG_F"); - - CLASS_ID weapon_binocular = TEXT2CLSID("WP_BINOC"); - CLASS_ID weapon_knife = TEXT2CLSID("WP_KNIFE"); - CLASS_ID weapon_bm16 = TEXT2CLSID("WP_BM16"); - CLASS_ID weapon_groza = TEXT2CLSID("WP_GROZA"); - CLASS_ID weapon_svd = TEXT2CLSID("WP_SVD"); - CLASS_ID weapon_ak74 = TEXT2CLSID("WP_AK74"); - CLASS_ID weapon_lr300 = TEXT2CLSID("WP_LR300"); - CLASS_ID weapon_hpsa = TEXT2CLSID("WP_HPSA"); - CLASS_ID weapon_pm = TEXT2CLSID("WP_PM"); - CLASS_ID weapon_rg6 = TEXT2CLSID("WP_RG6"); - CLASS_ID weapon_rpg7 = TEXT2CLSID("WP_RPG7"); - CLASS_ID weapon_shotgun = TEXT2CLSID("WP_SHOTG"); - CLASS_ID weapon_autoshotgun = TEXT2CLSID("WP_ASHTG"); - CLASS_ID weapon_svu = TEXT2CLSID("WP_SVU"); - CLASS_ID weapon_usp45 = TEXT2CLSID("WP_USP45"); - CLASS_ID weapon_val = TEXT2CLSID("WP_VAL"); - CLASS_ID weapon_vintorez = TEXT2CLSID("WP_VINT"); - CLASS_ID weapon_walther = TEXT2CLSID("WP_WALTH"); - CLASS_ID weapon_magazine = TEXT2CLSID("WP_MAGAZ"); - CLASS_ID weapon_stationary_machine_gun = TEXT2CLSID("W_STMGUN"); - -private: - xr_set weapons; - xr_set monsters; - xr_set zones; - xr_set devices; - -} - -imgui_clsid_manager; - - -enum eSelectedType { - kSelectedType_All, - kSelectedType_SmartTerrain, - kSelectedType_SmartCover, - kSelectedType_LevelChanger, - kSelectedType_Artefact, - kSelectedType_Stalker, - kSelectedType_Car, - kSelectedType_Monster_All, - kSelectedType_Monster_BloodSucker, - kSelectedType_Monster_Boar, - kSelectedType_Monster_Dog, - kSelectedType_Monster_Flesh, - kSelectedType_Monster_PseudoDog, - kSelectedType_Monster_Burer, - kSelectedType_Monster_Cat, - kSelectedType_Monster_Chimera, - kSelectedType_Monster_Controller, - kSelectedType_Monster_Izlom, - kSelectedType_Monster_Poltergeist, - kSelectedType_Monster_PseudoGigant, - kSelectedType_Monster_Zombie, - kSelectedType_Monster_Snork, - kSelectedType_Monster_Tushkano, - kSelectedType_Monster_PsyDog, - kSelectedType_Monster_PsyDogPhantom, - kSelectedType_Weapon_All, - kSelectedType_Weapon_Binocular, - kSelectedType_Weapon_Knife, - kSelectedType_Weapon_BM16, - kSelectedType_Weapon_Groza, - kSelectedType_Weapon_SVD, - kSelectedType_Weapon_AK74, - kSelectedType_Weapon_LR300, - kSelectedType_Weapon_HPSA, - kSelectedType_Weapon_PM, - kSelectedType_Weapon_RG6, - kSelectedType_Weapon_RPG7, - kSelectedType_Weapon_Shotgun, - kSelectedType_Weapon_AutoShotgun, - kSelectedType_Weapon_SVU, - kSelectedType_Weapon_USP45, - kSelectedType_Weapon_VAL, - kSelectedType_Weapon_VINTOREZ, - kSelectedType_Weapon_WALTHER, - kSelectedType_Weapon_Magazine, - kSelectedType_Weapon_StationaryMachineGun, - kSelectedType_Count -}; - -struct { - - bool show_alive_creatures{}; - int selected_type{}; - char search_string[256]{}; - char category_names[(eSelectedType::kSelectedType_Count)][32]; - const char* combo_items[(eSelectedType::kSelectedType_Count)]{}; - int counts[(eSelectedType::kSelectedType_Count)]{}; - - xr_hash_map type_to_class; - xr_hash_map class_to_type; - - eSelectedType convertCLSIDToType(CLASS_ID id) - { - eSelectedType result = eSelectedType::kSelectedType_Count; - - if (class_to_type.find(id) != class_to_type.end()) - result = class_to_type.at(id); - - return result; - } - - const char* convertTypeToString(int type) - { - switch (static_cast(type)) - { - case eSelectedType::kSelectedType_All: - { - return "All"; - } - case eSelectedType::kSelectedType_Monster_All: - { - return "Monster - All"; - } - case eSelectedType::kSelectedType_Weapon_All: - { - return "Weapon - All"; - } - } - - - if (type_to_class.find(eSelectedType(type)) != type_to_class.end()) - { - char name[16]{}; - CLASS_ID id = type_to_class.at(eSelectedType(type)); - CLSID2TEXT(id, name); - - for (int i = 0; i < 16; ++i) - { - if (name[i] == 32) - { - name[i] = '\0'; - } - } - const char* pTranslatedName = g_pStringTable ? g_pStringTable->translate(name).c_str() : name; - char result[32]{}; - - - if (imgui_clsid_manager.is_monster(id)) - { - memcpy_s(result, sizeof(result), "Monster - ", sizeof("Monster - ")); - memcpy_s(&result[0] + sizeof("Monster -"), sizeof(result), pTranslatedName, strlen(pTranslatedName)); - } - else if (imgui_clsid_manager.is_weapon(id)) - { - memcpy_s(result, sizeof(result), "Weapon - ", sizeof("Weapon - ")); - memcpy_s(&result[0] + sizeof("Weapon -"), sizeof(result), pTranslatedName, strlen(pTranslatedName)); - } - else - { - memcpy_s(result, sizeof(result), pTranslatedName, strlen(pTranslatedName)); - } - - return result; - } - - return "unknown"; - } - - bool filter(CLASS_ID id) - { - bool result{}; - - if (selected_type == eSelectedType::kSelectedType_All) - { - result = true; - return result; - } - - if (selected_type == eSelectedType::kSelectedType_Monster_All) - { - if (imgui_clsid_manager.is_monster(id)) - { - result = true; - return result; - } - } - - if (selected_type == eSelectedType::kSelectedType_Weapon_All) - { - if (imgui_clsid_manager.is_weapon(id)) - { - result = true; - return result; - } - } - - if (class_to_type.find(id) != class_to_type.end()) - { - result = selected_type == class_to_type.at(id); - } - - return result; - } - - void count(CLASS_ID id) - { - counts[(eSelectedType::kSelectedType_All)] += 1; - - if (imgui_clsid_manager.is_monster(id)) - { - counts[eSelectedType::kSelectedType_Monster_All] += 1; - - if (class_to_type.find(id) != class_to_type.end()) - counts[class_to_type.at(id)] += 1; - - } - else if (imgui_clsid_manager.is_weapon(id)) - { - counts[eSelectedType::kSelectedType_Weapon_All] += 1; - - if (class_to_type.find(id) != class_to_type.end()) - counts[class_to_type.at(id)] += 1; - } - else - { - if (class_to_type.find(id) != class_to_type.end()) - { - counts[class_to_type.at(id)] += 1; - } - } - } - - void init() - { - type_to_class[eSelectedType::kSelectedType_SmartTerrain] = imgui_clsid_manager.smart_terrain; - type_to_class[eSelectedType::kSelectedType_SmartCover] = imgui_clsid_manager.smart_cover; - type_to_class[eSelectedType::kSelectedType_LevelChanger] = imgui_clsid_manager.level_changer; - type_to_class[eSelectedType::kSelectedType_Artefact] = imgui_clsid_manager.artefact; - type_to_class[eSelectedType::kSelectedType_Stalker] = imgui_clsid_manager.stalker; - type_to_class[eSelectedType::kSelectedType_Car] = imgui_clsid_manager.car; - type_to_class[eSelectedType::kSelectedType_Monster_BloodSucker] = imgui_clsid_manager.monster_bloodsucker; - type_to_class[eSelectedType::kSelectedType_Monster_Boar] = imgui_clsid_manager.monster_boar; - type_to_class[eSelectedType::kSelectedType_Monster_Dog] = imgui_clsid_manager.monster_dog; - type_to_class[eSelectedType::kSelectedType_Monster_Flesh] = imgui_clsid_manager.monster_flesh; - type_to_class[eSelectedType::kSelectedType_Monster_PseudoDog] = imgui_clsid_manager.monster_pseudodog; - type_to_class[eSelectedType::kSelectedType_Monster_Burer] = imgui_clsid_manager.monster_burer; - type_to_class[eSelectedType::kSelectedType_Monster_Cat] = imgui_clsid_manager.monster_cat; - type_to_class[eSelectedType::kSelectedType_Monster_Chimera] = imgui_clsid_manager.monster_chimera; - type_to_class[eSelectedType::kSelectedType_Monster_Controller] = imgui_clsid_manager.monster_controller; - type_to_class[eSelectedType::kSelectedType_Monster_Izlom] = imgui_clsid_manager.monster_izlom; - type_to_class[eSelectedType::kSelectedType_Monster_Poltergeist] = imgui_clsid_manager.monster_poltergeist; - type_to_class[eSelectedType::kSelectedType_Monster_PseudoGigant] = imgui_clsid_manager.monster_pseudogigant; - type_to_class[eSelectedType::kSelectedType_Monster_Zombie] = imgui_clsid_manager.monster_zombie; - type_to_class[eSelectedType::kSelectedType_Monster_Snork] = imgui_clsid_manager.monster_snork; - type_to_class[eSelectedType::kSelectedType_Monster_Tushkano] = imgui_clsid_manager.monster_tushkano; - type_to_class[eSelectedType::kSelectedType_Monster_PsyDog] = imgui_clsid_manager.monster_psydog; - type_to_class[eSelectedType::kSelectedType_Monster_PsyDogPhantom] = imgui_clsid_manager.monster_psydogphantom; - - - type_to_class[eSelectedType::kSelectedType_Weapon_Binocular] = imgui_clsid_manager.weapon_binocular; - type_to_class[eSelectedType::kSelectedType_Weapon_Knife] = imgui_clsid_manager.weapon_knife; - type_to_class[eSelectedType::kSelectedType_Weapon_BM16] = imgui_clsid_manager.weapon_bm16; - type_to_class[eSelectedType::kSelectedType_Weapon_Groza] = imgui_clsid_manager.weapon_groza; - type_to_class[eSelectedType::kSelectedType_Weapon_SVD] = imgui_clsid_manager.weapon_svd; - type_to_class[eSelectedType::kSelectedType_Weapon_AK74] = imgui_clsid_manager.weapon_ak74; - type_to_class[eSelectedType::kSelectedType_Weapon_LR300] = imgui_clsid_manager.weapon_lr300; - type_to_class[eSelectedType::kSelectedType_Weapon_HPSA] = imgui_clsid_manager.weapon_hpsa; - type_to_class[eSelectedType::kSelectedType_Weapon_PM] = imgui_clsid_manager.weapon_pm; - type_to_class[eSelectedType::kSelectedType_Weapon_RG6] = imgui_clsid_manager.weapon_rg6; - type_to_class[eSelectedType::kSelectedType_Weapon_RPG7] = imgui_clsid_manager.weapon_rpg7; - type_to_class[eSelectedType::kSelectedType_Weapon_Shotgun] = imgui_clsid_manager.weapon_shotgun; - type_to_class[eSelectedType::kSelectedType_Weapon_AutoShotgun] = imgui_clsid_manager.weapon_autoshotgun; - type_to_class[eSelectedType::kSelectedType_Weapon_SVU] = imgui_clsid_manager.weapon_svu; - type_to_class[eSelectedType::kSelectedType_Weapon_USP45] = imgui_clsid_manager.weapon_usp45; - type_to_class[eSelectedType::kSelectedType_Weapon_VAL] = imgui_clsid_manager.weapon_val; - type_to_class[eSelectedType::kSelectedType_Weapon_VINTOREZ] = imgui_clsid_manager.weapon_vintorez; - type_to_class[eSelectedType::kSelectedType_Weapon_WALTHER] = imgui_clsid_manager.weapon_walther; - type_to_class[eSelectedType::kSelectedType_Weapon_Magazine] = imgui_clsid_manager.weapon_magazine; - type_to_class[eSelectedType::kSelectedType_Weapon_StationaryMachineGun] = imgui_clsid_manager.weapon_stationary_machine_gun; - - for (const std::pair& pair : type_to_class) - { - class_to_type[pair.second] = pair.first; - } - - for (int i = 0; i < (eSelectedType::kSelectedType_Count); ++i) - { - char* pPtr = &category_names[i][0]; - const char* pStr = convertTypeToString(i); - - memcpy_s(pPtr, sizeof(category_names[i]), pStr, strlen(pStr)); - - combo_items[i] = pPtr; - } - } -} - -imgui_search_manager; +#include "ImUtils.h" void RenderSearchManagerWindow() { @@ -386,6 +22,9 @@ void RenderSearchManagerWindow() if (!ai().get_alife()) return; + if (g_pClsidManager == nullptr) + return; + if (ImGui::Begin("Search Manager"), &Engine.External.EditorStates[static_cast(EditorUI::Game_SearchManager)]) { constexpr size_t kItemSize = sizeof(imgui_search_manager.combo_items) / sizeof(imgui_search_manager.combo_items[0]); @@ -408,10 +47,10 @@ void RenderSearchManagerWindow() if (ImGui::CollapsingHeader(colh_monsters)) { - for (const auto& id : imgui_clsid_manager.get_monsters()) + for (const auto& id : g_pClsidManager->get_monsters()) { char monster_name[32]{}; - sprintf_s(monster_name, sizeof(monster_name), "%s: %d", imgui_clsid_manager.translateCLSID(id), imgui_search_manager.counts[imgui_search_manager.convertCLSIDToType(id)]); + sprintf_s(monster_name, sizeof(monster_name), "%s: %d", g_pClsidManager->translateCLSID(id), imgui_search_manager.counts[imgui_search_manager.convertCLSIDToType(id)]); ImGui::Text(monster_name); } } @@ -421,10 +60,10 @@ void RenderSearchManagerWindow() if (ImGui::CollapsingHeader(colh_weapons)) { - for (const auto& id : imgui_clsid_manager.get_weapons()) + for (const auto& id : g_pClsidManager->get_weapons()) { char weapon_name[32]{}; - sprintf_s(weapon_name, sizeof(weapon_name), "%s: %d", imgui_clsid_manager.translateCLSID(id), imgui_search_manager.counts[imgui_search_manager.convertCLSIDToType(id)]); + sprintf_s(weapon_name, sizeof(weapon_name), "%s: %d", g_pClsidManager->translateCLSID(id), imgui_search_manager.counts[imgui_search_manager.convertCLSIDToType(id)]); ImGui::Text(weapon_name); } } @@ -501,9 +140,7 @@ void RenderSearchManagerWindow() if (passed_filter) { - xr_string name; - - name = pObject->cName().c_str(); + xr_string name = pObject->cName().c_str(); if (pCasted) { @@ -540,8 +177,6 @@ void RenderSearchManagerWindow() ImGui::Text("translated name: [%s]", Platform::ANSI_TO_UTF8(g_pStringTable->translate(pCasted->Name()).c_str()).c_str()); ImGui::Text("position: %f %f %f", pObject->Position().x, pObject->Position().y, pObject->Position().z); - - ImGui::EndTooltip(); } } @@ -613,46 +248,138 @@ void RenderSearchManagerWindow() } } +clsid_manager imgui_clsid_manager; + void InitImGuiCLSIDInGame() { - imgui_clsid_manager.add_monster(TEXT2CLSID("SM_BLOOD")); - imgui_clsid_manager.add_monster(TEXT2CLSID("SM_BOARW")); - imgui_clsid_manager.add_monster(TEXT2CLSID("SM_DOG_S")); - imgui_clsid_manager.add_monster(TEXT2CLSID("SM_FLESH")); - imgui_clsid_manager.add_monster(TEXT2CLSID("SM_P_DOG")); - imgui_clsid_manager.add_monster(TEXT2CLSID("SM_BURER")); - imgui_clsid_manager.add_monster(TEXT2CLSID("SM_CAT_S")); - imgui_clsid_manager.add_monster(TEXT2CLSID("SM_CHIMS")); - imgui_clsid_manager.add_monster(TEXT2CLSID("SM_CONTR")); - imgui_clsid_manager.add_monster(TEXT2CLSID("SM_IZLOM")); - imgui_clsid_manager.add_monster(TEXT2CLSID("SM_POLTR")); - imgui_clsid_manager.add_monster(TEXT2CLSID("SM_GIANT")); - imgui_clsid_manager.add_monster(TEXT2CLSID("SM_ZOMBI")); - imgui_clsid_manager.add_monster(TEXT2CLSID("SM_SNORK")); - imgui_clsid_manager.add_monster(TEXT2CLSID("SM_TUSHK")); - imgui_clsid_manager.add_monster(TEXT2CLSID("SM_DOG_P")); - imgui_clsid_manager.add_monster(TEXT2CLSID("SM_DOG_F")); - - imgui_clsid_manager.add_weapon(TEXT2CLSID("WP_BINOC")); - imgui_clsid_manager.add_weapon(TEXT2CLSID("WP_KNIFE")); - imgui_clsid_manager.add_weapon(TEXT2CLSID("WP_BM16")); - imgui_clsid_manager.add_weapon(TEXT2CLSID("WP_GROZA")); - imgui_clsid_manager.add_weapon(TEXT2CLSID("WP_SVD")); - imgui_clsid_manager.add_weapon(TEXT2CLSID("WP_AK74")); - imgui_clsid_manager.add_weapon(TEXT2CLSID("WP_LR300")); - imgui_clsid_manager.add_weapon(TEXT2CLSID("WP_HPSA")); - imgui_clsid_manager.add_weapon(TEXT2CLSID("WP_PM")); - imgui_clsid_manager.add_weapon(TEXT2CLSID("WP_RG6")); - imgui_clsid_manager.add_weapon(TEXT2CLSID("WP_RPG7")); - imgui_clsid_manager.add_weapon(TEXT2CLSID("WP_SHOTG")); - imgui_clsid_manager.add_weapon(TEXT2CLSID("WP_ASHTG")); - imgui_clsid_manager.add_weapon(TEXT2CLSID("WP_MAGAZ")); - imgui_clsid_manager.add_weapon(TEXT2CLSID("WP_SVU")); - imgui_clsid_manager.add_weapon(TEXT2CLSID("WP_USP45")); - imgui_clsid_manager.add_weapon(TEXT2CLSID("WP_VAL")); - imgui_clsid_manager.add_weapon(TEXT2CLSID("WP_VINT")); - imgui_clsid_manager.add_weapon(TEXT2CLSID("WP_WALTH")); - imgui_clsid_manager.add_weapon(TEXT2CLSID("W_STMGUN")); + imgui_clsid_manager.add_monster(imgui_clsid_manager.monster_bloodsucker); + imgui_clsid_manager.add_monster(imgui_clsid_manager.monster_boar); + imgui_clsid_manager.add_monster(imgui_clsid_manager.monster_dog); + imgui_clsid_manager.add_monster(imgui_clsid_manager.monster_flesh); + imgui_clsid_manager.add_monster(imgui_clsid_manager.monster_pseudodog); + imgui_clsid_manager.add_monster(imgui_clsid_manager.monster_burer); + imgui_clsid_manager.add_monster(imgui_clsid_manager.monster_cat); + imgui_clsid_manager.add_monster(imgui_clsid_manager.monster_chimera); + imgui_clsid_manager.add_monster(imgui_clsid_manager.monster_controller); + imgui_clsid_manager.add_monster(imgui_clsid_manager.monster_izlom); + imgui_clsid_manager.add_monster(imgui_clsid_manager.monster_poltergeist); + imgui_clsid_manager.add_monster(imgui_clsid_manager.monster_pseudogigant); + imgui_clsid_manager.add_monster(imgui_clsid_manager.monster_zombie); + imgui_clsid_manager.add_monster(imgui_clsid_manager.monster_snork); + imgui_clsid_manager.add_monster(imgui_clsid_manager.monster_tushkano); + imgui_clsid_manager.add_monster(imgui_clsid_manager.monster_psydog); + imgui_clsid_manager.add_monster(imgui_clsid_manager.monster_psydogphantom); + + imgui_clsid_manager.add_weapon(imgui_clsid_manager.weapon_binocular); + imgui_clsid_manager.add_weapon(imgui_clsid_manager.weapon_knife); + imgui_clsid_manager.add_weapon(imgui_clsid_manager.weapon_bm16); + imgui_clsid_manager.add_weapon(imgui_clsid_manager.weapon_groza); + imgui_clsid_manager.add_weapon(imgui_clsid_manager.weapon_svd); + imgui_clsid_manager.add_weapon(imgui_clsid_manager.weapon_ak74); + imgui_clsid_manager.add_weapon(imgui_clsid_manager.weapon_lr300); + imgui_clsid_manager.add_weapon(imgui_clsid_manager.weapon_hpsa); + imgui_clsid_manager.add_weapon(imgui_clsid_manager.weapon_pm); + imgui_clsid_manager.add_weapon(imgui_clsid_manager.weapon_rg6); + imgui_clsid_manager.add_weapon(imgui_clsid_manager.weapon_rpg7); + imgui_clsid_manager.add_weapon(imgui_clsid_manager.weapon_shotgun); + imgui_clsid_manager.add_weapon(imgui_clsid_manager.weapon_autoshotgun); + imgui_clsid_manager.add_weapon(imgui_clsid_manager.weapon_svu); + imgui_clsid_manager.add_weapon(imgui_clsid_manager.weapon_usp45); + imgui_clsid_manager.add_weapon(imgui_clsid_manager.weapon_val); + imgui_clsid_manager.add_weapon(imgui_clsid_manager.weapon_vintorez); + imgui_clsid_manager.add_weapon(imgui_clsid_manager.weapon_walther); + imgui_clsid_manager.add_weapon(imgui_clsid_manager.weapon_magazine); + imgui_clsid_manager.add_weapon(imgui_clsid_manager.weapon_stationary_machine_gun); + + imgui_clsid_manager.add_item(imgui_clsid_manager.item_torch); + imgui_clsid_manager.add_item(imgui_clsid_manager.item_detector_scientific); + imgui_clsid_manager.add_item(imgui_clsid_manager.item_detector_elite); + imgui_clsid_manager.add_item(imgui_clsid_manager.item_detector_advanced); + imgui_clsid_manager.add_item(imgui_clsid_manager.item_detector_simple); + imgui_clsid_manager.add_item(imgui_clsid_manager.item_d_pda); + imgui_clsid_manager.add_item(imgui_clsid_manager.item_pda); + imgui_clsid_manager.add_item(imgui_clsid_manager.item_medkit); + imgui_clsid_manager.add_item(imgui_clsid_manager.item_bandage); + imgui_clsid_manager.add_item(imgui_clsid_manager.item_antirad); + imgui_clsid_manager.add_item(imgui_clsid_manager.item_food); + imgui_clsid_manager.add_item(imgui_clsid_manager.item_bottle); + imgui_clsid_manager.add_item(imgui_clsid_manager.item_ii_attch); + + imgui_clsid_manager.add_ammo(imgui_clsid_manager.ammo_base); + imgui_clsid_manager.add_ammo(imgui_clsid_manager.ammo_vog25); + imgui_clsid_manager.add_ammo(imgui_clsid_manager.ammo_og7b); + imgui_clsid_manager.add_ammo(imgui_clsid_manager.ammo_m209); + imgui_clsid_manager.add_ammo(imgui_clsid_manager.ammo_f1); + imgui_clsid_manager.add_ammo(imgui_clsid_manager.ammo_rgd5); + + imgui_clsid_manager.add_outfit(imgui_clsid_manager.outfit); + imgui_clsid_manager.add_outfit(imgui_clsid_manager.helmet); + + imgui_clsid_manager.add_addon(imgui_clsid_manager.addon_scope); + imgui_clsid_manager.add_addon(imgui_clsid_manager.addon_silen); + imgui_clsid_manager.add_addon(imgui_clsid_manager.addon_glaun); + + imgui_clsid_manager.add_artefact(imgui_clsid_manager.artefact); + imgui_clsid_manager.add_artefact(imgui_clsid_manager.artefact_s); + + imgui_clsid_manager.add_vehicle(imgui_clsid_manager.car); + + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_helmet); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_out_exo); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_out_military); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_out_scientific); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_out_stalker); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_weapon_ak74); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_weapon_magazine_gl); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_weapon_binocular); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_weapon_bm16); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_weapon_fn2000); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_weapon_fort); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_weapon_groza); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_weapon_hpsa); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_weapon_knife); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_weapon_lr300); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_weapon_magazine); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_weapon_pm); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_weapon_rg6); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_weapon_rpg7); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_weapon_shotgun); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_weapon_svd); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_weapon_svu); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_weapon_usp45); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_weapon_val); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_weapon_vintorez); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_weapon_walther); + + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_ammo_base); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_ammo_og7b); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_ammo_m209); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_ammo_vog25); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_f1); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_rgd5); + //imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_rpg7); + + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_art_mercury_ball); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_art_black_drops); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_art_needles); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_art_bast_artefact); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_art_gravi_black); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_art_dummy); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_art_zuda); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_art_thorn); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_art_faded_ball); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_art_electric_ball); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_art_rusty_hair); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_art_galantine); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_art_gravi); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_art_cta); + + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_addon_scope); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_addon_silen); + imgui_clsid_manager.add_mp_stuff(imgui_clsid_manager.mp_addon_glaun); + + + g_pClsidManager = &imgui_clsid_manager; } diff --git a/src/xrGame/ImUtils/SpawnManager.cpp b/src/xrGame/ImUtils/SpawnManager.cpp index af9521a482..312005a1dd 100644 --- a/src/xrGame/ImUtils/SpawnManager.cpp +++ b/src/xrGame/ImUtils/SpawnManager.cpp @@ -6,709 +6,870 @@ #include "../alife_time_manager.h" #include "../ui/UIInventoryUtilities.h" -#include "../xrEngine/XR_IOConsole.h" -#include "../xrEngine/string_table.h" - #include "ai_space.h" +#include "ImUtils.h" + +using Section = xr_vector>; +struct SectionData +{ + Section Sorted{}; + Section Unsorted{}; +}; struct { // weapon tab - bool weapon_sort_by_max_cost{}; + bool sort_by_max_cost{}; bool weapon_sort_by_max_hit_power{}; bool weapon_sort_by_max_fire_distance{}; - bool weapon_sort_by_min_cost{}; + bool sort_by_min_cost{}; bool weapon_sort_by_min_hit_power{}; bool weapon_sort_by_min_fire_distance{}; - bool weapon_spawn_on_level{}; - char weapon_spawn_count[3]{}; + bool spawn_on_level{}; + char spawn_count[4]{}; // weapon tab + + SectionData WeaponsSections = {}; + SectionData ItemsSections = {}; + SectionData AmmoSections = {}; + SectionData OutfitSections = {}; + SectionData AddonSections = {}; + SectionData ArtefactSections = {}; + SectionData MpStuffSections = {}; + + Section Vehicles{}; + Section Others{}; +} imgui_spawn_manager; + + +static void SectionStatistics(const SectionData& sections) { + size_t total = sections.Sorted.size() + sections.Unsorted.size(); + ImGui::Text("Total sections count: %zu", total); + ImGui::Text("Total sections count (can be sorted): %zu", sections.Sorted.size()); + ImGui::Text("Total sections count (can't be sorted): %zu", sections.Unsorted.size()); + ImGui::Separator(); } -imgui_spawn_manager; +constexpr size_t kSpawnManagerMaxSectionName = 64; -extern CSE_Abstract* CALifeSimulator__spawn_item2(CALifeSimulator* self_, LPCSTR section, const Fvector& position, - u32 level_vertex_id, GameGraph::_GRAPH_ID game_vertex_id, ALife::_OBJECT_ID id_parent); -void execute_console_command_deferred(CConsole* c, LPCSTR string_to_execute); +float SpawnManager_ParseHitPower(const shared_str& hit_str); +void SpawnManager_RenderTooltip(CInifile::Sect* section); +bool SpawnManager_RenderButtonOrImage(CInifile::Sect* section, const char* imname); +void SpawnManager_HandleButtonPress(CInifile::Sect* section); +void SpawnManager_ProcessSections(Section& sections, size_t& number_imgui); -void RenderSpawnManagerWindow() +void InitSections() { + if (g_pClsidManager == nullptr) + { + R_ASSERT(!"! clsid manager uninitialized!"); + return; + } + + //xr_set classes = {}; + for (const auto& pSection : pSettings->sections()) + { + if (pSection == nullptr) + continue; + + std::string_view name = pSection->Name.c_str(); + + if (name.empty()) + continue; + + if (!pSection->line_exist("class")) + continue; + + CLASS_ID classId = pSettings->r_clsid(name.data(), "class"); + + bool isInvItem = pSection->line_exist("cost") && pSection->line_exist("inv_weight"); + size_t mp_index = name.find("mp_"); + if (g_pClsidManager->is_mp_stuff(classId) || (mp_index != std::string_view::npos && mp_index == 0)) + { + if (isInvItem) + { + imgui_spawn_manager.MpStuffSections.Sorted.push_back({ name, pSection }); + } + else + { + imgui_spawn_manager.MpStuffSections.Unsorted.push_back({ name, pSection }); + } + } + else if (g_pClsidManager->is_weapon(classId)) + { + if (isInvItem) + { + imgui_spawn_manager.WeaponsSections.Sorted.push_back({ name, pSection }); + } + else + { + imgui_spawn_manager.WeaponsSections.Unsorted.push_back({ name, pSection }); + } + } + else if (g_pClsidManager->is_item(classId)) + { + if (!pSection->line_exist("immunities_sect")) + continue; + + if (isInvItem) + { + imgui_spawn_manager.ItemsSections.Sorted.push_back({ name, pSection }); + } + else + { + imgui_spawn_manager.ItemsSections.Unsorted.push_back({ name, pSection }); + } + } + else if (g_pClsidManager->is_ammo(classId)) + { + if (isInvItem) + { + imgui_spawn_manager.AmmoSections.Sorted.push_back({ name, pSection }); + } + else + { + imgui_spawn_manager.AmmoSections.Unsorted.push_back({ name, pSection }); + } + } + else if (g_pClsidManager->is_outfit(classId)) + { + if (isInvItem) + { + imgui_spawn_manager.OutfitSections.Sorted.push_back({ name, pSection }); + } + else + { + imgui_spawn_manager.OutfitSections.Unsorted.push_back({ name, pSection }); + } + } + else if (g_pClsidManager->is_addon(classId)) + { + if (isInvItem) + { + imgui_spawn_manager.AddonSections.Sorted.push_back({ name, pSection }); + } + else + { + imgui_spawn_manager.AddonSections.Unsorted.push_back({ name, pSection }); + } + } + else if (g_pClsidManager->is_artefact(classId)) + { + if (isInvItem) + { + imgui_spawn_manager.ArtefactSections.Sorted.push_back({ name, pSection }); + } + else + { + imgui_spawn_manager.ArtefactSections.Unsorted.push_back({ name, pSection }); + } + } + else if (g_pClsidManager->is_vehicle(classId)) + { + imgui_spawn_manager.Vehicles.push_back({ name, pSection }); + } + else { + //string32 temp; CLSID2TEXT(classId, temp); + //classes.insert(temp); + + imgui_spawn_manager.Others.push_back({ name, pSection }); + } + } +} + +void RenderSpawnManagerWindow() { if (!Engine.External.EditorStates[static_cast(EditorUI::Game_SpawnManager)]) return; - if (!g_pGameLevel) + if (g_pGameLevel == nullptr) return; - if (!ai().get_alife()) + if (ai().get_alife() == nullptr) return; - if (!g_pStringTable) + if (g_pClsidManager == nullptr) return; - constexpr size_t kSpawnManagerMaxSectionName = 64; + auto maxSortCost = [](Section& collection) + { + std::sort(collection.begin(), collection.end(), [](const auto& pair_left, const auto& pair_right)->bool + { + if (pair_left.second && pair_right.second) + { + const char* pLeftName = pair_left.first.data(); + const char* pRightName = pair_right.first.data(); + + float cost_left{}; + float cost_right{}; + + if (pSettings->line_exist(pLeftName, "cost")) + { + cost_left = pSettings->r_float(pLeftName, "cost"); + } + + if (pSettings->line_exist(pRightName, "cost")) + { + cost_right = pSettings->r_float(pRightName, "cost"); + } + + return cost_left > cost_right; + } + + return false; + }); + }; + + auto minSortCost = [](Section& collection) + { + std::sort(collection.begin(), collection.end(), [](const auto& pair_left, const auto& pair_right) -> bool + { + if (pair_left.second && pair_right.second) + { + const char* pLeftName = pair_left.first.data(); + const char* pRightName = pair_right.first.data(); + + float value_left{}; + float value_right{}; + + if (pSettings->line_exist(pLeftName, "cost")) + { + value_left = pSettings->r_float(pLeftName, "cost"); + } + + if (pSettings->line_exist(pRightName, "cost")) + { + value_right = pSettings->r_float(pRightName, "cost"); + } + + return value_left < value_right; + } + + return false; + }); + }; if (ImGui::Begin("Spawn Manager", &Engine.External.EditorStates[static_cast(EditorUI::Game_SpawnManager)])) { - if (ImGui::BeginTabBar("##TabBar_InGameSpawnManager")) + if (ImGui::Checkbox("spawn on Level", &imgui_spawn_manager.spawn_on_level)) { - if (ImGui::BeginTabItem("Items")) - { + } + ImGui::SetItemTooltip("if this checkbox is enabled that means it will spawn on level not in inventory"); + ImGui::InputText("count##IT_InGameSpawnManager", imgui_spawn_manager.spawn_count, sizeof(imgui_spawn_manager).spawn_count); + ImGui::SetItemTooltip("How many items to spawn by one click, from 1 to specified number by user input"); + if (ImGui::Checkbox("sort by max cost##CheckBox_InGameSpawnManager", &imgui_spawn_manager.sort_by_max_cost)) + { + imgui_spawn_manager.sort_by_min_cost = false; + } + ImGui::SetItemTooltip("Sorts items by maximum cost field that defined in weapon section in ltx file"); + if (ImGui::Checkbox("sort by min cost##CheckBox_InGameSpawnManager", &imgui_spawn_manager.sort_by_min_cost)) + { + imgui_spawn_manager.sort_by_max_cost = false; + } + ImGui::SetItemTooltip("Sorts items by minimal cost field that defined in weapon section in ltx file"); - ImGui::EndTabItem(); - } + ImGui::Separator(); - if (ImGui::BeginTabItem("Artefacts")) + if (ImGui::BeginTabBar("##TabBar_InGameSpawnManager")) + { + if (ImGui::BeginTabItem("Items")) { + size_t number_imgui{}; + SectionStatistics(imgui_spawn_manager.ItemsSections); + SpawnManager_ProcessSections(imgui_spawn_manager.ItemsSections.Sorted, number_imgui); + if (imgui_spawn_manager.sort_by_max_cost) + { + maxSortCost(imgui_spawn_manager.ItemsSections.Sorted); + } + else if (imgui_spawn_manager.sort_by_min_cost) + { + minSortCost(imgui_spawn_manager.ItemsSections.Sorted); + } - + if (imgui_spawn_manager.ItemsSections.Unsorted.size() > 0) + { + ImGui::SeparatorText("Unsorted"); + SpawnManager_ProcessSections(imgui_spawn_manager.ItemsSections.Unsorted, number_imgui); + } ImGui::EndTabItem(); } if (ImGui::BeginTabItem("Weapons")) { - if (pSettings) - { - size_t total_count_sort{}; - size_t total_count_unsort{}; - - auto translate_difficulty = [](ESingleGameDifficulty value) -> const char* { - switch (value) - { - case egdNovice: - { - return "novice"; - } - case egdStalker: - { - return "stalker"; - } - case egdVeteran: - { - return "veteran"; - } - case egdMaster: - { - return "master"; - } - default: - return "unknown"; - } - }; - - /* for fast disabling copy and paste (but delete what is necessary) - imgui_spawn_manager.weapon_sort_by_max_cost = false; - imgui_spawn_manager.weapon_sort_by_max_hit_power = false; - imgui_spawn_manager.weapon_sort_by_max_fire_distance = false; - imgui_spawn_manager.weapon_sort_by_min_cost = false; - imgui_spawn_manager.weapon_sort_by_min_hit_power = false; - imgui_spawn_manager.weapon_sort_by_min_fire_distance = false; - */ - - if (ImGui::Checkbox("sort by max cost##CheckBox_InGameSpawnManager", &imgui_spawn_manager.weapon_sort_by_max_cost)) + auto translate_difficulty = [](ESingleGameDifficulty value) -> const char* { + switch (value) { - imgui_spawn_manager.weapon_sort_by_max_fire_distance = false; - imgui_spawn_manager.weapon_sort_by_max_hit_power = false; - imgui_spawn_manager.weapon_sort_by_min_cost = false; - imgui_spawn_manager.weapon_sort_by_min_fire_distance = false; - imgui_spawn_manager.weapon_sort_by_min_hit_power = false; - } - ImGui::SetItemTooltip("Sorts items by maximum cost field that defined in weapon section in ltx file"); - - - if (ImGui::Checkbox("sort by max fire distance##CheckBox_InGameSpawnManager", &imgui_spawn_manager.weapon_sort_by_max_fire_distance)) + case egdNovice: { - imgui_spawn_manager.weapon_sort_by_max_cost = false; - imgui_spawn_manager.weapon_sort_by_max_hit_power = false; - imgui_spawn_manager.weapon_sort_by_min_cost = false; - imgui_spawn_manager.weapon_sort_by_min_fire_distance = false; - imgui_spawn_manager.weapon_sort_by_min_hit_power = false; + return "novice"; } - ImGui::SetItemTooltip("Sorts items by maximum fire distance field that defined in weapon section in ltx file"); - - if (ImGui::Checkbox("sort by max hit power##CheckBox_InGameSpawnManager", &imgui_spawn_manager.weapon_sort_by_max_hit_power)) + case egdStalker: { - imgui_spawn_manager.weapon_sort_by_max_cost = false; - imgui_spawn_manager.weapon_sort_by_max_fire_distance = false; - imgui_spawn_manager.weapon_sort_by_min_cost = false; - imgui_spawn_manager.weapon_sort_by_min_fire_distance = false; - imgui_spawn_manager.weapon_sort_by_min_hit_power = false; + return "stalker"; } - ImGui::SetItemTooltip("Sorts items by maximum hit_power field for current game difficulty[%s] that defined in weapon section in ltx file", translate_difficulty(g_SingleGameDifficulty)); - - if (ImGui::Checkbox("sort by min cost##CheckBox_InGameSpawnManager", &imgui_spawn_manager.weapon_sort_by_min_cost)) + case egdVeteran: { - imgui_spawn_manager.weapon_sort_by_max_cost = false; - imgui_spawn_manager.weapon_sort_by_max_hit_power = false; - imgui_spawn_manager.weapon_sort_by_max_fire_distance = false; - imgui_spawn_manager.weapon_sort_by_min_hit_power = false; - imgui_spawn_manager.weapon_sort_by_min_fire_distance = false; + return "veteran"; } - ImGui::SetItemTooltip("Sorts items by minimal cost field that defined in weapon section in ltx file"); - - if (ImGui::Checkbox("sort by min fire distance##CheckBox_InGameSpawnManager", &imgui_spawn_manager.weapon_sort_by_min_fire_distance)) + case egdMaster: { - imgui_spawn_manager.weapon_sort_by_max_cost = false; - imgui_spawn_manager.weapon_sort_by_max_hit_power = false; - imgui_spawn_manager.weapon_sort_by_max_fire_distance = false; - imgui_spawn_manager.weapon_sort_by_min_cost = false; - imgui_spawn_manager.weapon_sort_by_min_hit_power = false; + return "master"; } - ImGui::SetItemTooltip("Sorts items by minimal fire_distance field that defined in weapon section in ltx file"); - - if (ImGui::Checkbox("sort by min hit power##CheckBox_InGameSpawnManager", &imgui_spawn_manager.weapon_sort_by_min_hit_power)) - { - imgui_spawn_manager.weapon_sort_by_max_cost = false; - imgui_spawn_manager.weapon_sort_by_max_hit_power = false; - imgui_spawn_manager.weapon_sort_by_max_fire_distance = false; - imgui_spawn_manager.weapon_sort_by_min_cost = false; - imgui_spawn_manager.weapon_sort_by_min_fire_distance = false; + default: + return "unknown"; } - ImGui::SetItemTooltip("Sorts items by minimal hit_power field for current game difficulty[%s]that defined in weapon section in ltx file", translate_difficulty(g_SingleGameDifficulty)); + }; + + if (ImGui::Checkbox("sort by max fire distance##CheckBox_InGameSpawnManager", &imgui_spawn_manager.weapon_sort_by_max_fire_distance)) + { + imgui_spawn_manager.weapon_sort_by_max_hit_power = false; + imgui_spawn_manager.weapon_sort_by_min_fire_distance = false; + imgui_spawn_manager.weapon_sort_by_min_hit_power = false; + } + ImGui::SetItemTooltip("Sorts items by maximum fire distance field that defined in weapon section in ltx file"); - ImGui::InputText("count##IT_InGameSpawnManager", imgui_spawn_manager.weapon_spawn_count, sizeof(imgui_spawn_manager).weapon_spawn_count); - ImGui::SetItemTooltip("How many items to spawn by one click, from 1 to specified number by user input"); + if (ImGui::Checkbox("sort by max hit power##CheckBox_InGameSpawnManager", &imgui_spawn_manager.weapon_sort_by_max_hit_power)) + { + imgui_spawn_manager.weapon_sort_by_max_fire_distance = false; + imgui_spawn_manager.weapon_sort_by_min_fire_distance = false; + imgui_spawn_manager.weapon_sort_by_min_hit_power = false; + } + ImGui::SetItemTooltip("Sorts items by maximum hit_power field for current game difficulty[%s] that defined in weapon section in ltx file", translate_difficulty(g_SingleGameDifficulty)); - if (ImGui::Checkbox("spawn on Level", &imgui_spawn_manager.weapon_spawn_on_level)) - { + if (ImGui::Checkbox("sort by min fire distance##CheckBox_InGameSpawnManager", &imgui_spawn_manager.weapon_sort_by_min_fire_distance)) + { + imgui_spawn_manager.weapon_sort_by_max_hit_power = false; + imgui_spawn_manager.weapon_sort_by_max_fire_distance = false; + imgui_spawn_manager.weapon_sort_by_min_hit_power = false; + } + ImGui::SetItemTooltip("Sorts items by minimal fire_distance field that defined in weapon section in ltx file"); - } - ImGui::SetItemTooltip("if this checkbox is enabled that means it will spawn on level not in inventory"); + if (ImGui::Checkbox("sort by min hit power##CheckBox_InGameSpawnManager", &imgui_spawn_manager.weapon_sort_by_min_hit_power)) + { + imgui_spawn_manager.weapon_sort_by_max_hit_power = false; + imgui_spawn_manager.weapon_sort_by_max_fire_distance = false; + imgui_spawn_manager.weapon_sort_by_min_fire_distance = false; + } + ImGui::SetItemTooltip("Sorts items by minimal hit_power field for current game difficulty[%s]that defined in weapon section in ltx file", translate_difficulty(g_SingleGameDifficulty)); - ImGui::Separator(); + ImGui::Text("current difficulty: %s", translate_difficulty(g_SingleGameDifficulty)); + SectionStatistics(imgui_spawn_manager.WeaponsSections); - // that has all fields for sorting - xr_vector> section_names_sort; - // lack of some fields for sorting thus can't be included for 'sorting' categorty - xr_vector> section_names_unsort; + if (imgui_spawn_manager.sort_by_max_cost) + { + maxSortCost(imgui_spawn_manager.WeaponsSections.Sorted); + } + else if (imgui_spawn_manager.sort_by_min_cost) + { + minSortCost(imgui_spawn_manager.WeaponsSections.Sorted); + } - for (const auto& pSection : pSettings->sections()) + if (imgui_spawn_manager.weapon_sort_by_max_fire_distance) + { + std::sort(imgui_spawn_manager.WeaponsSections.Sorted.begin(), imgui_spawn_manager.WeaponsSections.Sorted.end(), + [](const auto& pair_left, const auto& pair_right) -> bool { - if (pSection) + if (pair_left.second && pair_right.second) { - std::string_view name = pSection->Name.c_str(); + const char* pLeftName = pair_left.first.data(); + const char* pRightName = pair_right.first.data(); + + float value_left{}; + float value_right{}; - if (!name.empty()) + if (pSettings->line_exist(pLeftName, "fire_distance")) { - size_t index = name.find("wpn_"); - if (index != std::string_view::npos && index == 0) - { - if (pSection->line_exist("hit_power") && pSection->line_exist("cost") && pSection->line_exist("fire_distance")) - { - section_names_sort.push_back({ name, pSection }); - ++total_count_sort; - } - else - { - section_names_unsort.push_back({ name, pSection }); - ++total_count_unsort; - } - } + value_left = pSettings->r_float(pLeftName, "fire_distance"); + } + + if (pSettings->line_exist(pRightName, "fire_distance")) + { + value_right = pSettings->r_float(pRightName, "fire_distance"); } + + return value_left > value_right; } - } - ImGui::Text("total [wpn_xxx] sections count: %d", total_count_sort + total_count_unsort); - ImGui::Text("total [wpn_xxx] sections count (can be sorted): %d", total_count_sort); - ImGui::Text("total [wpn_xxx] sections count (can't be sorted): %d", total_count_unsort); - ImGui::Text("current difficulty: %s", translate_difficulty(g_SingleGameDifficulty)); - ImGui::Separator(); + return false; + }); + } - if (imgui_spawn_manager.weapon_sort_by_max_cost) + if (imgui_spawn_manager.weapon_sort_by_min_fire_distance) + { + std::sort(imgui_spawn_manager.WeaponsSections.Sorted.begin(), imgui_spawn_manager.WeaponsSections.Sorted.end(), + [](const auto& pair_left, const auto& pair_right) -> bool { - std::sort(section_names_sort.begin(), section_names_sort.end(), [](const auto& pair_left, const auto& pair_right)->bool { - if (pSettings && pair_left.second && pair_right.second) - { - const char* pLeftName = pair_left.first.data(); - const char* pRightName = pair_right.first.data(); - - float cost_left{}; - float cost_right{}; + if (pair_left.second && pair_right.second) + { + const char* pLeftName = pair_left.first.data(); + const char* pRightName = pair_right.first.data(); - if (pSettings->line_exist(pLeftName, "cost")) - { - cost_left = pSettings->r_float(pLeftName, "cost"); - } + float value_left{}; + float value_right{}; - if (pSettings->line_exist(pRightName, "cost")) - { - cost_right = pSettings->r_float(pRightName, "cost"); - } + if (pSettings->line_exist(pLeftName, "fire_distance")) + { + value_left = pSettings->r_float(pLeftName, "fire_distance"); + } - return cost_left > cost_right; + if (pSettings->line_exist(pRightName, "fire_distance")) + { + value_right = pSettings->r_float(pRightName, "fire_distance"); } - return false; - }); - } + return value_left < value_right; + } - if (imgui_spawn_manager.weapon_sort_by_min_cost) - { - std::sort(section_names_sort.begin(), section_names_sort.end(), [](const auto& pair_left, const auto& pair_right)->bool { - if (pSettings && pair_left.second && pair_right.second) - { - const char* pLeftName = pair_left.first.data(); - const char* pRightName = pair_right.first.data(); + return false; + }); + } + + if (imgui_spawn_manager.weapon_sort_by_max_hit_power) + { + std::sort(imgui_spawn_manager.WeaponsSections.Sorted.begin(), imgui_spawn_manager.WeaponsSections.Sorted.end(), [](const auto& pair_left, const auto& pair_right)->bool { + if (pair_left.second && pair_right.second) + { + const char* pLeftName = pair_left.first.data(); + const char* pRightName = pair_right.first.data(); - float value_left{}; - float value_right{}; + float value_left{}; + float value_right{}; - if (pSettings->line_exist(pLeftName, "cost")) + if (pSettings->line_exist(pLeftName, "hit_power")) + { + auto hit_str = pSettings->r_string_wb(pLeftName, "hit_power"); + string32 buffer{}; + if (g_SingleGameDifficulty == egdNovice) { - value_left = pSettings->r_float(pLeftName, "cost"); + _GetItem(*hit_str, 3, buffer); + value_left = atof(buffer); } - - if (pSettings->line_exist(pRightName, "cost")) + else if (g_SingleGameDifficulty == egdStalker) { - value_right = pSettings->r_float(pRightName, "cost"); + _GetItem(*hit_str, 2, buffer); + value_left = atof(buffer); + } + else if (g_SingleGameDifficulty == egdVeteran) + { + _GetItem(*hit_str, 1, buffer); + value_left = atof(buffer); + } + else if (g_SingleGameDifficulty == egdMaster) + { + _GetItem(*hit_str, 0, buffer); + value_left = atof(buffer); } - - return value_left < value_right; } - return false; - }); - } - - if (imgui_spawn_manager.weapon_sort_by_max_fire_distance) - { - std::sort(section_names_sort.begin(), section_names_sort.end(), [](const auto& pair_left, const auto& pair_right)->bool { - if (pSettings && pair_left.second && pair_right.second) + if (pSettings->line_exist(pRightName, "hit_power")) { - const char* pLeftName = pair_left.first.data(); - const char* pRightName = pair_right.first.data(); - - float value_left{}; - float value_right{}; - - if (pSettings->line_exist(pLeftName, "fire_distance")) + auto hit_str = pSettings->r_string_wb(pRightName, "hit_power"); + string32 buffer{}; + if (g_SingleGameDifficulty == egdNovice) { - value_left = pSettings->r_float(pLeftName, "fire_distance"); + _GetItem(*hit_str, 3, buffer); + value_right = atof(buffer); } - - if (pSettings->line_exist(pRightName, "fire_distance")) + else if (g_SingleGameDifficulty == egdStalker) { - value_right = pSettings->r_float(pRightName, "fire_distance"); + _GetItem(*hit_str, 2, buffer); + value_right = atof(buffer); + } + else if (g_SingleGameDifficulty == egdVeteran) + { + _GetItem(*hit_str, 1, buffer); + value_right = atof(buffer); + } + else if (g_SingleGameDifficulty == egdMaster) + { + _GetItem(*hit_str, 0, buffer); + value_right = atof(buffer); } - - return value_left > value_right; } - return false; - }); - } + return value_left > value_right; + } + + return false; + }); + } - if (imgui_spawn_manager.weapon_sort_by_min_fire_distance) + if (imgui_spawn_manager.weapon_sort_by_min_hit_power) + { + std::sort(imgui_spawn_manager.WeaponsSections.Sorted.begin(), imgui_spawn_manager.WeaponsSections.Sorted.end(), + [](const auto& pair_left, const auto& pair_right) -> bool { - std::sort(section_names_sort.begin(), section_names_sort.end(), [](const auto& pair_left, const auto& pair_right)->bool { - if (pSettings && pair_left.second && pair_right.second) - { - const char* pLeftName = pair_left.first.data(); - const char* pRightName = pair_right.first.data(); + if (pair_left.second && pair_right.second) + { + const char* pLeftName = pair_left.first.data(); + const char* pRightName = pair_right.first.data(); - float value_left{}; - float value_right{}; + float value_left{}; + float value_right{}; - if (pSettings->line_exist(pLeftName, "fire_distance")) + if (pSettings->line_exist(pLeftName, "hit_power")) + { + auto hit_str = pSettings->r_string_wb(pLeftName, "hit_power"); + string32 buffer{}; + if (g_SingleGameDifficulty == egdNovice) { - value_left = pSettings->r_float(pLeftName, "fire_distance"); + _GetItem(*hit_str, 3, buffer); + value_left = atof(buffer); } - - if (pSettings->line_exist(pRightName, "fire_distance")) + else if (g_SingleGameDifficulty == egdStalker) { - value_right = pSettings->r_float(pRightName, "fire_distance"); + _GetItem(*hit_str, 2, buffer); + value_left = atof(buffer); + } + else if (g_SingleGameDifficulty == egdVeteran) + { + _GetItem(*hit_str, 1, buffer); + value_left = atof(buffer); + } + else if (g_SingleGameDifficulty == egdMaster) + { + _GetItem(*hit_str, 0, buffer); + value_left = atof(buffer); } - - return value_left < value_right; } - return false; - }); - } - - if (imgui_spawn_manager.weapon_sort_by_max_hit_power) - { - std::sort(section_names_sort.begin(), section_names_sort.end(), [](const auto& pair_left, const auto& pair_right)->bool { - if (pSettings && pair_left.second && pair_right.second) + if (pSettings->line_exist(pRightName, "hit_power")) { - const char* pLeftName = pair_left.first.data(); - const char* pRightName = pair_right.first.data(); - - float value_left{}; - float value_right{}; - - - if (pSettings->line_exist(pLeftName, "hit_power")) + auto hit_str = pSettings->r_string_wb(pRightName, "hit_power"); + string32 buffer{}; + if (g_SingleGameDifficulty == egdNovice) { - auto hit_str = pSettings->r_string_wb(pLeftName, "hit_power"); - string32 buffer{}; - if (g_SingleGameDifficulty == egdNovice) - { - _GetItem(*hit_str, 3, buffer); - value_left = atof(buffer); - } - else if (g_SingleGameDifficulty == egdStalker) - { - _GetItem(*hit_str, 2, buffer); - value_left = atof(buffer); - } - else if (g_SingleGameDifficulty == egdVeteran) - { - _GetItem(*hit_str, 1, buffer); - value_left = atof(buffer); - } - else if (g_SingleGameDifficulty == egdMaster) - { - _GetItem(*hit_str, 0, buffer); - value_left = atof(buffer); - } + _GetItem(*hit_str, 3, buffer); + value_right = atof(buffer); } - - if (pSettings->line_exist(pRightName, "hit_power")) + else if (g_SingleGameDifficulty == egdStalker) { - auto hit_str = pSettings->r_string_wb(pRightName, "hit_power"); - string32 buffer{}; - if (g_SingleGameDifficulty == egdNovice) - { - _GetItem(*hit_str, 3, buffer); - value_right = atof(buffer); - } - else if (g_SingleGameDifficulty == egdStalker) - { - _GetItem(*hit_str, 2, buffer); - value_right = atof(buffer); - } - else if (g_SingleGameDifficulty == egdVeteran) - { - _GetItem(*hit_str, 1, buffer); - value_right = atof(buffer); - } - else if (g_SingleGameDifficulty == egdMaster) - { - _GetItem(*hit_str, 0, buffer); - value_right = atof(buffer); - } + _GetItem(*hit_str, 2, buffer); + value_right = atof(buffer); + } + else if (g_SingleGameDifficulty == egdVeteran) + { + _GetItem(*hit_str, 1, buffer); + value_right = atof(buffer); + } + else if (g_SingleGameDifficulty == egdMaster) + { + _GetItem(*hit_str, 0, buffer); + value_right = atof(buffer); } - - return value_left > value_right; } - return false; - }); - } + return value_left < value_right; + } - if (imgui_spawn_manager.weapon_sort_by_min_hit_power) - { - std::sort(section_names_sort.begin(), section_names_sort.end(), [](const auto& pair_left, const auto& pair_right)->bool { - if (pSettings && pair_left.second && pair_right.second) - { - const char* pLeftName = pair_left.first.data(); - const char* pRightName = pair_right.first.data(); + return false; + }); + } - float value_left{}; - float value_right{}; + size_t number_imgui{}; + SpawnManager_ProcessSections(imgui_spawn_manager.WeaponsSections.Sorted, number_imgui); - if (pSettings->line_exist(pLeftName, "hit_power")) - { - auto hit_str = pSettings->r_string_wb(pLeftName, "hit_power"); - string32 buffer{}; - if (g_SingleGameDifficulty == egdNovice) - { - _GetItem(*hit_str, 3, buffer); - value_left = atof(buffer); - } - else if (g_SingleGameDifficulty == egdStalker) - { - _GetItem(*hit_str, 2, buffer); - value_left = atof(buffer); - } - else if (g_SingleGameDifficulty == egdVeteran) - { - _GetItem(*hit_str, 1, buffer); - value_left = atof(buffer); - } - else if (g_SingleGameDifficulty == egdMaster) - { - _GetItem(*hit_str, 0, buffer); - value_left = atof(buffer); - } - } + if (imgui_spawn_manager.WeaponsSections.Unsorted.size() > 0) + { + ImGui::SeparatorText("Unsorted"); + SpawnManager_ProcessSections(imgui_spawn_manager.WeaponsSections.Unsorted, number_imgui); + } - if (pSettings->line_exist(pRightName, "hit_power")) - { - auto hit_str = pSettings->r_string_wb(pRightName, "hit_power"); - string32 buffer{}; - if (g_SingleGameDifficulty == egdNovice) - { - _GetItem(*hit_str, 3, buffer); - value_right = atof(buffer); - } - else if (g_SingleGameDifficulty == egdStalker) - { - _GetItem(*hit_str, 2, buffer); - value_right = atof(buffer); - } - else if (g_SingleGameDifficulty == egdVeteran) - { - _GetItem(*hit_str, 1, buffer); - value_right = atof(buffer); - } - else if (g_SingleGameDifficulty == egdMaster) - { - _GetItem(*hit_str, 0, buffer); - value_right = atof(buffer); - } - } + ImGui::EndTabItem(); + } - return value_left < value_right; - } + if (ImGui::BeginTabItem("Ammo")) + { + size_t number_imgui{}; + SectionStatistics(imgui_spawn_manager.AmmoSections); + SpawnManager_ProcessSections(imgui_spawn_manager.AmmoSections.Sorted, number_imgui); - return false; - }); - } + if (imgui_spawn_manager.sort_by_max_cost) + { + maxSortCost(imgui_spawn_manager.AmmoSections.Sorted); + } + else if (imgui_spawn_manager.sort_by_min_cost) + { + minSortCost(imgui_spawn_manager.AmmoSections.Sorted); + } - size_t number_imgui{}; - for (const auto& data : section_names_sort) - { - const auto& section_name = data.first; - const auto& pSection = data.second; + if (imgui_spawn_manager.AmmoSections.Unsorted.size() > 0) + { + ImGui::SeparatorText("Unsorted"); + SpawnManager_ProcessSections(imgui_spawn_manager.AmmoSections.Unsorted, number_imgui); + } - if (!section_name.empty() && pSection) - { - char imname[kSpawnManagerMaxSectionName]{}; - memcpy_s(imname, sizeof(imname), section_name.data(), section_name.size()); + ImGui::EndTabItem(); + } - char index[6]{}; - sprintf_s(index, sizeof(index), "##%zu", number_imgui); - memcpy_s(imname + section_name.size(), sizeof(imname), index, sizeof(index)); + if (ImGui::BeginTabItem("Addons")) + { + size_t number_imgui{}; + SectionStatistics(imgui_spawn_manager.AddonSections); + SpawnManager_ProcessSections(imgui_spawn_manager.AddonSections.Sorted, number_imgui); - auto surfaceParams = ::Render->getSurface("ui\\ui_icon_equipment"); - bool isPressed = false; - if (surfaceParams.Surface != nullptr) - { - float x = pSettings->r_float(section_name.data(), "inv_grid_x") * INV_GRID_WIDTH(isHQIcons); - float y = pSettings->r_float(section_name.data(), "inv_grid_y") * INV_GRID_HEIGHT(isHQIcons); - float w = pSettings->r_float(section_name.data(), "inv_grid_width") * INV_GRID_WIDTH(isHQIcons); - float h = pSettings->r_float(section_name.data(), "inv_grid_height") * INV_GRID_HEIGHT(isHQIcons); - ImGui::SeparatorText(section_name.data()); - isPressed = ImGui::ImageButton(imname, surfaceParams.Surface, { w, h }, - { x / surfaceParams.w, y / surfaceParams.h }, - { (x + w) / surfaceParams.w, (y + h) / surfaceParams.h } - ); - } - else - { - isPressed = ImGui::Button(imname); - } + if (imgui_spawn_manager.sort_by_max_cost) + { + maxSortCost(imgui_spawn_manager.AddonSections.Sorted); + } + else if (imgui_spawn_manager.sort_by_min_cost) + { + minSortCost(imgui_spawn_manager.AddonSections.Sorted); + } + if (imgui_spawn_manager.AddonSections.Unsorted.size() > 0) + { + ImGui::SeparatorText("Unsorted"); + SpawnManager_ProcessSections(imgui_spawn_manager.AddonSections.Unsorted, number_imgui); + } - if (isPressed) - { - int count = atoi(imgui_spawn_manager.weapon_spawn_count); + ImGui::EndTabItem(); + } - if (count == 0) - count = 1; + if (ImGui::BeginTabItem("Artefacts")) + { + size_t number_imgui{}; + SectionStatistics(imgui_spawn_manager.ArtefactSections); + SpawnManager_ProcessSections(imgui_spawn_manager.ArtefactSections.Sorted, number_imgui); - if (Console) - { - xr_string cmd; - - if (!imgui_spawn_manager.weapon_spawn_on_level) - { - cmd += "g_spawn_inv "; - } - else - { - cmd += "g_spawn "; - } - - cmd += section_name.data(); - cmd += " "; - cmd += std::to_string(count); - - execute_console_command_deferred(Console, cmd.c_str()); - } + if (imgui_spawn_manager.sort_by_max_cost) + { + maxSortCost(imgui_spawn_manager.ArtefactSections.Sorted); + } + else if (imgui_spawn_manager.sort_by_min_cost) + { + minSortCost(imgui_spawn_manager.ArtefactSections.Sorted); + } + if (imgui_spawn_manager.ArtefactSections.Unsorted.size() > 0) + { + ImGui::SeparatorText("Unsorted"); + SpawnManager_ProcessSections(imgui_spawn_manager.ArtefactSections.Unsorted, number_imgui); + } - } + ImGui::EndTabItem(); + } - if (ImGui::BeginItemTooltip()) - { - if (pSection->line_exist("inv_name")) - { - const char* pTranslateSectionName = pSettings->r_string(section_name.data(), "inv_name"); - const auto& pTranslatedString = g_pStringTable->translate(pTranslateSectionName); - ImGui::Text("In game name: [%s]", Platform::ANSI_TO_UTF8(pTranslatedString.c_str()).c_str()); - } + if (ImGui::BeginTabItem("Outfits")) + { + size_t number_imgui{}; + SectionStatistics(imgui_spawn_manager.OutfitSections); + SpawnManager_ProcessSections(imgui_spawn_manager.OutfitSections.Sorted, number_imgui); - if (pSection->line_exist("cost")) - { - const char* pCost = pSettings->r_string(section_name.data(), "cost"); - ImGui::Text("cost: [%s]", pCost); - } + if (imgui_spawn_manager.sort_by_max_cost) + { + maxSortCost(imgui_spawn_manager.OutfitSections.Sorted); + } + else if (imgui_spawn_manager.sort_by_min_cost) + { + minSortCost(imgui_spawn_manager.OutfitSections.Sorted); + } + if (imgui_spawn_manager.OutfitSections.Unsorted.size() > 0) + { + ImGui::SeparatorText("Unsorted"); + SpawnManager_ProcessSections(imgui_spawn_manager.OutfitSections.Unsorted, number_imgui); + } - if (pSection->line_exist("inv_weight")) - { - const char* pInvW = pSettings->r_string(section_name.data(), "inv_weight"); - ImGui::Text("inventory weight: [%s]", pInvW); - } + ImGui::EndTabItem(); + } - if (pSection->line_exist("hit_power")) - { - auto hit_str = pSettings->r_string_wb(section_name.data(), "hit_power"); - float value{}; - string32 buffer{}; - if (g_SingleGameDifficulty == egdNovice) - { - value = atof(_GetItem(*hit_str, 3, buffer)); - } - else if (g_SingleGameDifficulty == egdStalker) - { - value = atof(_GetItem(*hit_str, 2, buffer)); - } - else if (g_SingleGameDifficulty == egdVeteran) - { - value = atof(_GetItem(*hit_str, 1, buffer)); - } - else if (g_SingleGameDifficulty == egdMaster) - { - value = atof(_GetItem(*hit_str, 0, buffer)); - } - - ImGui::Text("hit power: [%.2f]", value); - } + if (ImGui::BeginTabItem("Mp Stuffs")) + { + size_t number_imgui{}; + SectionStatistics(imgui_spawn_manager.MpStuffSections); + SpawnManager_ProcessSections(imgui_spawn_manager.MpStuffSections.Sorted, number_imgui); - if (pSection->line_exist("fire_distance")) - { - const char* pField = pSettings->r_string(section_name.data(), "fire_distance"); - ImGui::Text("fire distance: [%s]", pField); - } + if (imgui_spawn_manager.sort_by_max_cost) + { + maxSortCost(imgui_spawn_manager.MpStuffSections.Sorted); + } + else if (imgui_spawn_manager.sort_by_min_cost) + { + minSortCost(imgui_spawn_manager.MpStuffSections.Sorted); + } + if (imgui_spawn_manager.MpStuffSections.Unsorted.size() > 0) + { + ImGui::SeparatorText("Unsorted"); + SpawnManager_ProcessSections(imgui_spawn_manager.MpStuffSections.Unsorted, number_imgui); + } - ImGui::EndTooltip(); - } + ImGui::EndTabItem(); + } - ImGui::NewLine(); - ++number_imgui; - } - } + if (imgui_spawn_manager.Vehicles.size() > 0) + { + if (ImGui::BeginTabItem("Vehicles")) + { + size_t number_imgui{}; + ImGui::Text("total sections count: %d", imgui_spawn_manager.Vehicles.size()); + SpawnManager_ProcessSections(imgui_spawn_manager.Vehicles, number_imgui); - ImGui::SeparatorText("Unsorted"); + ImGui::EndTabItem(); + } + } - for (const auto& data : section_names_unsort) - { - const auto& section_name = data.first; - const auto& pSection = data.second; + if (imgui_spawn_manager.Others.size() > 0) + { + if (ImGui::BeginTabItem("Others")) + { + size_t number_imgui{}; + ImGui::Text("total sections count: %d", imgui_spawn_manager.Others.size()); + SpawnManager_ProcessSections(imgui_spawn_manager.Others, number_imgui); - if (!section_name.empty() && pSection) - { - char imname[kSpawnManagerMaxSectionName]{}; - memcpy_s(imname, sizeof(imname), section_name.data(), section_name.size()); + ImGui::EndTabItem(); + } + } - char index[6]{}; - sprintf_s(index, sizeof(index), "##%zu", number_imgui); - memcpy_s(imname + section_name.size(), sizeof(imname), index, sizeof(index)); + ImGui::EndTabBar(); + } - if (ImGui::Button(imname)) - { + ImGui::End(); + } +} - int count = atoi(imgui_spawn_manager.weapon_spawn_count); +void SpawnManager_ProcessSections(Section& sections, size_t& number_imgui) +{ + for (const auto& data : sections) + { + const auto& section_name = data.first; + const auto& pSection = data.second; - if (count == 0) - count = 1; + if (!section_name.empty() && pSection) + { + char imname[kSpawnManagerMaxSectionName]{}; + memcpy_s(imname, sizeof(imname), section_name.data(), section_name.size()); - if (Console) - { - xr_string cmd; - - if (!imgui_spawn_manager.weapon_spawn_on_level) - { - cmd += "g_spawn_inv "; - } - else - { - cmd += "g_spawn "; - } - - cmd += section_name.data(); - cmd += " "; - cmd += std::to_string(count); - - execute_console_command_deferred(Console, cmd.c_str()); - } - } + char index[10]{}; + sprintf_s(index, sizeof(index), "##%zu", number_imgui); + memcpy_s(imname + section_name.size(), sizeof(imname), index, sizeof(index)); - if (ImGui::BeginItemTooltip()) - { - if (pSection->line_exist("inv_name")) - { - const char* pTranslateSectionName = pSettings->r_string(section_name.data(), "inv_name"); - const auto& pTranslatedString = g_pStringTable->translate(pTranslateSectionName); - ImGui::Text("In game name: [%s]", Platform::ANSI_TO_UTF8(pTranslatedString.c_str()).c_str()); - } + if (SpawnManager_RenderButtonOrImage(pSection, imname)) + { + SpawnManager_HandleButtonPress(pSection); + } - if (pSection->line_exist("cost")) - { - const char* pCost = pSettings->r_string(section_name.data(), "cost"); - ImGui::Text("cost: [%s]", pCost); - } + SpawnManager_RenderTooltip(pSection); - if (pSection->line_exist("inv_weight")) - { - const char* pInvW = pSettings->r_string(section_name.data(), "inv_weight"); - ImGui::Text("inventory weight: [%s]", pInvW); - } + ImGui::NewLine(); + ++number_imgui; + } + } - if (pSection->line_exist("hit_power")) - { - auto hit_str = pSettings->r_string_wb(section_name.data(), "hit_power"); - float value{}; - string32 buffer{}; - if (g_SingleGameDifficulty == egdNovice) - { - value = atof(_GetItem(*hit_str, 3, buffer)); - } - else if (g_SingleGameDifficulty == egdStalker) - { - value = atof(_GetItem(*hit_str, 2, buffer)); - } - else if (g_SingleGameDifficulty == egdVeteran) - { - value = atof(_GetItem(*hit_str, 1, buffer)); - } - else if (g_SingleGameDifficulty == egdMaster) - { - value = atof(_GetItem(*hit_str, 0, buffer)); - } - - ImGui::Text("hit power: [%.2f]", value); - } + std::sort(sections.begin(), sections.end()); +} - if (pSection->line_exist("fire_distance")) - { - const char* pField = pSettings->r_string(section_name.data(), "fire_distance"); - ImGui::Text("fire distance: [%s]", pField); - } +bool SpawnManager_RenderButtonOrImage(CInifile::Sect* section, const char* imname) +{ + static const auto surfaceParams = ::Render->getSurface("ui\\ui_icon_equipment"); + + bool isIcon = section->line_exist("inv_grid_x") + && section->line_exist("inv_grid_y") + && section->line_exist("inv_grid_width") + && section->line_exist("inv_grid_height"); + + if (surfaceParams.Surface == nullptr || !isIcon) + return ImGui::Button(imname); + + auto name = section->Name.c_str(); + float x = pSettings->r_float(name, "inv_grid_x") * INV_GRID_WIDTH(isHQIcons); + float y = pSettings->r_float(name, "inv_grid_y") * INV_GRID_HEIGHT(isHQIcons); + float w = pSettings->r_float(name, "inv_grid_width") * INV_GRID_WIDTH(isHQIcons); + float h = pSettings->r_float(name, "inv_grid_height") * INV_GRID_HEIGHT(isHQIcons); + + ImGui::SeparatorText(name); + return ImGui::ImageButton(imname, surfaceParams.Surface, { w, h }, + { x / surfaceParams.w, y / surfaceParams.h }, + { (x + w) / surfaceParams.w, (y + h) / surfaceParams.h }); + +} - ImGui::EndTooltip(); - } +void SpawnManager_HandleButtonPress(CInifile::Sect* section) +{ + int count = atoi(imgui_spawn_manager.spawn_count); + if (count == 0) + count = 1; - ImGui::NewLine(); - ++number_imgui; - } - } + xr_string cmd = "g_spawn_inv "; + bool isInvItem = section->line_exist("cost") && section->line_exist("inv_weight"); + if (imgui_spawn_manager.spawn_on_level || !isInvItem) + { + cmd = "g_spawn "; + } + cmd += section->Name.c_str(); + cmd += " "; + cmd += xr_string::ToString(count); - } + execute_console_command_deferred(Console, cmd.c_str()); +} - ImGui::EndTabItem(); +void SpawnManager_RenderTooltip(CInifile::Sect* section) +{ + if (ImGui::BeginItemTooltip()) + { + if (section->line_exist("inv_name")) + { + const char* pTranslateSectionName = pSettings->r_string(section->Name.c_str(), "inv_name"); + if (pTranslateSectionName != nullptr) + { + const auto& pTranslatedString = g_pStringTable->translate(pTranslateSectionName); + ImGui::Text("In game name: [%s]", Platform::ANSI_TO_UTF8(pTranslatedString.c_str()).c_str()); } + } - ImGui::EndTabBar(); + if (section->line_exist("class")) + { + const char* pClass = pSettings->r_string(section->Name.c_str(), "class"); + ImGui::Text("class: [%s]", pClass); + } + + if (section->line_exist("cost")) + { + const char* pCost = pSettings->r_string(section->Name.c_str(), "cost"); + ImGui::Text("cost: [%s]", pCost); } + if (section->line_exist("inv_weight")) + { + const char* pInvW = pSettings->r_string(section->Name.c_str(), "inv_weight"); + ImGui::Text("inventory weight: [%s]", pInvW); + } - ImGui::End(); + if (section->line_exist("hit_power")) + { + auto hit_str = pSettings->r_string_wb(section->Name.c_str(), "hit_power"); + float value = SpawnManager_ParseHitPower(hit_str); + ImGui::Text("hit power: [%.2f]", value); + } + + if (section->line_exist("fire_distance")) + { + const char* pField = pSettings->r_string(section->Name.c_str(), "fire_distance"); + ImGui::Text("fire distance: [%s]", pField); + } + + ImGui::EndTooltip(); } } + +float SpawnManager_ParseHitPower(const shared_str& hit_str) { + string32 buffer{}; + float result{}; + + if (g_SingleGameDifficulty == egdNovice) { + result = atof(_GetItem(*hit_str, 3, buffer)); + } + else if (g_SingleGameDifficulty == egdStalker) { + result = atof(_GetItem(*hit_str, 2, buffer)); + } + else if (g_SingleGameDifficulty == egdVeteran) { + result = atof(_GetItem(*hit_str, 1, buffer)); + } + else if (g_SingleGameDifficulty == egdMaster) { + result = atof(_GetItem(*hit_str, 0, buffer)); + } + + return result; +} \ No newline at end of file diff --git a/src/xrGame/console_commands.cpp b/src/xrGame/console_commands.cpp index 3d5c75e508..fe75d25c92 100644 --- a/src/xrGame/console_commands.cpp +++ b/src/xrGame/console_commands.cpp @@ -1928,13 +1928,6 @@ class CCC_GSpawn : public IConsole_Command { return; } } - - if (g_pGameLevel == nullptr) { - return; - } - - - } virtual void fill_tips(vecTips& tips, u32 mode) override {