FlashLightVisualizer refactor + low power handheld light light radius fix (#11768)

* refactor: Removes FlashLightVisualizer (based on obsolete code) in favor or merging its functionality with HandheldLightComponent
fix: Low power lighting radius animations for lanterns, floodlights and flashlights now properly restore the original light radius when going back to full power

* refactor: Use the LightBehaviour component to animate HandheldLights
refactor: Remove unneeded HandheldLight definitions in some yaml files (already inherited by parents)
fix: Properly change the server side PointLightComponent Enabled property when turning HandheldLights on/off
feat: ReverseWhenFinished property on Fade light behaviours

* Empty commit to rerun CI with the new engine PR

* fix: Restore the correct HandheldLight addPrefix property, whoops

* refactor: blinkingBehaviourID -> blinkingBehaviourId, radiatingBehaviourID -> radiatingBehaviourId
This commit is contained in:
Francesco
2022-10-19 20:34:36 +02:00
committed by GitHub
parent af33db3cc3
commit 9727cc0da0
11 changed files with 281 additions and 212 deletions

View File

@@ -177,6 +177,14 @@ namespace Content.Client.Light.Components
[UsedImplicitly]
public sealed class FadeBehaviour : LightBehaviourAnimationTrack
{
/// <summary>
/// Automatically reverse the animation when EndValue is reached. In this particular case, MaxTime specifies the
/// time of the full animation, including the reverse interpolation.
/// </summary>
[DataField("reverseWhenFinished")]
[ViewVariables]
public bool ReverseWhenFinished { get; set; }
public override (int KeyFrameIndex, float FramePlayingTime) AdvancePlayback(
object context, int prevKeyFrameIndex, float prevPlayingTime, float frameTime)
{
@@ -189,22 +197,42 @@ namespace Content.Client.Light.Components
return (-1, playingTime);
}
switch (InterpolateMode)
// From 0 to MaxTime/2, we go from StartValue to EndValue. From MaxTime/2 to MaxTime, we reverse this interpolation.
if (ReverseWhenFinished)
{
case AnimationInterpolationMode.Linear:
ApplyProperty(InterpolateLinear(StartValue, EndValue, interpolateValue));
break;
case AnimationInterpolationMode.Cubic:
ApplyProperty(InterpolateCubic(EndValue, StartValue, EndValue, StartValue, interpolateValue));
break;
default:
case AnimationInterpolationMode.Nearest:
ApplyProperty(interpolateValue < 0.5f ? StartValue : EndValue);
break;
if (interpolateValue < 0.5f)
{
ApplyInterpolation(StartValue, EndValue, interpolateValue*2);
}
else
{
ApplyInterpolation(EndValue, StartValue, (interpolateValue-0.5f)*2);
}
}
else
{
ApplyInterpolation(StartValue, EndValue, interpolateValue);
}
return (-1, playingTime);
}
private void ApplyInterpolation(float start, float end, float interpolateValue)
{
switch (InterpolateMode)
{
case AnimationInterpolationMode.Linear:
ApplyProperty(InterpolateLinear(start, end, interpolateValue));
break;
case AnimationInterpolationMode.Cubic:
ApplyProperty(InterpolateCubic(end, start, end, start, interpolateValue));
break;
default:
case AnimationInterpolationMode.Nearest:
ApplyProperty(interpolateValue < 0.5f ? start : end);
break;
}
}
}
/// <summary>
@@ -369,11 +397,8 @@ namespace Content.Client.Light.Components
[ViewVariables(VVAccess.ReadOnly)]
private readonly List<AnimationContainer> _animations = new();
private float _originalRadius;
private float _originalEnergy;
private Angle _originalRotation;
private Color _originalColor;
private bool _originalEnabled;
[ViewVariables(VVAccess.ReadOnly)]
private Dictionary<string, object> _originalPropertyValues = new();
void ISerializationHooks.AfterDeserialization()
{
@@ -395,8 +420,6 @@ namespace Content.Client.Light.Components
{
base.Startup();
CopyLightSettings();
// TODO: Do NOT ensure component here. And use eventbus events instead...
Owner.EnsureComponent<AnimationPlayerComponent>();
@@ -445,15 +468,15 @@ namespace Content.Client.Light.Components
/// <summary>
/// If we disable all the light behaviours we want to be able to revert the light to its original state.
/// </summary>
private void CopyLightSettings()
private void CopyLightSettings(string property)
{
if (_entMan.TryGetComponent(Owner, out PointLightComponent? light))
{
_originalColor = light.Color;
_originalEnabled = light.Enabled;
_originalEnergy = light.Energy;
_originalRadius = light.Radius;
_originalRotation = light.Rotation;
var propertyValue = AnimationHelper.GetAnimatableProperty(light, property);
if (propertyValue != null)
{
_originalPropertyValues.Add(property, propertyValue);
}
}
else
{
@@ -479,6 +502,7 @@ namespace Content.Client.Light.Components
{
if (!animation.HasRunningAnimation(KeyPrefix + container.Key))
{
CopyLightSettings(container.LightBehaviour.Property);
container.LightBehaviour.UpdatePlaybackValues(container.Animation);
animation.Play(container.Animation, KeyPrefix + container.Key);
}
@@ -526,12 +550,27 @@ namespace Content.Client.Light.Components
if (resetToOriginalSettings && _entMan.TryGetComponent(Owner, out PointLightComponent? light))
{
light.Color = _originalColor;
light.Enabled = _originalEnabled;
light.Energy = _originalEnergy;
light.Radius = _originalRadius;
light.Rotation = _originalRotation;
foreach (var (property, value) in _originalPropertyValues)
{
AnimationHelper.SetAnimatableProperty(light, property, value);
}
}
_originalPropertyValues.Clear();
}
/// <summary>
/// Checks if at least one behaviour is running.
/// </summary>
/// <returns>Whether at least one behaviour is running, false if none is.</returns>
public bool HasRunningBehaviours()
{
if (!_entMan.TryGetComponent(Owner, out AnimationPlayerComponent? animation))
{
return false;
}
return _animations.Any(container => animation.HasRunningAnimation(KeyPrefix + container.Key));
}
/// <summary>