compose descriptionparser

This commit is contained in:
Rendo 2025-07-26 05:35:53 +05:00
commit 032f633597
13 changed files with 182 additions and 169 deletions

View file

@ -10,7 +10,6 @@ region = Rect2(477, 9, 60, 59)
[resource] [resource]
script = ExtResource("3_30qd0") script = ExtResource("3_30qd0")
Tags = []
Layer = 1 Layer = 1
DontRegister = false DontRegister = false
NameKey = "nerdus" NameKey = "nerdus"
@ -21,7 +20,4 @@ ReloadTime = 10.0
ReloadProgress = 0.0 ReloadProgress = 0.0
Preview = SubResource("AtlasTexture_ivp5w") Preview = SubResource("AtlasTexture_ivp5w")
Order = 11 Order = 11
Parameters = Dictionary[String, float]({
"max_hp": 30.0
})
metadata/_custom_type_script = "uid://cyenlko1knygw" metadata/_custom_type_script = "uid://cyenlko1knygw"

View file

@ -18,7 +18,4 @@ ReloadTime = 1.0
ReloadProgress = 0.0 ReloadProgress = 0.0
Preview = SubResource("AtlasTexture_wu2q8") Preview = SubResource("AtlasTexture_wu2q8")
Order = 0 Order = 0
Parameters = Dictionary[String, float]({
"max_hp": 30.0
})
metadata/_custom_type_script = "uid://cqxj7o8hdm82n" metadata/_custom_type_script = "uid://cqxj7o8hdm82n"

View file

@ -18,7 +18,4 @@ ReloadTime = 1.0
ReloadProgress = 0.0 ReloadProgress = 0.0
Preview = SubResource("AtlasTexture_drksh") Preview = SubResource("AtlasTexture_drksh")
Order = 2 Order = 2
Parameters = Dictionary[String, float]({
"max_hp": 30.0
})
metadata/_custom_type_script = "uid://cqxj7o8hdm82n" metadata/_custom_type_script = "uid://cqxj7o8hdm82n"

View file

@ -18,7 +18,4 @@ ReloadTime = 1.0
ReloadProgress = 0.0 ReloadProgress = 0.0
Preview = SubResource("AtlasTexture_q44xp") Preview = SubResource("AtlasTexture_q44xp")
Order = 1 Order = 1
Parameters = Dictionary[String, float]({
"max_hp": 30.0
})
metadata/_custom_type_script = "uid://cqxj7o8hdm82n" metadata/_custom_type_script = "uid://cqxj7o8hdm82n"

View file

@ -18,7 +18,4 @@ ReloadTime = 1.0
ReloadProgress = 0.0 ReloadProgress = 0.0
Preview = SubResource("AtlasTexture_73ahc") Preview = SubResource("AtlasTexture_73ahc")
Order = 5 Order = 5
Parameters = Dictionary[String, float]({
"max_hp": 30.0
})
metadata/_custom_type_script = "uid://cqxj7o8hdm82n" metadata/_custom_type_script = "uid://cqxj7o8hdm82n"

View file

@ -989,7 +989,6 @@ metadata/_edit_lock_ = true
[node name="Right_Eye" type="Sprite2D" parent="CanvasGroup/basic_zombie_walk/Zombie/Butt/Body/Head/HeadParticle/Head"] [node name="Right_Eye" type="Sprite2D" parent="CanvasGroup/basic_zombie_walk/Zombie/Butt/Body/Head/HeadParticle/Head"]
position = Vector2(-16, -8.00001) position = Vector2(-16, -8.00001)
scale = Vector2(1, 1)
texture = SubResource("AtlasTexture_vcc72") texture = SubResource("AtlasTexture_vcc72")
centered = false centered = false
offset = Vector2(-2, -2) offset = Vector2(-2, -2)
@ -997,7 +996,6 @@ metadata/_edit_lock_ = true
[node name="Left_Eye" type="Sprite2D" parent="CanvasGroup/basic_zombie_walk/Zombie/Butt/Body/Head/HeadParticle/Head"] [node name="Left_Eye" type="Sprite2D" parent="CanvasGroup/basic_zombie_walk/Zombie/Butt/Body/Head/HeadParticle/Head"]
position = Vector2(-4, -9) position = Vector2(-4, -9)
scale = Vector2(1, 1)
texture = SubResource("AtlasTexture_kto0i") texture = SubResource("AtlasTexture_kto0i")
centered = false centered = false
offset = Vector2(-2, -2) offset = Vector2(-2, -2)

