209 lines
7.3 KiB
C#
209 lines
7.3 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace SessionZero.Data;
|
|
|
|
[SzfObject("character_template")]
|
|
public class CharacterTemplate : SzfObject
|
|
{
|
|
public string GameSystem { get; set; } = string.Empty;
|
|
public List<RequiredDatasetReference> RequiredDatasets { get; set; } = new();
|
|
public List<TemplateSection> Sections { get; set; } = new();
|
|
|
|
public override void PopulateFromMetadata(Dictionary<string, SzfField> metadata)
|
|
{
|
|
base.PopulateFromMetadata(metadata);
|
|
|
|
if (metadata.TryGetValue("GameSystem", out var gameSystemField))
|
|
GameSystem = gameSystemField.Value?.ToString() ?? string.Empty;
|
|
}
|
|
|
|
public override void ParseSections(List<SzfSection> sections)
|
|
{
|
|
// Parse [Required Datasets] section
|
|
var requiredDatasetsSection =
|
|
sections.FirstOrDefault(s => s.Name.Equals("Required Datasets", StringComparison.OrdinalIgnoreCase));
|
|
if (requiredDatasetsSection != null)
|
|
{
|
|
foreach (var field in requiredDatasetsSection.Fields)
|
|
{
|
|
var reference = DatasetReference.Parse(field.Value?.ToString() ?? string.Empty);
|
|
if (reference != null)
|
|
{
|
|
RequiredDatasets.Add(new RequiredDatasetReference
|
|
{
|
|
Alias = field.Name,
|
|
Reference = reference
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
// Parse [Section: ...] and [Section....] sections
|
|
foreach (var szfSection in sections)
|
|
{
|
|
if (szfSection.Name.StartsWith("Section:", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
var templateSection = new TemplateSection
|
|
{
|
|
Name = szfSection.Name.Replace("Section:", "").Trim()
|
|
};
|
|
|
|
foreach (var field in szfSection.Fields)
|
|
{
|
|
templateSection.Fields.Add(ConvertToTemplateField(field));
|
|
}
|
|
|
|
Sections.Add(templateSection);
|
|
}
|
|
else if (szfSection.Name.StartsWith("Section.", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
// Handle subsections by finding their parent
|
|
var parts = szfSection.Name.Split('.');
|
|
if (parts.Length >= 2)
|
|
{
|
|
var parentSectionName = parts[0] + ":" + parts[1].Trim(); // Reconstruct parent name
|
|
var parentSection = Sections.FirstOrDefault(s =>
|
|
s.Name.Equals(parentSectionName.Replace("Section:", "").Trim(),
|
|
StringComparison.OrdinalIgnoreCase));
|
|
if (parentSection != null)
|
|
{
|
|
var subSection = new TemplateSection
|
|
{
|
|
Name = string.Join(".", parts.Skip(2)).Trim() // Name for the subsection
|
|
};
|
|
|
|
foreach (var field in szfSection.Fields)
|
|
{
|
|
subSection.Fields.Add(ConvertToTemplateField(field));
|
|
}
|
|
|
|
parentSection.Subsections.Add(subSection);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private TemplateField ConvertToTemplateField(SzfField szfField)
|
|
{
|
|
return new TemplateField
|
|
{
|
|
Name = szfField.Name,
|
|
Type = ParseDatasetFieldType(szfField.Type),
|
|
Value = szfField.Value
|
|
};
|
|
}
|
|
|
|
private DatasetFieldType ParseDatasetFieldType(string typeString)
|
|
{
|
|
return typeString.ToLower() switch
|
|
{
|
|
"text" => DatasetFieldType.Text,
|
|
"text-field" => DatasetFieldType.TextField,
|
|
"number" => DatasetFieldType.Number,
|
|
"bool" => DatasetFieldType.Boolean,
|
|
"calculated" => DatasetFieldType.Calculated,
|
|
"system" => DatasetFieldType.System,
|
|
"dataset-reference" => DatasetFieldType.DatasetReference,
|
|
"dataset-type" => DatasetFieldType.DatasetType,
|
|
"dataset-reference-multiple" => DatasetFieldType.DatasetReferenceMultiple,
|
|
"dataset-type-multiple" => DatasetFieldType.DatasetTypeMultiple,
|
|
"group" => DatasetFieldType.Group,
|
|
_ => DatasetFieldType.Text // Default to text if unknown
|
|
};
|
|
}
|
|
|
|
public override void GenerateMetadata(SzfFieldWriter writer)
|
|
{
|
|
// Call base to ensure common metadata is generated first if base had any specific generation logic
|
|
base.GenerateMetadata(writer);
|
|
|
|
writer.WriteField("GameSystem", "text", GameSystem);
|
|
}
|
|
|
|
public override void GenerateContent(SzfFieldWriter writer)
|
|
{
|
|
// Generate [Required Datasets] section
|
|
if (RequiredDatasets.Any() || writer.Options.IncludeEmptySections)
|
|
{
|
|
writer.AppendSectionHeader("Required Datasets");
|
|
foreach (var reqDataset in RequiredDatasets)
|
|
{
|
|
writer.WriteField(reqDataset.Alias, "dataset-reference", reqDataset.Reference?.ToString());
|
|
}
|
|
|
|
writer.AppendLine();
|
|
}
|
|
|
|
// Generate Template Sections
|
|
foreach (var section in Sections)
|
|
{
|
|
GenerateTemplateSection(writer, section, "Section");
|
|
writer.AppendLine();
|
|
}
|
|
}
|
|
|
|
private void GenerateTemplateSection(SzfFieldWriter writer, TemplateSection section, string parentPath)
|
|
{
|
|
var currentPath = $"{parentPath}: {section.Name}";
|
|
writer.AppendSectionHeader(currentPath);
|
|
|
|
foreach (var field in section.Fields)
|
|
{
|
|
writer.WriteField(field.Name, field.Type, field.Value);
|
|
}
|
|
|
|
foreach (var subSection in section.Subsections)
|
|
{
|
|
GenerateTemplateSubSection(writer, subSection, $"Section.{section.Name}");
|
|
}
|
|
}
|
|
|
|
private void GenerateTemplateSubSection(SzfFieldWriter writer, TemplateSection subSection, string parentPath)
|
|
{
|
|
var currentPath = $"{parentPath}.{subSection.Name}";
|
|
writer.AppendSectionHeader(currentPath);
|
|
|
|
foreach (var field in subSection.Fields)
|
|
{
|
|
writer.WriteField(field.Name, field.Type, field.Value);
|
|
}
|
|
|
|
foreach (var nestedSubSection in subSection.Subsections)
|
|
{
|
|
// Handle deeper nesting if needed, recursively calling this method
|
|
GenerateTemplateSubSection(writer, nestedSubSection, currentPath);
|
|
}
|
|
}
|
|
|
|
public override SzfValidationResult Validate()
|
|
{
|
|
var result = base.Validate(); // Run base validation first
|
|
|
|
if (string.IsNullOrWhiteSpace(GameSystem))
|
|
result.AddError("GameSystem is required for CharacterTemplate");
|
|
|
|
return result;
|
|
}
|
|
}
|
|
|
|
public class RequiredDatasetReference
|
|
{
|
|
public string Alias { get; set; } = string.Empty;
|
|
public DatasetReference? Reference { get; set; }
|
|
}
|
|
|
|
public class TemplateSection
|
|
{
|
|
public string Name { get; set; } = string.Empty;
|
|
public List<TemplateField> Fields { get; set; } = new();
|
|
public List<TemplateSection> Subsections { get; set; } = new(); // For nested sections
|
|
}
|
|
|
|
public class TemplateField
|
|
{
|
|
public string Name { get; set; } = string.Empty;
|
|
public DatasetFieldType Type { get; set; }
|
|
public object? Value { get; set; }
|
|
} |