Files
beyond/Assets/AI/Demon/ShieldDamage.cs
Szymon Miś 83e6b40c2a Demon Fixes
2025-09-04 14:25:26 +02:00

191 lines
4.8 KiB
C#

using Invector;
using Invector.vCharacterController;
using UnityEngine;
namespace DemonBoss.Magic
{
/// <summary>
/// Component that adds damage when the player gets too close to the shield.
/// Add to the shield object along with Sphere Collider (IsTrigger = true).
/// </summary>
public class ShieldDamage : MonoBehaviour
{
[Header("Damage Configuration")]
[Tooltip("Damage dealt to the player")]
public int damage = 15;
[Tooltip("Knockback force")]
public float knockbackForce = 10f;
[Tooltip("Player Tag")]
public string playerTag = "Player";
[Tooltip("Time between consecutive hits (so as not to deal damage to every frame)")]
public float damageInterval = 1f;
[Header("Effects")]
[Tooltip("Sound effect when dealing damage")]
public AudioClip damageSound;
[Tooltip("Visual effect when dealing damage")]
public GameObject damageEffect;
[Header("Debug")]
[Tooltip("Enable debug logs")]
public bool enableDebug = false;
private AudioSource audioSource;
private float lastDamageTime;
private void Awake()
{
if (damageSound != null)
{
audioSource = GetComponent<AudioSource>();
if (audioSource == null)
{
audioSource = gameObject.AddComponent<AudioSource>();
audioSource.playOnAwake = false;
audioSource.spatialBlend = 1f; // 3D sound
}
}
}
private void OnTriggerStay(Collider other)
{
if (other.CompareTag(playerTag) && Time.time >= lastDamageTime + damageInterval)
{
DealDamageToPlayer(other);
lastDamageTime = Time.time;
}
}
private void DealDamageToPlayer(Collider playerCollider)
{
if (enableDebug) Debug.Log($"[ShieldDamage] I deal {damage} damage to the player: {playerCollider.name}");
Vector3 hitPoint = playerCollider.ClosestPoint(transform.position);
Vector3 hitDirection = (playerCollider.transform.position - transform.position).normalized;
vDamage damageInfo = new vDamage(damage)
{
sender = transform,
hitPosition = hitPoint
};
if (knockbackForce > 0f)
{
damageInfo.force = hitDirection * knockbackForce;
}
bool damageDealt = false;
// 1) vIDamageReceiver
var damageReceiver = playerCollider.GetComponent<vIDamageReceiver>() ??
playerCollider.GetComponentInParent<vIDamageReceiver>();
if (damageReceiver != null)
{
damageReceiver.TakeDamage(damageInfo);
damageDealt = true;
if (enableDebug) Debug.Log("[ShieldDamage] Damage dealt by vIDamageReceiver");
}
// 2) vHealthController
if (!damageDealt)
{
var healthController = playerCollider.GetComponent<vHealthController>() ??
playerCollider.GetComponentInParent<vHealthController>();
if (healthController != null)
{
healthController.TakeDamage(damageInfo);
damageDealt = true;
if (enableDebug) Debug.Log("[ShieldDamage] Damage dealt by vHealthController");
}
}
// 3) vThirdPersonController
if (!damageDealt)
{
var tpc = playerCollider.GetComponent<vThirdPersonController>() ??
playerCollider.GetComponentInParent<vThirdPersonController>();
if (tpc != null)
{
// SprawdŸ czy to Beyond variant
if (tpc is Beyond.bThirdPersonController beyond)
{
if (!beyond.GodMode && !beyond.isImmortal)
{
tpc.TakeDamage(damageInfo);
damageDealt = true;
if (enableDebug) Debug.Log("[ShieldDamage] Damage dealt by bThirdPersonController");
}
else
{
if (enableDebug) Debug.Log("[ShieldDamage] Player is immortal - no damage");
}
}
else
{
tpc.TakeDamage(damageInfo);
damageDealt = true;
if (enableDebug) Debug.Log("[ShieldDamage] Damage dealt by vThirdPersonController");
}
}
}
if (damageDealt)
{
PlayEffects(hitPoint);
}
else if (enableDebug)
{
Debug.LogWarning("[ShieldDamage] Cannot deal damage - missing required component!");
}
}
private void PlayEffects(Vector3 hitPoint)
{
// Play hit sound
if (audioSource != null && damageSound != null)
{
audioSource.PlayOneShot(damageSound);
}
// Show visual effect
if (damageEffect != null)
{
GameObject effect = Instantiate(damageEffect, hitPoint, Quaternion.identity);
Destroy(effect, 2f); // Remove after 2 seconds
}
}
#if UNITY_EDITOR
/// <summary>
/// Draw damage range visualization in Scene View
/// </summary>
private void OnDrawGizmosSelected()
{
// Show damage range
Collider col = GetComponent<Collider>();
if (col != null && col.isTrigger)
{
Gizmos.color = Color.red;
if (col is SphereCollider sphere)
{
Gizmos.DrawWireSphere(transform.position, sphere.radius);
}
else if (col is CapsuleCollider capsule)
{
// Approximate capsule visualization
Gizmos.DrawWireSphere(transform.position, capsule.radius);
}
}
}
#endif
}
}