View file

@ -54,6 +54,7 @@ material = SubResource("ShaderMaterial_yfuxj")
texture = ExtResource("2_ffrjr") texture = ExtResource("2_ffrjr")
hframes = 10 hframes = 10
vframes = 2 vframes = 2
frame = 1
[node name="AnimationPlayer" parent="." index="1"] [node name="AnimationPlayer" parent="." index="1"]
libraries = { libraries = {

View file

@ -1,9 +1,8 @@
using System.Collections.Generic;
using Godot; using Godot;
using Newlon;
using Newlon.Components; using Newlon.Components;
using Newlon.Components.GUI.Seedpackets; using Newlon.Components.GUI.Seedpackets;
using Newlon.Components.Plants;
using Newlon.Systems.Effects;
public partial class Previewport : SubViewport public partial class Previewport : SubViewport
{ {
@ -48,21 +47,7 @@ public partial class Previewport : SubViewport
if (current_display is Entity entity) if (current_display is Entity entity)
entity.DisableBrain(); entity.DisableBrain();
string descriptionText;
if (resource.isDescriptionParsed == false)
{
var unparsedDescription = Tr(resource.DescriptionKey);
var keys = GetRequestedKeys(unparsedDescription);
FillPlaceholders(keys, resource, current_display);
descriptionText = ReplaceTextUsingDict(keys, unparsedDescription);
resource.parsedDescription = descriptionText;
resource.isDescriptionParsed = true;
}
else
{
descriptionText = resource.parsedDescription;
}
var rwd = Tr("rwd_" + resource.NameKey); var rwd = Tr("rwd_" + resource.NameKey);
if (rwd == "rwd_" + resource.NameKey) if (rwd == "rwd_" + resource.NameKey)
{ {
@ -73,138 +58,9 @@ public partial class Previewport : SubViewport
rwd += "\n"; rwd += "\n";
} }
description.Text = rwd + descriptionText; description.Text = rwd + DescriptionParser.GetParsed(resource,current_display);
} }
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)
{
string request = key.Split('|')[0];
var namePropertyPair = request.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;
}
float value = property.As<float>();
placeholderDictionary[key] = value;
}
}
// Apply any modifiers
foreach (var key in placeholderDictionary.Keys)
{
if (key.Split('|').Length < 2) continue;
string[] modifiers = key.Split('|')[1..];
float value = placeholderDictionary[key];
foreach (var mod in modifiers)
{
if (mod != "")
{
switch (mod[0])
{
case '%':
value *= 100;
break;
case '*':
if (placeholderDictionary.ContainsKey(mod[1..]))
{
value *= placeholderDictionary[mod[1..]];
}
else if (float.TryParse(mod[1..], out float result))
{
value *= result;
}
break;
case '/':
if (placeholderDictionary.ContainsKey(mod[1..]))
{
value /= placeholderDictionary[mod[1..]];
}
else if (float.TryParse(mod[1..], out float result))
{
value /= result;
}
break;
}
}
}
placeholderDictionary[key] = value;
}
}
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;
}
} }

View file

