public override void OnHit(RaycastHit rh)
    {
        if (origin.CanDamage(Character.FromObject(rh.collider.gameObject), allowFriendlyFire, allowSelfDamage))
        {
            // If the target has health, damage it
            DamageHitbox hitbox = rh.collider.GetComponent <DamageHitbox>();
            if (hitbox != null)
            {
                // Calculate damage
                int damageToDeal = damage;
                if (hitbox.critical)
                {
                    damageToDeal = Mathf.CeilToInt(damageToDeal * criticalMultiplier);
                }
                hitbox.Damage(damageToDeal, origin, type);
                // Play damage effects
            }

            // If the target has physics, knock it around
            Rigidbody rb = rh.collider.GetComponentInParent <Rigidbody>();
            if (rb != null)
            {
                rb.AddForceAtPosition(transform.forward * knockback, rh.point, ForceMode.Impulse);
                // Play knockback effects
            }

            base.OnHit(rh);
        }

        // Otherwise, ignore and resume normal operation
    }
    public static void PointDamage(GameObject origin, Faction originFaction, GameObject attackedObject, int damage, DamageType cause, bool isSevere)
    {
        DamageHitbox hitbox = attackedObject.GetComponent <DamageHitbox>(); // Checks collider gameObject for a damageHitbox script

        if (hitbox != null)
        {
            hitbox.Damage(damage, origin, originFaction, cause, isSevere);
        }
    }
    public void SingleAttack(Entity attacker, Vector3 position, Vector3 direction)
    {
        attackEffects.Invoke();

        bool          hitSuccessful      = false;
        Character     attackingCharacter = attacker as Character;
        List <Health> alreadyDamaged     = new List <Health>();

        Collider[] inRange = Physics.OverlapSphere(position, range, detection);
        for (int i = 0; i < inRange.Length; i++)
        {
            Vector3 closestPoint = Explosion.GetColliderPointFromCentre(inRange[i], position);

            bool inAngle = Vector3.Angle(direction, closestPoint - position) <= angle / 2;
            if (!inAngle)
            {
                continue;
            }

            Ray  checkRay    = new Ray(position, closestPoint - position);
            bool lineOfSight = Physics.Raycast(checkRay, out RaycastHit hit, range, detection) && hit.collider == inRange[i];
            if (!lineOfSight)
            {
                continue;
            }

            bool canAttack = attackingCharacter == null || attackingCharacter.CanDamage(hit.collider.GetComponent <Character>(), attackFriendlies, false);
            if (!canAttack)
            {
                continue;
            }


            hitSuccessful = true;

            DamageHitbox dh = hit.collider.GetComponent <DamageHitbox>();
            if (dh != null && !alreadyDamaged.Contains(dh.healthScript))
            {
                dh.Damage(damage, attacker, type);
                alreadyDamaged.Add(dh.healthScript);
            }

            Rigidbody rb = hit.collider.GetComponentInParent <Rigidbody>();
            if (rb != null)
            {
                rb.AddForceAtPosition(checkRay.direction * knockback, hit.point, ForceMode.Impulse);
            }
        }

        if (hitSuccessful == true)
        {
            hitEffects.Invoke();
        }
    }
    public static void PointDamage(GameObject origin, Faction originFaction, GameObject attackedObject, int damage, float criticalMultiplier, DamageType normalCause, DamageType criticalCause)
    {
        DamageHitbox hitbox = attackedObject.GetComponent <DamageHitbox>(); // Checks collider gameObject for a damageHitbox script

        if (hitbox != null)
        {
            Debug.Log("Hit");

            hitbox.Damage(damage, criticalMultiplier, origin, originFaction, normalCause, criticalCause);
        }
    }
    /*
     * // Start is called before the first frame update
     * void Start()
     * {
     *
     * }
     *
     * // Update is called once per frame
     * void Update()
     * {
     *
     * }
     */

    private void OnTriggerStay(Collider c)
    {
        //print("Dealing damage at " + Time.time);
        DamageHitbox dh = c.GetComponent <DamageHitbox>();

        if (dh != null)
        {
            //print("Hitbox detected");
            dh.Damage(Mathf.RoundToInt(damagePerSecond * Time.deltaTime), gameObject, null, damageType, isSevere);
        }
    }
    public static void InstantExplosion(GameObject origin, Faction originFaction, Transform explosionOrigin, int damage, float knockback, float blastRadius, float explosionTime, AnimationCurve damageFalloff, AnimationCurve knockbackFalloff, LayerMask blastDetection, DamageType cause, bool isSevere)
    {
        List <Health> alreadyDamaged = new List <Health>();

        Collider[] affectedObjects = Physics.OverlapSphere(explosionOrigin.position, blastRadius, blastDetection);
        foreach (Collider c in affectedObjects)
        {
            Vector3    targetDirection = c.transform.position - explosionOrigin.position;
            RaycastHit isVulnerable;
            if (Physics.Raycast(explosionOrigin.position, targetDirection, out isVulnerable, blastRadius, blastDetection))
            {
                if (isVulnerable.collider == c)
                {
                    float i = isVulnerable.distance / blastRadius;

                    DamageHitbox hitbox = c.GetComponent <DamageHitbox>(); // Checks collider gameObject for a damageHitbox script
                    if (hitbox != null)
                    {
                        bool undamagedCheck = false;
                        foreach (Health h in alreadyDamaged)
                        {
                            if (h == hitbox.healthScript)
                            {
                                undamagedCheck = true;
                            }
                        }

                        if (undamagedCheck == false)
                        {
                            int d = Mathf.RoundToInt(damage * damageFalloff.Evaluate(i));
                            hitbox.Damage(d, origin, originFaction, cause, isSevere);
                            Debug.Log("Dealt " + d + " damage to " + hitbox.name + " at " + hitbox.transform.position + ".");
                            alreadyDamaged.Add(hitbox.healthScript);
                        }
                    }

                    Knockback(isVulnerable.collider.gameObject, knockback * knockbackFalloff.Evaluate(i), targetDirection);
                }
            }
        }
    }
