コード例 #1
0
    public static MinMaxRange CalculateDamageConversion(ActorData data, int[] convertedDamageMin,
                                                        int[] convertedDamageMax, IEnumerable <GroupType> tags,
                                                        MinMaxRange damageContainer, float[] conversions, ElementType element,
                                                        HashSet <BonusType> multi, StatBonus minBonus, StatBonus maxBonus, StatBonus multiplierBonus)
    {
        float baseMin = damageContainer.min + minBonus.CalculateStat(0);
        float baseMax = damageContainer.max + maxBonus.CalculateStat(0);

        float finalBaseMin = baseMin;
        float finalBaseMax = baseMax;

        for (int i = 0; i < 7; i++)
        {
            if (conversions[i] == 0)
            {
                continue;
            }

            float convertedMin = baseMin * conversions[i];
            float convertedMax = baseMax * conversions[i];

            finalBaseMin -= convertedMin;
            finalBaseMax -= convertedMax;

            HashSet <BonusType> bonusesForConverted = new HashSet <BonusType>(multi);
            bonusesForConverted.UnionWith(Helpers.GetMultiplierTypes(AbilityType.NON_ABILITY, element, (ElementType)i));
            StatBonus totalMultiplierBonus = data.GetMultiStatBonus(null, tags, bonusesForConverted.ToArray());
            totalMultiplierBonus.AddBonuses(multiplierBonus);

            convertedMin = totalMultiplierBonus.CalculateStat(convertedMin);
            convertedMax = totalMultiplierBonus.CalculateStat(convertedMax);

            convertedDamageMin[i] += (int)Math.Max(convertedMin, 0);
            convertedDamageMax[i] += (int)Math.Max(convertedMax, 0);
        }
        MinMaxRange returnValue = new MinMaxRange();

        if (finalBaseMin < 1)
        {
            finalBaseMin = 0;
        }
        if (finalBaseMax < 1)
        {
            finalBaseMax = 0;
        }
        if (finalBaseMax == 0 && finalBaseMin == 0)
        {
            returnValue.min = 0;
            returnValue.max = 0;
        }
        else
        {
            StatBonus finalMultiplier = data.GetMultiStatBonus(null, tags, multi.ToArray());
            finalMultiplier.AddBonuses(multiplierBonus);
            returnValue.min = (int)Math.Max(finalMultiplier.CalculateStat(finalBaseMin), 0);
            returnValue.max = (int)Math.Max(finalMultiplier.CalculateStat(finalBaseMax), 0);
        }

        return(returnValue);
    }
コード例 #2
0
ファイル: Equipment.cs プロジェクト: v-duong/HeroTowerGame
    protected static float CalculateStat(float stat, Dictionary <BonusType, StatBonus> dic, params BonusType[] bonusTypes)
    {
        StatBonus totalBonus = new StatBonus();

        foreach (BonusType bonusType in bonusTypes)
        {
            if (dic.TryGetValue(bonusType, out StatBonus bonus))
            {
                totalBonus.AddBonuses(bonus);
            }
        }
        return(totalBonus.CalculateStat(stat));
    }
コード例 #3
0
    public StatBonus GetTotalStatBonus(IEnumerable <GroupType> groupTypes)
    {
        StatBonus returnBonus = new StatBonus();

        if (groupTypes == null)
        {
            return(returnBonus);
        }

        var intersectingTypes = GetGroupTypeIntersect(groupTypes);

        if (intersectingTypes.Count() == 0)
        {
            return(returnBonus);
        }

        foreach (GroupType type in intersectingTypes)
        {
            returnBonus.AddBonuses(statBonuses[type]);
        }
        returnBonus.UpdateCurrentMultiply();

        return(returnBonus);
    }
