From 89b9549c12a6726887b377a31361988a6f56c590 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 26 Jan 2026 19:24:58 +0000
Subject: [PATCH 1/5] Initial plan
From abfe28ad49b2b4d5f79acdb3073baac466a7a8cb Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 26 Jan 2026 19:33:05 +0000
Subject: [PATCH 2/5] Add category attributes to TombEngine Moveables.xml
Added category attributes to all 941 moveables in the TombEngine catalog with appropriate categorization:
- PLAYER (13): Lara and her components
- VEHICLE (13): Vehicles and their animations
- ENEMY (111): Hostile enemies and dangerous creatures
- CREATURE (13): Non-hostile animals
- BOSS (20): Boss enemies
- NPC (9): Non-player characters
- PROJECTILE (13): Projectiles and weapons
- TRAP (67): Traps and obstacles
- PICKUP (86): Pickupable items (weapons, ammo, health)
- EMITTER (7): Particle emitters
- PUZZLE (188): Puzzle items, keys, and related objects
- DOOR (51): All door types
- SWITCH (36): Switches and levers
- DECORATION (208): Decorative and visual objects
- MECHANISM (62): Mechanisms and machinery
AI objects and internal markers intentionally left without categories.
Co-authored-by: TrainWrack <120750885+TrainWrack@users.noreply.github.com>
---
.../Catalogs/Engines/TombEngine/Moveables.xml | 1882 ++++++++---------
TombLib/TombLib/Wad/Catalog/TrCatalog.cs | 48 +-
2 files changed, 987 insertions(+), 943 deletions(-)
diff --git a/TombLib/TombLib/Catalogs/Engines/TombEngine/Moveables.xml b/TombLib/TombLib/Catalogs/Engines/TombEngine/Moveables.xml
index bbf2c6c7d..f5e604bfb 100644
--- a/TombLib/TombLib/Catalogs/Engines/TombEngine/Moveables.xml
+++ b/TombLib/TombLib/Catalogs/Engines/TombEngine/Moveables.xml
@@ -1,753 +1,753 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -756,204 +756,204 @@
-
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TombLib/TombLib/Wad/Catalog/TrCatalog.cs b/TombLib/TombLib/Wad/Catalog/TrCatalog.cs
index 09d3e727e..9168dc04a 100644
--- a/TombLib/TombLib/Wad/Catalog/TrCatalog.cs
+++ b/TombLib/TombLib/Wad/Catalog/TrCatalog.cs
@@ -50,6 +50,7 @@ private struct Item
public bool FreeRotation { get; set; }
public bool IsHidden { get; set; }
public bool IsEssential { get; set; }
+ public string Category { get; set; }
}
private struct ItemSound
@@ -125,6 +126,7 @@ public static int PredictSoundMapSize(TRVersion.Game version, bool IsNg, int num
public static bool IsHidden(TRVersion.Game version, uint id) => GetMoveable(version, id)?.IsHidden ?? false;
public static bool IsEssential(TRVersion.Game version, uint id) => GetMoveable(version, id)?.IsEssential ?? false;
public static bool IsFreelyRotateable(TRVersion.Game version, uint id) => GetMoveable(version, id)?.FreeRotation ?? false;
+ public static string GetMoveableCategory(TRVersion.Game version, uint id) => GetMoveable(version, id)?.Category ?? string.Empty;
public static string GetSpriteSequenceTombEngineSlot(TRVersion.Game version, uint id)
{
@@ -192,6 +194,19 @@ public static bool IsStaticShatterable(TRVersion.Game version, uint id)
return entry.Shatterable;
}
+ public static string GetStaticCategory(TRVersion.Game version, uint id)
+ {
+ Game game;
+ if (!Games.TryGetValue(version.Native(), out game))
+ return string.Empty;
+
+ Item entry;
+ if (!game.Statics.TryGetValue(id, out entry))
+ return string.Empty;
+
+ return entry.Category ?? string.Empty;
+ }
+
public static uint? GetItemIndex(TRVersion.Game version, string name, out bool isMoveable)
{
Game game;
@@ -416,6 +431,32 @@ public static IDictionary GetAllStatics(TRVersion.Game version)
return Games[version.Native()].Statics.DicSelect(item => item.Value.Names.LastOrDefault());
}
+ public static IEnumerable GetAllMoveableCategories(TRVersion.Game version)
+ {
+ Game game;
+ if (!Games.TryGetValue(version.Native(), out game))
+ return Enumerable.Empty();
+
+ return game.Moveables.Values
+ .Select(item => item.Category)
+ .Where(category => !string.IsNullOrEmpty(category))
+ .Distinct()
+ .OrderBy(category => category);
+ }
+
+ public static IEnumerable GetAllStaticCategories(TRVersion.Game version)
+ {
+ Game game;
+ if (!Games.TryGetValue(version.Native(), out game))
+ return Enumerable.Empty();
+
+ return game.Statics.Values
+ .Select(item => item.Category)
+ .Where(category => !string.IsNullOrEmpty(category))
+ .Distinct()
+ .OrderBy(category => category);
+ }
+
public static IDictionary GetAllSpriteSequences(TRVersion.Game version)
{
return Games[version.Native()].SpriteSequences.DicSelect(item => item.Value.Names.LastOrDefault());
@@ -539,6 +580,7 @@ public static void LoadCatalog(string rootFolder)
bool hidden = bool.Parse(moveableNode.Attributes["hidden"]?.Value ?? "false");
bool essential = bool.Parse(moveableNode.Attributes["essential"]?.Value ?? "true");
string tombEngineSlot = moveableNode.Attributes["ten"]?.Value ?? string.Empty;
+ string category = moveableNode.Attributes["category"]?.Value ?? string.Empty;
game.Moveables.Add(id, new Item
{
@@ -549,7 +591,8 @@ public static void LoadCatalog(string rootFolder)
TombEngineSlot = tombEngineSlot,
FreeRotation = isFreeRotation,
IsHidden = hidden,
- IsEssential = essential
+ IsEssential = essential,
+ Category = category
});
}
}
@@ -566,7 +609,8 @@ public static void LoadCatalog(string rootFolder)
uint id = uint.Parse(staticNode.Attributes["id"].Value);
string[] names = (staticNode.Attributes["name"]?.Value ?? "").Split('|');
bool shatter = bool.Parse(staticNode.Attributes["shatter"]?.Value ?? "false");
- game.Statics.Add(id, new Item { Names = new List(names), Shatterable = shatter });
+ string category = staticNode.Attributes["category"]?.Value ?? string.Empty;
+ game.Statics.Add(id, new Item { Names = new List(names), Shatterable = shatter, Category = category });
}
}
From b3807d1f9aedc1a24fee7d5ff424e3314b3cf749 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 26 Jan 2026 19:37:35 +0000
Subject: [PATCH 3/5] Add category attributes to TR4 XML files
- Added category attributes to all 520 moveables in TR4/Moveables.xml
- Added category attributes to all 160 statics in TR4/Statics.xml
- Used TombEngine categorization logic for consistency
- Categories: PLAYER, VEHICLE, ENEMY, CREATURE, BOSS, NPC, PROJECTILE, TRAP, PICKUP, EMITTER, PUZZLE, DOOR, SWITCH, DECORATION, MECHANISM, ARCHITECTURE, SHATTER
---
.../Catalogs/Engines/TR4/Moveables.xml | 1040 ++++++++---------
.../TombLib/Catalogs/Engines/TR4/Statics.xml | 320 ++---
2 files changed, 680 insertions(+), 680 deletions(-)
diff --git a/TombLib/TombLib/Catalogs/Engines/TR4/Moveables.xml b/TombLib/TombLib/Catalogs/Engines/TR4/Moveables.xml
index 732172546..c05fb04c0 100644
--- a/TombLib/TombLib/Catalogs/Engines/TR4/Moveables.xml
+++ b/TombLib/TombLib/Catalogs/Engines/TR4/Moveables.xml
@@ -1,523 +1,523 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/TombLib/TombLib/Catalogs/Engines/TR4/Statics.xml b/TombLib/TombLib/Catalogs/Engines/TR4/Statics.xml
index 907cbdfcd..6e1aff8d6 100644
--- a/TombLib/TombLib/Catalogs/Engines/TR4/Statics.xml
+++ b/TombLib/TombLib/Catalogs/Engines/TR4/Statics.xml
@@ -1,163 +1,163 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
From 5162f8c016068dc307d69888e5a293aedf765b74 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 26 Jan 2026 19:40:31 +0000
Subject: [PATCH 4/5] Add filter button to ItemBrowser with dynamic category
filtering
Co-authored-by: TrainWrack <120750885+TrainWrack@users.noreply.github.com>
---
.../ToolWindows/ItemBrowser.Designer.cs | 17 ++-
TombEditor/ToolWindows/ItemBrowser.cs | 126 ++++++++++++++++--
2 files changed, 130 insertions(+), 13 deletions(-)
diff --git a/TombEditor/ToolWindows/ItemBrowser.Designer.cs b/TombEditor/ToolWindows/ItemBrowser.Designer.cs
index a1e6492f8..68838d5cd 100644
--- a/TombEditor/ToolWindows/ItemBrowser.Designer.cs
+++ b/TombEditor/ToolWindows/ItemBrowser.Designer.cs
@@ -19,6 +19,7 @@ private void InitializeComponent()
this.panelItem = new TombEditor.Controls.PanelRenderingItem();
this.panelHeader = new System.Windows.Forms.Panel();
this.butAddItem = new DarkUI.Controls.DarkButton();
+ this.butFilter = new DarkUI.Controls.DarkButton();
this.comboItems = new TombLib.Controls.DarkSearchableComboBox();
this.panelRightBottom = new System.Windows.Forms.Panel();
this.lblFromWad = new DarkUI.Controls.DarkLabel();
@@ -48,6 +49,7 @@ private void InitializeComponent()
// panelHeader
//
this.panelHeader.Controls.Add(this.butAddItem);
+ this.panelHeader.Controls.Add(this.butFilter);
this.panelHeader.Controls.Add(this.comboItems);
this.panelHeader.Dock = System.Windows.Forms.DockStyle.Top;
this.panelHeader.Location = new System.Drawing.Point(0, 25);
@@ -67,13 +69,25 @@ private void InitializeComponent()
this.butAddItem.TabIndex = 3;
this.butAddItem.Tag = "AddItem";
//
+ // butFilter
+ //
+ this.butFilter.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.butFilter.Checked = false;
+ this.butFilter.Image = global::TombEditor.Properties.Resources.general_filter_16;
+ this.butFilter.Location = new System.Drawing.Point(231, 2);
+ this.butFilter.Name = "butFilter";
+ this.butFilter.Size = new System.Drawing.Size(24, 23);
+ this.butFilter.TabIndex = 2;
+ this.toolTip.SetToolTip(this.butFilter, "Filter items");
+ this.butFilter.Click += new System.EventHandler(this.butFilter_Click);
+ //
// comboItems
//
this.comboItems.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.comboItems.Location = new System.Drawing.Point(3, 2);
this.comboItems.Name = "comboItems";
- this.comboItems.Size = new System.Drawing.Size(249, 23);
+ this.comboItems.Size = new System.Drawing.Size(222, 23);
this.comboItems.TabIndex = 1;
this.comboItems.Format += new System.Windows.Forms.ListControlConvertEventHandler(this.comboItems_Format);
this.comboItems.SelectedIndexChanged += new System.EventHandler(this.comboItems_SelectedIndexChanged);
@@ -185,6 +199,7 @@ private void InitializeComponent()
private Controls.PanelRenderingItem panelItem;
private System.Windows.Forms.Panel panelHeader;
private DarkUI.Controls.DarkButton butAddItem;
+ private DarkUI.Controls.DarkButton butFilter;
private TombLib.Controls.DarkSearchableComboBox comboItems;
private System.Windows.Forms.Panel panelRightBottom;
private System.Windows.Forms.Panel panelRight;
diff --git a/TombEditor/ToolWindows/ItemBrowser.cs b/TombEditor/ToolWindows/ItemBrowser.cs
index bf45da702..858b0fc21 100644
--- a/TombEditor/ToolWindows/ItemBrowser.cs
+++ b/TombEditor/ToolWindows/ItemBrowser.cs
@@ -1,5 +1,6 @@
using DarkUI.Docking;
using System;
+using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Forms;
@@ -13,6 +14,8 @@ namespace TombEditor.ToolWindows
public partial class ItemBrowser : DarkToolWindow
{
private readonly Editor _editor;
+ private HashSet _selectedCategories = new HashSet();
+ private bool _staticsOnlyFilter = false;
public ItemBrowser()
{
@@ -46,18 +49,7 @@ private void EditorEventRaised(IEditorEvent obj)
obj is Editor.GameVersionChangedEvent ||
obj is Editor.ConfigurationChangedEvent)
{
- var allMoveables = _editor.Level.Settings.WadGetAllMoveables();
- var allStatics = _editor.Level.Settings.WadGetAllStatics();
-
- comboItems.GameVersion = _editor.Level.Settings.GameVersion;
- comboItems.Items.Clear();
- foreach (var moveable in allMoveables.Values)
- if (!_editor.Configuration.RenderingItem_HideInternalObjects ||
- !TrCatalog.IsHidden(_editor.Level.Settings.GameVersion, moveable.Id.TypeId))
- comboItems.Items.Add(moveable);
-
- foreach (var staticMesh in allStatics.Values)
- comboItems.Items.Add(staticMesh);
+ PopulateItemsList();
if (comboItems.Items.Count > 0)
{
@@ -74,6 +66,9 @@ obj is Editor.GameVersionChangedEvent ||
{
comboItems.SelectedIndex = 0;
+ var allMoveables = _editor.Level.Settings.WadGetAllMoveables();
+ var allStatics = _editor.Level.Settings.WadGetAllStatics();
+
// Update visible conflicting item, otherwise it's not updated in 3D control.
if (comboItems.SelectedItem is WadMoveable)
{
@@ -229,5 +224,112 @@ private void butItemDown_Click(object sender, EventArgs e)
else
comboItems.SelectedIndex = 0;
}
+
+ private void PopulateItemsList()
+ {
+ var allMoveables = _editor.Level.Settings.WadGetAllMoveables();
+ var allStatics = _editor.Level.Settings.WadGetAllStatics();
+
+ comboItems.GameVersion = _editor.Level.Settings.GameVersion;
+ comboItems.Items.Clear();
+
+ // Add moveables with filtering
+ if (!_staticsOnlyFilter)
+ {
+ foreach (var moveable in allMoveables.Values)
+ {
+ if (!_editor.Configuration.RenderingItem_HideInternalObjects ||
+ !TrCatalog.IsHidden(_editor.Level.Settings.GameVersion, moveable.Id.TypeId))
+ {
+ // Apply category filter if any categories are selected
+ if (_selectedCategories.Count == 0 || ShouldIncludeMoveable(moveable))
+ {
+ comboItems.Items.Add(moveable);
+ }
+ }
+ }
+ }
+
+ // Add statics with filtering
+ foreach (var staticMesh in allStatics.Values)
+ {
+ // Apply category filter if any categories are selected
+ if (_selectedCategories.Count == 0 || ShouldIncludeStatic(staticMesh))
+ {
+ comboItems.Items.Add(staticMesh);
+ }
+ }
+ }
+
+ private bool ShouldIncludeMoveable(WadMoveable moveable)
+ {
+ var category = TrCatalog.GetMoveableCategory(_editor.Level.Settings.GameVersion, moveable.Id.TypeId);
+ return !string.IsNullOrEmpty(category) && _selectedCategories.Contains(category);
+ }
+
+ private bool ShouldIncludeStatic(WadStatic staticMesh)
+ {
+ var category = TrCatalog.GetStaticCategory(_editor.Level.Settings.GameVersion, staticMesh.Id.TypeId);
+ return !string.IsNullOrEmpty(category) && _selectedCategories.Contains(category);
+ }
+
+ private void butFilter_Click(object sender, EventArgs e)
+ {
+ // Get all available categories from the current game version
+ var moveableCategories = TrCatalog.GetAllMoveableCategories(_editor.Level.Settings.GameVersion).ToList();
+ var staticCategories = TrCatalog.GetAllStaticCategories(_editor.Level.Settings.GameVersion).ToList();
+ var allCategories = moveableCategories.Union(staticCategories).Distinct().OrderBy(c => c).ToList();
+
+ // Create context menu
+ var contextMenu = new DarkUI.Controls.DarkContextMenu();
+
+ // Add "Clear Filter" option
+ var clearItem = new System.Windows.Forms.ToolStripMenuItem("Clear Filter");
+ clearItem.Checked = _selectedCategories.Count == 0 && !_staticsOnlyFilter;
+ clearItem.Click += (s, ev) =>
+ {
+ _selectedCategories.Clear();
+ _staticsOnlyFilter = false;
+ PopulateItemsList();
+ };
+ contextMenu.Items.Add(clearItem);
+
+ // Add "Statics Only" option
+ var staticsOnlyItem = new System.Windows.Forms.ToolStripMenuItem("Statics Only");
+ staticsOnlyItem.Checked = _staticsOnlyFilter;
+ staticsOnlyItem.Click += (s, ev) =>
+ {
+ _staticsOnlyFilter = !_staticsOnlyFilter;
+ if (_staticsOnlyFilter)
+ _selectedCategories.Clear(); // Clear category filters when enabling statics only
+ PopulateItemsList();
+ };
+ contextMenu.Items.Add(staticsOnlyItem);
+
+ // Add separator
+ contextMenu.Items.Add(new System.Windows.Forms.ToolStripSeparator());
+
+ // Add category items
+ foreach (var category in allCategories)
+ {
+ var categoryItem = new System.Windows.Forms.ToolStripMenuItem(category);
+ categoryItem.Checked = _selectedCategories.Contains(category);
+ categoryItem.Click += (s, ev) =>
+ {
+ if (_selectedCategories.Contains(category))
+ _selectedCategories.Remove(category);
+ else
+ {
+ _selectedCategories.Add(category);
+ _staticsOnlyFilter = false; // Disable statics only when selecting categories
+ }
+ PopulateItemsList();
+ };
+ contextMenu.Items.Add(categoryItem);
+ }
+
+ // Show the menu below the filter button
+ contextMenu.Show(butFilter, new System.Drawing.Point(0, butFilter.Height));
+ }
}
}
From be9569204bc91b7fb7fe7da5f1199ca3c7b09941 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 26 Jan 2026 19:41:41 +0000
Subject: [PATCH 5/5] Address code review feedback - simplify type names
Co-authored-by: TrainWrack <120750885+TrainWrack@users.noreply.github.com>
---
TombEditor/ToolWindows/ItemBrowser.cs | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/TombEditor/ToolWindows/ItemBrowser.cs b/TombEditor/ToolWindows/ItemBrowser.cs
index 858b0fc21..6be251773 100644
--- a/TombEditor/ToolWindows/ItemBrowser.cs
+++ b/TombEditor/ToolWindows/ItemBrowser.cs
@@ -284,7 +284,7 @@ private void butFilter_Click(object sender, EventArgs e)
var contextMenu = new DarkUI.Controls.DarkContextMenu();
// Add "Clear Filter" option
- var clearItem = new System.Windows.Forms.ToolStripMenuItem("Clear Filter");
+ var clearItem = new ToolStripMenuItem("Clear Filter");
clearItem.Checked = _selectedCategories.Count == 0 && !_staticsOnlyFilter;
clearItem.Click += (s, ev) =>
{
@@ -295,7 +295,7 @@ private void butFilter_Click(object sender, EventArgs e)
contextMenu.Items.Add(clearItem);
// Add "Statics Only" option
- var staticsOnlyItem = new System.Windows.Forms.ToolStripMenuItem("Statics Only");
+ var staticsOnlyItem = new ToolStripMenuItem("Statics Only");
staticsOnlyItem.Checked = _staticsOnlyFilter;
staticsOnlyItem.Click += (s, ev) =>
{
@@ -307,12 +307,12 @@ private void butFilter_Click(object sender, EventArgs e)
contextMenu.Items.Add(staticsOnlyItem);
// Add separator
- contextMenu.Items.Add(new System.Windows.Forms.ToolStripSeparator());
+ contextMenu.Items.Add(new ToolStripSeparator());
// Add category items
foreach (var category in allCategories)
{
- var categoryItem = new System.Windows.Forms.ToolStripMenuItem(category);
+ var categoryItem = new ToolStripMenuItem(category);
categoryItem.Checked = _selectedCategories.Contains(category);
categoryItem.Click += (s, ev) =>
{