Ultimate_Light_Manager.cs
using Sandbox;
using System;
using System.Collections.Generic;

[Title( "Ultimate Light Manager" )]
[Category( "Light" )]
[Icon( "light_mode" )]
public class LightManager : Component, Component.ExecuteInEditor
{
    [Property, Group("General"), Title("Light Color")] 
    public Color LightColor { get; set; } = Color.White;

    [Property, Group("General"), Title("Max Brightness")] 
    public float TargetBrightness { get; set; } = 1.0f;

    [Property, Group("General"), Title("Start Enabled")] 
    public bool IsEnabled { get; set; } = true;

    [Property, Group("General"), Title("Interaction (Click)")]
    public bool Clickable { get; set; } = true;

    [Property, Group("Motion Sensor"), Title("Enable Sensor")]
    public bool SensorEnabled { get; set; } = false;

    [Property, Group("Motion Sensor")] 
    public float SensorRange { get; set; } = 200.0f;

    [Property, Group("Motion Sensor")] 
    public float SensorFadeSpeed { get; set; } = 2.0f;

    [Property, Group("Disco Mode")] public bool DiscoMode { get; set; } = false;
    [Property, Group("Disco Mode")] public float DiscoSpeed { get; set; } = 20.0f;
    [Property, Group("Disco Mode")] public float RainbowSpeed { get; set; } = 5.0f;

    [Property, Group("Horror Mode")] public bool HorrorMode { get; set; } = false;
    [Property, Group("Horror Mode")] public float HorrorStability { get; set; } = 0.7f;

    [Property, Group("Fire Mode")] public bool FireMode { get; set; } = false;
    [Property, Group("Fire Mode")] public float FireSpeed { get; set; } = 10.0f;
    [Property, Group("Fire Mode")] public float FireIntensity { get; set; } = 0.1f;

    [Property, Group("Blink Mode")] public bool BlinkEnabled { get; set; } = false;
    [Property, Group("Blink Mode")] public float BlinkInterval { get; set; } = 0.5f;

    [Property, Group("Color Cycle")] public bool CycleEnabled { get; set; } = false;
    [Property, Group("Color Cycle")] public List<Color> CycleColors { get; set; } = new List<Color>();
    [Property, Group("Color Cycle")] public float ColorDuration { get; set; } = 2.0f;

    [Property, Group("Audio"), Title("Turn On Sound")]
    [Description("Sound played when the light turns on.")]
    public SoundEvent SoundOn { get; set; }

    [Property, Group("Audio"), Title("Turn Off Sound")]
    [Description("Sound played when the light turns off.")]
    public SoundEvent SoundOff { get; set; }

    [Property, Group("Audio"), Title("Ambient Sound (Loop)")]
    [Description("Sound played continuously (e.g., Neon hum, Fire crackle).")]
    public SoundEvent SoundLoop { get; set; }

    [Property, Group("Audio"), Title("Ambient Volume")]
    [Range(0f, 1f)]
    public float LoopVolume { get; set; } = 1.0f;

    [RequireComponent] public PointLight LightComponent { get; private set; }
    private float _sensorFactor = 1.0f; 
    private SoundHandle _loopHandle;
    private bool _wasEnabled; 

    protected override void OnStart()
    {
        _wasEnabled = IsEnabled;
    }

    protected override void OnUpdate()
    {
        if ( LightComponent == null ) return;

        CheckInteraction();
        UpdateMotionSensor();
        UpdateAudioSystem();

        Color finalColor = CalculateColor();
        float finalBrightness = CalculateBrightness();

        float totalBrightness = finalBrightness * _sensorFactor;
        LightComponent.LightColor = finalColor * totalBrightness;
        LightComponent.Enabled = IsEnabled && _sensorFactor > 0.01f;
    }

    protected override void OnDestroy()
    {
        _loopHandle?.Stop();
    }

    private void UpdateAudioSystem()
    {
        if ( IsEnabled != _wasEnabled )
        {
            if ( IsEnabled )
            {
                if ( SoundOn != null ) Sound.Play( SoundOn, Transform.Position );
            }
            else
            {
                if ( SoundOff != null ) Sound.Play( SoundOff, Transform.Position );
            }
            _wasEnabled = IsEnabled;
        }

        if ( IsEnabled && SoundLoop != null )
        {
            if ( !_loopHandle.IsValid() )
                _loopHandle = Sound.Play( SoundLoop, Transform.Position );

            _loopHandle.Position = Transform.Position;
            _loopHandle.Volume = LoopVolume * _sensorFactor;
        }
        else
        {
            _loopHandle?.Stop();
        }
    }

    private void UpdateMotionSensor()
    {
        if ( !SensorEnabled ) { _sensorFactor = 1.0f; return; }
        if ( Scene.Camera == null ) return;

        float dist = GameObject.Transform.Position.Distance( Scene.Camera.Transform.Position );
        float target = (dist < SensorRange) ? 1.0f : 0.0f;
        _sensorFactor = MathX.Lerp( _sensorFactor, target, Time.Delta * SensorFadeSpeed );
    }

    private void CheckInteraction()
    {
        if ( !Clickable || Scene.Camera == null ) return;
        if ( Input.Pressed( "attack1" ) )
        {
            var ray = Scene.Camera.ScreenPixelToRay( Mouse.Position );
            var tr = Scene.Trace.Ray( ray, 5000f ).IgnoreGameObjectHierarchy( Scene.Camera.GameObject ).Run();
            if ( tr.Hit && tr.GameObject == GameObject ) IsEnabled = !IsEnabled;
        }
    }

    private Color CalculateColor()
    {
        if ( DiscoMode ) return new ColorHsv( (Time.Now * RainbowSpeed * 50f) % 360f, 1, 1 ).ToColor();
        if ( CycleEnabled && CycleColors != null && CycleColors.Count > 1 )
        {
            float duration = Math.Max( ColorDuration, 0.1f );
            float r = Time.Now / duration;
            return Color.Lerp( CycleColors[(int)r % CycleColors.Count], CycleColors[((int)r + 1) % CycleColors.Count], r - (float)Math.Floor(r) );
        }
        return LightColor;
    }

    private float CalculateBrightness()
    {
        if ( !IsEnabled ) return 0.0f;
        if ( DiscoMode ) return (MathF.Sin( Time.Now * DiscoSpeed ) > 0) ? TargetBrightness : 0f;
        if ( HorrorMode && Game.Random.Float(0,1) > HorrorStability ) return Game.Random.Float(0,1) > 0.5f ? 0f : TargetBrightness * 0.1f;
        if ( FireMode ) {
            float noise = (MathF.Sin(Time.Now*FireSpeed) + MathF.Sin(Time.Now*FireSpeed*0.5f)) / 2f;
            return Math.Max(0, TargetBrightness + (noise * FireIntensity));
        }
        if ( BlinkEnabled ) {
             float i = Math.Max(BlinkInterval, 0.05f);
             return ((Time.Now % (i*2)) < i) ? TargetBrightness : 0f;
        }
        return TargetBrightness;
    }
}