Indicate nodes not supported by current event#1156
Conversation
Nickelony
left a comment
There was a problem hiding this comment.
Looks good! I'll poke Copilot as well to review just in case.
There was a problem hiding this comment.
Pull request overview
Adds metadata-driven support/unsupported event type tagging for visual scripting nodes, and surfaces a UI warning when a node is used under an incompatible event type.
Changes:
- Parse new
!Supported/!Unsupportedmetadata tags intoNodeFunctiondefinitions. - Add support checks (
IsUnsupported) toNodeFunctionand propagate current event type into the node editor UI. - Document the new metadata tags in the TEN node catalog Readme.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| TombLib/TombLib/Utils/ScriptingUtils.cs | Parses !Supported / !Unsupported tags into event type lists. |
| TombLib/TombLib/LevelData/VisualScripting/TriggerNodeEnumerations.cs | Stores per-node supported/unsupported event lists and exposes IsUnsupported. |
| TombLib/TombLib/Catalogs/TEN Node Catalogs/Readme.md | Documents the new metadata tag syntax and available event types. |
| TombLib/TombLib.Forms/Controls/VisualScripting/NodeEditor.cs | Displays a warning indicator/message when a node is incompatible with the current event type. |
| TombEditor/Forms/FormEventSetEditor.cs | Propagates event type changes into TriggerManager. |
| TombEditor/Controls/TriggerManager.cs | Exposes EventType and forwards it to the embedded node editor. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| var matrix = new System.Drawing.Imaging.ColorMatrix { Matrix33 = LabelOpacity, Matrix22 = 0.0f }; | ||
| var attributes = new System.Drawing.Imaging.ImageAttributes(); | ||
| attributes.SetColorMatrix(matrix, System.Drawing.Imaging.ColorMatrixFlag.Default, System.Drawing.Imaging.ColorAdjustType.Bitmap); | ||
|
|
||
| var icon = Properties.Resources.general_Warning_16; | ||
| var iconRect = new Rectangle(rect.X, rect.Y + (rect.Height - icon.Height), icon.Width, icon.Height); | ||
| e.Graphics.DrawImage(icon, iconRect, 0, 0, icon.Width, icon.Height, GraphicsUnit.Pixel, attributes); | ||
| iconOffset = icon.Width + 2; |
There was a problem hiding this comment.
ImageAttributes is created in the paint path but never disposed, which can leak GDI resources over time (especially during frequent repaints). Also, setting Matrix22 = 0.0f zeroes the blue channel; if the intent is only to apply opacity, keep the RGB diagonal at 1.0 and only change Matrix33. Fix by disposing ImageAttributes (e.g., via a using) and correcting the color matrix so it doesn’t unintentionally alter colors.
| var matrix = new System.Drawing.Imaging.ColorMatrix { Matrix33 = LabelOpacity, Matrix22 = 0.0f }; | |
| var attributes = new System.Drawing.Imaging.ImageAttributes(); | |
| attributes.SetColorMatrix(matrix, System.Drawing.Imaging.ColorMatrixFlag.Default, System.Drawing.Imaging.ColorAdjustType.Bitmap); | |
| var icon = Properties.Resources.general_Warning_16; | |
| var iconRect = new Rectangle(rect.X, rect.Y + (rect.Height - icon.Height), icon.Width, icon.Height); | |
| e.Graphics.DrawImage(icon, iconRect, 0, 0, icon.Width, icon.Height, GraphicsUnit.Pixel, attributes); | |
| iconOffset = icon.Width + 2; | |
| var matrix = new System.Drawing.Imaging.ColorMatrix | |
| { | |
| Matrix00 = 1.0f, | |
| Matrix11 = 1.0f, | |
| Matrix22 = 1.0f, | |
| Matrix33 = LabelOpacity, | |
| Matrix44 = 1.0f | |
| }; | |
| using (var attributes = new System.Drawing.Imaging.ImageAttributes()) | |
| { | |
| attributes.SetColorMatrix(matrix, System.Drawing.Imaging.ColorMatrixFlag.Default, System.Drawing.Imaging.ColorAdjustType.Bitmap); | |
| var icon = Properties.Resources.general_Warning_16; | |
| var iconRect = new Rectangle(rect.X, rect.Y + (rect.Height - icon.Height), icon.Width, icon.Height); | |
| e.Graphics.DrawImage(icon, iconRect, 0, 0, icon.Width, icon.Height, GraphicsUnit.Pixel, attributes); | |
| iconOffset = icon.Width + 2; | |
| } |
| var values = TextExtensions.ExtractValues(comment.Substring(tagId.Length, comment.Length - tagId.Length)); | ||
| foreach (var v in values) | ||
| { | ||
| if (Enum.TryParse(v.Trim(), out EventType eventType)) |
There was a problem hiding this comment.
Enum.TryParse here is case-sensitive, while the metadata tag match uses case-insensitive comparison. This can cause valid values (e.g., different casing in scripts) to be silently ignored. Use the Enum.TryParse(string, bool ignoreCase, out TEnum) overload with ignoreCase: true, and consider avoiding duplicates when adding to targetList to prevent repeated entries if multiple tags are present.
| if (Enum.TryParse(v.Trim(), out EventType eventType)) | |
| if (Enum.TryParse(v.Trim(), true, out EventType eventType) && !targetList.Contains(eventType)) |
| - **!Supported "TYPE" "TYPE" "..." - defines supported event types for a given node. Each event type should be | ||
| enclosed in quotes. If event is not supported by a node, it will display a warning message when misplaced. | ||
| Possible event types are: **OnVolumeEnter, OnVolumeInside, OnVolumeLeave, OnLoop, OnLoadGame, OnSaveGame, | ||
| OnLevelStart, OnLevelEnd, OnUseItem, OnFreeze**. | ||
|
|
||
| - **!Unsupported "TYPE" "TYPE" "..." - defines unsupported event types for a given node. Acts in an opposite way |
There was a problem hiding this comment.
The markdown bold markup is unbalanced for the !Supported / !Unsupported entries (missing closing ** after the tag pattern), which will render the rest of the section incorrectly. Close the bold around just the tag syntax (e.g., **!Supported "TYPE" ...**) and consider the small grammar fix “If an event is not supported…” for clarity.
| - **!Supported "TYPE" "TYPE" "..." - defines supported event types for a given node. Each event type should be | |
| enclosed in quotes. If event is not supported by a node, it will display a warning message when misplaced. | |
| Possible event types are: **OnVolumeEnter, OnVolumeInside, OnVolumeLeave, OnLoop, OnLoadGame, OnSaveGame, | |
| OnLevelStart, OnLevelEnd, OnUseItem, OnFreeze**. | |
| - **!Unsupported "TYPE" "TYPE" "..." - defines unsupported event types for a given node. Acts in an opposite way | |
| - **!Supported "TYPE" "TYPE" "..."** - defines supported event types for a given node. Each event type should be | |
| enclosed in quotes. If an event is not supported by a node, it will display a warning message when misplaced. | |
| Possible event types are: **OnVolumeEnter, OnVolumeInside, OnVolumeLeave, OnLoop, OnLoadGame, OnSaveGame, | |
| OnLevelStart, OnLevelEnd, OnUseItem, OnFreeze**. | |
| - **!Unsupported "TYPE" "TYPE" "..."** - defines unsupported event types for a given node. Acts in an opposite way |
|
|
||
| private static void ParseEventTypeList(string comment, string tagId, List<EventType> targetList) | ||
| { | ||
| var values = TextExtensions.ExtractValues(comment.Substring(tagId.Length, comment.Length - tagId.Length)); |
There was a problem hiding this comment.
comment.Substring(tagId.Length, comment.Length - tagId.Length) is equivalent to comment.Substring(tagId.Length) and is harder to read than necessary. Simplifying this reduces cognitive overhead and removes an easy place for accidental off-by-one edits later.
| var values = TextExtensions.ExtractValues(comment.Substring(tagId.Length, comment.Length - tagId.Length)); | |
| var values = TextExtensions.ExtractValues(comment.Substring(tagId.Length)); |
Adds an indication that a node is not supported by the current event type:
To define whether node is supported or not supported by a particular event type, define new metadata entries:
-- !Unsupported "OnLoop" "OnLevelStart"-- !Supported "OnVolumeEnter"