private void ApplyKnockback(object receiver, Damage.DamageEventArgs e)
        {
            if (receiver.GetType() == typeof(DamageableBase) || receiver.GetType().IsSubclassOf(typeof(DamageableBase)))
            {
                var damagable = (DamageableBase)receiver;
                var go        = damagable.gameObject;
                var rb        = go.GetComponent <Rigidbody2D>();
                if (rb)
                {
                    Vector3 forceDir = ((Vector3)rb.position - e.HitPoint).normalized;
                    forceDir  = Vector3.Project(forceDir, Vector2.right).normalized;
                    forceDir += Vector3.up * _upwardModifier;
                    forceDir  = forceDir.normalized;
                    rb.AddForce(forceDir * _knockbackForce, ForceMode2D.Impulse);
                    rb.AddForce(_flatForceVector, ForceMode2D.Impulse);

                    if (_debug)
                    {
                        Debug.Log("Applying Knockback!");
                        var rbPos = (Vector3)rb.position;

                        // Pink: The initial difference line.
                        Debug.DrawLine(e.HitPoint, rbPos, new Color(255f, 0f, 97f), 0.5f);
                        // Red: The force direction.
                        Debug.DrawLine(rbPos, rbPos + forceDir * 5f, Color.red, 0.5f);
                        // Blue: The flat force vector.
                        Debug.DrawLine(rbPos, rbPos + _flatForceVector, Color.blue, 0.5f);
                    }
                }
            }
        }
        /// <summary>
        /// Checks for an IDamagable on the target GameObject, then attempts to call its ApplyDamage method.
        /// If an IDamagable isn't found, returns false.
        /// </summary>
        /// <param name="damageTarget"> The Target to look for an IDamagable on.</param>
        /// <param name="args"> Damage Event Arguments.</param>
        /// <returns></returns>
        public virtual bool TryDealDamage(GameObject damageTarget, Damage.DamageEventArgs args)
        {
            if (!CanDealDamage)
            {
                return(false);
            }
            if (args.DamageValue <= 0)
            {
                return(false);
            }
            IDamageable damageable = damageTarget.GetComponent <IDamageable>();

            if (damageable != null)
            {
                if (this.faction == damageable.GetFaction() && !Damage.FriendlyFireEnabled)
                {
                    return(false);
                }

                // By using a ref parameter, we can see the results of the damage delt after it has been changed by resistances and multipliers.
                damageable.ApplyDamage(this, ref args);
                if (args.DamageValue > 0)
                {
                    OnDealDamage(damageable, args);
                    return(true);
                }
            }
            // No IDamagable Found - Return false.
            return(false);
        }
        public virtual bool TryDealDamage(GameObject damageTarget, float damage, Vector3?hitPoint = null)
        {
            Vector3 point = (hitPoint != null) ? (Vector3)hitPoint : transform.position;        // Default on transform position if no hitPoint is set.

            Damage.DamageEventArgs e = new Damage.DamageEventArgs(damage, point, damageType, faction);
            return(TryDealDamage(damageTarget, e));
        }
Esempio n. 4
0
        protected virtual IEnumerator CoEffectTimer()
        {
            if (TickInterval > Duration)
            {
                TickInterval = Duration;
            }
            //Note: There is no initial tick at t=0.
            int ticks = 1;

            Timer = 0f;
            while (Timer < Duration)
            {
                Timer += Time.deltaTime;

                if (Timer > TickInterval * ticks)
                {
                    Damage.DamageEventArgs args = new Damage.DamageEventArgs(DamageValue, Vector3.zero, damageType, faction, Damage.DamageEventType.DOT);
                    TryDealDamage(AttachedDamageable.gameObject, args);
                    ticks++;
                }

                OnUpdateValue(Timer);
                yield return(null);
            }

            Timer = Duration;
            if (DestroySelfWhenFinished)
            {
                Destroy(gameObject);
            }
        }
 private void DoOnTakeDamage(object sender, Damage.DamageEventArgs e)
 {
     if (_playMaker)
     {
         _playMaker.SendEvent(_onDamageEventName);
     }
 }
