Reduce stack usage during static initialization (#4184)

* Reduce stack usage during static initialization

* Implement `ABS` macro for `TWO_ACTOR_PARAMS`
This commit is contained in:
GaryOderNichts 2024-06-16 05:28:42 +02:00 committed by GitHub
parent cd7c5ab316
commit f99993af85
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 32 additions and 26 deletions

View File

@ -16,7 +16,7 @@ ActorDB* ActorDB::Instance;
#undef DEFINE_ACTOR_UNSET #undef DEFINE_ACTOR_UNSET
struct AddPair { struct AddPair {
std::string name; const char* name;
ActorInit& init; ActorInit& init;
}; };
@ -24,7 +24,7 @@ struct AddPair {
#define DEFINE_ACTOR(name, _1, allocType) { #name, name##_InitVars }, #define DEFINE_ACTOR(name, _1, allocType) { #name, name##_InitVars },
#define DEFINE_ACTOR_UNSET(_0) #define DEFINE_ACTOR_UNSET(_0)
static const std::vector<AddPair> initialActorTable = { static constexpr AddPair initialActorTable[] = {
#include "tables/actor_table.h" #include "tables/actor_table.h"
}; };
@ -33,7 +33,7 @@ static const std::vector<AddPair> initialActorTable = {
#undef DEFINE_ACTOR #undef DEFINE_ACTOR
// https://wiki.cloudmodding.com/oot/Actor_List_(Variables) // https://wiki.cloudmodding.com/oot/Actor_List_(Variables)
static std::unordered_map<u16, const char*> actorDescriptions = { static constexpr std::pair<u16, const char*> actorDescriptionData[] = {
{ ACTOR_PLAYER, "Link" }, { ACTOR_PLAYER, "Link" },
{ ACTOR_EN_TEST, "Stalfos" }, { ACTOR_EN_TEST, "Stalfos" },
{ ACTOR_EN_GIRLA, "Shop Items" }, { ACTOR_EN_GIRLA, "Shop Items" },
@ -464,6 +464,7 @@ static std::unordered_map<u16, const char*> actorDescriptions = {
{ ACTOR_BG_JYA_BLOCK, "Silver Block (Child Era)" }, { ACTOR_BG_JYA_BLOCK, "Silver Block (Child Era)" },
{ ACTOR_OBJ_WARP2BLOCK, "Navi Infospot (Green, Time Block)" } { ACTOR_OBJ_WARP2BLOCK, "Navi Infospot (Green, Time Block)" }
}; };
static std::unordered_map<u16, const char*> actorDescriptions = std::unordered_map<u16, const char*>(std::begin(actorDescriptionData), std::end(actorDescriptionData));
ActorDB::ActorDB() { ActorDB::ActorDB() {
db.reserve(ACTOR_NUMBER_MAX); // reserve size for all initial entries so we don't do it for each db.reserve(ACTOR_NUMBER_MAX); // reserve size for all initial entries so we don't do it for each

View File

@ -59,4 +59,4 @@ typedef struct GetItemEntry {
/* 0x10 */ uint16_t drawItemId; // Will be a copy of itemId unless the item is an ice trap. Needed for particles to function on ice traps. /* 0x10 */ uint16_t drawItemId; // Will be a copy of itemId unless the item is an ice trap. Needed for particles to function on ice traps.
/* 0x11 */ uint16_t drawModIndex; // Will be a copy of modIndex unless the item is an ice trap. Needed for particles to function on ice traps. /* 0x11 */ uint16_t drawModIndex; // Will be a copy of modIndex unless the item is an ice trap. Needed for particles to function on ice traps.
CustomDrawFunc drawFunc; CustomDrawFunc drawFunc;
}; // size = 0x11 } GetItemEntry; // size = 0x11

View File

@ -4660,7 +4660,7 @@ void RandomizerSettingsWindow::DrawElement() {
bool hasItems = false; bool hasItems = false;
for (auto& [randomizerCheck, rcObject] : rcObjects) { for (auto& [randomizerCheck, rcObject] : rcObjects) {
if (rcObject->visibleInImgui && !excludedLocations.count(rcObject->rc) && if (rcObject->visibleInImgui && !excludedLocations.count(rcObject->rc) &&
locationSearch.PassFilter(rcObject->rcSpoilerName.c_str())) { locationSearch.PassFilter(rcObject->rcSpoilerName)) {
hasItems = true; hasItems = true;
break; break;
@ -4672,7 +4672,7 @@ void RandomizerSettingsWindow::DrawElement() {
if (ImGui::TreeNode(RandomizerCheckObjects::GetRCAreaName(rcArea).c_str())) { if (ImGui::TreeNode(RandomizerCheckObjects::GetRCAreaName(rcArea).c_str())) {
for (auto& [randomizerCheck, rcObject] : rcObjects) { for (auto& [randomizerCheck, rcObject] : rcObjects) {
if (rcObject->visibleInImgui && !excludedLocations.count(rcObject->rc) && if (rcObject->visibleInImgui && !excludedLocations.count(rcObject->rc) &&
locationSearch.PassFilter(rcObject->rcSpoilerName.c_str())) { locationSearch.PassFilter(rcObject->rcSpoilerName)) {
if (ImGui::ArrowButton(std::to_string(rcObject->rc).c_str(), ImGuiDir_Right)) { if (ImGui::ArrowButton(std::to_string(rcObject->rc).c_str(), ImGuiDir_Right)) {
excludedLocations.insert(rcObject->rc); excludedLocations.insert(rcObject->rc);
@ -4686,7 +4686,7 @@ void RandomizerSettingsWindow::DrawElement() {
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
} }
ImGui::SameLine(); ImGui::SameLine();
ImGui::Text("%s", rcObject->rcShortName.c_str()); ImGui::Text("%s", rcObject->rcShortName);
} }
} }
ImGui::TreePop(); ImGui::TreePop();
@ -4731,7 +4731,7 @@ void RandomizerSettingsWindow::DrawElement() {
Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick();
} }
ImGui::SameLine(); ImGui::SameLine();
ImGui::Text("%s", rcObject->rcShortName.c_str()); ImGui::Text("%s", rcObject->rcShortName);
} }
} }
ImGui::TreePop(); ImGui::TreePop();
@ -4997,7 +4997,7 @@ void RandomizerSettingsWindow::DrawElement() {
if (ImGui::Button("Enable Visible")) { if (ImGui::Button("Enable Visible")) {
for (auto [rtArea, rtObjects] : RandomizerTricks::GetAllRTObjectsByArea()) { for (auto [rtArea, rtObjects] : RandomizerTricks::GetAllRTObjectsByArea()) {
for (auto [randomizerTrick, rtObject] : rtObjects) { for (auto [randomizerTrick, rtObject] : rtObjects) {
if (!rtObject.rtGlitch && !enabledTricks.count(rtObject.rt) && trickSearch.PassFilter(rtObject.rtShortName.c_str()) && areaTreeDisabled[rtArea] && RandomizerTricks::CheckRTTags(showTag, *rtObject.rtTags)) { if (!rtObject.rtGlitch && !enabledTricks.count(rtObject.rt) && trickSearch.PassFilter(rtObject.rtShortName) && areaTreeDisabled[rtArea] && RandomizerTricks::CheckRTTags(showTag, *rtObject.rtTags)) {
enabledTricks.insert(randomizerTrick); enabledTricks.insert(randomizerTrick);
} }
} }
@ -5017,7 +5017,7 @@ void RandomizerSettingsWindow::DrawElement() {
bool hasTricks = false; bool hasTricks = false;
for (auto [randomizerTrick, rtObject] : rtObjects) { for (auto [randomizerTrick, rtObject] : rtObjects) {
if (rtObject.visibleInImgui && if (rtObject.visibleInImgui &&
trickSearch.PassFilter(rtObject.rtShortName.c_str()) && trickSearch.PassFilter(rtObject.rtShortName) &&
!enabledTricks.count(rtObject.rt) && !enabledTricks.count(rtObject.rt) &&
RandomizerTricks::CheckRTTags(showTag, *rtObject.rtTags) && RandomizerTricks::CheckRTTags(showTag, *rtObject.rtTags) &&
!rtObject.rtGlitch) { !rtObject.rtGlitch) {
@ -5032,7 +5032,7 @@ void RandomizerSettingsWindow::DrawElement() {
if (ImGui::TreeNode(RandomizerTricks::GetRTAreaName(rtArea).c_str())) { if (ImGui::TreeNode(RandomizerTricks::GetRTAreaName(rtArea).c_str())) {
for (auto [randomizerTrick, rtObject] : rtObjects) { for (auto [randomizerTrick, rtObject] : rtObjects) {
if (rtObject.visibleInImgui && if (rtObject.visibleInImgui &&
trickSearch.PassFilter(rtObject.rtShortName.c_str()) && trickSearch.PassFilter(rtObject.rtShortName) &&
!enabledTricks.count(rtObject.rt) && !enabledTricks.count(rtObject.rt) &&
RandomizerTricks::CheckRTTags(showTag, *rtObject.rtTags) && RandomizerTricks::CheckRTTags(showTag, *rtObject.rtTags) &&
!rtObject.rtGlitch) { !rtObject.rtGlitch) {
@ -5048,8 +5048,8 @@ void RandomizerSettingsWindow::DrawElement() {
} }
DrawTagChips(*rtObject.rtTags); DrawTagChips(*rtObject.rtTags);
ImGui::SameLine(); ImGui::SameLine();
ImGui::Text("%s", rtObject.rtShortName.c_str()); ImGui::Text("%s", rtObject.rtShortName);
UIWidgets::InsertHelpHoverText(rtObject.rtDesc.c_str()); UIWidgets::InsertHelpHoverText(rtObject.rtDesc);
} }
} }
areaTreeDisabled[rtArea] = true; areaTreeDisabled[rtArea] = true;
@ -5107,7 +5107,7 @@ void RandomizerSettingsWindow::DrawElement() {
for (auto [rtArea, rtObjects] : RandomizerTricks::GetAllRTObjectsByArea()) { for (auto [rtArea, rtObjects] : RandomizerTricks::GetAllRTObjectsByArea()) {
for (auto [randomizerTrick, rtObject] : rtObjects) { for (auto [randomizerTrick, rtObject] : rtObjects) {
auto etfound = enabledTricks.find(randomizerTrick); auto etfound = enabledTricks.find(randomizerTrick);
if (!rtObject.rtGlitch && etfound != enabledTricks.end() && trickSearch.PassFilter(rtObject.rtShortName.c_str()) && areaTreeEnabled[rtArea] && RandomizerTricks::CheckRTTags(showTag, *rtObject.rtTags)) { if (!rtObject.rtGlitch && etfound != enabledTricks.end() && trickSearch.PassFilter(rtObject.rtShortName) && areaTreeEnabled[rtArea] && RandomizerTricks::CheckRTTags(showTag, *rtObject.rtTags)) {
enabledTricks.erase(etfound); enabledTricks.erase(etfound);
} }
} }
@ -5127,7 +5127,7 @@ void RandomizerSettingsWindow::DrawElement() {
bool hasTricks = false; bool hasTricks = false;
for (auto [randomizerTrick, rtObject] : rtObjects) { for (auto [randomizerTrick, rtObject] : rtObjects) {
if (rtObject.visibleInImgui && if (rtObject.visibleInImgui &&
trickSearch.PassFilter(rtObject.rtShortName.c_str()) && trickSearch.PassFilter(rtObject.rtShortName) &&
enabledTricks.count(rtObject.rt) && enabledTricks.count(rtObject.rt) &&
RandomizerTricks::CheckRTTags(showTag, *rtObject.rtTags) && RandomizerTricks::CheckRTTags(showTag, *rtObject.rtTags) &&
!rtObject.rtGlitch) { !rtObject.rtGlitch) {
@ -5143,7 +5143,7 @@ void RandomizerSettingsWindow::DrawElement() {
for (auto [randomizerTrick, rtObject] : rtObjects) { for (auto [randomizerTrick, rtObject] : rtObjects) {
auto etfound = enabledTricks.find(rtObject.rt); auto etfound = enabledTricks.find(rtObject.rt);
if (rtObject.visibleInImgui && if (rtObject.visibleInImgui &&
trickSearch.PassFilter(rtObject.rtShortName.c_str()) && trickSearch.PassFilter(rtObject.rtShortName) &&
etfound != enabledTricks.end() && etfound != enabledTricks.end() &&
RandomizerTricks::CheckRTTags(showTag, *rtObject.rtTags) && RandomizerTricks::CheckRTTags(showTag, *rtObject.rtTags) &&
!rtObject.rtGlitch) { !rtObject.rtGlitch) {
@ -5164,8 +5164,8 @@ void RandomizerSettingsWindow::DrawElement() {
} }
DrawTagChips(*rtObject.rtTags); DrawTagChips(*rtObject.rtTags);
ImGui::SameLine(); ImGui::SameLine();
ImGui::Text("%s", rtObject.rtShortName.c_str()); ImGui::Text("%s", rtObject.rtShortName);
UIWidgets::InsertHelpHoverText(rtObject.rtDesc.c_str()); UIWidgets::InsertHelpHoverText(rtObject.rtDesc);
} }
} }
areaTreeEnabled[rtArea] = true; areaTreeEnabled[rtArea] = true;

View File

@ -6,7 +6,7 @@
#include "soh/OTRGlobals.h" #include "soh/OTRGlobals.h"
// RandomizerCheck, RCVORMQ, RCTYPE, RCAREA, ActorId, SceneId, ActorParams, OG ItemID, "Short name", "Spoiler name", vanillaCompletion // RandomizerCheck, RCVORMQ, RCTYPE, RCAREA, ActorId, SceneId, ActorParams, OG ItemID, "Short name", "Spoiler name", vanillaCompletion
std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = { static constexpr std::pair<RandomizerCheck, RandomizerCheckObject> rcObjectsData[] = {
RC_OBJECT(RC_KF_KOKIRI_SWORD_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_KOKIRI_FOREST, ACTOR_EN_BOX, SCENE_KOKIRI_FOREST, 1248, GI_SWORD_KOKIRI, "Kokiri Sword Chest", "KF Kokiri Sword Chest", true), RC_OBJECT(RC_KF_KOKIRI_SWORD_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_KOKIRI_FOREST, ACTOR_EN_BOX, SCENE_KOKIRI_FOREST, 1248, GI_SWORD_KOKIRI, "Kokiri Sword Chest", "KF Kokiri Sword Chest", true),
RC_OBJECT(RC_KF_MIDOS_TOP_LEFT_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_KOKIRI_FOREST, ACTOR_EN_BOX, SCENE_MIDOS_HOUSE, 22944, GI_RUPEE_BLUE, "Mido Top Left Chest", "KF Mido Top Left Chest", false), RC_OBJECT(RC_KF_MIDOS_TOP_LEFT_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_KOKIRI_FOREST, ACTOR_EN_BOX, SCENE_MIDOS_HOUSE, 22944, GI_RUPEE_BLUE, "Mido Top Left Chest", "KF Mido Top Left Chest", false),
RC_OBJECT(RC_KF_MIDOS_TOP_RIGHT_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_KOKIRI_FOREST, ACTOR_EN_BOX, SCENE_MIDOS_HOUSE, 22945, GI_RUPEE_BLUE, "Mido Top Right Chest", "KF Mido Top Right Chest", false), RC_OBJECT(RC_KF_MIDOS_TOP_RIGHT_CHEST, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_KOKIRI_FOREST, ACTOR_EN_BOX, SCENE_MIDOS_HOUSE, 22945, GI_RUPEE_BLUE, "Mido Top Right Chest", "KF Mido Top Right Chest", false),
@ -775,6 +775,7 @@ std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = {
RC_OBJECT(RC_UNKNOWN_CHECK, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_INVALID, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, GI_NONE, "Invalid Check", "Invalid Check", false), RC_OBJECT(RC_UNKNOWN_CHECK, RCVORMQ_BOTH, RCTYPE_STANDARD, RCAREA_INVALID, ACTOR_ID_MAX, SCENE_ID_MAX, 0x00, GI_NONE, "Invalid Check", "Invalid Check", false),
}; };
std::map<RandomizerCheck, RandomizerCheckObject> rcObjects = std::map<RandomizerCheck, RandomizerCheckObject>(std::begin(rcObjectsData), std::end(rcObjectsData));
std::map<RandomizerCheckArea, std::string> rcAreaNames = { std::map<RandomizerCheckArea, std::string> rcAreaNames = {
{ RCAREA_KOKIRI_FOREST, "Kokiri Forest"}, { RCAREA_KOKIRI_FOREST, "Kokiri Forest"},

View File

@ -7,7 +7,10 @@
enum ActorID : int; enum ActorID : int;
enum SceneID : int; enum SceneID : int;
#define TWO_ACTOR_PARAMS(a, b) (abs(a) << 16) | abs(b) // ABS macro to use since `std::abs` is not constexpr yet
#define ABS(x) ((x) < 0 ? -(x) : (x))
#define TWO_ACTOR_PARAMS(a, b) (ABS(a) << 16) | ABS(b)
#define RC_OBJECT(rc, rc_v_or_mq, rc_type, rc_area, actor_id, scene_id, actor_params, og_item_id, rc_shortname, rc_spoilername, vanillaCompletion) \ #define RC_OBJECT(rc, rc_v_or_mq, rc_type, rc_area, actor_id, scene_id, actor_params, og_item_id, rc_shortname, rc_spoilername, vanillaCompletion) \
{ rc, {rc, rc_v_or_mq, rc_type, rc_area, actor_id, scene_id, actor_params, og_item_id, false, rc_shortname, rc_spoilername, vanillaCompletion} } { rc, {rc, rc_v_or_mq, rc_type, rc_area, actor_id, scene_id, actor_params, og_item_id, false, rc_shortname, rc_spoilername, vanillaCompletion} }
@ -22,8 +25,8 @@ typedef struct {
int32_t actorParams; int32_t actorParams;
GetItemID ogItemId; GetItemID ogItemId;
bool visibleInImgui; bool visibleInImgui;
std::string rcShortName; const char* rcShortName;
std::string rcSpoilerName; const char* rcSpoilerName;
bool vanillaCompletion; bool vanillaCompletion;
} RandomizerCheckObject; } RandomizerCheckObject;

View File

@ -1089,7 +1089,7 @@ bool ShouldShowCheck(RandomizerCheckObject check) {
IsVisibleInCheckTracker(check) && IsVisibleInCheckTracker(check) &&
(checkSearch.Filters.Size == 0 || (checkSearch.Filters.Size == 0 ||
checkSearch.PassFilter(RandomizerCheckObjects::GetRCAreaName(check.rcArea).c_str()) || checkSearch.PassFilter(RandomizerCheckObjects::GetRCAreaName(check.rcArea).c_str()) ||
checkSearch.PassFilter(check.rcShortName.c_str())) checkSearch.PassFilter(check.rcShortName))
); );
} }

View File

@ -21,7 +21,7 @@ std::vector<RandomizerTrickTag> extremeBase{RTTAG_EXTREME};
// Experimental - not implemented; these tricks may let you put the game into a softlockable state // Experimental - not implemented; these tricks may let you put the game into a softlockable state
// Please see https://www.youtube.com/playlist?list=PLqsXSioZwQyoa23_27l5NZq5IZdKRi5Sm for reference on performing several of these tricks // Please see https://www.youtube.com/playlist?list=PLqsXSioZwQyoa23_27l5NZq5IZdKRi5Sm for reference on performing several of these tricks
// RandomizerTrick, RTVORMQ, RTAREA, rt_tags rt_glitch (is it a glitch) "Short name", "Description" // RandomizerTrick, RTVORMQ, RTAREA, rt_tags rt_glitch (is it a glitch) "Short name", "Description"
std::unordered_map<RandomizerTrick, RandomizerTrickObject> rtObjects = { static constexpr std::pair<RandomizerTrick, RandomizerTrickObject> rtObjectsData[] = {
RT_OBJECT(RT_ACUTE_ANGLE_CLIP, RTVORMQ_BOTH, RTAREA_GENERAL, &advancedBase, true, "Acute angle clip", "Enables locations requiring jumpslash clips through walls which meet at an acute angle."), RT_OBJECT(RT_ACUTE_ANGLE_CLIP, RTVORMQ_BOTH, RTAREA_GENERAL, &advancedBase, true, "Acute angle clip", "Enables locations requiring jumpslash clips through walls which meet at an acute angle."),
RT_OBJECT(RT_ADVANCED_CLIPS, RTVORMQ_BOTH, RTAREA_GENERAL, &advancedBase, true, "Advanced clips", "Enables locations requiring clips through walls and objects requiring precise jumps or other tricks."), RT_OBJECT(RT_ADVANCED_CLIPS, RTVORMQ_BOTH, RTAREA_GENERAL, &advancedBase, true, "Advanced clips", "Enables locations requiring clips through walls and objects requiring precise jumps or other tricks."),
RT_OBJECT(RT_BLANK_A, RTVORMQ_BOTH, RTAREA_GENERAL, &advancedBase, true, "Blank A", "Enables locations requiring blank A button; NOTE: this requires the 'Quick Putaway' restoration."), RT_OBJECT(RT_BLANK_A, RTVORMQ_BOTH, RTAREA_GENERAL, &advancedBase, true, "Blank A", "Enables locations requiring blank A button; NOTE: this requires the 'Quick Putaway' restoration."),
@ -208,6 +208,7 @@ std::unordered_map<RandomizerTrick, RandomizerTrickObject> rtObjects = {
RT_OBJECT(RT_GANON_MQ_SHADOW_TRIAL, RTVORMQ_MQ, RTAREA_GANONS_CASTLE, &noviceBase, false, "Shadow Trial MQ Torch with Bow", "You can light the torch in this room without a fire source by shooting an arrow through the lit torch at the beginning of the room. Because the room is so dark and the unlit torch is so far away, it can be difficult to aim the shot correctly."), RT_OBJECT(RT_GANON_MQ_SHADOW_TRIAL, RTVORMQ_MQ, RTAREA_GANONS_CASTLE, &noviceBase, false, "Shadow Trial MQ Torch with Bow", "You can light the torch in this room without a fire source by shooting an arrow through the lit torch at the beginning of the room. Because the room is so dark and the unlit torch is so far away, it can be difficult to aim the shot correctly."),
RT_OBJECT(RT_GANON_MQ_LIGHT_TRIAL, RTVORMQ_MQ, RTAREA_GANONS_CASTLE, &intermediateBase, /*todo*/ false, "Light Trial MQ without Hookshot", "If you move quickly you can sneak past the edge of a flame wall before it can rise up to block you. In this case to do it without taking damage is especially precise.") RT_OBJECT(RT_GANON_MQ_LIGHT_TRIAL, RTVORMQ_MQ, RTAREA_GANONS_CASTLE, &intermediateBase, /*todo*/ false, "Light Trial MQ without Hookshot", "If you move quickly you can sneak past the edge of a flame wall before it can rise up to block you. In this case to do it without taking damage is especially precise.")
}; };
std::unordered_map<RandomizerTrick, RandomizerTrickObject> rtObjects = std::unordered_map<RandomizerTrick, RandomizerTrickObject>(std::begin(rtObjectsData), std::end(rtObjectsData));
std::unordered_map<RandomizerTrickArea, std::string> rtAreaNames = { std::unordered_map<RandomizerTrickArea, std::string> rtAreaNames = {
{ RTAREA_GENERAL, "General Tricks"}, { RTAREA_GENERAL, "General Tricks"},

View File

@ -71,8 +71,8 @@ typedef struct {
std::vector<RandomizerTrickTag> *rtTags; std::vector<RandomizerTrickTag> *rtTags;
bool rtGlitch; bool rtGlitch;
bool visibleInImgui; bool visibleInImgui;
std::string rtShortName; const char* rtShortName;
std::string rtDesc; const char* rtDesc;
} RandomizerTrickObject; } RandomizerTrickObject;
namespace RandomizerTricks { namespace RandomizerTricks {