コード例 #4
0
    /// <summary>
    /// Calculates Elemental Conversions. Each element is run once so conversion chains cannot happen.
    /// After conversion, the converted damage is calculated with all multiplier bonuses and
    /// is added to an array. Afterwards it should be added to the main damage dictionary/array.
    /// </summary>
    /// <param name="data"></param>
    /// <param name="flatDamageMod"></param>
    /// <param name="convertedDamageMin"></param>
    /// <param name="convertedDamageMax"></param>
    /// <param name="tags"></param>
    /// <param name="damageContainer"></param>
    /// <param name="element"></param>
    /// <param name="multi"></param>
    /// <param name="minBonus"></param>
    /// <param name="maxBonus"></param>
    /// <param name="multiplierBonus"></param>
    /// <returns></returns>
    private MinMaxRange CalculateDamageConversion(ActorData data, float flatDamageMod, int[] convertedDamageMin,
                                                  int[] convertedDamageMax, IEnumerable <GroupType> tags,
                                                  AbilityDamageContainer damageContainer, ElementType element,
                                                  HashSet <BonusType> multi, StatBonus minBonus = null, StatBonus maxBonus = null, StatBonus multiplierBonus = null)
    {
        float baseMin, baseMax;

        if (minBonus != null)
        {
            baseMin = damageContainer.baseMin + minBonus.CalculateStat(0) * flatDamageMod;
        }
        else
        {
            baseMin = damageContainer.baseMin + damageContainer.minBonus.CalculateStat(0) * flatDamageMod;
        }

        if (maxBonus != null)
        {
            baseMax = damageContainer.baseMax + maxBonus.CalculateStat(0) * flatDamageMod;
        }
        else
        {
            baseMax = damageContainer.baseMax + damageContainer.maxBonus.CalculateStat(0) * flatDamageMod;
        }

        float finalBaseMin = baseMin;
        float finalBaseMax = baseMax;

        for (int i = 0; i < 7; i++)
        {
            if (damageContainer.conversions[i] == 0)
            {
                continue;
            }

            float convertedMin = baseMin * damageContainer.conversions[i];
            float convertedMax = baseMax * damageContainer.conversions[i];

            finalBaseMin -= convertedMin;
            finalBaseMax -= convertedMax;

            HashSet <BonusType> bonusesForConverted = new HashSet <BonusType>(multi);
            bonusesForConverted.UnionWith(Helpers.GetMultiplierTypes(abilityBase.abilityType, element, (ElementType)i));
            StatBonus totalMultiplierBonus = data.GetMultiStatBonus(abilityBonuses, tags, bonusesForConverted.ToArray());
            totalMultiplierBonus.AddBonuses(multiplierBonus);

            convertedMin = totalMultiplierBonus.CalculateStat(convertedMin);
            convertedMax = totalMultiplierBonus.CalculateStat(convertedMax);

            convertedDamageMin[i] += (int)Math.Max(convertedMin * finalDamageModifier, 0);
            convertedDamageMax[i] += (int)Math.Max(convertedMax * finalDamageModifier, 0);
        }
        MinMaxRange returnValue = new MinMaxRange();

        if (finalBaseMin < 1)
        {
            finalBaseMin = 0;
        }
        if (finalBaseMax < 1)
        {
            finalBaseMax = 0;
        }
        if (finalBaseMax == 0 && finalBaseMin == 0)
        {
            returnValue.min = 0;
            returnValue.max = 0;
        }
        else
        {
            StatBonus finalMultiplier = data.GetMultiStatBonus(abilityBonuses, tags, multi.ToArray());
            finalMultiplier.AddBonuses(multiplierBonus);
            returnValue.min = (int)Math.Max(finalMultiplier.CalculateStat(finalBaseMin) * finalDamageModifier, 0);
            returnValue.max = (int)Math.Max(finalMultiplier.CalculateStat(finalBaseMax) * finalDamageModifier, 0);
        }

        return(returnValue);
    }
