newlon/scripts/gui/choose_your_seeds/Previewport.cs
2025-07-26 03:04:32 +05:00

141 lines
3.6 KiB
C#

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<Control>().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<string, float> GetRequestedKeys(string text)
{
var result = new Dictionary<string, float>();
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<string, float> placeholderDictionary, EntityResource resource, Node searchScene)
{
var searchList = new List<GodotObject>() { 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<float>();
}
}
}
private string ReplaceTextUsingDict(Dictionary<string, float> dictionary, string text)
{
var resStr = text;
foreach (var key in dictionary.Keys)
{
resStr = resStr.Replace('{' + key + '}', dictionary[key].ToString());
}
return resStr;
}
}