Example #7
0
        public IEnumerator HitboxTakesDamage()
        {
            // Instantiates 'attacker', adds Character script and Faction scriptableObject
            GameObject o = Object.Instantiate(GameObject.CreatePrimitive(PrimitiveType.Cube), new Vector3(0, 0, -3), Quaternion.identity);
            Character  c = o.AddComponent <Character>();

            c.faction = Resources.Load("Factions/Good Guys") as Faction;

            // Creates 'attacked' gameObject and adds health script
            GameObject g             = Object.Instantiate(GameObject.CreatePrimitive(PrimitiveType.Cube), Vector3.zero, Quaternion.identity);
            Health     h             = g.AddComponent <Health>();
            int        currentHealth = h.values.current; // Saves attacked gameObject's current health
            // Adds DamageHitbox script to object, and links it to health script
            DamageHitbox dh = g.AddComponent <DamageHitbox>();

            dh.healthScript = h;

            Debug.Log(h.values.current);
            Debug.Log(currentHealth);

            yield return(new WaitForEndOfFrame());

            Debug.Log("schlep");

            // Deals damage to attacked gameObject's hitbox
            dh.Damage(5, c, DamageType.Shot);

            Debug.Log("frank");

            yield return(new WaitForEndOfFrame());

            Debug.Log("hashbrown");
            Debug.Log(h.values.current);
            Debug.Log(currentHealth);

            // Checks if attacked object's health has changed
            Assert.IsTrue(h.values.current != currentHealth);
        }