コード例 #5
0
ファイル: Actor.cs プロジェクト: v-duong/HeroTowerGame
    public Dictionary <ElementType, float> ScaleSecondaryDamageValue(Actor target, Dictionary <ElementType, MinMaxRange> baseDamage, IEnumerable <GroupType> effectTags)
    {
        HashSet <GroupType> targetTypes = target.GetActorTagsAsTarget();
        Dictionary <BonusType, StatBonus> whenHitBonusDict = new Dictionary <BonusType, StatBonus>();

        int[]               minDamage          = new int[7];
        int[]               maxDamage          = new int[7];
        int[]               convertedMinDamage = new int[7];
        int[]               convertedMaxDamage = new int[7];
        float[]             conversions        = new float[7];
        HashSet <GroupType> tagsToUse          = new HashSet <GroupType>(effectTags);

        tagsToUse.UnionWith(GetActorTagsAndDataTags());

        foreach (TriggeredEffect triggeredEffect in Data.TriggeredEffects[TriggerType.WHEN_HITTING])
        {
            if (targetTypes.Contains(triggeredEffect.BaseEffect.restriction) && triggeredEffect.RollTriggerChance())
            {
                if (whenHitBonusDict.ContainsKey(triggeredEffect.BaseEffect.statBonusType))
                {
                    whenHitBonusDict[triggeredEffect.BaseEffect.statBonusType].AddBonus(triggeredEffect.BaseEffect.statModifyType, triggeredEffect.Value);
                }
                else
                {
                    StatBonus bonus = new StatBonus();
                    bonus.AddBonus(triggeredEffect.BaseEffect.statModifyType, triggeredEffect.Value);
                    whenHitBonusDict.Add(triggeredEffect.BaseEffect.statBonusType, bonus);
                }
            }
        }

        foreach (ElementType elementType in Enum.GetValues(typeof(ElementType)))
        {
            if (!baseDamage.ContainsKey(elementType))
            {
                baseDamage[elementType] = new MinMaxRange();
            }
            minDamage[(int)elementType] = baseDamage[elementType].min;
            maxDamage[(int)elementType] = baseDamage[elementType].max;

            HashSet <BonusType> minTypes   = new HashSet <BonusType>();
            HashSet <BonusType> maxTypes   = new HashSet <BonusType>();
            HashSet <BonusType> multiTypes = new HashSet <BonusType>();

            Helpers.GetGlobalAndFlatDamageTypes(elementType, tagsToUse, minTypes, maxTypes, multiTypes);
            multiTypes.UnionWith(Helpers.GetMultiplierTypes(AbilityType.NON_ABILITY, elementType));

            StatBonus minBonus   = Data.GetMultiStatBonus(tagsToUse, minTypes.ToArray());
            StatBonus maxBonus   = Data.GetMultiStatBonus(tagsToUse, maxTypes.ToArray());
            StatBonus multiBonus = new StatBonus();

            foreach (KeyValuePair <BonusType, StatBonus> keyValue in whenHitBonusDict)
            {
                if (minTypes.Contains(keyValue.Key))
                {
                    minBonus.AddBonuses(keyValue.Value);
                }
                else if (maxTypes.Contains(keyValue.Key))
                {
                    maxBonus.AddBonuses(keyValue.Value);
                }
                else if (multiTypes.Contains(keyValue.Key))
                {
                    multiBonus.AddBonuses(keyValue.Value);
                }
            }

            HashSet <BonusType> availableConversions = Data.BonusesIntersection(null, Helpers.GetConversionTypes(elementType));
            if (availableConversions.Count > 0)
            {
                Array.Clear(conversions, 0, 7);
                ActorAbility.GetElementConversionValues(Data, tagsToUse, availableConversions, conversions, null);
                MinMaxRange baseRange = ActorAbility.CalculateDamageConversion(Data, convertedMinDamage, convertedMaxDamage, tagsToUse, baseDamage[elementType], conversions, elementType, multiTypes, minBonus, maxBonus, multiBonus);
                minDamage[(int)elementType] = baseRange.min;
                maxDamage[(int)elementType] = baseRange.max;
            }
            else
            {
                Data.GetMultiStatBonus(multiBonus, null, tagsToUse, multiTypes.ToArray());
                minDamage[(int)elementType] = (int)Math.Max(multiBonus.CalculateStat(baseDamage[elementType].min + minBonus.CalculateStat(0f)), 0);
                maxDamage[(int)elementType] = (int)Math.Max(multiBonus.CalculateStat(baseDamage[elementType].max + maxBonus.CalculateStat(0f)), 0);
            }
        }

        float critChance = Data.GetMultiStatBonus(tagsToUse, BonusType.GLOBAL_CRITICAL_CHANCE).CalculateStat(0f);
        bool  isCrit     = UnityEngine.Random.Range(0f, 100f) < critChance;
        Dictionary <ElementType, float> returnDict = new Dictionary <ElementType, float>();

        foreach (ElementType elementType in Enum.GetValues(typeof(ElementType)))
        {
            float damage = UnityEngine.Random.Range(minDamage[(int)elementType] + convertedMinDamage[(int)elementType], maxDamage[(int)elementType] + convertedMaxDamage[(int)elementType] + 1);

            if (isCrit)
            {
                damage *= 1 + (Data.GetMultiStatBonus(tagsToUse, BonusType.GLOBAL_CRITICAL_DAMAGE).CalculateStat(50) / 100f);
            }

            returnDict.Add(elementType, damage);
        }

        return(returnDict);
    }