SlotMachineFx.cs
using System;
using Sandbox;

namespace Casino.RpSlot;

public sealed class SlotMachineFx : Component
{
    private static readonly SoundEvent SpinSound    = new( "sounds/slot/spin.wav" );
    private static readonly SoundEvent WinSound     = new( "sounds/slot/win.wav" );
    private static readonly SoundEvent JackpotSound = new( "sounds/slot/jackpot.wav" );
    private static readonly SoundEvent LoseSound    = new( "sounds/slot/lose.wav" );
    private static readonly SoundEvent AmbientSound = new( "sounds/slot/ambient.wav" );
    private static readonly SoundEvent ClickSound   = new( "sounds/slot/click.wav" );

    [Property] public int JackpotThreshold { get; set; } = 1000;

    private SoundHandle _ambientHandle;
    private bool _wantAmbient;

    protected override void OnUpdate()
    {
        if ( _wantAmbient && !_ambientHandle.IsValid )
            PlayAmbientOnce();
    }

    public void StartAmbient()
    {
        if ( _wantAmbient ) return;
        _wantAmbient = true;
        PlayAmbientOnce();
    }

    public void StopAmbient()
    {
        _wantAmbient = false;
        _ambientHandle.Stop();
    }

    public void PlayClick()
    {
        TryPlay( ClickSound );
    }

    public void OnSpinStartedLocal()
    {
        TryPlay( SpinSound );
    }

    public void OnSpinResultLocal( int amount )
    {
        if ( amount <= 0 )
        {
            TryPlay( LoseSound );
            return;
        }

        if ( amount >= JackpotThreshold )
            TryPlay( JackpotSound );
        else
            TryPlay( WinSound );
    }

    private void PlayAmbientOnce()
    {
        try
        {
            _ambientHandle = Sound.Play( AmbientSound, WorldPosition );
            _ambientHandle.Volume = 0.3f;
        }
        catch ( Exception ex )
        {
            Log.Warning( $"[Slot] Échec lecture ambient : {ex.Message}" );
        }
    }

    private void TryPlay( SoundEvent evt )
    {
        if ( evt == null ) return;
        try { Sound.Play( evt, WorldPosition ); }
        catch ( Exception ex ) { Log.Warning( $"[Slot] Échec lecture son : {ex.Message}" ); }
    }
}