Example #8
0
 public void DoDamage()
 {
     _damageHitbox.Damage();
 }
    public void Detonate(Vector3 centre, Entity origin)
    {
        onExplosionStart.Invoke();

        Character     attacker       = origin as Character;
        List <Health> alreadyDamaged = new List <Health>();

        //RaycastHit[] affected = Physics.SphereCastAll(position, blastRadius, Vector3.forward, 0, hitDetection);
        Collider[] affected = Physics.OverlapSphere(centre, blastRadius, hitDetection);
        for (int i = 0; i < affected.Length; i++)
        {
            // Calculates the closest point and raycast towards it to check that it is not behind cover
            Vector3 closestPoint = GetColliderPointFromCentre(affected[i], centre);
            Ray     checkRay     = new Ray(centre, closestPoint - centre);
            bool    lineOfSight  = Physics.Raycast(checkRay, out RaycastHit hit, blastRadius, hitDetection) && hit.collider == affected[i];
            if (!lineOfSight)
            {
                continue;
            }


            // If raycast hits, collider is in the path of the explosion. Check if the object can be attacked by the user
            bool canAttack = attacker == null || attacker.CanDamage(hit.collider.GetComponent <Character>(), friendlyFire, selfDamage);
            if (!canAttack)
            {
                continue;
            }


            // If check is positive, attacker is not restricted from attacking the target (no faction or faction is hostile)
            float distanceZeroToOne = hit.distance / blastRadius;
            // If the collider is attached to an object that wasn't already damaged by the explosion
            DamageHitbox dh = hit.collider.GetComponent <DamageHitbox>();
            if (dh != null && !alreadyDamaged.Contains(dh.healthScript))
            {
                float multipliedDamage = damage * damageFalloff.Evaluate(distanceZeroToOne);
                Debug.Log(multipliedDamage);
                dh.Damage(Mathf.RoundToInt(multipliedDamage), origin, type);
                alreadyDamaged.Add(dh.healthScript);
            }
            // If the collider is affected by physics, knock it around
            Rigidbody rb = hit.collider.GetComponentInParent <Rigidbody>();
            if (rb != null)
            {
                float multipliedKnockback = knockback * knockbackFalloff.Evaluate(distanceZeroToOne);
                rb.AddForceAtPosition(checkRay.direction * multipliedKnockback, hit.point, ForceMode.Impulse);
            }
        }



        /*
         * List<Health> alreadyDamaged = new List<Health>();
         * List<Rigidbody> alreadyKnockedBack = new List<Rigidbody>();
         * Character attacker = origin as Character;
         *
         * Collider[] affectedObjects = Physics.OverlapSphere(position, blastRadius, hitDetection);
         * foreach (Collider c in affectedObjects)
         * {
         *  Ray check = new Ray(position, c.transform.position - position);
         *  // If a check is successful between the collider and the blast origin
         *  if (Physics.Raycast(check, out RaycastHit hit, blastRadius, hitDetection) && hit.collider == c)
         *  {
         *      // If the collider can be attacked
         *      if (Character.CanDamage(attacker, Character.FromObject(hit.collider.gameObject), friendlyFire, selfDamage))
         *      {
         *          float distanceFromOrigin = blastRadius / hit.distance;
         *
         *          // Check if entity can be damaged, and if it hasn't already
         *          DamageHitbox dh = hit.collider.GetComponent<DamageHitbox>();
         *          if (dh != null && !alreadyDamaged.Contains(dh.healthScript))
         *          {
         *              int damageToDeal = Mathf.RoundToInt(damage * damageFalloff.Evaluate(distanceFromOrigin));
         *              dh.Damage(damageToDeal, origin, type);
         *              alreadyDamaged.Add(dh.healthScript);
         *          }
         *
         *          // Check if entity can be knocked back, and if it hasn't already
         *          Rigidbody rb = hit.collider.GetComponentInParent<Rigidbody>();
         *          if (rb != null && !alreadyKnockedBack.Contains(rb))
         *          {
         *              float knockbackToInflict = knockback * knockbackFalloff.Evaluate(distanceFromOrigin);
         *              rb.AddForceAtPosition(check.direction * knockbackToInflict, hit.point, ForceMode.Impulse);
         *          }
         *      }
         *
         *
         *
         *
         *
         *
         *
         *
         *
         *
         *  }
         * }
         */

        onExplosionEnd.Invoke();
    }