using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
/// <summary>
/// GAME 1303 Tier 2 — "This is what hurts you." A trigger that damages Hurtboxes
/// on the opposing team while it's active.
///
/// SETUP
/// 1. Empty CHILD of the attacker (e.g. "SwordHitbox") positioned in front of them.
/// 2. BoxCollider2D (Is Trigger ON) + this script. Start with the child DISABLED
/// in the Inspector (uncheck the GameObject). MeleeAttack turns it on for the
/// swing window; BossController and EnemyPatrol can too.
/// 3. Set Target Team to whoever this should hurt.
/// 4. Layer: "Hitbox" (see Hurtbox notes on the collision matrix).
///
/// Each time the hitbox is enabled it forgets who it already hit, so one swing
/// hits each enemy once, but the next swing can hit them again.
///
/// A hitbox that's always on (e.g. an enemy's body) works too — set Repeat Delay
/// so it re-hits every N seconds while overlapping.
/// </summary>
[RequireComponent(typeof(Collider2D))]
public class Hitbox : MonoBehaviour
{
public Team targetTeam = Team.Enemy;
public int damage = 1;
[Header("Knockback")]
public float knockbackForce = 6f;
public float knockbackUpward = 3f;
[Header("Repeat (for always-on hitboxes)")]
[Tooltip("0 = hit each target once per activation. >0 = re-hit every N seconds.")]
public float repeatDelay = 0f;
[Header("Events")]
public UnityEvent<Hurtbox> OnHit; // ComboCounter.RegisterHit, hit SFX, hit-stop, particles
private readonly Dictionary<Hurtbox, float> lastHitTime = new Dictionary<Hurtbox, float>();
private ComboCounter combo;
void Awake()
{
GetComponent<Collider2D>().isTrigger = true;
combo = GetComponentInParent<ComboCounter>();
}
void OnEnable()
{
lastHitTime.Clear();
}
void OnTriggerEnter2D(Collider2D other) => TryHit(other);
void OnTriggerStay2D(Collider2D other) { if (repeatDelay > 0f) TryHit(other); }
void TryHit(Collider2D other)
{
Hurtbox hb = other.GetComponent<Hurtbox>();
if (hb == null) return;
if (hb.team != targetTeam && hb.team != Team.Neutral) return;
// Already hit this target this activation?
if (lastHitTime.TryGetValue(hb, out float t))
{
if (repeatDelay <= 0f) return;
if (Time.time - t < repeatDelay) return;
}
int finalDamage = damage;
if (combo != null) finalDamage = Mathf.RoundToInt(damage * combo.DamageMultiplier);
Vector2 origin = transform.parent != null ? (Vector2)transform.parent.position : (Vector2)transform.position;
if (hb.ReceiveHit(finalDamage, origin, knockbackForce, knockbackUpward))
{
lastHitTime[hb] = Time.time;
OnHit?.Invoke(hb);
}
}
}