Files
BABA_YAGA/Assets/Scripts/Trap/PoisonGasTrap.cs
2026-07-02 08:59:23 +07:00

125 lines
4.3 KiB
C#

using System.Collections;
using System.Collections.Generic;
using Fusion;
using UnityEngine;
using Opsive.UltimateCharacterController.Traits;
public class PoisonGasTrap : TrapBase
{
private List<GameObject> affectedPlayers = new List<GameObject>();
protected override void OnTriggered(GameObject victim)
{
// Start the server-side poison gas zone routine
StartCoroutine(GasZoneRoutine());
}
private IEnumerator GasZoneRoutine()
{
float elapsed = 0f;
float tickInterval = 1.0f; // Deal damage every 1 second
float duration = trapData.EffectDuration;
float radius = trapData.EffectRadius;
float damagePerTick = trapData.Damage; // Sát thương mỗi tick
Debug.Log($"[Server] Poison Gas Trap activated. Duration: {duration}s, Radius: {radius}m");
while (elapsed < duration)
{
// Find all potential targets in radius
Collider[] overlaps = Physics.OverlapSphere(transform.position, radius, LayerMask.GetMask("Player"));
List<GameObject> currentTicks = new List<GameObject>();
foreach (var col in overlaps)
{
if (IsTargetValid(col.gameObject))
{
currentTicks.Add(col.gameObject);
// Apply damage
var health = col.gameObject.GetComponent<Health>();
if (health != null && health.IsAlive())
{
health.Damage(damagePerTick, transform.position, Vector3.zero, 0);
Debug.Log($"[Server] Poison Gas applied {damagePerTick} damage to {col.gameObject.name}");
}
// If player is newly entered the gas, turn on their UI overlay
if (!affectedPlayers.Contains(col.gameObject))
{
affectedPlayers.Add(col.gameObject);
var netObj = col.gameObject.GetComponent<NetworkObject>();
if (netObj != null)
{
RPC_TogglePoisonOverlay(netObj.InputAuthority, netObj.Id, true);
}
}
}
}
// If player left the gas area, turn off their UI overlay
for (int i = affectedPlayers.Count - 1; i >= 0; --i)
{
var p = affectedPlayers[i];
if (p == null || !currentTicks.Contains(p))
{
if (p != null)
{
var netObj = p.GetComponent<NetworkObject>();
if (netObj != null)
{
RPC_TogglePoisonOverlay(netObj.InputAuthority, netObj.Id, false);
}
}
affectedPlayers.RemoveAt(i);
}
}
yield return new WaitForSeconds(tickInterval);
elapsed += tickInterval;
}
// Clean up: turn off overlay for any remaining players in zone
foreach (var p in affectedPlayers)
{
if (p != null)
{
var netObj = p.GetComponent<NetworkObject>();
if (netObj != null)
{
RPC_TogglePoisonOverlay(netObj.InputAuthority, netObj.Id, false);
}
}
}
affectedPlayers.Clear();
// Despawn the trap
DespawnTrap();
}
[Rpc(RpcSources.StateAuthority, RpcTargets.InputAuthority)]
private void RPC_TogglePoisonOverlay([RpcTarget] PlayerRef targetPlayer, NetworkId victimId, bool show)
{
// Resolve the victim GameObject using NetworkId on the client
var victimNetObj = Runner.FindObject(victimId);
if (victimNetObj != null)
{
var overlay = victimNetObj.GetComponentInChildren<PoisonScreenOverlay>();
if (overlay != null)
{
overlay.SetOverlayActive(show);
}
}
}
// Draw the gas radius in editor for debugging
private void OnDrawGizmosSelected()
{
if (trapData != null)
{
Gizmos.color = new Color(0, 1, 0, 0.3f);
Gizmos.DrawSphere(transform.position, trapData.EffectRadius);
}
}
}