@ -0,0 +1,173 @@
using System.Collections.Generic;
using Newlon.Components.Plants;
using Newlon.Systems.Effects;
using Godot;
using Newlon.Resources;
namespace Newlon;
public static class DescriptionParser
{
public static string GetParsed(EntityResource resource, Node searchScene)
{
string descriptionText;
if (resource.isDescriptionParsed == false)
{
var unparsedDescription = TranslationServer.Translate(resource.DescriptionKey);
var keys = GetRequestedKeys(unparsedDescription);
FillPlaceholders(keys, resource, searchScene);
descriptionText = ReplaceTextUsingDict(keys, unparsedDescription);
resource.parsedDescription = descriptionText;
resource.isDescriptionParsed = true;
}
else
{
descriptionText = resource.parsedDescription;
}
return descriptionText;
}
private static 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 static 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)
{
string request = key.Split('|')[0];
var namePropertyPair = request.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;
}
float value = property.As<float>();
value = float.Round(value, 3);
placeholderDictionary[key] = value;
}
}
// Apply any modifiers
foreach (var key in placeholderDictionary.Keys)
{
if (key.Split('|').Length < 2) continue;
string[] modifiers = key.Split('|')[1..];
float value = placeholderDictionary[key];
for (int i = 0; i < modifiers.Length; i++)
{
if (modifiers[i] != "")
{
switch (modifiers[i][0])
{
case '%':
value *= 100;
break;
case '*':
if (placeholderDictionary.ContainsKey(modifiers[i][1..]))
{
value *= placeholderDictionary[modifiers[i][1..]];
}
else if (float.TryParse(modifiers[i][1..], out float mult))
{
value *= mult;
}
break;
case '/':
if (placeholderDictionary.ContainsKey(modifiers[i][1..]))
{
value /= placeholderDictionary[modifiers[i][1..]];
}
else if (float.TryParse(modifiers[i][1..], out float div))
{
value /= div;
}
break;
case '+':
if (float.TryParse(modifiers[i][1..], out float add))
{
value += add;
}
break;
case '-':
if(float.TryParse(modifiers[i][1..], out float sub))
{
value -= sub;
}
break;
}
}
}
placeholderDictionary[key] = value;
}
}
private static 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;
}
}

View file

@ -0,0 +1 @@
uid://bmb41nht2es3h

View file

@ -32,11 +32,11 @@ snowpea_desc,"Health points: [color=DARK_RED]{MaxHP}[/color].
Reload time: [color=DARK_RED]{ReloadTime} seconds[/color]. Reload time: [color=DARK_RED]{ReloadTime} seconds[/color].
Pea damage: [color=DARK_RED]{_damage}[/color]. Pea damage: [color=DARK_RED]{_damage}[/color].
Firerate: [color=DARK_RED]{FireTimer.wait_time} seconds[/color]. Firerate: [color=DARK_RED]{FireTimer.wait_time} seconds[/color].
Slow percentage: [color=STEEL_BLUE]{Multiplier|%}%[/color].","Очки здоровья: [color=DARK_RED]{MaxHP}[/color]. Slow percentage: [color=STEEL_BLUE]{Multiplier|*-1|+1|%}%[/color].","Очки здоровья: [color=DARK_RED]{MaxHP}[/color].
Время перезарядки: [color=DARK_RED]{ReloadTime} секунд[/color]. Время перезарядки: [color=DARK_RED]{ReloadTime} секунд[/color].
Урон от гороха: [color=DARK_RED]{_damage}[/color]. Урон от гороха: [color=DARK_RED]{_damage}[/color].
Задержка стрельбы: [color=DARK_RED]{FireTimer.wait_time} секунды[/color]. Задержка стрельбы: [color=DARK_RED]{FireTimer.wait_time} секунды[/color].
Процент замедления: [color=STEEL_BLUE]{Multiplier|%}%[/color]." Процент замедления: [color=STEEL_BLUE]{Multiplier|*-1|+1|%}%[/color]."
spikeweed,Spikeweed,Колючка spikeweed,Spikeweed,Колючка
spikeweed_desc,"Health points: [color=DARK_RED]{MaxHP}[/color]. spikeweed_desc,"Health points: [color=DARK_RED]{MaxHP}[/color].
Reload time: [color=DARK_RED]{ReloadTime} seconds[/color]. Reload time: [color=DARK_RED]{ReloadTime} seconds[/color].

1 keys en ru
32
33
34
35
36
37
38
39
40
41
42

Binary file not shown.

Binary file not shown.