json handling

This commit is contained in:
grimsace
2026-07-01 15:03:12 -05:00
parent 6520e215ba
commit 6c306a4a0f
3 changed files with 199 additions and 4 deletions
+116 -3
View File
@@ -9,6 +9,9 @@ using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using finder2e_foundry_converter.Models;
using finder2e_foundry_converter.Services;
using System.Text.Json.Nodes;
using System.Text.Json;
using finder2e_foundry_converter.Converters;
namespace finder2e_foundry_converter.ViewModels
{
@@ -132,18 +135,128 @@ namespace finder2e_foundry_converter.ViewModels
}
}
[ObservableProperty]
private string _generatedNpcJson = string.Empty;
[ObservableProperty]
private string _temporaryNpcPath = string.Empty;
[RelayCommand]
private async Task Generate()
{
// Minimal validation
if (string.IsNullOrEmpty(SelectedModel))
{
StatusMessage = "Please select a model first.";
return;
}
StatusMessage = "Generating...";
var result = await CurrentService.GenerateResponseAsync(CurrentAddress, SelectedModel, Description, ImageItems.Select(i => i.Path).ToList());
StatusMessage = result;
StatusMessage = "Generating NPC from template...";
try
{
// Load template JSON
var cwd = Directory.GetCurrentDirectory();
var templatePath = Path.Combine(cwd, "foundry_templates", "npc_template.json");
if (!File.Exists(templatePath))
{
StatusMessage = $"Template not found at {templatePath}";
return;
}
var templateText = await File.ReadAllTextAsync(templatePath);
var node = JsonNode.Parse(templateText)!.AsObject();
// Fill basic fields
node["name"] = string.IsNullOrWhiteSpace(Name) ? "NPC" : Name;
node["img"] = node["img"] ?? "systems/pf2e/icons/default-icons/npc.svg";
// system defaults
var systemNode = node["system"] as JsonObject ?? new JsonObject();
node["system"] = systemNode;
// Set description/blurb and level
if (!systemNode.TryGetPropertyValue("details", out var detailsNode) || detailsNode is null)
{
detailsNode = new JsonObject();
systemNode["details"] = detailsNode;
}
var details = detailsNode.AsObject();
details["blurb"] = Description ?? string.Empty;
if (!details.TryGetPropertyValue("level", out var levelNode) || levelNode is null)
{
details["level"] = new JsonObject();
}
details["level"].AsObject()["value"] = SelectedLevel;
// Default to pf2e for now
string gameSystem = "pf2e";
// Compute numeric stats using NpcConverter helper functions with conservative tiers
var abilityTier = "moderate";
var perceptionTier = "moderate";
var acTier = "moderate";
var savingTier = "moderate";
var hpTier = "moderate";
var abilities = new JsonObject();
string[] abilityNames = new[] { "str", "dex", "con", "int", "wis", "cha" };
foreach (var ab in abilityNames)
{
var modRes = NpcConverter.AbilityScoreModifier(SelectedLevel, abilityTier, gameSystem);
abilities[ab] = new JsonObject { ["mod"] = modRes.IsSuccess ? modRes.Value : 0 };
}
systemNode["abilities"] = abilities;
// Perception
var percRes = NpcConverter.PerceptionModifier(SelectedLevel, perceptionTier, gameSystem);
systemNode["perception"] = new JsonObject { ["mod"] = percRes.IsSuccess ? percRes.Value : 0, ["details"] = string.Empty };
// Saves
var fort = NpcConverter.SavingThrow(SelectedLevel, savingTier, gameSystem);
var reflex = NpcConverter.SavingThrow(SelectedLevel, savingTier, gameSystem);
var will = NpcConverter.SavingThrow(SelectedLevel, savingTier, gameSystem);
systemNode["saves"] = new JsonObject
{
["fortitude"] = new JsonObject { ["value"] = fort.IsSuccess ? fort.Value : 0, ["saveDetail"] = string.Empty },
["reflex"] = new JsonObject { ["value"] = reflex.IsSuccess ? reflex.Value : 0, ["saveDetail"] = string.Empty },
["will"] = new JsonObject { ["value"] = will.IsSuccess ? will.Value : 0, ["saveDetail"] = string.Empty }
};
// AC
var acRes = NpcConverter.Ac(SelectedLevel, acTier, gameSystem);
if (!systemNode.TryGetPropertyValue("attributes", out var attributesNode) || attributesNode is null)
{
attributesNode = new JsonObject();
systemNode["attributes"] = attributesNode;
}
var attributes = attributesNode.AsObject();
attributes["ac"] = new JsonObject { ["value"] = acRes.IsSuccess ? acRes.Value : 10, ["details"] = string.Empty };
// HP
var hpRes = NpcConverter.Hp(SelectedLevel, hpTier, gameSystem);
attributes["hp"] = new JsonObject { ["value"] = hpRes.IsSuccess ? hpRes.Value : 10, ["temp"] = 0, ["max"] = hpRes.IsSuccess ? hpRes.Value : 10, ["details"] = string.Empty };
// Skills (leave empty for now)
systemNode["skills"] = new JsonObject();
// Finalize JSON text
GeneratedNpcJson = node.ToJsonString(new JsonSerializerOptions { WriteIndented = true });
// Save to a temporary file while generating
var tempDir = Path.Combine(Path.GetTempPath(), "Finder2eFoundryConverter");
if (!Directory.Exists(tempDir)) Directory.CreateDirectory(tempDir);
var safeName = string.IsNullOrWhiteSpace(Name) ? "npc" : string.Concat(Name.Select(ch => Path.GetInvalidFileNameChars().Contains(ch) ? '_' : ch));
var tempPath = Path.Combine(tempDir, $"{safeName}_{DateTime.Now:yyyyMMddHHmmss}.json");
await File.WriteAllTextAsync(tempPath, GeneratedNpcJson);
TemporaryNpcPath = tempPath;
StatusMessage = $"NPC generated and saved to temporary path: {tempPath}";
}
catch (Exception ex)
{
StatusMessage = $"Error generating NPC: {ex.Message}";
}
}
[RelayCommand]