using System.Text.Json.Serialization; using Cthangover.Core.Factories; using Cthangover.Core.UI.Theming; using Godot; namespace Cthangover.Core.Interactive { /// /// JSON-driven definition of an interactive scene object loaded from mods. /// The texture is always full-screen (alpha determines visibility outside the collider). /// The collider defines the clickable region in normalised 0..1 viewport coordinates. /// Interactives keep their own resolver and {"Items": [...]} envelope; /// unlike other entity kinds they are not part of the kind-routed pipeline. /// public class InteractiveDefinition : IIdentifiable { /// Unique identifier used in scenario commands and registry lookups. [JsonPropertyName("id")] public string ID { get; set; } /// Owning mod identifier set by ModManager during collection. [JsonIgnore] public string ModId { get; set; } /// Texture key resolved via ModManager.ResolveTexture. Full-screen with alpha. [JsonPropertyName("texture")] public string Texture { get; set; } /// Visual layer: "background", "foreground" or "ui". Defaults to "foreground". [JsonPropertyName("layer")] public string Layer { get; set; } = "foreground"; /// Z-index for ordering within the layer. Higher = on top. [JsonPropertyName("zIndex")] public int ZIndex { get; set; } /// Whether the object is initially enabled (responds to input). Default true. [JsonPropertyName("enabled")] public bool Enabled { get; set; } = true; /// Whether the object is initially visible. Default true. [JsonPropertyName("visible")] public bool Visible { get; set; } = true; /// Mouse cursor override when hovering (Godot CursorShape enum name, e.g. "PointingHand"). [JsonPropertyName("cursor")] public string Cursor { get; set; } /// Collider shape and position in normalised viewport coordinates (0..1). [JsonPropertyName("hitArea")] public HitAreaDefinition HitArea { get; set; } /// Visual highlight settings applied on hover. [JsonPropertyName("highlight")] public HighlightDefinition Highlight { get; set; } /// Actions triggered by pointer events. [JsonPropertyName("actions")] public InteractiveActionDefinition Actions { get; set; } } /// /// Shape and position of the clickable collider in normalised viewport /// coordinates (0..1), where (0,0) is the top-left corner and (1,1) is bottom-right. /// public class HitAreaDefinition { /// "rect", "circle" or "polygon". Defaults to "rect". [JsonPropertyName("type")] public string Type { get; set; } = "rect"; /// X position of the collider origin (top-left for rect, centre for circle). Normalised 0..1. [JsonPropertyName("x")] public float X { get; set; } /// Y position of the collider origin. Normalised 0..1. [JsonPropertyName("y")] public float Y { get; set; } /// Width for rect type. Normalised 0..1. [JsonPropertyName("width")] public float Width { get; set; } = 0.1f; /// Height for rect type. Normalised 0..1. [JsonPropertyName("height")] public float Height { get; set; } = 0.1f; /// Radius for circle type. Normalised 0..1 (relative to viewport min dimension). [JsonPropertyName("radius")] public float Radius { get; set; } = 0.05f; /// Polygon vertices as an array of normalised Vector2 points. Only for "polygon" type. [JsonPropertyName("vertices")] [JsonConverter(typeof(Vector2ArrayJsonConverter))] public Vector2[] Vertices { get; set; } } /// /// Highlight effect applied when the pointer hovers over the collider. /// Uses a shader-based colour modulation on the full-screen texture. /// public class HighlightDefinition { /// Modulate colour as a hex string (e.g. "#FFFF0033"). Parsed to Godot.Color at runtime. [JsonPropertyName("color")] public string ColorHex { get; set; } = "#FFFF0033"; /// Pulse scale multiplier applied during hover (e.g. 1.02 = 2% bigger). [JsonPropertyName("scale")] public float Scale { get; set; } = 1.02f; /// Duration in seconds of the hover/unhover animation. [JsonPropertyName("duration")] public float Duration { get; set; } = 0.15f; /// Parsed Godot.Color from ColorHex. Computed at load time, not serialised. [JsonIgnore] public Color Color => ParseColor(ColorHex); private static Color ParseColor(string hex) { if (string.IsNullOrEmpty(hex)) return UiTokens.Alpha(UiTokens.Accent, 0.3f); try { return new Color(hex); } catch { return UiTokens.Alpha(UiTokens.Accent, 0.3f); } } } /// /// Actions dispatched on pointer events. /// public class InteractiveActionDefinition { /// Action executed on left-click. [JsonPropertyName("onClick")] public ClickAction OnClick { get; set; } /// Inline DSL commands executed on mouse enter. [JsonPropertyName("onHoverEnter")] public string OnHoverEnter { get; set; } /// Inline DSL commands executed on mouse leave. [JsonPropertyName("onHoverLeave")] public string OnHoverLeave { get; set; } } /// /// Click action descriptor. Supports a referenced .scenario file /// and/or inline DSL commands. /// public class ClickAction { /// Path to a .scenario file within a mod. [JsonPropertyName("scenario")] public string Scenario { get; set; } /// Inline DSL commands to execute (one command per array element). [JsonPropertyName("commands")] public string[] Commands { get; set; } } }