mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-09-22 13:57:07 +00:00
fix: preserve special menu item text flags (#1011)
* fix: preserve T4 special menu item text flags * fix: preserve IW3 special menu item text flags * refactor: define IW3 and T4 dynamic window flags * chore: also apply WindowDefDynamicFlag changes to iw4 and iw5 --------- Co-authored-by: Jan Laupetin <[email protected]>
This commit is contained in:
@@ -2528,18 +2528,18 @@ namespace IW3
|
||||
|
||||
enum WindowDefDynamicFlag : unsigned int
|
||||
{
|
||||
WINDOW_FLAG_1 = 0x1,
|
||||
WINDOW_FLAG_MOUSE_OVER = 0x1,
|
||||
WINDOW_FLAG_FOCUSED = 0x2,
|
||||
WINDOW_FLAG_VISIBLE = 0x4,
|
||||
WINDOW_FLAG_FADING_OUT = 0x10,
|
||||
WINDOW_FLAG_FADING_IN = 0x20,
|
||||
WINDOW_FLAG_HOVERED = 0x40,
|
||||
WINDOW_FLAG_LISTBOX_HOVER_100 = 0x100,
|
||||
WINDOW_FLAG_LISTBOX_HOVER_200 = 0x200,
|
||||
WINDOW_FLAG_LISTBOX_HOVER_400 = 0x400,
|
||||
WINDOW_FLAG_LISTBOX_HOVER_800 = 0x800,
|
||||
WINDOW_FLAG_LISTBOX_HOVER_1000 = 0x1000,
|
||||
WINDOW_FLAG_4000 = 0x4000,
|
||||
WINDOW_FLAG_MOUSE_OVER_TEXT = 0x40,
|
||||
WINDOW_FLAG_LISTBOX_PREV_ARROW = 0x100,
|
||||
WINDOW_FLAG_LISTBOX_NEXT_ARROW = 0x200,
|
||||
WINDOW_FLAG_LISTBOX_THUMB = 0x400,
|
||||
WINDOW_FLAG_LISTBOX_PREV_PAGE = 0x800,
|
||||
WINDOW_FLAG_LISTBOX_NEXT_PAGE = 0x1000,
|
||||
WINDOW_FLAG_FORCED_VISIBLE = 0x4000,
|
||||
WINDOW_FLAG_NON_DEFAULT_BACKCOLOR = 0x8000,
|
||||
WINDOW_FLAG_NON_DEFAULT_FORECOLOR = 0x10000,
|
||||
};
|
||||
@@ -2787,6 +2787,12 @@ namespace IW3
|
||||
ITEM_TYPE_GAME_MESSAGE_WINDOW = 0x13
|
||||
};
|
||||
|
||||
enum ItemDefFlag : unsigned int
|
||||
{
|
||||
ITEM_FLAG_SAVE_GAME_INFO = 0x1,
|
||||
ITEM_FLAG_CINEMATIC_SUBTITLE = 0x2,
|
||||
};
|
||||
|
||||
enum ItemDefDvarFlag
|
||||
{
|
||||
ITEM_DVAR_FLAG_ENABLE = 0x1,
|
||||
|
||||
@@ -2294,12 +2294,18 @@ namespace IW4
|
||||
|
||||
enum WindowDefDynamicFlag : unsigned int
|
||||
{
|
||||
WINDOW_FLAG_HOVERED = 0x1, // guessed
|
||||
WINDOW_FLAG_MOUSE_OVER = 0x1,
|
||||
WINDOW_FLAG_FOCUSED = 0x2,
|
||||
WINDOW_FLAG_VISIBLE = 0x4,
|
||||
WINDOW_FLAG_FADING_OUT = 0x10,
|
||||
WINDOW_FLAG_FADING_IN = 0x20,
|
||||
WINDOW_FLAG_MOUSE_OVER_TEXT = 0x40,
|
||||
WINDOW_FLAG_80 = 0x80,
|
||||
WINDOW_FLAG_LISTBOX_PREV_ARROW = 0x100,
|
||||
WINDOW_FLAG_LISTBOX_NEXT_ARROW = 0x200,
|
||||
WINDOW_FLAG_LISTBOX_THUMB = 0x400,
|
||||
WINDOW_FLAG_LISTBOX_PREV_PAGE = 0x800,
|
||||
WINDOW_FLAG_LISTBOX_NEXT_PAGE = 0x1000,
|
||||
WINDOW_FLAG_NON_DEFAULT_BACKCOLOR = 0x8000,
|
||||
WINDOW_FLAG_NON_DEFAULT_FORECOLOR = 0x10000
|
||||
};
|
||||
|
||||
@@ -3214,12 +3214,18 @@ namespace IW5
|
||||
// This is data from IW4, could be different for IW5, to be investigated
|
||||
enum WindowDefDynamicFlag : unsigned int
|
||||
{
|
||||
WINDOW_FLAG_HOVERED = 0x1, // guessed
|
||||
WINDOW_FLAG_MOUSE_OVER = 0x1,
|
||||
WINDOW_FLAG_FOCUSED = 0x2,
|
||||
WINDOW_FLAG_VISIBLE = 0x4, // confirmed
|
||||
WINDOW_FLAG_FADING_OUT = 0x10,
|
||||
WINDOW_FLAG_FADING_IN = 0x20,
|
||||
WINDOW_FLAG_MOUSE_OVER_TEXT = 0x40,
|
||||
WINDOW_FLAG_80 = 0x80,
|
||||
WINDOW_FLAG_LISTBOX_PREV_ARROW = 0x100,
|
||||
WINDOW_FLAG_LISTBOX_NEXT_ARROW = 0x200,
|
||||
WINDOW_FLAG_LISTBOX_THUMB = 0x400,
|
||||
WINDOW_FLAG_LISTBOX_PREV_PAGE = 0x800,
|
||||
WINDOW_FLAG_LISTBOX_NEXT_PAGE = 0x1000,
|
||||
WINDOW_FLAG_NON_DEFAULT_BACKCOLOR = 0x8000,
|
||||
WINDOW_FLAG_NON_DEFAULT_FORECOLOR = 0x10000
|
||||
};
|
||||
|
||||
@@ -2790,7 +2790,18 @@ namespace T4
|
||||
|
||||
enum WindowDefDynamicFlag : unsigned int
|
||||
{
|
||||
WINDOW_FLAG_MOUSE_OVER = 0x1,
|
||||
WINDOW_FLAG_FOCUSED = 0x2,
|
||||
WINDOW_FLAG_VISIBLE = 0x4,
|
||||
WINDOW_FLAG_FADING_OUT = 0x10,
|
||||
WINDOW_FLAG_FADING_IN = 0x20,
|
||||
WINDOW_FLAG_MOUSE_OVER_TEXT = 0x40,
|
||||
WINDOW_FLAG_LISTBOX_PREV_ARROW = 0x100,
|
||||
WINDOW_FLAG_LISTBOX_NEXT_ARROW = 0x200,
|
||||
WINDOW_FLAG_LISTBOX_THUMB = 0x400,
|
||||
WINDOW_FLAG_LISTBOX_PREV_PAGE = 0x800,
|
||||
WINDOW_FLAG_LISTBOX_NEXT_PAGE = 0x1000,
|
||||
WINDOW_FLAG_FORCED_VISIBLE = 0x4000,
|
||||
WINDOW_FLAG_NON_DEFAULT_BACKCOLOR = 0x8000,
|
||||
WINDOW_FLAG_NON_DEFAULT_FORECOLOR = 0x10000,
|
||||
};
|
||||
@@ -3057,6 +3068,12 @@ namespace T4
|
||||
ITEM_TYPE_GAME_MESSAGE_WINDOW = 0x13
|
||||
};
|
||||
|
||||
enum ItemDefFlag : unsigned int
|
||||
{
|
||||
ITEM_FLAG_SAVE_GAME_INFO = 0x1,
|
||||
ITEM_FLAG_CINEMATIC_SUBTITLE = 0x2,
|
||||
};
|
||||
|
||||
enum ItemDefDvarFlag
|
||||
{
|
||||
ITEM_DVAR_FLAG_ENABLE = 0x1,
|
||||
|
||||
@@ -562,6 +562,16 @@ namespace
|
||||
|
||||
item->window.name = ConvertString(commonItem.m_name);
|
||||
item->text = commonItem.m_text ? m_memory.Dup(commonItem.m_text->c_str()) : nullptr;
|
||||
if (commonItem.m_text_save_game)
|
||||
{
|
||||
item->text = m_memory.Dup("savegameinfo");
|
||||
item->itemFlags |= ITEM_FLAG_SAVE_GAME_INFO;
|
||||
}
|
||||
if (commonItem.m_text_cinematic_subtitle)
|
||||
{
|
||||
item->text = m_memory.Dup("cinematicsubtitle");
|
||||
item->itemFlags |= ITEM_FLAG_CINEMATIC_SUBTITLE;
|
||||
}
|
||||
item->window.group = ConvertString(commonItem.m_group);
|
||||
item->window.rectClient = ConvertRectDef(commonItem.m_rect);
|
||||
item->window.style = commonItem.m_style;
|
||||
|
||||
@@ -566,6 +566,16 @@ namespace
|
||||
|
||||
item->window.name = ConvertString(commonItem.m_name);
|
||||
item->text = commonItem.m_text ? m_memory.Dup(commonItem.m_text->c_str()) : nullptr;
|
||||
if (commonItem.m_text_save_game)
|
||||
{
|
||||
item->text = m_memory.Dup("savegameinfo");
|
||||
item->itemFlags |= ITEM_FLAG_SAVE_GAME_INFO;
|
||||
}
|
||||
if (commonItem.m_text_cinematic_subtitle)
|
||||
{
|
||||
item->text = m_memory.Dup("cinematicsubtitle");
|
||||
item->itemFlags |= ITEM_FLAG_CINEMATIC_SUBTITLE;
|
||||
}
|
||||
item->window.group = ConvertString(commonItem.m_group);
|
||||
item->window.rectClient = ConvertRectDef(commonItem.m_rect);
|
||||
item->window.style = commonItem.m_style;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
|
||||
@@ -535,10 +536,29 @@ namespace
|
||||
m_stream << "\n";
|
||||
}
|
||||
|
||||
void WriteItemTextProperties(const itemDef_s& item) const
|
||||
{
|
||||
const char* implicitText = nullptr;
|
||||
|
||||
if (item.itemFlags & ITEM_FLAG_SAVE_GAME_INFO)
|
||||
{
|
||||
WriteKeywordProperty("textsavegame", true);
|
||||
implicitText = "savegameinfo";
|
||||
}
|
||||
if (item.itemFlags & ITEM_FLAG_CINEMATIC_SUBTITLE)
|
||||
{
|
||||
WriteKeywordProperty("textcinematicsubtitle", true);
|
||||
implicitText = "cinematicsubtitle";
|
||||
}
|
||||
|
||||
if (!implicitText || (item.text && std::strcmp(item.text, implicitText) != 0))
|
||||
WriteItemTextProperty(item.text);
|
||||
}
|
||||
|
||||
void WriteItemData(const itemDef_s& item)
|
||||
{
|
||||
WriteStringProperty("name", item.window.name);
|
||||
WriteItemTextProperty(item.text);
|
||||
WriteItemTextProperties(item);
|
||||
WriteStringProperty("group", item.window.group);
|
||||
WriteRectProperty("rect", item.window.rectClient);
|
||||
WriteIntProperty("style", item.window.style, 0);
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
|
||||
@@ -539,10 +540,29 @@ namespace
|
||||
m_stream << "\n";
|
||||
}
|
||||
|
||||
void WriteItemTextProperties(const itemDef_s& item) const
|
||||
{
|
||||
const char* implicitText = nullptr;
|
||||
|
||||
if (item.itemFlags & ITEM_FLAG_SAVE_GAME_INFO)
|
||||
{
|
||||
WriteKeywordProperty("textsavegame", true);
|
||||
implicitText = "savegameinfo";
|
||||
}
|
||||
if (item.itemFlags & ITEM_FLAG_CINEMATIC_SUBTITLE)
|
||||
{
|
||||
WriteKeywordProperty("textcinematicsubtitle", true);
|
||||
implicitText = "cinematicsubtitle";
|
||||
}
|
||||
|
||||
if (!implicitText || (item.text && std::strcmp(item.text, implicitText) != 0))
|
||||
WriteItemTextProperty(item.text);
|
||||
}
|
||||
|
||||
void WriteItemData(const itemDef_s& item)
|
||||
{
|
||||
WriteStringProperty("name", item.window.name);
|
||||
WriteItemTextProperty(item.text);
|
||||
WriteItemTextProperties(item);
|
||||
WriteStringProperty("group", item.window.group);
|
||||
WriteRectProperty("rect", item.window.rectClient);
|
||||
WriteIntProperty("style", item.window.style, 0);
|
||||
|
||||
@@ -104,6 +104,16 @@ namespace
|
||||
exp material (localvarstring("ui_material"));
|
||||
}
|
||||
itemDef
|
||||
{
|
||||
name "save_game_info"
|
||||
textsavegame
|
||||
}
|
||||
itemDef
|
||||
{
|
||||
name "cinematic_subtitle"
|
||||
textcinematicsubtitle
|
||||
}
|
||||
itemDef
|
||||
{
|
||||
name "server_list"
|
||||
rect 20 60 300 200 0 0
|
||||
@@ -171,7 +181,7 @@ namespace
|
||||
REQUIRE(mainMenu->visibleExp.entries[2]->data.op == OP_RIGHTPAREN);
|
||||
REQUIRE(mainMenu->onOpen == R"("play" "menu_open" ; "setLocalVarInt" "ui_highlight" "5" ; )"s);
|
||||
|
||||
REQUIRE(mainMenu->itemCount == 3);
|
||||
REQUIRE(mainMenu->itemCount == 5);
|
||||
const auto* emptyTextItem = mainMenu->items[0];
|
||||
REQUIRE(emptyTextItem->parent == mainMenu);
|
||||
REQUIRE(emptyTextItem->text != nullptr);
|
||||
@@ -185,7 +195,15 @@ namespace
|
||||
REQUIRE(emptyTextItem->materialExp.numEntries == 3);
|
||||
REQUIRE(emptyTextItem->materialExp.entries[0]->data.op == OP_LOCALVARSTRING);
|
||||
|
||||
const auto* listItem = mainMenu->items[1];
|
||||
const auto* saveGameInfoItem = mainMenu->items[1];
|
||||
REQUIRE(saveGameInfoItem->text == "savegameinfo"s);
|
||||
REQUIRE(saveGameInfoItem->itemFlags == ITEM_FLAG_SAVE_GAME_INFO);
|
||||
|
||||
const auto* cinematicSubtitleItem = mainMenu->items[2];
|
||||
REQUIRE(cinematicSubtitleItem->text == "cinematicsubtitle"s);
|
||||
REQUIRE(cinematicSubtitleItem->itemFlags == ITEM_FLAG_CINEMATIC_SUBTITLE);
|
||||
|
||||
const auto* listItem = mainMenu->items[3];
|
||||
REQUIRE(listItem->typeData.listBox);
|
||||
REQUIRE(listItem->typeData.listBox->numColumns == 2);
|
||||
REQUIRE(listItem->typeData.listBox->columnInfo[1].pos == 120);
|
||||
@@ -197,7 +215,7 @@ namespace
|
||||
REQUIRE(listItem->typeData.listBox->selectIcon == selectMaterial);
|
||||
REQUIRE(listItem->typeData.listBox->onDoubleClick == R"("play" "mouse_click" ; )"s);
|
||||
|
||||
const auto* defaultTextItem = mainMenu->items[2];
|
||||
const auto* defaultTextItem = mainMenu->items[4];
|
||||
REQUIRE(defaultTextItem->type == 0);
|
||||
REQUIRE(defaultTextItem->typeData.editField);
|
||||
REQUIRE(defaultTextItem->typeData.editField->maxChars == 2);
|
||||
|
||||
@@ -110,6 +110,16 @@ namespace
|
||||
exp material (localvarstring("ui_material"));
|
||||
}
|
||||
itemDef
|
||||
{
|
||||
name "save_game_info"
|
||||
textsavegame
|
||||
}
|
||||
itemDef
|
||||
{
|
||||
name "cinematic_subtitle"
|
||||
textcinematicsubtitle
|
||||
}
|
||||
itemDef
|
||||
{
|
||||
name "server_list"
|
||||
rect 20 60 300 200 0 0
|
||||
@@ -186,7 +196,7 @@ namespace
|
||||
REQUIRE(mainMenu->onOpen == R"("play" "menu_open" ; "setLocalVarInt" "ui_highlight" "5" ; )"s);
|
||||
REQUIRE(mainMenu->onFocus == R"("setdvar" "ui_menu_focused" "1" ; )"s);
|
||||
|
||||
REQUIRE(mainMenu->itemCount == 3);
|
||||
REQUIRE(mainMenu->itemCount == 5);
|
||||
const auto* emptyTextItem = mainMenu->items[0];
|
||||
REQUIRE(emptyTextItem->parent == mainMenu);
|
||||
REQUIRE(emptyTextItem->text != nullptr);
|
||||
@@ -200,7 +210,15 @@ namespace
|
||||
REQUIRE(emptyTextItem->materialExp.numEntries == 3);
|
||||
REQUIRE(emptyTextItem->materialExp.entries[0]->data.op == OP_LOCALVARSTRING);
|
||||
|
||||
const auto* listItem = mainMenu->items[1];
|
||||
const auto* saveGameInfoItem = mainMenu->items[1];
|
||||
REQUIRE(saveGameInfoItem->text == "savegameinfo"s);
|
||||
REQUIRE(saveGameInfoItem->itemFlags == ITEM_FLAG_SAVE_GAME_INFO);
|
||||
|
||||
const auto* cinematicSubtitleItem = mainMenu->items[2];
|
||||
REQUIRE(cinematicSubtitleItem->text == "cinematicsubtitle"s);
|
||||
REQUIRE(cinematicSubtitleItem->itemFlags == ITEM_FLAG_CINEMATIC_SUBTITLE);
|
||||
|
||||
const auto* listItem = mainMenu->items[3];
|
||||
REQUIRE(listItem->typeData.listBox);
|
||||
REQUIRE(listItem->typeData.listBox->numColumns == 2);
|
||||
REQUIRE(listItem->typeData.listBox->columnInfo[1].pos == 120);
|
||||
@@ -216,7 +234,7 @@ namespace
|
||||
REQUIRE(listItem->typeData.listBox->onDoubleClick == R"("play" "mouse_click" ; )"s);
|
||||
REQUIRE(listItem->onListboxSelectionChange == R"("setdvar" "ui_server_selected" "1" ; )"s);
|
||||
|
||||
const auto* defaultTextItem = mainMenu->items[2];
|
||||
const auto* defaultTextItem = mainMenu->items[4];
|
||||
REQUIRE(defaultTextItem->type == 0);
|
||||
REQUIRE(defaultTextItem->typeData.editField);
|
||||
REQUIRE(defaultTextItem->typeData.editField->maxChars == 2);
|
||||
|
||||
@@ -353,6 +353,67 @@ namespace
|
||||
REQUIRE(parsed->m_menus[0]->m_items[1]->m_dvar == "player_name");
|
||||
}
|
||||
|
||||
TEST_CASE("MenuDumperIW3: Dumps special item text flags", "[iw3][menu][assetdumper]")
|
||||
{
|
||||
itemDef_s saveGameInfo{};
|
||||
saveGameInfo.window.name = "save_game_info";
|
||||
saveGameInfo.text = "savegameinfo";
|
||||
saveGameInfo.itemFlags = ITEM_FLAG_SAVE_GAME_INFO;
|
||||
|
||||
itemDef_s cinematicSubtitle{};
|
||||
cinematicSubtitle.window.name = "cinematic_subtitle";
|
||||
cinematicSubtitle.text = "cinematicsubtitle";
|
||||
cinematicSubtitle.itemFlags = ITEM_FLAG_CINEMATIC_SUBTITLE;
|
||||
|
||||
itemDef_s customSaveGameInfo{};
|
||||
customSaveGameInfo.window.name = "custom_save_game_info";
|
||||
customSaveGameInfo.text = "custom save game text";
|
||||
customSaveGameInfo.itemFlags = ITEM_FLAG_SAVE_GAME_INFO;
|
||||
|
||||
itemDef_s* items[]{&saveGameInfo, &cinematicSubtitle, &customSaveGameInfo};
|
||||
|
||||
menuDef_t menu{};
|
||||
menu.window.name = "special_item_text";
|
||||
menu.itemCount = static_cast<int>(std::size(items));
|
||||
menu.items = items;
|
||||
|
||||
Zone zone("MockZone", 0, GameId::IW3, GamePlatform::PC);
|
||||
zone.m_pools.AddAsset(std::make_unique<XAssetInfo<menuDef_t>>(ASSET_TYPE_MENU, menu.window.name, &menu));
|
||||
|
||||
MockSearchPath mockObjPath;
|
||||
MockOutputPath mockOutput;
|
||||
AssetDumpingContext context(zone, "", mockOutput, mockObjPath, std::nullopt);
|
||||
|
||||
menu::MenuDumperIW3 dumper;
|
||||
dumper.Dump(context);
|
||||
|
||||
const auto* file = mockOutput.GetMockedFile("ui_mp/special_item_text.menu");
|
||||
REQUIRE(file);
|
||||
|
||||
const auto output = file->AsString();
|
||||
const auto saveGameInfoPosition = output.find("save_game_info");
|
||||
const auto cinematicSubtitlePosition = output.find("cinematic_subtitle", saveGameInfoPosition);
|
||||
const auto customSaveGameInfoPosition = output.find("custom_save_game_info", cinematicSubtitlePosition);
|
||||
REQUIRE(saveGameInfoPosition != std::string::npos);
|
||||
REQUIRE(cinematicSubtitlePosition != std::string::npos);
|
||||
REQUIRE(customSaveGameInfoPosition != std::string::npos);
|
||||
|
||||
const auto saveGameInfoOutput = output.substr(saveGameInfoPosition, cinematicSubtitlePosition - saveGameInfoPosition);
|
||||
REQUIRE(saveGameInfoOutput.find("textsavegame") != std::string::npos);
|
||||
REQUIRE(saveGameInfoOutput.find("\"savegameinfo\"") == std::string::npos);
|
||||
|
||||
const auto cinematicSubtitleOutput = output.substr(cinematicSubtitlePosition, customSaveGameInfoPosition - cinematicSubtitlePosition);
|
||||
REQUIRE(cinematicSubtitleOutput.find("textcinematicsubtitle") != std::string::npos);
|
||||
REQUIRE(cinematicSubtitleOutput.find("\"cinematicsubtitle\"") == std::string::npos);
|
||||
|
||||
const auto customSaveGameInfoOutput = output.substr(customSaveGameInfoPosition);
|
||||
const auto customKeywordPosition = customSaveGameInfoOutput.find("textsavegame");
|
||||
const auto customTextPosition = customSaveGameInfoOutput.find("\"custom save game text\"");
|
||||
REQUIRE(customKeywordPosition != std::string::npos);
|
||||
REQUIRE(customTextPosition != std::string::npos);
|
||||
REQUIRE(customKeywordPosition < customTextPosition);
|
||||
}
|
||||
|
||||
TEST_CASE("MenuDumperIW3: Prefers parent menu list path over ui_mp fallback", "[iw3][menu][assetdumper]")
|
||||
{
|
||||
menuDef_t menu{};
|
||||
|
||||
@@ -353,6 +353,67 @@ namespace
|
||||
REQUIRE(parsed->m_menus[0]->m_items[1]->m_dvar == "player_name");
|
||||
}
|
||||
|
||||
TEST_CASE("MenuDumperT4: Dumps special item text flags", "[t4][menu][assetdumper]")
|
||||
{
|
||||
itemDef_s saveGameInfo{};
|
||||
saveGameInfo.window.name = "save_game_info";
|
||||
saveGameInfo.text = "savegameinfo";
|
||||
saveGameInfo.itemFlags = ITEM_FLAG_SAVE_GAME_INFO;
|
||||
|
||||
itemDef_s cinematicSubtitle{};
|
||||
cinematicSubtitle.window.name = "cinematic_subtitle";
|
||||
cinematicSubtitle.text = "cinematicsubtitle";
|
||||
cinematicSubtitle.itemFlags = ITEM_FLAG_CINEMATIC_SUBTITLE;
|
||||
|
||||
itemDef_s customSaveGameInfo{};
|
||||
customSaveGameInfo.window.name = "custom_save_game_info";
|
||||
customSaveGameInfo.text = "custom save game text";
|
||||
customSaveGameInfo.itemFlags = ITEM_FLAG_SAVE_GAME_INFO;
|
||||
|
||||
itemDef_s* items[]{&saveGameInfo, &cinematicSubtitle, &customSaveGameInfo};
|
||||
|
||||
menuDef_t menu{};
|
||||
menu.window.name = "special_item_text";
|
||||
menu.itemCount = static_cast<int>(std::size(items));
|
||||
menu.items = items;
|
||||
|
||||
Zone zone("MockZone", 0, GameId::T4, GamePlatform::PC);
|
||||
zone.m_pools.AddAsset(std::make_unique<XAssetInfo<menuDef_t>>(ASSET_TYPE_MENU, menu.window.name, &menu));
|
||||
|
||||
MockSearchPath mockObjPath;
|
||||
MockOutputPath mockOutput;
|
||||
AssetDumpingContext context(zone, "", mockOutput, mockObjPath, std::nullopt);
|
||||
|
||||
menu::MenuDumperT4 dumper;
|
||||
dumper.Dump(context);
|
||||
|
||||
const auto* file = mockOutput.GetMockedFile("ui_mp/special_item_text.menu");
|
||||
REQUIRE(file);
|
||||
|
||||
const auto output = file->AsString();
|
||||
const auto saveGameInfoPosition = output.find("save_game_info");
|
||||
const auto cinematicSubtitlePosition = output.find("cinematic_subtitle", saveGameInfoPosition);
|
||||
const auto customSaveGameInfoPosition = output.find("custom_save_game_info", cinematicSubtitlePosition);
|
||||
REQUIRE(saveGameInfoPosition != std::string::npos);
|
||||
REQUIRE(cinematicSubtitlePosition != std::string::npos);
|
||||
REQUIRE(customSaveGameInfoPosition != std::string::npos);
|
||||
|
||||
const auto saveGameInfoOutput = output.substr(saveGameInfoPosition, cinematicSubtitlePosition - saveGameInfoPosition);
|
||||
REQUIRE(saveGameInfoOutput.find("textsavegame") != std::string::npos);
|
||||
REQUIRE(saveGameInfoOutput.find("\"savegameinfo\"") == std::string::npos);
|
||||
|
||||
const auto cinematicSubtitleOutput = output.substr(cinematicSubtitlePosition, customSaveGameInfoPosition - cinematicSubtitlePosition);
|
||||
REQUIRE(cinematicSubtitleOutput.find("textcinematicsubtitle") != std::string::npos);
|
||||
REQUIRE(cinematicSubtitleOutput.find("\"cinematicsubtitle\"") == std::string::npos);
|
||||
|
||||
const auto customSaveGameInfoOutput = output.substr(customSaveGameInfoPosition);
|
||||
const auto customKeywordPosition = customSaveGameInfoOutput.find("textsavegame");
|
||||
const auto customTextPosition = customSaveGameInfoOutput.find("\"custom save game text\"");
|
||||
REQUIRE(customKeywordPosition != std::string::npos);
|
||||
REQUIRE(customTextPosition != std::string::npos);
|
||||
REQUIRE(customKeywordPosition < customTextPosition);
|
||||
}
|
||||
|
||||
TEST_CASE("MenuDumperT4: Prefers parent menu list path over ui_mp fallback", "[t4][menu][assetdumper]")
|
||||
{
|
||||
menuDef_t menu{};
|
||||
|
||||
Reference in New Issue
Block a user