public ushort GenerateDamage(IBattleEntity targetEntity, Skill skill, ref int hitmode, ref bool onyxEffect)
        {
            BattleEntity target = targetEntity?.BattleEntity;

            if (target == null)
            {
                return(0);
            }

            #region Definitions

            // Percent Damage
            if (target.Session is MapMonster monster && monster.IsPercentage && monster.TakesDamage > 0)
            {
                return((ushort)monster.TakesDamage);
            }

            AttackType attackType = Entity.GetAttackType(skill);

            int   morale     = Level + GetBuff(CardType.Morale, (byte)AdditionalTypes.Morale.MoraleIncreased)[0] - GetBuff(CardType.Morale, (byte)AdditionalTypes.Morale.MoraleDecreased)[0];
            short upgrade    = AttackUpgrade;
            int   critChance = Critical;
            int   critHit    = CriticalRate;
            int   minDmg     = MinDamage;
            int   maxDmg     = MaxDamage;
            int   hitRate    = HitRate;

            #endregion

            #region Get Weapon Stats

            if (Session is Character character)
            {
                if (skill == null)
                {
                    return(0);
                }
                if (skill.SkillVNum == 1085) // pas de bcard ...
                {
                    character.TeleportOnMap(targetEntity.GetPos().X, targetEntity.GetPos().Y);
                }
                if (character.Inventory.LoadBySlotAndType <WearableInstance>((byte)EquipmentType.Amulet, InventoryType.Equipment)?.Item?.Effect == 932)
                {
                    upgrade += 1;
                }
                DefenceUpgrade = character.Inventory?.Armor?.Upgrade ?? 0;

                if (CharacterHelper.Instance.GetClassAttackType(character.Class) == attackType)
                {
                    minDmg     += character.MinHit;
                    maxDmg     += character.MaxHit;
                    hitRate    += character.HitRate;
                    critChance += character.HitCriticalRate;
                    critHit    += character.HitCritical;
                    upgrade    += character.Inventory.PrimaryWeapon?.Upgrade ?? 0;
                }
                else
                {
                    minDmg     += character.MinDistance;
                    maxDmg     += character.MaxDistance;
                    hitRate    += character.DistanceRate;
                    critChance += character.DistanceCriticalRate;
                    critHit    += character.DistanceCritical;
                    upgrade    += character.Inventory.SecondaryWeapon?.Upgrade ?? 0;
                }
            }

            #endregion

            skill?.BCards?.ToList().ForEach(s => SkillBcards.Add(s));
            #region Switch skill.Type

            int targetDefence = target.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.AllIncreased)[0]
                                - target.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.AllDecreased)[0];

            byte targetDefenseUpgrade = (byte)(target.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.DefenceLevelIncreased)[0]
                                               - target.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.DefenceLevelDecreased)[0]);

            int targetDodge = target.GetBuff(CardType.DodgeAndDefencePercent, (byte)AdditionalTypes.DodgeAndDefencePercent.DodgeIncreased)[0]
                              - target.GetBuff(CardType.DodgeAndDefencePercent, (byte)AdditionalTypes.DodgeAndDefencePercent.DodgeDecreased)[0];

            int targetMorale = target.Level + target.GetBuff(CardType.Morale, (byte)AdditionalTypes.Morale.MoraleIncreased)[0]
                               - target.GetBuff(CardType.Morale, (byte)AdditionalTypes.Morale.MoraleDecreased)[0];

            int targetBoostpercentage = 0;

            int boost = GetBuff(CardType.AttackPower, (byte)AdditionalTypes.AttackPower.AllAttacksIncreased)[0]
                        - GetBuff(CardType.AttackPower, (byte)AdditionalTypes.AttackPower.AllAttacksDecreased)[0];

            int boostpercentage = GetBuff(CardType.Damage, (byte)AdditionalTypes.Damage.DamageIncreased)[0]
                                  - GetBuff(CardType.Damage, (byte)AdditionalTypes.Damage.DamageDecreased)[0];

            switch (attackType)
            {
            case AttackType.Close:
                targetDefence        += target.CloseDefence;
                targetDodge          += target.DefenceRate;
                targetBoostpercentage = target.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.MeleeIncreased)[0]
                                        - target.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.MeleeDecreased)[0];
                boost += GetBuff(CardType.AttackPower, (byte)AdditionalTypes.AttackPower.MeleeAttacksIncreased)[0]
                         - GetBuff(CardType.AttackPower, (byte)AdditionalTypes.AttackPower.MeleeAttacksDecreased)[0];
                boostpercentage += GetBuff(CardType.Damage, (byte)AdditionalTypes.Damage.MeleeIncreased)[0]
                                   - GetBuff(CardType.Damage, (byte)AdditionalTypes.Damage.MeleeDecreased)[0];
                break;

            case AttackType.Ranged:
                targetDefence        += target.RangedDefence;
                targetDodge          += target.DistanceDefenceRate;
                targetBoostpercentage = target.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.RangedIncreased)[0]
                                        - target.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.RangedDecreased)[0];
                boost += GetBuff(CardType.AttackPower, (byte)AdditionalTypes.AttackPower.RangedAttacksIncreased)[0]
                         - GetBuff(CardType.AttackPower, (byte)AdditionalTypes.AttackPower.RangedAttacksDecreased)[0];
                boostpercentage += GetBuff(CardType.Damage, (byte)AdditionalTypes.Damage.RangedIncreased)[0]
                                   - GetBuff(CardType.Damage, (byte)AdditionalTypes.Damage.RangedDecreased)[0];
                break;

            case AttackType.Magical:
                targetDefence        += target.MagicDefence;
                targetBoostpercentage = target.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.MagicalIncreased)[0]
                                        - target.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.MeleeDecreased)[0];
                boost += GetBuff(CardType.AttackPower, (byte)AdditionalTypes.AttackPower.MagicalAttacksIncreased)[0]
                         - GetBuff(CardType.AttackPower, (byte)AdditionalTypes.AttackPower.MagicalAttacksDecreased)[0];
                boostpercentage += GetBuff(CardType.Damage, (byte)AdditionalTypes.Damage.MagicalIncreased)[0]
                                   - GetBuff(CardType.Damage, (byte)AdditionalTypes.Damage.MagicalDecreased)[0];
                break;
            }
            targetDefence = (int)(targetDefence * (1 + targetBoostpercentage / 100D));
            minDmg       += boost;
            maxDmg       += boost;
            minDmg        = (int)(minDmg * (1 + boostpercentage / 100D));
            maxDmg        = (int)(maxDmg * (1 + boostpercentage / 100D));

            #endregion

            upgrade -= (short)(target.DefenceUpgrade + targetDefenseUpgrade);

            #region Detailed Calculation

            #region Dodge

            if (attackType != AttackType.Magical)
            {
                double multiplier = targetDodge / (hitRate + 1);
                if (multiplier > 5)
                {
                    multiplier = 5;
                }
                double chance = -0.25 * Math.Pow(multiplier, 3) - 0.57 * Math.Pow(multiplier, 2) + 25.3 * multiplier - 1.41;
                if (chance <= 1)
                {
                    chance = 1;
                }
                if (GetBuff(CardType.DodgeAndDefencePercent, (byte)AdditionalTypes.DodgeAndDefencePercent.DodgeIncreased)[0] != 0)
                {
                    chance = 10;
                }
                if (skill?.Type == 0 || skill?.Type == 1)
                {
                    if (ServerManager.Instance.RandomNumber() <= chance)
                    {
                        hitmode = 1;
                        SkillBcards.Clear();
                        return(0);
                    }
                }
            }

            #endregion

            #region Base Damage

            int baseDamage = ServerManager.Instance.RandomNumber(minDmg, maxDmg < minDmg ? minDmg + 1 : maxDmg) + morale - targetMorale;

            double upgradeBonus = 0;
            switch (Math.Abs(upgrade))
            {
            case 1:
                upgradeBonus = 0.1;
                break;

            case 2:
                upgradeBonus = 0.15;
                break;

            case 3:
                upgradeBonus = 0.22;
                break;

            case 4:
                upgradeBonus = 0.32;
                break;

            case 5:
                upgradeBonus = 0.43;
                break;

            case 6:
                upgradeBonus = 0.54;
                break;

            case 7:
                upgradeBonus = 0.65;
                break;

            case 8:
                upgradeBonus = 0.9;
                break;

            case 9:
                upgradeBonus = 1.2;
                break;

            case 10:
                upgradeBonus = 2;
                break;
            }
            if (upgrade < 0)
            {
                targetDefence += (int)(targetDefence * upgradeBonus);
            }
            else
            {
                baseDamage += (int)(baseDamage * upgradeBonus);
            }

            baseDamage -= target.HasBuff(CardType.SpecialDefence, (byte)AdditionalTypes.SpecialDefence.AllDefenceNullified) ? 0 : targetDefence;

            if (skill?.Type == 1 && Map.Map.GetDistance(Entity.GetPos(), targetEntity.GetPos()) < 4)
            {
                baseDamage = (int)(baseDamage * 0.85);
            }

            #endregion

            #region Elementary Damage

            #region Calculate Elemental Boost + Rate

            double elementalBoost   = 0;
            int    targetResistance = 0;
            int    elementalDamage  = GetBuff(CardType.Element, (byte)AdditionalTypes.Element.AllIncreased)[0] - GetBuff(CardType.Element, (byte)AdditionalTypes.Element.AllDecreased)[0];
            int    bonusrez         = target.GetBuff(CardType.ElementResistance, (byte)AdditionalTypes.ElementResistance.AllIncreased)[0] - target.GetBuff(CardType.ElementResistance, (byte)AdditionalTypes.ElementResistance.AllDecreased)[0];

            switch (Element)
            {
            case 1:
                bonusrez += target.GetBuff(CardType.ElementResistance, (byte)AdditionalTypes.ElementResistance.FireIncreased)[0]
                            - target.GetBuff(CardType.ElementResistance, (byte)AdditionalTypes.ElementResistance.FireDecreased)[0];
                elementalDamage += GetBuff(CardType.Element, (byte)AdditionalTypes.Element.FireIncreased)[0]
                                   - GetBuff(CardType.Element, (byte)AdditionalTypes.Element.FireDecreased)[0];
                targetResistance = target.FireResistance;
                switch (target.Element)
                {
                case 0:
                    elementalBoost = 1.3;         // Damage vs no element
                    break;

                case 1:
                    elementalBoost = 1;         // Damage vs fire
                    break;

                case 2:
                    elementalBoost = 2;         // Damage vs water
                    break;

                case 3:
                    elementalBoost = 1;         // Damage vs light
                    break;

                case 4:
                    elementalBoost = 1.5;         // Damage vs darkness
                    break;
                }
                break;

            case 2:
                bonusrez += target.GetBuff(CardType.ElementResistance, (byte)AdditionalTypes.ElementResistance.WaterIncreased)[0]
                            - target.GetBuff(CardType.ElementResistance, (byte)AdditionalTypes.ElementResistance.WaterDecreased)[0];
                elementalDamage += GetBuff(CardType.Element, (byte)AdditionalTypes.Element.WaterIncreased)[0]
                                   - GetBuff(CardType.Element, (byte)AdditionalTypes.Element.WaterDecreased)[0];
                targetResistance = target.WaterResistance;
                switch (target.Element)
                {
                case 0:
                    elementalBoost = 1.3;
                    break;

                case 1:
                    elementalBoost = 2;
                    break;

                case 2:
                    elementalBoost = 1;
                    break;

                case 3:
                    elementalBoost = 1.5;
                    break;

                case 4:
                    elementalBoost = 1;
                    break;
                }
                break;

            case 3:
                bonusrez += target.GetBuff(CardType.ElementResistance, (byte)AdditionalTypes.ElementResistance.LightIncreased)[0]
                            - target.GetBuff(CardType.ElementResistance, (byte)AdditionalTypes.ElementResistance.LightDecreased)[0];
                elementalDamage += GetBuff(CardType.Element, (byte)AdditionalTypes.Element.LightIncreased)[0]
                                   - GetBuff(CardType.Element, (byte)AdditionalTypes.Element.LightDecreased)[0];
                targetResistance = target.LightResistance;
                switch (target.Element)
                {
                case 0:
                    elementalBoost = 1.3;
                    break;

                case 1:
                    elementalBoost = 1.5;
                    break;

                case 2:
                    elementalBoost = 1;
                    break;

                case 3:
                    elementalBoost = 1;
                    break;

                case 4:
                    elementalBoost = 3;
                    break;
                }
                break;

            case 4:
                bonusrez += target.GetBuff(CardType.ElementResistance, (byte)AdditionalTypes.ElementResistance.DarkIncreased)[0]
                            - target.GetBuff(CardType.ElementResistance, (byte)AdditionalTypes.ElementResistance.DarkDecreased)[0];
                targetResistance = target.DarkResistance;
                elementalDamage += GetBuff(CardType.Element, (byte)AdditionalTypes.Element.DarkIncreased)[0]
                                   - GetBuff(CardType.Element, (byte)AdditionalTypes.Element.DarkDecreased)[0];
                switch (target.Element)
                {
                case 0:
                    elementalBoost = 1.3;
                    break;

                case 1:
                    elementalBoost = 1;
                    break;

                case 2:
                    elementalBoost = 1.5;
                    break;

                case 3:
                    elementalBoost = 3;
                    break;

                case 4:
                    elementalBoost = 1;
                    break;
                }
                break;
            }

            #endregion ;

            if (skill?.Element == 0)
            {
                switch (elementalBoost)
                {
                case 0.5:
                    elementalBoost = 0;
                    break;

                case 1:
                    elementalBoost = 0.05;
                    break;

                case 1.3:
                case 1.5:
                    elementalBoost = 0.15;
                    break;

                case 2:
                case 3:
                    elementalBoost = 0.2;
                    break;
                }
            }
            else if (skill?.Element != Element)
            {
                elementalBoost = 0;
            }
            int resistance = targetResistance + bonusrez;
            elementalDamage = (int)(elementalDamage + (baseDamage + 100) * ((ElementRate + ElementRateSp) / 100D));
            elementalDamage = (int)(elementalDamage / 100D * (100 - (resistance > 100 ? 100 : resistance)) * elementalBoost);

            #endregion

            #region Critical Damage

            critChance += GetBuff(CardType.Critical, (byte)AdditionalTypes.Critical.InflictingIncreased)[0]
                          - GetBuff(CardType.Critical, (byte)AdditionalTypes.Critical.InflictingReduced)[0];

            critHit += GetBuff(CardType.Critical, (byte)AdditionalTypes.Critical.DamageIncreased)[0]
                       - GetBuff(CardType.Critical, (byte)AdditionalTypes.Critical.DamageIncreasedInflictingReduced)[0];

            if (ServerManager.Instance.RandomNumber() <= critChance)
            {
                if (skill?.Type != 2 && attackType != AttackType.Magical)
                {
                    double multiplier = critHit / 100D;
                    multiplier  = multiplier > 3 ? 3 : multiplier;
                    baseDamage += (int)(baseDamage * multiplier);
                    hitmode     = 3;
                }
            }


            #endregion

            // OFFENSIVE POTION
            baseDamage += (int)(baseDamage * GetBuff(CardType.Item, (byte)AdditionalTypes.Item.AttackIncreased)[0] / 100D);

            if (Session is Character charact)
            {
                int[] weaponSoftDamage = charact.GetWeaponSoftDamage();
                if (ServerManager.Instance.RandomNumber() < weaponSoftDamage[0])
                {
                    charact.MapInstance.Broadcast(charact.GenerateEff(15));
                    baseDamage += (int)(baseDamage * (1 + (weaponSoftDamage[1] / 100D)));
                }

                if (charact.HasBuff(CardType.IncreaseDamage, (byte)AdditionalTypes.IncreaseDamage.IncreasingPropability, true))
                {
                    charact.MapInstance.Broadcast(charact.GenerateEff(15));
                    baseDamage += (int)(baseDamage * (1 + GetBuff(CardType.IncreaseDamage,
                                                                  (byte)AdditionalTypes.IncreaseDamage
                                                                  .IncreasingPropability)[0] / 100D));
                }

                if (charact.ChargeValue > 0)
                {
                    baseDamage         += charact.ChargeValue;
                    charact.ChargeValue = 0;
                    charact.RemoveBuff(0);
                }
                baseDamage += charact.Class == ClassType.Adventurer ? 20 : 0;
            }

            #region Total Damage

            int totalDamage = baseDamage + elementalDamage;
            totalDamage = totalDamage < 5 ? ServerManager.Instance.RandomNumber(1, 6) : totalDamage;

            #endregion

            if (Session is MapMonster)
            {
                if (Level < 45)
                {
                    //no minimum damage
                }
                else if (Level < 55)
                {
                    totalDamage += Level;
                }
                else if (Level < 60)
                {
                    totalDamage += Level * 2;
                }
                else if (Level < 65)
                {
                    totalDamage += Level * 3;
                }
                else if (Level < 70)
                {
                    totalDamage += Level * 4;
                }
                else
                {
                    totalDamage += Level * 5;
                }
            }

            if (targetEntity.GetSession() is Character chara && target.HasBuff(CardType.NoDefeatAndNoDamage, (byte)AdditionalTypes.NoDefeatAndNoDamage.TransferAttackPower))
            {
                chara.ChargeValue = totalDamage;
                chara.AddBuff(new Buff.Buff(0));
                totalDamage = 0;
                hitmode     = 1;
            }

            #endregion

            totalDamage = totalDamage > ushort.MaxValue ? ushort.MaxValue : totalDamage;

            #region Onyx Wings

            onyxEffect = GetBuff(CardType.StealBuff, (byte)AdditionalTypes.StealBuff.ChanceSummonOnyxDragon)[0] > ServerManager.Instance.RandomNumber();

            #endregion

            SkillBcards.Clear();
            totalDamage = totalDamage > ushort.MaxValue ? ushort.MaxValue : totalDamage;
            if (Session is Character charac && targetEntity is MapMonster cali && cali.MonsterVNum == 2305 && Caligor.IsRunning)
            {
                switch (charac.Faction)
                {
                case FactionType.Angel:
                    Caligor.AngelDamage += totalDamage + (onyxEffect ? totalDamage / 2 : 0);
                    break;

                case FactionType.Demon:
                    Caligor.DemonDamage += totalDamage + (onyxEffect ? totalDamage / 2 : 0);
                    break;
                }
            }
            return((ushort)totalDamage);
        }
Esempio n. 2
0
 public Buff(int v, Battle.BattleEntity entity)
 {
 }