145 lines
3.5 KiB
C#
145 lines
3.5 KiB
C#
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<string> 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<Identifier, AnimationSpan> animations
|
|
= new();
|
|
public Dictionary<Identifier, EffectDefinition> 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<SkinSelectors, SkinElement> elements
|
|
= new();
|
|
|
|
[PropertyList]
|
|
public PairList<SkinPropertyKey, PdtExpression> 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("<init>");
|
|
#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<Identifier, EffectState> 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<Clip, AnimationSpan> spans
|
|
= new();
|
|
|
|
[PropertyList]
|
|
public PairList<SkinPropertyKey, PdtExpression> 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);
|
|
}
|
|
}
|
|
}
|
|
}
|