using System.Collections;
using UnityEngine;
using UnityEngine.Events;
/// <summary>
/// GAME 1303 Tier 4 — A hazard that switches on and off: flame jets, electric arcs,
/// laser bars, geysers. Cutthroat Course (fire), Zap Attack (arcs).
///
/// SETUP
/// 1. Object with Collider2D (Is Trigger) + DamageOnContact (Damage or Instant Kill;
/// set Repeat Interval ~0.5 for a burning feel) + this script.
/// 2. Visuals: drag in a SpriteRenderer, a ParticleSystem, and/or a Light2D object — they're
/// enabled while the hazard is on and disabled while off. Warning Renderer (optional):
/// a faint "about to fire" sprite shown during Warning Time.
/// 3. On Time / Off Time / Start Delay. Start On for hazards that begin active.
/// 4. Always On = ignores the timer (a plain fire pit / acid pool). You then only get the
/// visual bookkeeping, which is still handy.
///
/// For a pure "acid pool that kills on touch" you don't need this at all — just a trigger
/// + DamageOnContact with Instant Kill. Use CyclingHazard when timing is the puzzle.
/// </summary>
[RequireComponent(typeof(DamageOnContact))]
public class CyclingHazard : MonoBehaviour
{
public bool alwaysOn = false;
public bool startOn = false;
public float startDelay = 0f;
public float onTime = 1f;
public float offTime = 1.5f;
public float warningTime = 0.3f;
[Header("Visuals (optional)")]
public SpriteRenderer sprite;
public ParticleSystem particles;
public GameObject lightObject;
public SpriteRenderer warningRenderer;
[Header("Audio")]
public string onSfx = "";
public AudioSource loopWhileOn;
public UnityEvent OnActivated;
public UnityEvent OnDeactivated;
public bool IsOn { get; private set; }
protected DamageOnContact damage;
protected virtual void Awake()
{
damage = GetComponent<DamageOnContact>();
}
protected virtual void Start()
{
if (warningRenderer) warningRenderer.enabled = false;
if (alwaysOn) { SetOn(true); return; }
SetOn(startOn);
StartCoroutine(Loop());
}
IEnumerator Loop()
{
yield return new WaitForSeconds(startDelay);
while (true)
{
if (IsOn)
{
yield return new WaitForSeconds(onTime);
SetOn(false);
}
else
{
yield return new WaitForSeconds(Mathf.Max(0f, offTime - warningTime));
if (warningRenderer) warningRenderer.enabled = true;
yield return new WaitForSeconds(warningTime);
if (warningRenderer) warningRenderer.enabled = false;
SetOn(true);
}
}
}
public virtual void SetOn(bool on)
{
IsOn = on;
if (damage) damage.enabled = on;
if (sprite) sprite.enabled = on;
if (lightObject) lightObject.SetActive(on);
if (particles) { if (on) particles.Play(); else particles.Stop(); }
if (loopWhileOn) { if (on && !loopWhileOn.isPlaying) loopWhileOn.Play(); else if (!on) loopWhileOn.Stop(); }
if (on)
{
if (!string.IsNullOrEmpty(onSfx)) AudioManager.Instance?.PlaySFX(onSfx);
OnActivated?.Invoke();
}
else OnDeactivated?.Invoke();
}
}