mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-09-08 15:07:06 +00:00
feat: add T4 menu dumping and loading (#986)
* feat: add T4 menu dumping * chore: align with latest changes * feat: add T4 menu loading Load T4 menulists and menu files through the shared menu parser. Preserve T4-specific menu and listbox fields and cover loading, dumping, linking, and round-trip behaviour. * chore: make flag fields unsigned * chore: rename `expOperationEnum` -> `operationEnum` * chore: use default enum numeration for T4 operationEnum * chore: remove unused members of operationEnum * chore: remove redundant op from operationEnum * refactor: align T4 expression operand names with IW3 * chore: small adjustment to iw3,t4 types --------- Co-authored-by: Jan Laupetin <[email protected]>
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
>game,T4
|
||||
|
||||
menulist,ui_mp/menus.txt
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
menuDef
|
||||
{
|
||||
name "main"
|
||||
fullscreen 1
|
||||
rect 0 0 640 480 0 0
|
||||
disablecolor 0.2 0.3 0.4 0.5
|
||||
forecolor 0.8 0.7 0.6 0.5
|
||||
visible when(dvarbool("ui_show_main"));
|
||||
onOpen
|
||||
{
|
||||
play menu_open;
|
||||
setLocalVarInt ui_highlight 5;
|
||||
}
|
||||
onFocus
|
||||
{
|
||||
setdvar ui_menu_focused 1;
|
||||
}
|
||||
itemDef
|
||||
{
|
||||
name "empty_text"
|
||||
text ""
|
||||
rect 10 20 180 24 1 2
|
||||
type 1
|
||||
visible 1
|
||||
forecolor 0.9 0.9 1 0.07
|
||||
dvar "ui_fallback_text"
|
||||
action
|
||||
{
|
||||
setItemColor empty_text borderColor 0.1 0.1 0.12 0.5;
|
||||
}
|
||||
exp material localvarstring("ui_material");
|
||||
}
|
||||
itemDef
|
||||
{
|
||||
name "server_list"
|
||||
rect 20 60 300 200 0 0
|
||||
type 6
|
||||
focusColor 0.1 0.2 0.3 0.4
|
||||
onListboxSelectionChange
|
||||
{
|
||||
setdvar ui_server_selected 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
loadMenu { "ui_mp/main.menu" }
|
||||
loadMenu { "ui_mp/popup.menu" }
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
menuDef
|
||||
{
|
||||
name "popup"
|
||||
rect 40 40 200 100 0 0
|
||||
popup
|
||||
visible when(partyismissingmappack());
|
||||
onESC
|
||||
{
|
||||
close self;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
#include "Game/T4/Menu/MenuDumperT4.h"
|
||||
#include "Game/T4/Menu/MenuListDumperT4.h"
|
||||
#include "Game/T4/T4.h"
|
||||
#include "Linker.h"
|
||||
#include "OatTestPaths.h"
|
||||
#include "SearchPath/MockOutputPath.h"
|
||||
#include "SearchPath/MockSearchPath.h"
|
||||
#include "SystemTestsPaths.h"
|
||||
#include "ZoneLoading.h"
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
using namespace T4;
|
||||
using namespace std::literals;
|
||||
|
||||
namespace
|
||||
{
|
||||
TEST_CASE("Menu loading and dumping (T4)", "[t4][menu][system]")
|
||||
{
|
||||
const auto testDataPath = oat::paths::GetSystemTestsDirectory() / "Game/T4/MenuRoundTrip";
|
||||
const auto testDataPathString = testDataPath.string();
|
||||
const auto outputPath = oat::paths::GetTempDirectory("MenuRoundTripT4");
|
||||
const auto outputPathString = outputPath.string();
|
||||
|
||||
const char* arguments[]{
|
||||
"SystemTests",
|
||||
"--verbose",
|
||||
"--base-folder",
|
||||
outputPathString.c_str(),
|
||||
"--asset-search-path",
|
||||
testDataPathString.c_str(),
|
||||
"--source-search-path",
|
||||
testDataPathString.c_str(),
|
||||
"--output-folder",
|
||||
outputPathString.c_str(),
|
||||
"MenuRoundTripT4",
|
||||
};
|
||||
|
||||
LinkerArgs linkerArgs;
|
||||
auto shouldContinue = true;
|
||||
REQUIRE(linkerArgs.ParseArgs(std::size(arguments), arguments, shouldContinue));
|
||||
REQUIRE(shouldContinue);
|
||||
|
||||
const auto linker = Linker::Create(std::move(linkerArgs));
|
||||
REQUIRE(linker->Start());
|
||||
|
||||
const auto zonePath = outputPath / "MenuRoundTripT4.ff";
|
||||
auto maybeZone = ZoneLoading::LoadZone(zonePath.string(), std::nullopt);
|
||||
REQUIRE(maybeZone);
|
||||
auto zone = std::move(*maybeZone);
|
||||
|
||||
const auto* menuList = zone->m_pools.GetAsset<AssetMenuList>("ui_mp/menus.txt");
|
||||
const auto* mainMenu = zone->m_pools.GetAsset<AssetMenu>("main");
|
||||
const auto* popupMenu = zone->m_pools.GetAsset<AssetMenu>("popup");
|
||||
REQUIRE(menuList);
|
||||
REQUIRE(mainMenu);
|
||||
REQUIRE(popupMenu);
|
||||
REQUIRE(menuList->Asset()->menuCount == 2);
|
||||
REQUIRE(mainMenu->Asset()->visibleExp.numEntries == 3);
|
||||
REQUIRE(mainMenu->Asset()->window.dynamicFlags[0] & WINDOW_FLAG_NON_DEFAULT_FORECOLOR);
|
||||
REQUIRE(mainMenu->Asset()->onFocus == R"("setdvar" "ui_menu_focused" "1" ; )"s);
|
||||
REQUIRE(mainMenu->Asset()->items[0]->text != nullptr);
|
||||
REQUIRE(mainMenu->Asset()->items[0]->text == ""s);
|
||||
REQUIRE(mainMenu->Asset()->items[0]->window.dynamicFlags[0] & WINDOW_FLAG_NON_DEFAULT_FORECOLOR);
|
||||
REQUIRE(mainMenu->Asset()->items[0]->action == R"("setItemColor" "empty_text" "borderColor" "0.1" "0.1" "0.12" "0.5" ; )"s);
|
||||
REQUIRE(mainMenu->Asset()->items[1]->onListboxSelectionChange == R"("setdvar" "ui_server_selected" "1" ; )"s);
|
||||
REQUIRE(mainMenu->Asset()->items[1]->typeData.listBox->focusColor[2] == 0.3f);
|
||||
REQUIRE(popupMenu->Asset()->visibleExp.entries[0]->data.op == OP_PARTYISMISSINGMAPPACK);
|
||||
|
||||
MockSearchPath objPath;
|
||||
MockOutputPath dumpOutput;
|
||||
AssetDumpingContext dumpingContext(*zone, "", dumpOutput, objPath, std::nullopt);
|
||||
menu::MenuListDumperT4 menuListDumper;
|
||||
menuListDumper.Dump(dumpingContext);
|
||||
menu::MenuDumperT4 menuDumper;
|
||||
menuDumper.Dump(dumpingContext);
|
||||
|
||||
const auto* dumpedMenuList = dumpOutput.GetMockedFile("ui_mp/menus.txt");
|
||||
const auto* dumpedMainMenu = dumpOutput.GetMockedFile("ui_mp/main.menu");
|
||||
const auto* dumpedPopupMenu = dumpOutput.GetMockedFile("ui_mp/popup.menu");
|
||||
REQUIRE(dumpedMenuList);
|
||||
REQUIRE(dumpedMainMenu);
|
||||
REQUIRE(dumpedPopupMenu);
|
||||
REQUIRE(dumpedMenuList->AsString().find("loadMenu { \"ui_mp/main.menu\" }") != std::string::npos);
|
||||
REQUIRE(dumpedMenuList->AsString().find("loadMenu { \"ui_mp/popup.menu\" }") != std::string::npos);
|
||||
REQUIRE(dumpedMainMenu->AsString().find("text \"\"") != std::string::npos);
|
||||
REQUIRE(dumpedMainMenu->AsString().find("visible when(dvarbool(\"ui_show_main\"));") != std::string::npos);
|
||||
REQUIRE(dumpedMainMenu->AsString().find("setItemColor empty_text borderColor 0.1 0.1 0.12 0.5;") != std::string::npos);
|
||||
REQUIRE(dumpedMainMenu->AsString().find("onListboxSelectionChange") != std::string::npos);
|
||||
REQUIRE(dumpedMainMenu->AsString().find("focusColor 0.1 0.2 0.3 0.4") != std::string::npos);
|
||||
REQUIRE(dumpedPopupMenu->AsString().find("partyismissingmappack()") != std::string::npos);
|
||||
}
|
||||
} // namespace
|
||||
Reference in New Issue
Block a user