using System.Collections; using System.Collections.Generic; using System.Text.RegularExpressions; using System.Text; using Godot; namespace Rokojori { [Tool] [GlobalClass] public partial class Flash:RJSequenceAction { [Export] public FlashEffect flashEffect; [Export] public Node3D[] targets; int animationID = -1; int actionID = -1; Vector3 randomization; List _materials; OmniLight3D light = null; Color ComputeLightColor( Color color, float phase ) { if ( phase < 5/100f ) { var n = MathX.NormalizeClamped( phase, 0, 5/100f ); color *= n; } else if ( phase > 95/100f ) { var n = MathX.NormalizeClamped( phase, 1, 95/100f ); color *= n; } return color; } public override void _OnTrigger() { if ( actionID != -1 ) { CancelAction( actionID ); } actionID = DispatchStart(); // RJLog.Log( "Setting actionID id", actionID, GetLastSequenceActionID() ); var flashCurve = flashEffect.flashCurve; var color = flashEffect.color.GetHDRColor(); var timeline = flashEffect.timeline; randomization = flashCurve.Randomize(); var duration = flashCurve.GetRandomizedDuration( randomization ); var transparentColor = color; var initialAlpha = transparentColor.A; transparentColor.A = 0; Material material = null; if ( FlashEffect.FlashLightMode.No_Light != flashEffect.lightMode ) { light = targets[ 0 ].CreateChild(); light.LightColor = ComputeLightColor( color, 0 ); light.LightEnergy = 0; light.OmniRange = flashEffect.lightRange; light.ShadowEnabled = flashEffect.lightHasShadows; // RJLog.Log( "Created Light", light.Name ); } if ( FlashEffect.MaterialMode.Flat_Standard3D == flashEffect.materialMode ) { var standardMaterial = new StandardMaterial3D(); standardMaterial.AlbedoColor = transparentColor; standardMaterial.ShadingMode = BaseMaterial3D.ShadingModeEnum.Unshaded; standardMaterial.Transparency = BaseMaterial3D.TransparencyEnum.Alpha; material = standardMaterial; } else if ( FlashEffect.MaterialMode.Fresnel_FresnelOverlay == flashEffect.materialMode ) { var fresnelMaterial = new FresnelOverlayMaterial(); fresnelMaterial.albedo.Set( transparentColor ); material = fresnelMaterial; } else if ( FlashEffect.MaterialMode.Scan_ScanGradient == flashEffect.materialMode ) { var scanMaterial = ScanGradientMaterial.White.Get(); scanMaterial.albedo.Set( transparentColor ); material = scanMaterial; } else if ( FlashEffect.MaterialMode.Shield_TriPlanarOverlay == flashEffect.materialMode ) { var shieldMaterial = TriPlanarOverlayMaterial.WhiteShield.Get(); shieldMaterial.albedo.Set( transparentColor ); material = shieldMaterial; } else { material = flashEffect.customMaterial; flashEffect.customFlashColorProperty.Set( material, transparentColor ); } _materials = new List(); Arrays.ForEach( targets, t => { var m = (Material) material.Duplicate( true ); _materials.Add( m ); Materials.AddOverlay( t, m ); } ); var start = TimeLineManager.GetPosition( timeline ); var end = start + duration; animationID = TimeLineScheduler.ScheduleSpanIn( timeline, 0, duration, ( int id, int type )=> { if ( animationID != id ) { return; } var phase = TimeLineManager.GetRangePhase( timeline, start, end ); var value = flashCurve.Sample( phase ); var phaseColor = color; phaseColor.A = value * initialAlpha; if ( light != null ) { light.LightEnergy = value * flashEffect.lightFlashCurveScale; light.LightColor = ComputeLightColor( color, phase ); } _materials.ForEach( ( m )=> { if ( FlashEffect.MaterialMode.Flat_Standard3D == flashEffect.materialMode ) { var sm = m as StandardMaterial3D; sm.AlbedoColor = phaseColor; } else if ( FlashEffect.MaterialMode.Fresnel_FresnelOverlay == flashEffect.materialMode ) { var sm = m as FresnelOverlayMaterial; sm.albedo.Set( phaseColor ); } else if ( FlashEffect.MaterialMode.Scan_ScanGradient == flashEffect.materialMode ) { var sm = m as ScanGradientMaterial; sm.albedo.Set( phaseColor ); sm.offset.Set( phase * 3 ); } else if ( FlashEffect.MaterialMode.Shield_TriPlanarOverlay == flashEffect.materialMode ) { var sm = m as TriPlanarOverlayMaterial; sm.albedo.Set( phaseColor ); } else if ( FlashEffect.MaterialMode.Custom_Material == flashEffect.materialMode ) { var sm = m as ShaderMaterial; flashEffect.customFlashColorProperty.Set( sm, phaseColor ); } } ); if ( type == TimeLineSpan.End ) { if ( light != null ) { light.LightEnergy = 0; light.LightColor = new Color( 0, 0, 0, 0 ); } CancelAction( actionID ); DispatchEnd( actionID ); } } ); // RJLog.Log( "Processing animationID", animationID ); } public override void CancelAction( int id ) { // RJLog.Log( "CancelAction", id ); if ( false && actionID != id ) { // RJLog.Log( "actionID != id", "id", id, "actionID", actionID ); return; } if ( light != null ) { // RJLog.Log( "Removing Light", light.Name ); Nodes.RemoveAndDelete( light ); light = null; } RemoveMaterials(); } void RemoveMaterials() { if ( _materials.Count != targets.Length ) { return; } for ( int i = 0; i < targets.Length; i++ ) { Materials.RemoveOverlay( targets[ i ], _materials[ i ] ); } _materials.Clear(); } } }