Esempio n. 1
0
    // Initialization + Setup
    #region
    public void SetupBaseProperties(AbilityDataSO abilityFromLibrary)
    {
        myAbilityData = abilityFromLibrary;

        // only for defenders. enemies don't have ability button gameobjects
        if (abilityImage)
        {
            abilityImage.sprite = abilityFromLibrary.sprite;
        }

        // Set base properties
        abilityName             = abilityFromLibrary.abilityName;
        abilityDescription      = abilityFromLibrary.description;
        abilityBaseCooldownTime = abilityFromLibrary.baseCooldownTime;
        abilityEnergyCost       = abilityFromLibrary.energyCost;
        abilityRange            = abilityFromLibrary.range;
        abilityPrimaryValue     = abilityFromLibrary.primaryValue;
        abilitySecondaryValue   = abilityFromLibrary.secondaryValue;
        abilityDamageType       = abilityFromLibrary.damageType;
        abilityType             = abilityFromLibrary.abilityType;
        weaponDamagePercentage  = abilityFromLibrary.weaponDamagePercentage;
        requiresMeleeWeapon     = abilityFromLibrary.requiresMeleeWeapon;
        requiresRangedWeapon    = abilityFromLibrary.requiresRangedWeapon;
        requiresShield          = abilityFromLibrary.requiresShield;

        // Set up info panel for defenders
        if (myLivingEntity != null &&
            myLivingEntity.defender)
        {
            AbilityInfoSheetController.Instance.BuildSheetFromData(abilityInfoSheet, abilityFromLibrary, AbilityInfoSheet.PivotDirection.Upwards);
        }
    }
    public float CalculateAndGetDamagePercentageModifier(LivingEntity attacker, LivingEntity victim, AbilityDataSO.DamageType damageType)
    {
        // Get damage type first
        AbilityDataSO.DamageType DamageType = damageType;

        // TO DO in future: this is where we modify the damage type based on character traits
        // (e.g. if a character has a buff that makes all it damage types magical

        float damageModifier = 1f;

        if (victim.isKnockedDown)
        {
            damageModifier += 0.5f;
        }
        if (victim.myPassiveManager.Exposed)
        {
            damageModifier += 0.5f;
        }
        if (attacker.myPassiveManager.Exhausted)
        {
            damageModifier -= 0.5f;
        }

        /*
         * if (PositionLogic.Instance.CanAttackerHitTargetsBackArc(attacker, victim))
         * {
         *  damageModifier += 1f;
         * }
         */
        if (victim.myPassiveManager.Flanked)
        {
            damageModifier += 0.5f;
        }
        if (victim.myPassiveManager.MagicImmunity && DamageType == AbilityDataSO.DamageType.Magic)
        {
            damageModifier = 0;
        }
        if (victim.myPassiveManager.PhysicalImmunity && DamageType == AbilityDataSO.DamageType.Physical)
        {
            damageModifier = 0;
        }

        // prevent modifier from going negative
        if (damageModifier < 0)
        {
            damageModifier = 0;
        }

        return(damageModifier);
    }
