예제 #1
0
    public override bool ApplyInstant(FormationUnit performer, FormationUnit target, Effect effect)
    {
        if (target == null)
        {
            return(false);
        }

        float moveChance = effect.IntegerParams[EffectIntParams.Chance].HasValue ?
                           (float)effect.IntegerParams[EffectIntParams.Chance].Value / 100 : 1;

        moveChance -= target.Character.GetSingleAttribute(AttributeType.Move).ModifiedValue;
        if (performer != null && performer.Character is Hero)
        {
            moveChance += performer.Character.GetSingleAttribute(AttributeType.MoveChance).ModifiedValue;
        }

        moveChance = Mathf.Clamp(moveChance, 0, 0.95f);
        if (RandomSolver.CheckSuccess(moveChance))
        {
            target.Push(PushParam);
            return(true);
        }
        return(false);
    }
예제 #2
0
    public static void ExecuteSkill(FormationUnit performerUnit, FormationUnit targetUnit, CombatSkill skill, SkillArtInfo artInfo)
    {
        SkillResult.Skill   = skill;
        SkillResult.ArtInfo = artInfo;

        var target    = targetUnit.Character;
        var performer = performerUnit.Character;

        ApplyConditions(performerUnit, targetUnit, skill);

        if (skill.Move != null && !performerUnit.CombatInfo.IsImmobilized)
        {
            if (skill.Move.Pullforward > 0)
            {
                performerUnit.Pull(skill.Move.Pullforward, false);
            }
            else if (skill.Move.Pushback > 0)
            {
                performerUnit.Push(skill.Move.Pushback, false);
            }
        }

        if (skill.Category == SkillCategory.Heal || skill.Category == SkillCategory.Support)
        {
            #region Heal

            if (skill.Heal != null)
            {
                float initialHeal = RandomSolver.Next(skill.Heal.MinAmount, skill.Heal.MaxAmount + 1) *
                                    (1 + performer.GetSingleAttribute(AttributeType.HpHealPercent).ModifiedValue);

                if (skill.IsCritValid)
                {
                    float critChance = performer[AttributeType.CritChance].ModifiedValue + skill.CritMod / 100;
                    if (RandomSolver.CheckSuccess(critChance))
                    {
                        int critHeal = target.Heal(initialHeal * 1.5f, true);
                        targetUnit.OverlaySlot.UpdateOverlay();
                        SkillResult.AddResultEntry(new SkillResultEntry(targetUnit, critHeal, SkillResultType.CritHeal));

                        ApplyEffects(performerUnit, targetUnit, skill);
                        if (targetUnit.Character.IsMonster == false)
                        {
                            DarkestDungeonManager.Data.Effects["crit_heal_stress_heal"].ApplyIndependent(targetUnit);
                        }
                        return;
                    }
                }

                int heal = target.Heal(initialHeal, true);
                targetUnit.OverlaySlot.UpdateOverlay();

                SkillResult.AddResultEntry(new SkillResultEntry(targetUnit, heal, SkillResultType.Heal));
                ApplyEffects(performerUnit, targetUnit, skill);
            }
            else
            {
                SkillResult.AddResultEntry(new SkillResultEntry(targetUnit, SkillResultType.Utility));
                ApplyEffects(performerUnit, targetUnit, skill);
            }

            #endregion
        }
        else
        {
            #region Damage

            float accuracy  = skill.Accuracy + performer.Accuracy;
            float hitChance = Mathf.Clamp(accuracy - target.Dodge, 0, 0.95f);
            float roll      = (float)RandomSolver.NextDouble();
            if (target.BattleModifiers != null && target.BattleModifiers.CanBeHit == false)
            {
                roll = float.MaxValue;
            }

            if (roll > hitChance)
            {
                if (!(skill.CanMiss == false || (target.BattleModifiers != null && target.BattleModifiers.CanBeMissed == false)))
                {
                    if (roll > Mathf.Min(accuracy, 0.95f))
                    {
                        SkillResult.AddResultEntry(new SkillResultEntry(targetUnit, SkillResultType.Miss));
                    }
                    else
                    {
                        SkillResult.AddResultEntry(new SkillResultEntry(targetUnit, SkillResultType.Dodge));
                    }

                    ApplyEffects(performerUnit, targetUnit, skill);
                    return;
                }
            }

            float initialDamage = performer is Hero?
                                  Mathf.Lerp(performer.MinDamage, performer.MaxDamage, (float)RandomSolver.NextDouble()) * (1 + skill.DamageMod) :
                                  Mathf.Lerp(skill.DamageMin, skill.DamageMax, (float)RandomSolver.NextDouble()) * performer.DamageMod;

            int damage = Mathf.CeilToInt(initialDamage * (1 - target.Protection));
            if (damage < 0)
            {
                damage = 0;
            }

            if (target.BattleModifiers != null && target.BattleModifiers.CanBeDamagedDirectly == false)
            {
                damage = 0;
            }

            if (skill.IsCritValid)
            {
                float critChance = performer.GetSingleAttribute(AttributeType.CritChance).ModifiedValue + skill.CritMod;
                if (RandomSolver.CheckSuccess(critChance))
                {
                    int critDamage = target.TakeDamage(damage * 1.5f);
                    targetUnit.OverlaySlot.UpdateOverlay();

                    if (target.HasZeroHealth)
                    {
                        SkillResult.AddResultEntry(new SkillResultEntry(targetUnit, critDamage, true, SkillResultType.Crit));
                    }
                    else
                    {
                        SkillResult.AddResultEntry(new SkillResultEntry(targetUnit, critDamage, SkillResultType.Crit));
                    }

                    ApplyEffects(performerUnit, targetUnit, skill);
                    if (targetUnit.Character.IsMonster == false)
                    {
                        DarkestDungeonManager.Data.Effects["Stress 2"].ApplyIndependent(targetUnit);
                    }
                    return;
                }
            }
            damage = target.TakeDamage(damage);
            targetUnit.OverlaySlot.UpdateOverlay();
            if (target.HasZeroHealth)
            {
                SkillResult.AddResultEntry(new SkillResultEntry(targetUnit, damage, true, SkillResultType.Hit));
            }
            else
            {
                SkillResult.AddResultEntry(new SkillResultEntry(targetUnit, damage, SkillResultType.Hit));
            }

            ApplyEffects(performerUnit, targetUnit, skill);

            #endregion
        }
    }