Esempio n. 6
0
        /// <summary>
        /// Checks for an IDamagable on the target GameObject, then attempts to call its ApplyDamage method.
        /// If an IDamagable isn't found, returns false.
        /// </summary>
        /// <param name="damageTarget"> The Target to look for an IDamagable on.</param>
        /// <param name="e"> Damage Event Arguments.</param>
        /// <returns></returns>
        public virtual bool TryDealDamage(GameObject damageTarget, Damage.DamageEventArgs e)
        {
            if (!CanDealDamage)
            {
                return(false);
            }
            if (e.DamageValue <= 0)
            {
                return(false);
            }
            IDamagable damagable = damageTarget.GetComponent <IDamagable>();

            if (damagable != null)
            {
                if (this.faction == damagable.GetFaction())
                {
                    return(false);
                }
                damagable.ApplyDamage(this, e);
                OnDealDamage(this, e);
                return(true);
            }
            // No IDamagable Found - Return false.
            return(false);
        }
 protected override void DoOnTakeDamage(object sender, Damage.DamageEventArgs damageEventArgs)
 {
     if (_animator)
     {
         if (_stateName.Length > 0)
         {
             _animator.Play(_stateName);
         }
     }
 }
Esempio n. 8
0
 protected virtual void InvokeMutateDamage(object sender, ref Damage.DamageEventArgs args)
 {
     // Make a temporary copy of the event to avoid possibility of
     // a race condition if the last subscriber unsubscribes
     // immediately after the null check and before the event is raised.
     Damage.DamageEventMutator handler = MutateDamage;
     if (handler != null)
     {
         handler(this, ref args);
     }
 }
Esempio n. 9
0
 protected override void HandleDamage(object sender, Damage.DamageEventArgs e)
 {
     // Add an invulnerability delay for non-bullets.
     if (e.DamageType != Damage.DamageType.Bullet)
     {
         if (_isInvulnerable)
         {
             return;
         }
         StartCoroutine(CoInvulnerabilityDelay(_invulnTime));
     }
     base.HandleDamage(sender, e);
 }
Esempio n. 10
0
 protected override void DoOnTakeDamage(object sender, Damage.DamageEventArgs e)
 {
     if (_spriteRenderer)
     {
         if (_effectCoroutine != null)
         {
             StopCoroutine(_effectCoroutine);
             _effectCoroutine      = null;
             _spriteRenderer.color = _originalColor;
         }
         _effectCoroutine = StartCoroutine(CoFlashColor(_takeDamageColor, _originalColor, _takeDamageFlashDuration));
     }
 }
 public override void MutateDamageEvent(object sender, ref Damage.DamageEventArgs args)
 {
     foreach (var tm in TypeValues)
     {
         if (args.DamageType == tm.DamageType)
         {
             args.DamageValue += tm.Value;
             if (args.DamageValue < 0)
             {
                 args.DamageValue = 0f;
             }
         }
     }
 }
        protected override void HandleDamage(object sender, ref Damage.DamageEventArgs args)
        {
            // Invulnerability Check.
            if (_useInvulnerability)
            {
                if (_isInvulnerable)
                {
                    return;
                }
                StartCoroutine(CoInvulnerabilityDelay(_invulnTime));
            }

            base.HandleDamage(sender, ref args);
        }
        protected override void DoOnTakeDamage(object sender, Damage.DamageEventArgs e)
        {
            if (_spriteRenderer)
            {
                if (_flashCoroutine != null)
                {
                    StopCoroutine(_flashCoroutine);

                    //Technically unnecessary, but it's a good, safe practice.
                    _flashCoroutine       = null;
                    _spriteRenderer.color = _originalColor;
                }
                _flashCoroutine = StartCoroutine(CoFlashColor(_color, _originalColor, _duration));
            }
        }
        //================================================================================

        #region Damage Handling

        public override void ApplyDamage(object sender, ref Damage.DamageEventArgs args)
        {
            if (IsDead)
            {
                args.DamageValue = 0f;
                return;
            }
            // Cannot receive damage from same faction.
            if (args.SourceFaction == Faction && args.SourceFaction != Damage.Faction.Generic)
            {
                return;
            }

            HandleDamage(sender, ref args);
        }
Esempio n. 15
0
        protected virtual void HandleDamage(object sender, Damage.DamageEventArgs e)
        {
            if (IsDead)
            {
                return;
            }
            float damage = CalculateDamage(e);

            currentHealth -= damage;
            OnUpdateHealth(currentHealth);
            if (currentHealth <= 0f)
            {
                currentHealth = 0f;
                HandleDeath();
            }
        }
