Fix inventory layout integration and qualify ordinary UI and radio guidance
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
ERRIC_InventoryMode : "{0F307326459A1395}Prefabs/MP/Modes/GameMode_Base.et" {
|
||||
components {
|
||||
SCR_RespawnSystemComponent "{56B2B4793051E7C9}" {
|
||||
m_SpawnLogic SCR_SpawnLogic {}
|
||||
}
|
||||
}
|
||||
m_bUseSpawnPreload 0
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
MetaFileClass {
|
||||
Name "{86FBBCE45AF62682}Prefabs/ERRIC_InventoryMode.et"
|
||||
Configurations {
|
||||
EntityTemplateResourceClass PC {}
|
||||
EntityTemplateResourceClass HEADLESS : PC {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
# Isolated stock inventory runtime control
|
||||
|
||||
This diagnostic addon depends only on installed vanilla Reforger (`58D0FB3206B6F859`). It must run without successor Core, AI, Intel, Map or Chat loaded. It has its own project, world and prefab identities. It is not a player mission or a multiplayer/admission test.
|
||||
|
||||
Copy this directory alone as the hidden runner's `addons/core`; select `Worlds/ERRIC_Inventory.ent` and command-line Workbench plugin `ERRIC_InventoryControlPlugin`, with `-erricInventoryControl 1 -errPlay 1`. Keep the separate private profile, muted hidden Gamescope containment, prefix lock and source-bound archive. The fixture emits `ERR SMOKE PASS/FAIL/COMPLETE` with explicit vanilla-control scope. No automatic reload; required completion count is one. Native compilation/runtime execution is pending.
|
||||
|
||||
The fixture waits at most 30 seconds in actual local `RplMode.None` for `SCR_PlayerController`. It creates one stock `{2F912ED6E399FF47}Prefabs/Characters/Factions/BLUFOR/US_Army/Character_US_Unarmed.et`, assigns that body once through native `SetControlledEntity`, waits for settling, then calls the controller's actual `ActionOpenInventory`. It verifies the exact body, native menu/top menu, root, native `GridLayoutWidget` named `StoragesListSlot` and its direct `Frame0` child. The open screenshot is requested after 500 ms. Public native `SCR_InventoryStorageManagerComponent.CloseInventory` closes it; another 500 ms later the fixture verifies closure and requests a closed screenshot. World teardown disposes the fixture actor; the diagnostic does not delete a possessed actor or modify its inventory, health, or controls.
|
||||
|
||||
`Action_OpenInventory` is not a toggle: the installed implementation always invokes `OpenInventory`. The menu's `Action_CloseInventory` is protected. Therefore this control deliberately uses the public native close method instead of incorrectly invoking the open method twice. No keyboard input or user-input usability is claimed.
|
||||
|
||||
Retain all raw GUI errors. The suspected vanilla source path is:
|
||||
|
||||
* `scripts/Game/Player/SCR_PlayerController.c:965`: `ActionOpenInventory` delegates to the body's native inventory manager.
|
||||
* `scripts/Game/Inventory/SCR_InventoryStorageManagerComponent.c:1756,1824`: normal inventory-open path uses `ChimeraMenuPreset.Inventory20Menu`.
|
||||
* `scripts/Game/UI/Inventory/SCR_InventoryMenuUI.c:1694`: `ShowStoragesList` creates `{FC579324F5E4B3A4}UI/layouts/Menus/Inventory/InventoryCharacterGrid.layout` beneath `StoragesListSlot`, then attaches `SCR_InventoryStoragesListUI`.
|
||||
* The installed `InventoryMain.layout` defines `StoragesListSlot` as a `GridLayoutWidget`; `InventoryCharacterGrid.layout` defines its root as `OverlayWidget Frame0`.
|
||||
* `scripts/Game/UI/Inventory/SCR_InventoryStoragesListUI.c:301–302` unconditionally calls two `LayoutSlot` operations on that root, which now has a native grid slot.
|
||||
|
||||
Successor ordinary runs 16:55:12 and 16:58:32 recorded exactly two `OverlayWidget Frame0 has invalid slot GridWidgetSlot ... expected LayoutSlot` errors when opening inventory. This source chain is a concrete hypothesis; this control must reproduce it without successor addons before attributing runtime errors to vanilla. A completed fixture alongside retained GUI errors is a failed clean-runtime report, not an error-free qualification. Workbench control evidence does not establish ordinary-game module parity.
|
||||
@@ -0,0 +1,126 @@
|
||||
// Diagnostic addon only. No successor scripts/resources or player audit policy.
|
||||
#ifdef WORKBENCH
|
||||
class ERRIC_InventoryModeClass : SCR_BaseGameModeClass {}
|
||||
class ERRIC_InventoryMode : SCR_BaseGameMode
|
||||
{
|
||||
protected SCR_PlayerController m_Controller;
|
||||
protected IEntity m_Character;
|
||||
protected SCR_InventoryStorageManagerComponent m_Inventory;
|
||||
protected SCR_InventoryMenuUI m_Menu;
|
||||
protected int m_Deadline;
|
||||
protected int m_Wait;
|
||||
protected int m_Step;
|
||||
protected bool m_Finished;
|
||||
|
||||
protected override void EOnInit(IEntity owner)
|
||||
{
|
||||
super.EOnInit(owner);
|
||||
string enabled;
|
||||
if (SCR_Global.IsEditMode() || !System.GetCLIParam("erricInventoryControl", enabled) || enabled != "1") return;
|
||||
if (!Replication.IsServer() || RplSession.Mode() != RplMode.None)
|
||||
{
|
||||
Fail("requires isolated native singleplayer Workbench mode");
|
||||
return;
|
||||
}
|
||||
m_Deadline = System.GetTickCount() + 30000;
|
||||
GetGame().GetCallqueue().CallLater(Probe, 100, true);
|
||||
}
|
||||
|
||||
protected void Fail(string reason)
|
||||
{
|
||||
if (m_Finished) return;
|
||||
m_Finished = true;
|
||||
if (GetGame()) GetGame().GetCallqueue().Remove(Probe);
|
||||
Print("ERR SMOKE FAIL: vanilla inventory control: " + reason, LogLevel.ERROR);
|
||||
}
|
||||
|
||||
protected bool Check(bool condition, string reason)
|
||||
{
|
||||
if (!condition) { Fail(reason); return false; }
|
||||
Print("ERR SMOKE PASS: vanilla inventory control: " + reason);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected bool SameBody()
|
||||
{
|
||||
if (!GetGame() || !m_Controller || !m_Character) return false;
|
||||
return GetGame().GetPlayerController() == m_Controller && m_Controller.GetControlledEntity() == m_Character;
|
||||
}
|
||||
|
||||
protected void Probe()
|
||||
{
|
||||
if (m_Finished || !GetGame() || !GetGame().GetWorld()) return;
|
||||
int now = System.GetTickCount();
|
||||
if (now > m_Deadline) { Fail("bounded native controller/menu deadline"); return; }
|
||||
if (now < m_Wait) return;
|
||||
if (m_Step == 0)
|
||||
{
|
||||
m_Controller = SCR_PlayerController.Cast(GetGame().GetPlayerController());
|
||||
if (!m_Controller) return;
|
||||
if (!Check(!m_Controller.GetControlledEntity(), "real local controller initially unassigned")) return;
|
||||
Resource resource = Resource.Load("{2F912ED6E399FF47}Prefabs/Characters/Factions/BLUFOR/US_Army/Character_US_Unarmed.et");
|
||||
if (!Check(resource && resource.IsValid(), "installed unmodified US_Unarmed resource")) return;
|
||||
EntitySpawnParams params = new EntitySpawnParams();
|
||||
params.TransformMode = ETransformMode.WORLD;
|
||||
vector origin = "6090 0 7160";
|
||||
origin[1] = GetGame().GetWorld().GetSurfaceY(origin[0], origin[2]) + 0.1;
|
||||
params.Transform[3] = origin;
|
||||
m_Character = GetGame().SpawnEntityPrefab(resource, GetGame().GetWorld(), params);
|
||||
if (!Check(m_Character != null, "one stock body spawned")) return;
|
||||
if (!Check(m_Controller.SetControlledEntity(m_Character), "native fixture-only body assignment succeeded")) return;
|
||||
m_Inventory = SCR_InventoryStorageManagerComponent.Cast(m_Character.FindComponent(SCR_InventoryStorageManagerComponent));
|
||||
if (!Check(m_Inventory != null, "stock inventory component present")) return;
|
||||
m_Step = 1;
|
||||
m_Wait = now + 1000;
|
||||
return;
|
||||
}
|
||||
if (!SameBody()) { Fail("original local controller/body changed"); return; }
|
||||
if (m_Step == 1)
|
||||
{
|
||||
if (!Check(SCR_InventoryMenuUI.GetInventoryMenu() == null, "inventory initially closed")) return;
|
||||
m_Controller.ActionOpenInventory();
|
||||
m_Step = 2;
|
||||
m_Wait = now + 500;
|
||||
return;
|
||||
}
|
||||
if (m_Step == 2)
|
||||
{
|
||||
m_Menu = SCR_InventoryMenuUI.GetInventoryMenu();
|
||||
if (!Check(m_Menu != null, "actual native Inventory20Menu opened")) return;
|
||||
ChimeraCharacter character = ChimeraCharacter.Cast(m_Character);
|
||||
if (!Check(character && m_Menu.GetCharacterController() == character.GetCharacterController(), "menu bound to exact stock body")) return;
|
||||
Widget root = m_Menu.GetRootWidget();
|
||||
if (!Check(root != null && GetGame().GetMenuManager().GetTopMenu() == m_Menu, "native inventory root and top menu")) return;
|
||||
Widget parent = root.FindAnyWidget("StoragesListSlot");
|
||||
if (!Check(parent && GridLayoutWidget.Cast(parent), "stock storage-list parent is native GridLayoutWidget")) return;
|
||||
Widget frame = parent.GetChildren();
|
||||
if (!Check(frame && frame.GetName() == "Frame0" && frame.GetParent() == parent, "stock Frame0 is direct child of native storage grid")) return;
|
||||
PrintFormat("ERRIC INVENTORY GEOMETRY: parent=%1 type=%2 child=%3 type=%4", parent.GetName(), parent.Type(), frame.GetName(), frame.Type());
|
||||
System.MakeScreenshot("$logs:erric-inventory-open");
|
||||
m_Step = 3;
|
||||
m_Wait = now + 500;
|
||||
return;
|
||||
}
|
||||
if (m_Step == 3)
|
||||
{
|
||||
if (!Check(SCR_InventoryMenuUI.GetInventoryMenu() == m_Menu, "same native menu retained for delayed capture")) return;
|
||||
// Action_OpenInventory opens only; public native CloseInventory is its counterpart.
|
||||
m_Inventory.CloseInventory();
|
||||
m_Step = 4;
|
||||
m_Wait = now + 500;
|
||||
return;
|
||||
}
|
||||
if (!Check(SCR_InventoryMenuUI.GetInventoryMenu() == null, "native inventory closed with original body retained")) return;
|
||||
System.MakeScreenshot("$logs:erric-inventory-closed");
|
||||
m_Finished = true;
|
||||
GetGame().GetCallqueue().Remove(Probe);
|
||||
Print("ERR SMOKE COMPLETE: vanilla inventory control; direct native API experiment only, no successor or input qualification");
|
||||
}
|
||||
|
||||
void ~ERRIC_InventoryMode()
|
||||
{
|
||||
if (GetGame()) GetGame().GetCallqueue().Remove(Probe);
|
||||
// World teardown owns the fixture entity; do not delete a possessed actor.
|
||||
}
|
||||
}
|
||||
#endif
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
[WorkbenchPluginAttribute(name: "Isolated vanilla inventory control", wbModules: {"WorldEditor"})]
|
||||
class ERRIC_InventoryControlPlugin : WorldEditorPlugin
|
||||
{
|
||||
override void RunCommandline()
|
||||
{
|
||||
string enabled, play;
|
||||
WorldEditor editor = Workbench.GetModule(WorldEditor);
|
||||
if (editor && System.GetCLIParam("erricInventoryControl", enabled) && enabled == "1" && System.GetCLIParam("errPlay", play) && play == "1")
|
||||
editor.SwitchToGameMode();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
SubScene {
|
||||
Parent "{853E92315D1D9EFE}worlds/Eden/Eden.ent"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
MetaFileClass {
|
||||
Name "{2AACCD1FDA9EB6E9}Worlds/ERRIC_Inventory.ent"
|
||||
Configurations {
|
||||
WorldResourceClass PC {}
|
||||
WorldResourceClass HEADLESS : PC {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
ERRIC_InventoryMode InventoryControl : "{86FBBCE45AF62682}Prefabs/ERRIC_InventoryMode.et" {}
|
||||
SCR_FactionManager Factions : "{589540B35EBA8CDC}Prefabs/MP/Managers/Factions/FactionManager_USxUSSR.et" {}
|
||||
SCR_LoadoutManager Loadouts : "{97EF4C1A41F63DDB}Prefabs/MP/Managers/Loadouts/LoadoutManager_USxUSSR.et" {}
|
||||
@@ -0,0 +1,6 @@
|
||||
GameProject {
|
||||
ID "ERRIC_InventoryControl"
|
||||
GUID "0FFD909E91FC329B"
|
||||
TITLE "Vanilla inventory diagnostic control (isolated)"
|
||||
Dependencies { "58D0FB3206B6F859" }
|
||||
}
|
||||
Reference in New Issue
Block a user