예제 #3
0
    public override bool ApplyQueued(FormationUnit performer, FormationUnit target, Effect effect)
    {
        if (target == null)
        {
            return(false);
        }

        if (target.Party.Units.Count < 2)
        {
            return(false);
        }

        if (IsPartyShuffle)
        {
            foreach (var unit in target.Party.Units)
            {
                float moveChance = effect.IntegerParams[EffectIntParams.Chance].HasValue ?
                                   (float)effect.IntegerParams[EffectIntParams.Chance].Value / 100 : 1;

                moveChance -= unit.Character.GetSingleAttribute(AttributeType.Move).ModifiedValue;
                if (performer != null && performer.Character is Hero)
                {
                    moveChance += performer.Character.GetSingleAttribute(AttributeType.MoveChance).ModifiedValue;
                }

                moveChance = Mathf.Clamp(moveChance, 0, 0.95f);
                if (RandomSolver.CheckSuccess(moveChance))
                {
                    var shuffleTargets = unit.Party.Units.FindAll(shuffle => shuffle != unit);
                    var shuffleRoll    = shuffleTargets[RandomSolver.Next(shuffleTargets.Count)];

                    if (shuffleRoll.Rank < unit.Rank)
                    {
                        unit.Pull(unit.Rank - shuffleRoll.Rank);
                    }
                    else
                    {
                        unit.Push(shuffleRoll.Rank - unit.Rank);
                    }
                    return(true);
                }
            }
            return(true);
        }
        else
        {
            float moveChance = effect.IntegerParams[EffectIntParams.Chance].HasValue ?
                               (float)effect.IntegerParams[EffectIntParams.Chance].Value / 100 : 1;

            moveChance -= target.Character.GetSingleAttribute(AttributeType.Move).ModifiedValue;
            if (performer != null && performer.Character is Hero)
            {
                moveChance += performer.Character.GetSingleAttribute(AttributeType.MoveChance).ModifiedValue;
            }

            moveChance = Mathf.Clamp(moveChance, 0, 0.95f);
            if (RandomSolver.CheckSuccess(moveChance))
            {
                var shuffleTargets = target.Party.Units.FindAll(unit => unit != target);
                var shuffleRoll    = shuffleTargets[RandomSolver.Next(shuffleTargets.Count)];

                if (shuffleRoll.Rank < target.Rank)
                {
                    target.Pull(target.Rank - shuffleRoll.Rank);
                }
                else
                {
                    target.Push(shuffleRoll.Rank - target.Rank);
                }
                return(true);
            }
            RaidSceneManager.RaidEvents.ShowPopupMessage(target, PopupMessageType.MoveResist);
            return(false);
        }
    }