using Cryville.Common; using Cryville.Common.Collections.Generic; using Cryville.Common.Pdt; using Cryville.Crtr.Extension; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; using System.Text; namespace Cryville.Crtr.Skin { public class SkinDefinition : MetaInfo { public const long CURRENT_FORMAT = 2; [JsonRequired] public long format; public string @base; [JsonRequired] public string ruleset; public List frames = new(); [JsonIgnore] public PdtSkin Root { get; private set; } public void LoadPdt(DirectoryInfo dir) { using StreamReader pdtreader = new(Path.Combine(dir.FullName, data + ".pdt"), Encoding.UTF8); var src = pdtreader.ReadToEnd(); var interpreter = new SkinInterpreter(src, null); var format = interpreter.GetFormatVersion(); if (format.Length == 1) { Root = new PdtSkin { elements = (SkinElement)new SkinInterpreter(src, new PdtBinder()).Interpret(typeof(SkinElement)) }; } else { Root = format[1] switch { 1 => (PdtSkin)new SkinInterpreter(src, new PdtBinder()).Interpret(typeof(PdtSkin)), _ => throw new NotSupportedException("Unsupported skin format"), }; } } } public class PdtSkin { public Dictionary animations = new(); public Dictionary effects = new(); public SkinElement elements; public void Optimize(PdtEvaluator etor) { foreach (var a in animations) { a.Value.Optimize(etor); } foreach (var e in effects) { var effect = e.Value; etor.ContextCascadeInsert(); etor.ContextCascadeUpdate(EffectInstance._VAR_EFFECT_INDEX, PropSrc.Error); foreach(var s in effect.states) { etor.Optimize(s.Value.duration); } effect.elements.Optimize(etor); etor.ContextCascadeDiscard(); } elements.Optimize(etor); } } public class SkinElement { [ElementList] public PairList elements = new(); [PropertyList] public PairList properties = new(); public bool IsDynamic { get; private set; } public void Optimize(PdtEvaluatorBase etor) { IsDynamic = true; foreach (var e in properties) { etor.Optimize(e.Value); if (!e.Value.IsConstant) IsDynamic = true; } foreach (var e in elements) { e.Key.Optimize(etor); e.Value.Optimize(etor); if (e.Value.IsDynamic) IsDynamic = true; } } } public class EffectDefinition { static readonly Identifier _ident_init = new(""); #pragma warning disable IDE1006 public PdtExpression duration { set { if (!states.TryGetValue(_ident_init, out EffectState s)) throw new InvalidOperationException("Cannot set duration and states at the same time"); s.duration = value; } } #pragma warning restore IDE1006 public Identifier init = _ident_init; public Dictionary states = new() { { _ident_init, new EffectState() { rewind = _ident_init } } }; public SkinElement elements; } public class EffectState { public PdtExpression duration; public Identifier rewind; public Identifier next; } public class AnimationSpan { [ElementList] public PairList spans = new(); [PropertyList] public PairList properties = new(); public void Optimize(PdtEvaluator etor) { foreach (var p in properties) { etor.Optimize(p.Value); } foreach (var e in spans) { e.Value.Optimize(etor); } } } }