using System.Collections.Generic; using Godot; using Newlon.Components; using Newlon.Components.GUI.Seedpackets; using Newlon.Components.Plants; using Newlon.Systems.Effects; public partial class Previewport : SubViewport { private Node current_display; private Texture2D start_Field; [Export] private Label title; [Export] private RichTextLabel description; [Export] private Sprite2D _frameField; public override void _Ready() { GetParent().GetViewport().GuiFocusChanged += OnFocusChanged; start_Field = _frameField.Texture; } public void OnFocusChanged(Control node) { if (GetParent().IsVisibleInTree() == false) return; if (node is Seedpacket packet) { ChangeDisplay(packet.GetResource()); } } private void ChangeDisplay(EntityResource resource) { // Expand with updates if (current_display != null) { current_display.QueueFree(); } if (resource.CustomFrame != null && resource.CustomFrame.almanachField != null) { _frameField.Texture = resource.CustomFrame.almanachField; } else _frameField.Texture = start_Field; current_display = resource.Scene.Instantiate(); title.Text = Tr(resource.NameKey); AddChild(current_display); if (current_display is Entity entity) entity.DisableBrain(); var unparsedDescription = Tr(resource.DescriptionKey); var keys = GetRequestedKeys(unparsedDescription); FillPlaceholders(keys, resource, current_display); var parsedDescription = ReplaceTextUsingDict(keys, unparsedDescription); description.Text = Tr("rwd_" + resource.NameKey) + "\n" + parsedDescription; } private Dictionary GetRequestedKeys(string text) { var result = new Dictionary(); int start = -1; for (int i = 0; i < text.Length; i++) { if (text[i] == '{') { start = i; } if (text[i] == '}') { if (start == -1) continue; result.Add(text.Substr(start + 1, i - start - 1), 0); start = -1; } } return result; } private void FillPlaceholders(Dictionary placeholderDictionary, EntityResource resource, Node searchScene) { var searchList = new List() { resource, searchScene }; while (searchList.Count > 0) { var lookedObject = searchList[0]; searchList.RemoveAt(0); if(lookedObject is Node lookedNode) searchList.AddRange(lookedNode.GetChildren()); if (lookedObject is Shooter shooter) { var projectile = shooter._projectile.Instantiate(); searchList.Add(projectile); } foreach (var property in lookedObject.GetPropertyList()) { if ((Variant.Type)property["type"].AsInt32() == Variant.Type.Object) { if (lookedObject.Get(property["name"].AsString()).AsGodotObject() is Effect effect) { searchList.Add(effect); } } } foreach (var key in placeholderDictionary.Keys) { var namePropertyPair = key.Split('.'); Variant property; if (namePropertyPair.Length == 2) { if ((namePropertyPair[0] == "?" && lookedObject != searchScene)||(namePropertyPair[0] != "?" && lookedObject is Node node && node.Name != namePropertyPair[0])) { continue; } property = lookedObject.Get(namePropertyPair[1]); } else { property = lookedObject.Get(namePropertyPair[0]); } if (property.VariantType == Variant.Type.Nil) { continue; } placeholderDictionary[key] = property.As(); } } } private string ReplaceTextUsingDict(Dictionary dictionary, string text) { var resStr = text; foreach (var key in dictionary.Keys) { resStr = resStr.Replace('{' + key + '}', dictionary[key].ToString()); } return resStr; } }