Beispiel #1
0
    public static void Attack(Fighter attacker, Fighter target, bool doAnimations)
    {
        IsBattling = true;

        int spd1 = StatsCalc.AttackSpeed(attacker.Unit.stats.speed, attacker.Weapon.weight, attacker.Unit.stats.constitution);
        int spd2 = StatsCalc.AttackSpeed(target.Unit.stats.speed, target.Weapon.weight, target.Unit.stats.constitution);

        bool repeated        = StatsCalc.RepeatedAttack(spd1, spd2);
        bool repeatedCounter = StatsCalc.RepeatedAttack(spd2, spd1);
        bool counter         = false;

        Cell[] counterArea = Map.GetExtendedArea(new Cell[1] {
            Map.UnitTile(target)
        }, target.Weapon.range, target.Weapon.rangedClosedSet, target.Weapon.closedSetMin);

        foreach (Cell c in counterArea)
        {
            if (c == Map.UnitTile(attacker))
            {
                counter = true;
                break;
            }
        }

        Offensive atk1 = new Offensive(attacker, target);
        Offensive cnt1 = null;

        Offensive atk2 = null;
        Offensive cnt2 = null;

        if (counter)
        {
            cnt1 = new Offensive(target, attacker)
            {
                IsCounter = true
            };
        }
        if (repeated)
        {
            atk2 = new Offensive(attacker, target, true);
        }
        if (repeatedCounter)
        {
            cnt2           = new Offensive(target, attacker, true);
            cnt1.IsCounter = true;
        }

        instance.StartCoroutine(DoAttacks(
                                    new Offensive[4]
        {
            atk1,
            cnt1,
            atk2,
            cnt2
        }
                                    ));
    }
Beispiel #2
0
        public Offensive(Fighter attacker, Fighter defender, bool repeated = false)
        {
            Attacker = attacker;
            Defender = defender;

            Seed = StatsCalc.Seed(new Vector2Int[2] {
                attacker.Position(), defender.Position()
            });
            Rand = new System.Random(Seed);

            IsPhysical = Attacker.Weapon.isPhysical;

            AtkStat = IsPhysical ? Attacker.Unit.stats.strength : Attacker.Unit.stats.magic;
            DefStat = IsPhysical ? Defender.Unit.stats.defense : Defender.Unit.stats.resistance;

            Cell = Map.UnitTile(Attacker);

            Support1 = StatsCalc.SupportBonus(Attacker);
            Support2 = StatsCalc.SupportBonus(Defender);

            TriangleBonus = StatsCalc.TriangleBonus(Attacker, Defender);
            TerrainBonus1 = StatsCalc.TerrainBonus(Map.UnitTile(Attacker));
            TerrainBonus2 = StatsCalc.TerrainBonus(Map.UnitTile(Defender));

            Speed1 = Attacker.Unit.stats.speed;
            Speed2 = Defender.Unit.stats.speed;

            Wgt1 = Attacker.Weapon.weight;
            Wgt2 = Defender.Weapon.weight;

            Con1 = Attacker.Unit.stats.constitution;
            Con2 = Defender.Unit.stats.constitution;

            Attack  = AtkStat;
            Defense = DefStat;

            Spd1 = StatsCalc.AttackSpeed(Speed1, Wgt1, Con1);
            Spd2 = StatsCalc.AttackSpeed(Speed2, Wgt2, Con2);

            Atk = StatsCalc.PhysicalAttack(Attack, Attacker.Weapon.might, TriangleBonus, StatsCalc.WeaponEffectiveness(Attacker.Weapon, Defender), Support1, false);
            Def = StatsCalc.PhysicalDefense(TerrainBonus2, Defense, Support2);

            HitRate = StatsCalc.HitRate(Attacker.Weapon.hit, Attacker.Unit.stats.skill, Attacker.Unit.stats.luck, Support1);
            Avoid   = StatsCalc.Avoid(Speed2, Defender.Unit.stats.luck, TerrainBonus2, Support2);
            Acc     = StatsCalc.Accuracy(HitRate, Avoid, TriangleBonus);

            CritRate   = StatsCalc.CriticalRate(Attacker.Weapon.crit, Attacker.Unit.stats.skill, Support1, StatsCalc.ClassCrit(Attacker.Unit.unitClass));
            CritEvade  = StatsCalc.CriticalEvade(Defender.Unit.stats.luck, Support2);
            CritChance = StatsCalc.CriticalChance(CritRate, CritEvade);

            if (StatsCalc.ClassCriticalModifier.ContainsKey(Attacker.Unit.unitClass))
            {
                CritChance += StatsCalc.ClassCriticalModifier[Attacker.Unit.unitClass];
            }

            if (repeated)
            {
                CritChance += Attacker.Unit.stats.pursuitCriticalCoefficient;
            }

            Hit  = Rand.Next(0, 100) <= Acc;
            Crit = Rand.Next(0, 100) <= CritChance;

            Damage = Crit ? StatsCalc.CriticalDamage(StatsCalc.Damage(Atk, Def)) : StatsCalc.Damage(Atk, Def);

            if (Attacker.LastTarget == Defender)
            {
                Attacker.RepeatedTarget++;
            }
            else
            {
                Attacker.LastTarget     = Defender;
                Attacker.RepeatedTarget = 0;
            }
        }