Esempio n. 16
0
        //================================================================================

        #region Damage Handling

        public override void ApplyDamage(object sender, Damage.DamageEventArgs e)
        {
            if (IsDead)
            {
                return;
            }
            // Cannot receive damage from same faction.
            if (e.SourceFaction == Faction && e.SourceFaction != Damage.Faction.Generic)
            {
                //Debug.Log("SAME FACTION DAMAGE");
                return;
            }

            // We still call TakeDamage if the damage would kill them, and leave it up to the delgates to check for death.
            HandleDamage(sender, e);
            //if(!IsDead)
            base.ApplyDamage(sender, e);    // Simply Calls OnTakeDamage(sender, e);
        }
Esempio n. 17
0
        protected override void DoOnTakeDamage(object sender, Damage.DamageEventArgs damageEventArgs)
        {
            if (_filterByDamageType)
            {
                if (damageEventArgs.DamageType != _typeFilter)
                {
                    return;
                }
            }
            if (_damageEffectPrefab)
            {
                var go = GameObject.Instantiate(_damageEffectPrefab);
                go.transform.position = damageEventArgs.HitPoint;
                go.transform.LookAt(damageEventArgs.HitPoint + damageEventArgs.HitNormal);

                Destroy(go, _destroyTime);
            }
        }
        public override void MutateDamageEvent(object sender, ref Damage.DamageEventArgs args)
        {
            if (ShieldHealth.IsDead)
            {
                return;
            }
            var healthBefore = ShieldHealth.CurrentHealth;

            ShieldHealth.ApplyDamage(sender, ref args);
            if (ShieldHealth.IsDead)
            {
                var overflow = args.DamageValue - healthBefore;
                args.DamageValue = overflow;
                OnShieldDestroyed();
                this.enabled = false;
            }
            else
            {
                args.DamageValue = 0f;
            }
        }
        protected virtual void HandleDamage(object sender, ref Damage.DamageEventArgs args)
        {
            if (IsDead)
            {
                return;
            }
            InvokeMutateDamage(sender, ref args);
            float damage = CalculateDamage(args);

            args.DamageValue = damage;
            currentHealth   -= damage;

            // We still call TakeDamage if the damage would kill them, and leave it up to the listeners to check for death.
            InvokeOnTakeDamage(sender, args);

            if (currentHealth <= 0f)
            {
                currentHealth = 0f;
                HandleDeath();
            }
            OnUpdateHealth(currentHealth);
        }
 protected abstract void DoOnTakeDamage(object sender, Damage.DamageEventArgs damageEventArgs);
Esempio n. 21
0
        public virtual void ApplyDamage(object sender, float damage, Vector3 hitPoint)
        {
            var args = new Damage.DamageEventArgs(damage, hitPoint);

            ApplyDamage(sender, ref args);
        }
 protected override void DoOnTakeDamage(object sender, Damage.DamageEventArgs e)
 {
     OnTakeDamageEvent.Invoke();
 }
 public abstract void MutateDamageEvent(object sender, ref Damage.DamageEventArgs args);
Esempio n. 24
0
 protected override void DoOnTakeDamage(object sender, Damage.DamageEventArgs damageEventArgs)
 {
     PlayAnimation(_takeDamageState);
 }
Esempio n. 25
0
 public virtual void ApplyDamage(object sender, Damage.DamageEventArgs e)
 {
     OnTakeDamage(sender, e);
 }
Esempio n. 26
0
 protected override void DoOnTakeDamage(object sender, Damage.DamageEventArgs damageEventArgs)
 {
     _audioSource.PlayOneShot(_clipToPlay);
 }
Esempio n. 27
0
 public override void ApplyDamage(object sender, Damage.DamageEventArgs e)
 {
     base.ApplyDamage(sender, e);
     //if(_debug) Debug.Log(this.gameObject.name + " RECEIVED DAMAGE: " + e.DamageValue);
 }
Esempio n. 28
0
        public virtual void ApplyDamage(float damage)
        {
            var args = new Damage.DamageEventArgs(damage, this.transform.position);

            ApplyDamage(this, ref args);
        }
 /// <summary>
 /// Calculates the effective damage on the HealthManager, AFTER mutators.
 /// Override this for changing how damage is handled specifically on this class.
 /// Alternatively, attach a mutator.
 /// </summary>
 /// <param name="args"></param>
 /// <returns></returns>
 protected virtual float CalculateDamage(Damage.DamageEventArgs args)
 {
     // For the simplest case, just pass the raw DamageValue.
     return(args.DamageValue);
 }
 protected override void DoOnDealDamage(object sender, Damage.DamageEventArgs args)
 {
     ApplyKnockback(sender, args);
 }