Camera/FallingCameraEffect.cs
using Sandbox.Utility;
using System.Drawing;
namespace Opium;
public record struct TimedSoundEntry
{
[KeyProperty] public float Time { get; set; }
[KeyProperty] public SoundEvent Sound { get; set; }
}
public partial class FallingCameraEffect : WeaponEffect
{
public TimeUntil TimeUntilRotated { get; set; } = 1.5f;
public TimeUntil TimeUntilHitFloor { get; set; } = 0.5f;
[Property] public float HitFloorTime { get; set; } = 0.5f;
[Property] public float RotateTime { get; set; } = 1.5f;
[Property] public Curve HitFloorCurve { get; set; }
[Property] public Curve RotationCurve { get; set; }
[Property] public Vector3 PositionOffset { get; set; }
[Property] public Angles Angles { get; set; }
[Property] public CameraEffect HitFloorEffect { get; set; }
[Property] public CameraEffect HitFirstObjectEffect { get; set; }
[Property] public float RandSize = 1.0f;
protected override void OnEnabled()
{
TimeUntilHitFloor = HitFloorTime;
TimeUntilRotated = RotateTime;
// Play another camera effect after (X) time
AsyncEffect();
AsyncFirstFall();
AsyncDamage();
Log.Info( "Enabled falling efx" );
}
async void AsyncFirstFall()
{
await GameTask.DelaySeconds( 1f );
if ( HitFirstObjectEffect is not null )
{
HitFirstObjectEffect.Player = Player;
HitFirstObjectEffect.Enabled = true;
}
Log.Info( "Hit first object!" );
}
async void AsyncDamage()
{
await GameTask.DelaySeconds( 0.7f );
Player.GameObject.TakeDamage( Opium.DamageInfo.Bullet( 25, Player.GameObject, Player.GameObject ) );
Player.ActiveWeapon.ViewModel.Components.Get<ViewModel>()?.ModelRenderer.Set( "b_falling", false );
await GameTask.DelaySeconds( 0.3f );
Player.GameObject.TakeDamage( Opium.DamageInfo.Bullet( 50, Player.GameObject, Player.GameObject ) );
}
async void AsyncEffect()
{
await GameTask.DelaySeconds( TimeUntilHitFloor );
if ( HitFloorEffect is not null )
{
HitFloorEffect.Player = Player;
HitFloorEffect.Enabled = true;
}
}
protected override void OnDisabled()
{
base.OnDisabled();
Player.EyeAngles = Player.EyeAngles.WithPitch( 0f );
Log.Info( "Disable" );
}
public override bool TickEffect()
{
if ( Player is not null )
{
if ( !PositionOffset.IsNearlyZero() )
Player.ExtraCamOffset = PositionOffset * HitFloorCurve.Evaluate( 1 - TimeUntilHitFloor.Fraction );
var delta = TimeUntilHitFloor.Fraction;
delta = Easing.EaseOut( delta );
Vector3 rand = Vector3.Random;
rand.z = 0;
rand = rand.Normal;
var rotation = Player.MainCamera.Transform.Rotation;
Player.ExtraCamOffset += (rotation.Right * rand.x + rotation.Up * rand.y) * (1 - ( delta * 2 )) * RandSize;
Player.EyeAngles = Player.EyeAngles.WithPitch( 90f );
Player.CameraRotationOffset *= Rotation.From( Angles * RotationCurve.Evaluate( TimeUntilRotated.Fraction.Clamp( 0, 1 ) ) );
}
return TimeUntilHitFloor;
}
}