Esempio n. 3
0
    public void SetupBaseProperties(AbilityDataSO abilityFromLibrary)
    {
        myAbilityData = abilityFromLibrary;

        abilityImage = abilityFromLibrary.abilityImage;
        Image image = GetComponent <Image>();

        // only for defenders. enemies don't have ability button gameobjects, so GetComponent<Image> will cause a null ref on enemies.
        if (image)
        {
            GetComponent <Image>().sprite = abilityImage;
        }

        abilityName             = abilityFromLibrary.abilityName;
        abilityDescription      = abilityFromLibrary.abilityDescription;
        abilityBaseCooldownTime = abilityFromLibrary.abilityBaseCooldownTime;
        abilityAPCost           = abilityFromLibrary.abilityAPCost;
        abilityRange            = abilityFromLibrary.abilityRange;
        abilityPrimaryValue     = abilityFromLibrary.abilityPrimaryValue;
        abilitySecondaryValue   = abilityFromLibrary.abilitySecondaryValue;

        abilityAttackType = abilityFromLibrary.abilityAttackType;
        abilityDamageType = abilityFromLibrary.abilityDamageType;
        usesMeleeWeapon   = abilityFromLibrary.usesMeleeWeapon;
        usesRangedWeapon  = abilityFromLibrary.usesRangedWeapon;

        // Set up info panel for defenders
        if (myLivingEntity.GetComponent <Defender>())
        {
            cdText.text          = abilityFromLibrary.abilityBaseCooldownTime.ToString();
            rangeText.text       = abilityFromLibrary.abilityRange.ToString();
            apCostText.text      = abilityFromLibrary.abilityAPCost.ToString();
            nameText.text        = abilityFromLibrary.abilityName.ToString();
            descriptionText.text = abilityFromLibrary.abilityDescription.ToString();
        }
    }
    // Overload method used for aoe damage events not caused by spells/abilities (e.g. volatile passive)
    public void CreateAoEAttackEvent(LivingEntity attacker, int damage, TileScript aoeCentrePoint, int aoeSize, bool excludeCentreTile, bool friendlyFire, AbilityDataSO.DamageType damageType)
    {
        Debug.Log("Starting new AoE damage event...");

        Defender defender = attacker.GetComponent <Defender>();
        Enemy    enemy    = attacker.GetComponent <Enemy>();

        List <TileScript>   tilesInAoERadius = LevelManager.Instance.GetTilesWithinRange(aoeSize, aoeCentrePoint, excludeCentreTile);
        List <LivingEntity> livingEntitiesWithinAoeRadius = new List <LivingEntity>();
        List <LivingEntity> finalList = new List <LivingEntity>();

        // Get all living entities within the blast radius
        foreach (LivingEntity livingEntity in LivingEntityManager.Instance.allLivingEntities)
        {
            if (tilesInAoERadius.Contains(livingEntity.TileCurrentlyOn))
            {
                livingEntitiesWithinAoeRadius.Add(livingEntity);
            }
        }

        // if this ability doesn't not damage friendly targets, filter out friendly targets from the list
        if (friendlyFire == false)
        {
            foreach (LivingEntity livingEntity in livingEntitiesWithinAoeRadius)
            {
                if (defender && livingEntity.GetComponent <Enemy>())
                {
                    finalList.Add(livingEntity);
                }

                else if (enemy && livingEntity.GetComponent <Defender>())
                {
                    finalList.Add(livingEntity);
                }
            }
        }

        // Else if this ability can damage everything, add all living entities within the blast radius to the final list
        else if (friendlyFire == true)
        {
            finalList.AddRange(livingEntitiesWithinAoeRadius);
        }

        // Deal damage to all characters in the final list
        foreach (LivingEntity livingEntity in finalList)
        {
            //livingEntity.HandleDamage(livingEntity.CalculateDamage(damage, livingEntity, attacker), attacker, true);
            HandleDamage(CalculateDamage(damage, livingEntity, attacker, damageType), attacker, livingEntity, true);
        }
    }
    public int CalculateDamage(int abilityBaseDamage, LivingEntity victim, LivingEntity attacker, AbilityDataSO.DamageType damageType)
    {
        int newDamageValue = 0;

        // Establish base ability damage value
        newDamageValue += abilityBaseDamage;
        Debug.Log("Base damage value: " + newDamageValue);

        // add bonus strength
        newDamageValue += attacker.currentStrength;
        Debug.Log("Damage value after strength added: " + newDamageValue);

        // multiply/divide the damage value based on factors like vulnerable, knock down, magic vulnerability, etc
        newDamageValue = (int)(newDamageValue * CalculateAndGetDamagePercentageModifier(attacker, victim, damageType));
        Debug.Log("Damage value after percentage modifers like knockdown added: " + newDamageValue);

        return(newDamageValue);
    }
    public void HandleDamage(int damageAmount, LivingEntity attacker, LivingEntity victim, bool playVFXInstantly = false, AbilityDataSO.AttackType attackType = AbilityDataSO.AttackType.None, AbilityDataSO.DamageType damageType = AbilityDataSO.DamageType.None)
    {
        int blockAfter  = victim.currentBlock;
        int healthAfter = victim.currentHealth;

        if (victim.currentBlock == 0)
        {
            healthAfter = victim.currentHealth - damageAmount;
            blockAfter  = 0;
        }
        else if (victim.currentBlock > 0)
        {
            blockAfter = victim.currentBlock;
            Debug.Log("block after = " + blockAfter);
            blockAfter = blockAfter - damageAmount;
            Debug.Log("block after = " + blockAfter);
            if (blockAfter < 0)
            {
                healthAfter  = victim.currentHealth;
                healthAfter += blockAfter;
                blockAfter   = 0;
                Debug.Log("block after = " + blockAfter);
            }
        }

        if (victim.hasBarrier && healthAfter < victim.currentHealth)
        {
            damageAmount = 0;
            healthAfter  = victim.currentHealth;
            victim.ModifyCurrentBarrierStacks(-1);
        }

        // Poisonous trait
        if (attacker.myPassiveManager.Poisonous && healthAfter < victim.currentHealth)
        {
            victim.ModifyPoison(attacker.myPassiveManager.poisonousStacks);
        }

        // Remove sleeping
        if (victim.isSleeping && damageAmount > 0)
        {
            Debug.Log("Damage taken, removing sleep");
            victim.ModifySleeping(-victim.currentSleepingStacks);
        }

        // Enrage
        if (victim.myPassiveManager.Enrage && healthAfter < victim.currentHealth)
        {
            Debug.Log("Enrage triggered, gaining strength");
            victim.ModifyCurrentStrength(victim.myPassiveManager.enrageStacks);
        }

        if (victim.myPassiveManager.Adaptive && healthAfter < victim.currentHealth)
        {
            Debug.Log("Adaptive triggered, gaining block");
            victim.ModifyCurrentBlock(victim.myPassiveManager.adaptiveStacks);
        }

        // remove camoflage if damaged
        if (victim.isCamoflaged && healthAfter < victim.currentHealth)
        {
            victim.RemoveCamoflage();
        }

        victim.currentHealth     = healthAfter;
        victim.currentBlock      = blockAfter;
        victim.myHealthBar.value = victim.CalculateHealthBarPosition();
        victim.UpdateCurrentHealthText();


        victim.SetCurrentBlock(victim.currentBlock);

        if (damageAmount > 0)
        {
            StartCoroutine(VisualEffectManager.Instance.CreateDamageEffect(victim.transform.position, damageAmount, playVFXInstantly));
        }

        if (victim.myPassiveManager.Thorns)
        {
            // TO DO: this needs be updated when we implement damage and attack types
            // if two characters with thorns attack each other, they will continously thorns damage each other until 1 dies
            // thorns damage can only be triggered by a melee attack
            if (attackType == AbilityDataSO.AttackType.Melee)
            {
                HandleDamage(CalculateDamage(victim.myPassiveManager.thornsStacks, victim, attacker, AbilityDataSO.DamageType.None), attacker, victim);
            }
        }

        if (victim.myPassiveManager.LightningShield)
        {
            // TO DO: this needs be updated when we implement damage and attack types
            // if two characters with thorns attack each other, they will continously thorns damage each other until 1 dies
            // thorns damage can only be triggered by a melee attack
            HandleDamage(CalculateDamage(victim.myPassiveManager.lightningShieldStacks, victim, attacker, AbilityDataSO.DamageType.Magic), attacker, victim);
        }

        if (victim.timesAttackedThisTurn == 0 && victim.myPassiveManager.QuickReflexes && victim.IsAbleToMove())
        {
            StartCoroutine(VisualEffectManager.Instance.CreateStatusEffect(victim.transform.position, "Quick Reflexes", true));
            StartCoroutine(victim.StartQuickReflexesMove());
        }
        victim.timesAttackedThisTurn++;

        if (victim.currentHealth <= 0)
        {
            StartCoroutine(victim.HandleDeath());
        }
    }