예제 #1
0
        public short GetCooldown(Character character)
        {
            short cooldown;

            if (character.Cooldowns.ContainsKey(SkillVNum))
            {
                cooldown = character.Cooldowns[SkillVNum];
            }
            else
            {
                cooldown = Cooldown;
            }

            cooldown += (short)((Cooldown / 100D) * character.GetBuff(BCardType.CardType.Morale, (byte)AdditionalTypes.Morale.SkillCooldownIncreased)[0]);
            cooldown += (short)((Cooldown / 100D) * character.GetBuff(BCardType.CardType.Casting, (byte)AdditionalTypes.Casting.EffectDurationIncreased)[0]);

            return(cooldown);
        }
예제 #2
0
        /// <summary>
        /// Generate the Monster -&gt; Character Damage
        /// </summary>
        /// <param name="targetCharacter"></param>
        /// <param name="skill"></param>
        /// <param name="hitmode"></param>
        /// <returns></returns>
        private int GenerateDamage(Character targetCharacter, Skill skill, ref int hitmode)
        {
            //Warning: This code contains a huge amount of copypasta!

            #region Definitions

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

            int  playerDefense        = targetCharacter.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.DefenceLevelDecreased, false)[0];
            byte playerDefenseUpgrade = (byte)targetCharacter.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.DefenceLevelIncreased, false)[0];
            int  playerDodge          = targetCharacter.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.DefenceLevelIncreased, false)[0];

            WearableInstance playerArmor = targetCharacter.Inventory.LoadBySlotAndType <WearableInstance>((byte)EquipmentType.Armor, InventoryType.Wear);
            if (playerArmor != null)
            {
                playerDefenseUpgrade += playerArmor.Upgrade;
            }

            short mainUpgrade    = Monster.AttackUpgrade;
            int   mainCritChance = Monster.CriticalChance;
            int   mainCritHit    = Monster.CriticalRate - 30;
            int   mainMinDmg     = Monster.DamageMinimum;
            int   mainMaxDmg     = Monster.DamageMaximum;
            int   mainHitRate    = Monster.Concentrate; //probably missnamed, check later
            if (mainMaxDmg == 0)
            {
                mainMinDmg     = Monster.Level * 8;
                mainMaxDmg     = Monster.Level * 12;
                mainCritChance = 10;
                mainCritHit    = 120;
                mainHitRate    = Monster.Level / 2 + 1;
            }

            #endregion

            #region Get Player defense

            int boostpercentage;
            switch (Monster.AttackClass)
            {
            case 0:
                playerDefense += targetCharacter.Defence
                                 + targetCharacter.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.MeleeDecreased, false)[0];
                playerDodge += targetCharacter.DefenceRate
                               + targetCharacter.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.RangedDecreased, false)[0];
                boostpercentage = targetCharacter.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.MeleeDecreased, false)[0];
                playerDefense   = (int)(playerDefense * (1 + boostpercentage / 100D));
                boostpercentage = targetCharacter.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.MagicalDecreased, false)[0];
                playerDodge     = (int)(playerDodge * (1 + boostpercentage / 100D));
                break;

            case 1:
                playerDefense += targetCharacter.DistanceDefence
                                 + targetCharacter.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.RangedIncreased, false)[0];
                playerDodge += targetCharacter.DistanceDefenceRate
                               + targetCharacter.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.RangedIncreased, false)[0];
                boostpercentage = targetCharacter.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.RangedIncreased, false)[0];
                playerDefense   = (int)(playerDefense * (1 + boostpercentage / 100D));
                boostpercentage = targetCharacter.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.RangedIncreased, false)[0];
                playerDodge     = (int)(playerDodge * (1 + boostpercentage / 100D));
                break;

            case 2:
                playerDefense += targetCharacter.MagicalDefence
                                 + targetCharacter.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.MagicalDecreased, false)[0];
                boostpercentage = targetCharacter.GetBuff(CardType.Defence, (byte)AdditionalTypes.Defence.MagicalDecreased, false)[0];
                playerDefense   = (int)(playerDefense * (1 + boostpercentage / 100D));
                break;

            default:
                throw new Exception($"Monster.AttackClass {Monster.AttackClass} not implemented");
            }

            #endregion

            #region Basic Damage Data Calculation

            mainCritChance += targetCharacter.GetBuff(CardType.Critical, (byte)AdditionalTypes.Critical.ReceivingIncreased, false)[0];
            mainCritChance -= targetCharacter.GetBuff(CardType.Critical, (byte)AdditionalTypes.Critical.ReceivingDecreased, false)[0];
            mainCritHit    += targetCharacter.GetBuff(CardType.Critical, (byte)AdditionalTypes.Critical.DamageFromCriticalIncreased, false)[0];
            mainCritHit    -= targetCharacter.GetBuff(CardType.Critical, (byte)AdditionalTypes.Critical.DamageFromCriticalDecreased, false)[0];
            mainUpgrade    -= playerDefenseUpgrade;
            if (mainUpgrade < -10)
            {
                mainUpgrade = -10;
            }
            else if (mainUpgrade > 10)
            {
                mainUpgrade = 10;
            }

            #endregion

            #region Detailed Calculation

            #region Dodge

            double multiplier = playerDodge / (double)mainHitRate;
            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 (Monster.AttackClass == 0 || Monster.AttackClass == 1)
            {
                if (ServerManager.Instance.RandomNumber() <= chance)
                {
                    hitmode = 1;
                    return(0);
                }
            }

            #endregion

            #region Base Damage

            int baseDamage = ServerManager.Instance.RandomNumber(mainMinDmg, mainMaxDmg + 1);
            baseDamage += Monster.Level - targetCharacter.Level;
            int elementalDamage = 0; // placeholder for BCard etc...

            if (skill != null)
            {
                // baseDamage += skill.Damage / 4;  it's a bcard need a skillbcardload
                // elementalDamage += skill.ElementalDamage / 4;  it's a bcard need a skillbcardload
            }

            switch (mainUpgrade)
            {
            case -10:
                playerDefense += playerDefense * 2;
                break;

            case -9:
                playerDefense += (int)(playerDefense * 1.2);
                break;

            case -8:
                playerDefense += (int)(playerDefense * 0.9);
                break;

            case -7:
                playerDefense += (int)(playerDefense * 0.65);
                break;

            case -6:
                playerDefense += (int)(playerDefense * 0.54);
                break;

            case -5:
                playerDefense += (int)(playerDefense * 0.43);
                break;

            case -4:
                playerDefense += (int)(playerDefense * 0.32);
                break;

            case -3:
                playerDefense += (int)(playerDefense * 0.22);
                break;

            case -2:
                playerDefense += (int)(playerDefense * 0.15);
                break;

            case -1:
                playerDefense += (int)(playerDefense * 0.1);
                break;

            case 0:
                break;

            case 1:
                baseDamage += (int)(baseDamage * 0.1);
                break;

            case 2:
                baseDamage += (int)(baseDamage * 0.15);
                break;

            case 3:
                baseDamage += (int)(baseDamage * 0.22);
                break;

            case 4:
                baseDamage += (int)(baseDamage * 0.32);
                break;

            case 5:
                baseDamage += (int)(baseDamage * 0.43);
                break;

            case 6:
                baseDamage += (int)(baseDamage * 0.54);
                break;

            case 7:
                baseDamage += (int)(baseDamage * 0.65);
                break;

            case 8:
                baseDamage += (int)(baseDamage * 0.9);
                break;

            case 9:
                baseDamage += (int)(baseDamage * 1.2);
                break;

            case 10:
                baseDamage += baseDamage * 2;
                break;

            // sush don't tell ciapa
            default:
                if (mainUpgrade > 10)
                {
                    baseDamage += baseDamage * (mainUpgrade / 5);
                }
                break;
            }

            #endregion

            #region Elementary Damage

            int bonusrez = targetCharacter.GetBuff(CardType.ElementResistance, (byte)AdditionalTypes.ElementResistance.AllIncreased, false)[0];

            #region Calculate Elemental Boost + Rate

            double elementalBoost    = 0;
            int    playerRessistance = 0;
            switch (Monster.Element)
            {
            case 0:
                break;

            case 1:
                bonusrez         += targetCharacter.GetBuff(CardType.ElementResistance, (byte)AdditionalTypes.ElementResistance.FireIncreased, false)[0];
                playerRessistance = targetCharacter.FireResistance;
                switch (targetCharacter.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         += targetCharacter.GetBuff(CardType.ElementResistance, (byte)AdditionalTypes.ElementResistance.WaterIncreased, false)[0];
                playerRessistance = targetCharacter.WaterResistance;
                switch (targetCharacter.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         += targetCharacter.GetBuff(CardType.ElementResistance, (byte)AdditionalTypes.ElementResistance.LightIncreased, false)[0];
                playerRessistance = targetCharacter.LightResistance;
                switch (targetCharacter.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         += targetCharacter.GetBuff(CardType.ElementResistance, (byte)AdditionalTypes.ElementResistance.DarkIncreased, false)[0];
                playerRessistance = targetCharacter.DarkResistance;
                switch (targetCharacter.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 (Monster.Element == 0)
            {
                if (elementalBoost == 0.5)
                {
                    elementalBoost = 0;
                }
                else if (elementalBoost == 1)
                {
                    elementalBoost = 0.05;
                }
                else if (elementalBoost == 1.3)
                {
                    elementalBoost = 0;
                }
                else if (elementalBoost == 1.5)
                {
                    elementalBoost = 0.15;
                }
                else if (elementalBoost == 2)
                {
                    elementalBoost = 0.2;
                }
                else if (elementalBoost == 3)
                {
                    elementalBoost = 0.2;
                }
            }
            elementalDamage = (int)((elementalDamage + (elementalDamage + baseDamage) * (Monster.ElementRate / 100D)) * elementalBoost);
            elementalDamage = elementalDamage / 100 * (100 - playerRessistance - bonusrez);
            if (elementalDamage < 0)
            {
                elementalDamage = 0;
            }

            #endregion

            #region Critical Damage

            if (ServerManager.Instance.RandomNumber() <= mainCritChance)
            {
                if (Monster.AttackClass == 2)
                {
                }
                else
                {
                    baseDamage += (int)(baseDamage * (mainCritHit / 100D));
                    hitmode     = 3;
                }
            }

            #endregion

            #region Total Damage

            int totalDamage = baseDamage + elementalDamage - playerDefense;
            if (totalDamage < 5)
            {
                totalDamage = ServerManager.Instance.RandomNumber(1, 6);
            }

            #endregion

            #endregion

            #region Minimum damage

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

            #endregion

            return(totalDamage);
        }
예제 #3
0
        public BattleEntity(Character character, Skill skill)
        {
            Session          = character.Session;
            HpMax            = character.HPMax;
            MpMax            = character.MPMax;
            Buffs            = character.Buff.GetAllItems();
            BCards           = character.EquipmentBCards.GetAllItems();
            Level            = character.Level;
            EntityType       = EntityType.Player;
            DamageMinimum    = character.MinHit;
            DamageMaximum    = character.MaxHit;
            Hitrate          = character.HitRate;
            CritChance       = character.HitCriticalRate;
            CritRate         = character.HitCritical;
            Morale           = character.Level;
            FireResistance   = character.FireResistance;
            WaterResistance  = character.WaterResistance;
            LightResistance  = character.LightResistance;
            ShadowResistance = character.DarkResistance;
            PositionX        = character.PositionX;
            PositionY        = character.PositionY;
            Invisible        = character.Invisible;

            ItemInstance weapon = null;

            if (skill != null)
            {
                switch (skill.Type)
                {
                case 0:
                    AttackType = AttackType.Melee;
                    if (character.Class == ClassType.Archer)
                    {
                        DamageMinimum = character.MinDistance;
                        DamageMaximum = character.MaxDistance;
                        Hitrate       = character.DistanceRate;
                        CritChance    = character.DistanceCriticalRate;
                        CritRate      = character.DistanceCritical;
                        weapon        = character.Inventory.LoadBySlotAndType((byte)EquipmentType.SecondaryWeapon, InventoryType.Wear);
                    }
                    else
                    {
                        weapon = character.Inventory.LoadBySlotAndType((byte)EquipmentType.MainWeapon, InventoryType.Wear);
                    }
                    break;

                case 1:
                    AttackType = AttackType.Range;
                    if (character.Class == ClassType.Adventurer || character.Class == ClassType.Swordman || character.Class == ClassType.Magician || character.Class == ClassType.Wreastler)
                    {
                        DamageMinimum = character.MinDistance;
                        DamageMaximum = character.MaxDistance;
                        Hitrate       = character.DistanceRate;
                        CritChance    = character.DistanceCriticalRate;
                        CritRate      = character.DistanceCritical;
                        weapon        = character.Inventory.LoadBySlotAndType((byte)EquipmentType.SecondaryWeapon, InventoryType.Wear);
                    }
                    else
                    {
                        weapon = character.Inventory.LoadBySlotAndType((byte)EquipmentType.MainWeapon, InventoryType.Wear);
                    }
                    break;

                case 2:
                    AttackType = AttackType.Magical;
                    weapon     = character.Inventory.LoadBySlotAndType((byte)EquipmentType.MainWeapon, InventoryType.Wear);
                    break;

                case 3:
                    weapon = character.Inventory.LoadBySlotAndType((byte)EquipmentType.MainWeapon, InventoryType.Wear);
                    switch (character.Class)
                    {
                    case ClassType.Adventurer:
                    case ClassType.Swordman:
                        AttackType = AttackType.Melee;
                        break;

                    case ClassType.Archer:
                        AttackType = AttackType.Range;
                        break;

                    case ClassType.Magician:
                        AttackType = AttackType.Magical;
                        break;

                    case ClassType.Wreastler:
                        AttackType = AttackType.Melee;
                        break;
                    }
                    break;

                case 5:
                    AttackType = AttackType.Melee;
                    switch (character.Class)
                    {
                    case ClassType.Adventurer:
                    case ClassType.Swordman:
                    case ClassType.Magician:
                    case ClassType.Wreastler:
                        weapon = character.Inventory.LoadBySlotAndType((byte)EquipmentType.MainWeapon, InventoryType.Wear);
                        break;

                    case ClassType.Archer:
                        weapon = character.Inventory.LoadBySlotAndType((byte)EquipmentType.SecondaryWeapon, InventoryType.Wear);
                        break;
                    }
                    break;
                }
            }
            else
            {
                weapon = character.Inventory.LoadBySlotAndType((byte)EquipmentType.SecondaryWeapon, InventoryType.Wear);
                switch (character.Class)
                {
                case ClassType.Adventurer:
                case ClassType.Swordman:
                    AttackType = AttackType.Melee;
                    break;

                case ClassType.Archer:
                    AttackType = AttackType.Range;
                    break;

                case ClassType.Magician:
                    AttackType = AttackType.Magical;
                    break;

                case ClassType.Wreastler:
                    AttackType = AttackType.Melee;
                    break;
                }
            }

            if (weapon != null)
            {
                AttackUpgrade       = weapon.Upgrade;
                WeaponDamageMinimum = weapon.DamageMinimum + weapon.Item.DamageMinimum;
                WeaponDamageMaximum = weapon.DamageMaximum + weapon.Item.DamageMinimum;

                ShellWeaponEffects = character.ShellEffectMain.ToList();
            }

            ItemInstance armor = character.Inventory.LoadBySlotAndType((byte)EquipmentType.Armor, InventoryType.Wear);

            if (armor != null)
            {
                DefenseUpgrade      = armor.Upgrade;
                ArmorMeleeDefense   = armor.CloseDefence + armor.Item.CloseDefence;
                ArmorRangeDefense   = armor.DistanceDefence + armor.Item.DistanceDefence;
                ArmorMagicalDefense = armor.MagicDefence + armor.Item.MagicDefence;

                ShellArmorEffects = character.ShellEffectArmor.ToList();
            }

            CellonOptions = Session.Character.CellonOptions.GetAllItems();

            MeleeDefense      = character.Defence - ArmorMeleeDefense;
            MeleeDefenseDodge = character.DefenceRate;
            RangeDefense      = character.DistanceDefence - ArmorRangeDefense;
            RangeDefenseDodge = character.DistanceDefenceRate;
            MagicalDefense    = character.MagicalDefence - ArmorMagicalDefense;
            Element           = character.Element;
            ElementRate       = character.ElementRate + character.ElementRateSP;

            RangeDefense += character.GetBuff(BCardType.CardType.DodgeAndDefencePercent, (byte)AdditionalTypes.DodgeAndDefencePercent.DodgingRangedIncreased)[0];
        }