2025-01-03 12:09:23 +00:00
|
|
|
using System.Collections;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Text.RegularExpressions;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using Godot;
|
2025-10-24 11:38:51 +00:00
|
|
|
using System.Linq;
|
2025-01-03 12:09:23 +00:00
|
|
|
|
|
|
|
|
namespace Rokojori
|
|
|
|
|
{
|
|
|
|
|
[Tool]
|
2025-11-26 14:23:59 +00:00
|
|
|
[GlobalClass, Icon("res://addons/rokojori_action_library/Icons/Flash.svg")]
|
2025-01-08 18:46:17 +00:00
|
|
|
public partial class Flash:SequenceAction
|
2025-01-03 12:09:23 +00:00
|
|
|
{
|
|
|
|
|
[Export]
|
|
|
|
|
public FlashEffect flashEffect;
|
|
|
|
|
|
2026-02-12 09:48:23 +00:00
|
|
|
// Node3D[] _targets = [];
|
2025-05-27 20:07:15 +00:00
|
|
|
|
|
|
|
|
[Export]
|
2026-02-12 09:48:23 +00:00
|
|
|
public Node3D[] targets;
|
|
|
|
|
// {
|
|
|
|
|
// get => _targets;
|
|
|
|
|
// set
|
|
|
|
|
// {
|
|
|
|
|
// _targets = value;
|
|
|
|
|
// _allTargets = null;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
2025-05-27 20:07:15 +00:00
|
|
|
|
2025-01-03 12:09:23 +00:00
|
|
|
[Export]
|
2025-05-27 20:07:15 +00:00
|
|
|
public bool includeChildren = false;
|
|
|
|
|
|
|
|
|
|
bool refresh = false;
|
|
|
|
|
|
2026-02-12 09:48:23 +00:00
|
|
|
// Node3D[] _allTargets;
|
|
|
|
|
// public Node3D[] allTargets
|
|
|
|
|
// {
|
|
|
|
|
// get
|
|
|
|
|
// {
|
|
|
|
|
// if ( _allTargets != null )
|
|
|
|
|
// {
|
|
|
|
|
// return _allTargets;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// if ( includeChildren )
|
|
|
|
|
// {
|
|
|
|
|
// _allTargets = Nodes.GetAnyChildren( _targets ).ToArray();
|
|
|
|
|
// }
|
|
|
|
|
// else
|
|
|
|
|
// {
|
|
|
|
|
// _allTargets = _targets;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// _allTargets = Lists.Filter( Lists.From( allTargets ), t => t as GeometryInstance3D != null ).ToArray();
|
|
|
|
|
|
|
|
|
|
// return _allTargets;
|
|
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
// }
|
2025-05-27 20:07:15 +00:00
|
|
|
|
|
|
|
|
|
2026-02-12 09:48:23 +00:00
|
|
|
// int animationID = -1;
|
|
|
|
|
// int actionID = -1;
|
2025-01-03 12:09:23 +00:00
|
|
|
|
2026-02-12 09:48:23 +00:00
|
|
|
// Vector3 randomization;
|
|
|
|
|
// List<Material> _materials;
|
2025-01-03 12:09:23 +00:00
|
|
|
|
2026-02-12 09:48:23 +00:00
|
|
|
// OmniLight3D light = null;
|
2025-01-03 12:09:23 +00:00
|
|
|
|
2025-10-24 11:38:51 +00:00
|
|
|
// [Export]
|
|
|
|
|
// public Node3D debugProcessIndicator;
|
|
|
|
|
|
|
|
|
|
// [Export]
|
|
|
|
|
// public Vector3 debugProcessIndicatorFull = new Vector3( 5, 0, 0 );
|
|
|
|
|
|
|
|
|
|
// [Export]
|
|
|
|
|
// public StandardMaterial3D debugMaterial;
|
|
|
|
|
|
2025-06-19 17:22:25 +00:00
|
|
|
public override string[] _GetConfigurationWarnings()
|
|
|
|
|
{
|
|
|
|
|
var warnigns = new List<string>();
|
|
|
|
|
|
|
|
|
|
if ( flashEffect == null )
|
|
|
|
|
{
|
|
|
|
|
warnigns.Add( HierarchyName.Of( this ) + ":" + "No flash effect assigned");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for ( int i = 0; i < targets.Length; i++ )
|
|
|
|
|
{
|
|
|
|
|
if ( targets[ i ] == null )
|
|
|
|
|
{
|
|
|
|
|
warnigns.Add( HierarchyName.Of( this ) + ":" +"A null target is assigned in the targets array at index " + i );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return warnigns.ToArray();
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-03 12:09:23 +00:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-12 09:48:23 +00:00
|
|
|
List<Node3D> GetAllTargets()
|
|
|
|
|
{
|
|
|
|
|
var allTargets = new List<Node3D>();
|
|
|
|
|
|
|
|
|
|
if ( includeChildren )
|
|
|
|
|
{
|
|
|
|
|
allTargets = Nodes.GetAnyChildren( targets );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
allTargets.AddRange( targets );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
allTargets = Lists.Filter( Lists.From( allTargets ), t => t as GeometryInstance3D != null );
|
|
|
|
|
|
|
|
|
|
return allTargets;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int actionID = -1;
|
|
|
|
|
|
2025-01-08 18:46:17 +00:00
|
|
|
protected override void _OnTrigger()
|
2025-01-03 12:09:23 +00:00
|
|
|
{
|
|
|
|
|
if ( actionID != -1 )
|
|
|
|
|
{
|
|
|
|
|
CancelAction( actionID );
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-08 18:46:17 +00:00
|
|
|
|
2025-01-03 12:09:23 +00:00
|
|
|
actionID = DispatchStart();
|
|
|
|
|
|
2026-02-12 09:48:23 +00:00
|
|
|
var currentTargets = GetAllTargets();
|
|
|
|
|
|
|
|
|
|
if ( currentTargets.Count == 0 )
|
|
|
|
|
{
|
|
|
|
|
DispatchEnd( actionID );
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var runner = new FlashRunnerData();
|
|
|
|
|
runner.targets = currentTargets;
|
|
|
|
|
|
|
|
|
|
_runnerData[ actionID ] = runner;
|
|
|
|
|
|
|
|
|
|
|
2025-01-18 20:02:20 +00:00
|
|
|
var random = LCG.WithSeed( networkSeed );
|
2025-01-08 18:46:17 +00:00
|
|
|
|
2025-01-18 12:49:14 +00:00
|
|
|
// RJLog.Log( "Setting actionID id", actionID, GetLastSequenceActionID() );
|
2025-01-03 12:09:23 +00:00
|
|
|
|
|
|
|
|
var flashCurve = flashEffect.flashCurve;
|
|
|
|
|
var color = flashEffect.color.GetHDRColor();
|
2026-02-12 09:48:23 +00:00
|
|
|
var timeline = TimeLineManager.Ensure( flashEffect.timeline );
|
2025-01-03 12:09:23 +00:00
|
|
|
|
2026-02-12 09:48:23 +00:00
|
|
|
runner.randomization = flashCurve.Randomize( random );
|
|
|
|
|
var duration = flashCurve.GetRandomizedDuration( runner.randomization );
|
2025-01-03 12:09:23 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
var transparentColor = color;
|
|
|
|
|
var initialAlpha = transparentColor.A;
|
|
|
|
|
|
|
|
|
|
transparentColor.A = 0;
|
|
|
|
|
|
|
|
|
|
Material material = null;
|
|
|
|
|
|
2026-02-12 09:48:23 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.LogInfo( "Applying Targets:", currentTargets );
|
|
|
|
|
|
|
|
|
|
OmniLight3D light;
|
2025-01-03 12:09:23 +00:00
|
|
|
|
|
|
|
|
if ( FlashEffect.FlashLightMode.No_Light != flashEffect.lightMode )
|
|
|
|
|
{
|
2026-02-12 09:48:23 +00:00
|
|
|
runner.light = currentTargets[ 0 ].CreateChild<OmniLight3D>();
|
|
|
|
|
light = runner.light;
|
2025-01-03 12:09:23 +00:00
|
|
|
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 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-02-12 09:48:23 +00:00
|
|
|
runner.materials = new List<Material>();
|
2025-01-03 12:09:23 +00:00
|
|
|
|
2026-02-12 09:48:23 +00:00
|
|
|
currentTargets.ForEach(
|
2025-01-03 12:09:23 +00:00
|
|
|
t =>
|
|
|
|
|
{
|
|
|
|
|
var m = (Material) material.Duplicate( true );
|
|
|
|
|
|
2026-02-12 09:48:23 +00:00
|
|
|
runner.materials.Add( m );
|
2025-01-03 12:09:23 +00:00
|
|
|
|
|
|
|
|
Materials.AddOverlay( t, m );
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
2025-01-19 20:35:51 +00:00
|
|
|
var start = timeline.position;
|
2025-01-03 12:09:23 +00:00
|
|
|
var end = start + duration;
|
|
|
|
|
|
2025-01-18 12:49:14 +00:00
|
|
|
|
2025-10-24 11:38:51 +00:00
|
|
|
|
2026-02-12 09:48:23 +00:00
|
|
|
runner.animationID = TimeLineManager.ScheduleSpanIn( timeline, 0, duration,
|
2025-01-19 20:35:51 +00:00
|
|
|
( TimeLineSpan span, TimeLineSpanUpdateType type )=>
|
2025-10-24 11:38:51 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// debugProcessIndicator.Position = debugProcessIndicatorFull * span.phase;
|
2025-01-03 12:09:23 +00:00
|
|
|
|
2026-02-12 09:48:23 +00:00
|
|
|
if ( runner.animationID != span.id )
|
2025-01-03 12:09:23 +00:00
|
|
|
{
|
|
|
|
|
return;
|
2025-01-18 12:49:14 +00:00
|
|
|
}
|
2025-01-03 12:09:23 +00:00
|
|
|
|
2025-10-24 11:38:51 +00:00
|
|
|
// debugProcessIndicator.Position = debugProcessIndicatorFull * span.phase;
|
|
|
|
|
|
2025-01-19 20:35:51 +00:00
|
|
|
var phase = span.phase;
|
2025-01-03 12:09:23 +00:00
|
|
|
|
|
|
|
|
|
2026-02-12 09:48:23 +00:00
|
|
|
var value = flashCurve.Sample( span.elapsed );
|
|
|
|
|
|
|
|
|
|
|
2025-10-24 11:38:51 +00:00
|
|
|
|
|
|
|
|
|
2025-01-03 12:09:23 +00:00
|
|
|
var phaseColor = color;
|
|
|
|
|
phaseColor.A = value * initialAlpha;
|
|
|
|
|
|
2026-02-12 09:48:23 +00:00
|
|
|
this.LogInfo( phase, value );
|
|
|
|
|
|
2025-10-24 11:38:51 +00:00
|
|
|
// debugMaterial.AlbedoColor = phaseColor;
|
|
|
|
|
|
2026-02-12 09:48:23 +00:00
|
|
|
if ( runner.light != null )
|
2025-01-03 12:09:23 +00:00
|
|
|
{
|
2026-02-12 09:48:23 +00:00
|
|
|
runner.light.LightEnergy = value * flashEffect.lightFlashCurveScale;
|
|
|
|
|
runner.light.LightColor = ComputeLightColor( color, phase );
|
2025-01-03 12:09:23 +00:00
|
|
|
}
|
|
|
|
|
|
2026-02-12 09:48:23 +00:00
|
|
|
runner.materials.ForEach(
|
2025-01-03 12:09:23 +00:00
|
|
|
( 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 );
|
2026-02-12 09:48:23 +00:00
|
|
|
sm.offset.Set( phase );
|
2025-01-03 12:09:23 +00:00
|
|
|
}
|
|
|
|
|
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 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
2025-01-19 20:35:51 +00:00
|
|
|
);
|
2025-01-03 12:09:23 +00:00
|
|
|
|
|
|
|
|
|
2025-01-08 18:46:17 +00:00
|
|
|
if ( type == TimeLineSpanUpdateType.End )
|
2025-01-03 12:09:23 +00:00
|
|
|
{
|
2026-02-12 09:48:23 +00:00
|
|
|
if ( runner.light != null )
|
2025-01-03 12:09:23 +00:00
|
|
|
{
|
2026-02-12 09:48:23 +00:00
|
|
|
runner.light.LightEnergy = 0;
|
|
|
|
|
runner.light.LightColor = new Color( 0, 0, 0, 0 );
|
2025-01-03 12:09:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CancelAction( actionID );
|
|
|
|
|
DispatchEnd( actionID );
|
|
|
|
|
}
|
2025-10-24 11:38:51 +00:00
|
|
|
|
2025-01-03 12:09:23 +00:00
|
|
|
|
2025-10-24 11:38:51 +00:00
|
|
|
},
|
|
|
|
|
this
|
2025-01-19 20:35:51 +00:00
|
|
|
).id;
|
2025-01-03 12:09:23 +00:00
|
|
|
|
|
|
|
|
|
2026-02-12 09:48:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Dictionary<int,FlashRunnerData> _runnerData = new Dictionary<int, FlashRunnerData>();
|
2025-01-03 12:09:23 +00:00
|
|
|
|
|
|
|
|
public override void CancelAction( int id )
|
|
|
|
|
{
|
2026-02-12 09:48:23 +00:00
|
|
|
if ( ! _runnerData.ContainsKey( id ))
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var data = _runnerData[ id ];
|
|
|
|
|
var light = data.light;
|
|
|
|
|
var nodes = data.targets;
|
|
|
|
|
var materials = data.materials;
|
2025-01-03 12:09:23 +00:00
|
|
|
|
|
|
|
|
if ( light != null )
|
|
|
|
|
{
|
|
|
|
|
// RJLog.Log( "Removing Light", light.Name );
|
|
|
|
|
Nodes.RemoveAndDelete( light );
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-12 09:48:23 +00:00
|
|
|
RemoveMaterials( nodes, materials );
|
2025-01-03 12:09:23 +00:00
|
|
|
|
2026-02-12 09:48:23 +00:00
|
|
|
_runnerData.Remove( id );
|
2025-01-03 12:09:23 +00:00
|
|
|
}
|
|
|
|
|
|
2026-02-12 09:48:23 +00:00
|
|
|
void RemoveMaterials( List<Node3D> allTargets, List<Material> materials )
|
2025-01-03 12:09:23 +00:00
|
|
|
{
|
|
|
|
|
|
2026-02-12 09:48:23 +00:00
|
|
|
for ( int i = 0; i < allTargets.Count ; i++ )
|
2025-01-03 12:09:23 +00:00
|
|
|
{
|
2026-02-12 09:48:23 +00:00
|
|
|
Materials.RemoveOverlay( allTargets[ i ], materials[ i ] );
|
2025-01-03 12:09:23 +00:00
|
|
|
}
|
|
|
|
|
|
2026-02-12 09:48:23 +00:00
|
|
|
// _materials.Clear();
|
2025-01-03 12:09:23 +00:00
|
|
|
}
|
|
|
|
|
|
2026-02-12 09:48:23 +00:00
|
|
|
public class FlashRunnerData
|
|
|
|
|
{
|
|
|
|
|
public List<Node3D> targets;
|
|
|
|
|
public List<Material> materials;
|
|
|
|
|
public OmniLight3D light;
|
|
|
|
|
public int animationID;
|
|
|
|
|
public int actionID;
|
|
|
|
|
public Vector3 randomization;
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-01-03 12:09:23 +00:00
|
|
|
}
|