using Photon.Pun; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; public class NetworkedProjectileAreaOfEffectOverTimeWithTickEvent : NetworkedAreaOfEffectOverTime { [Header("Visuals")] [SerializeField] private GameObject hitParticlesPrefab; public ProjectileAbility projectileAbility; public UnityEvent> onTickHappened = new UnityEvent>(); public UnityEvent> onTargetHitByProjectile = new UnityEvent>(); NetworkedAntiProjectile possibleBlock; protected List processedTargets = new List(); protected List projectileTargets = new List(); public void InitProjectileStats() { if (photonView.IsMine) { photonView.RPC(nameof(RPC_RemoteInitProjectile), RpcTarget.Others, AbilityIndexer.Instance.Abilities.IndexOf(projectileAbility)); } } private void Update() { if (!photonView.IsMine) return; if (waitingForDestroy) return; this.transform.position += this.transform.forward * projectileAbility.projectileSpeed * Time.deltaTime; } protected override void OnTickPerformed() { if (targets.Count > 0) onTickHappened.Invoke(owner, ownerTag, targets); } [PunRPC] protected void RPC_RemoteInitProjectile(int abilityIndex) { projectileAbility = (ProjectileAbility)AbilityIndexer.Instance.Abilities[abilityIndex]; } private void OnTriggerEnter(Collider other) { if (waitingForDestroy) return; possibleTarget = other.GetComponentInParent(); if (possibleTarget != null) { if (!canHitSelf) if (possibleTarget == owner) return; } target = other.GetComponentInParent(); if (target == null) return; if (projectileAbility == null) return; if (!target.IsValidTarget(projectileAbility.targettingTags)) return; //Debug.Log($"TT[{Time.frameCount}] Past validation checks for {target.name}"); if (processedTargets.Contains(target)) return; processedTargets.Add(target); hitPositionCorrected = target.transform.position; hitPositionCorrected.y = this.transform.position.y; onTargetHit.Invoke(hitPositionCorrected); if (!photonView.IsMine) return; possibleBlock = target.GetComponentInParent(); if (possibleBlock != null) { waitingForDestroy = true; possibleBlock.SendBlockNotice(); StartCoroutine(DelayedDestroy()); return; } //Debug.Log($"TT[{Time.frameCount}] About to process effects"); projectileTargets.Clear(); projectileTargets.Add(target); foreach (BaseEffect effect in projectileAbility.abilityEffects) { //Debug.Log($"TT[{Time.frameCount}] Applying effect: {effect.name}"); effect.ApplyEffect(ownerTag, projectileTargets); } if(projectileTargets.Count > 0) { //Debug.Log($"TT[{Time.frameCount}] OnProjectileHit {projectileTargets.Count}"); onTargetHitByProjectile.Invoke(owner, ownerTag, projectileTargets); } if (!projectileAbility.canPierce) { waitingForDestroy = true; StartCoroutine(DelayedDestroy()); } } }