using UnityEditor; using UnityEngine; using AnimatorAsCode.V1; using System.Collections.Generic; using gay.lilyy.aaccore; using gay.lilyy.aacshared.runtimecomponents; using gay.lilyy.Common; namespace gay.lilyy.aacshared.layers { /** ported from v5 */ [InitializeOnLoad] public class LanternFlicker : LayerGroup { private static readonly LanternFlicker _instance = new(); static LanternFlicker() { } public override string DisplayName => "Lantern Flicker"; public override string SystemName => "lantern_flicker"; public override bool shouldWarnIfNotApplicable => false; private Transform GetLantern(AACAssets assets) { return AACUtils.FindChildRecursive(assets.ctx.AvatarRootTransform, "Lantern Floater"); } public override bool IsApplicable(AACAssets assets) { var definition = ComponentHelper.GetComponentInChildrenWithError(assets.ctx.AvatarRootObject); if (definition == null) return false; if (!definition.enabled) return false; var lamp = GetLantern(assets); if (lamp == null) { Logger.LogWarning("Lamp Light could not be found!"); return false; } var light = lamp.GetComponentInChildren(); return light != null; } private void CreateFlickerLayer(AACAssets assets) { var lamp = GetLantern(assets); var light = lamp.GetComponentInChildren(); var layer = assets.fx.NewLayer("Lantern Flicker"); var flickerParam = layer.BoolParameter("LanternFlicker"); var off = layer.NewState("Off").WithAnimation( assets.aac.NewClip().Animating(anim => { if (light != null) { anim.Animates(light, "m_Enabled").WithFrameCountUnit(sec => { sec.Constant(0, 0); }); anim.Animates(light, "m_Intensity").WithFrameCountUnit(sec => { sec.Constant(0, light.intensity); }); } }) ); layer.WithDefaultState(off); var on = layer.NewState("Flicker").WithAnimation( assets.aac.NewClip().Animating(anim => { AnimateLantern(assets, anim, lamp); }).Looping() ); off.TransitionsTo(on).When(flickerParam.IsEqualTo(true)); on.TransitionsTo(off).When(flickerParam.IsEqualTo(false)); } private void CreateBrightnessLayer(AACAssets assets) { var lamp = GetLantern(assets); var light = lamp.GetComponentInChildren(); if (light == null) return; var layer = assets.fx.NewLayer("Lantern Brightness"); var brightnessParam = layer.FloatParameter("LanternBrightness"); var state = layer.NewState("Brightness").WithAnimation( assets.aac.NewClip().Animating(anim => { anim.Animates(light, "m_Enabled").WithUnit(AacFlUnit.Frames, sec => { sec.Linear(0, 0); sec.Linear(1, 1); }); anim.AnimatesColor(light, "m_Color").WithUnit(AacFlUnit.Frames, sec => { sec.Linear(0, light.color * 0); sec.Linear(100, light.color); }); }) ).WithMotionTime(brightnessParam); } private void AnimateLantern(AACAssets assets, AacFlEditClip anim, Transform lantern) { var renderer = lantern.GetComponent(); var light = lantern.GetComponentInChildren(); if (renderer == null) { Logger.LogWarning("AnimateLantern: Missing renderer on lantern"); return; } var rng = new System.Random("lillithlanternrandomseed".GetHashCode()); var keyframes = new List<(float time, double value)>(); float time = 0; while (time < 60) { double value = rng.NextDouble(); keyframes.Add((time, value)); time += (float)(rng.NextDouble() * (0.3 - 0.05) + 0.05); } if (keyframes.Count == 0) { Logger.LogWarning("AnimateLantern: No keyframes generated"); } if (light != null) { anim.Animates(light, "m_Intensity").WithSecondsUnit(sec => { foreach (var (t, v) in keyframes) { sec.Easing(t, (float)v * light.intensity); } }); } if (assets.isPC) { Logger.LogInfo("Using PC material for lantern flicker"); Color initialColor = renderer.sharedMaterial.GetColor("_Emission_Color"); // ValueFactory Orbits var prop = "material._Emission_Color"; void animateChannel(string suffix, float initial) { anim.Animates(renderer, $"{prop}.{suffix}").WithSecondsUnit(sec => { foreach (var (t, v) in keyframes) { sec.Easing(t, initial * (float)v); } }); } animateChannel("x", initialColor.r); animateChannel("y", initialColor.g); animateChannel("z", initialColor.b); animateChannel("w", initialColor.a); } else { // Toon Standard Logger.LogInfo("Using Non-PC material for lantern flicker"); // float initialStrength = renderer.sharedMaterial.GetFloat("_EmissionStrength"); // this still isnt running before vqt for some cursed reason so im just gonna hardcode this var initialStrength = 2; anim.Animates(renderer, "material._EmissionStrength").WithSecondsUnit(sec => { foreach (var (t, v) in keyframes) { sec.Easing(t, initialStrength * (float)v); } }); } } public override void Run(AACAssets assets) { CreateFlickerLayer(assets); CreateBrightnessLayer(assets); } } }