// // Licensed under the MIT License. See LICENSE file in the project root for full license information. // namespace MUnique.OpenMU.Tests; using Moq; using MUnique.OpenMU.DataModel.Configuration.Items; using MUnique.OpenMU.DataModel.Entities; using MUnique.OpenMU.GameLogic; using MUnique.OpenMU.GameLogic.Attributes; /// /// Tests the with some exemplary data. /// /// /// The most price values here are directly taken from stores on GMO. /// However, I guess they are calculated and shown by the client, if you just show such an item in the merchant store. /// [TestFixture] public class ItemPriceCalculatorTest { /// /// The calculator which is tested. /// private readonly ItemPriceCalculator _calculator = new(); /// /// Tests if the apple price is calculated correctly. /// /// The level. /// The price. [TestCase(0, 20)] [TestCase(1, 40)] public void Apple(byte level, int price) { this.CheckPrice(0, 1, 1, 1, 1, 14, 5, level, price); } /// /// Tests if the small heal potion price is calculated correctly. /// /// The level. /// The price. [TestCase(0, 80)] [TestCase(1, 160)] public void SmallHealPotion(byte level, int price) { this.CheckPrice(1, 40, 1, 1, 1, 14, 10, level, price); } /// /// Tests if the heal potion price is calculated correctly. /// /// The level. /// The price. [TestCase(0, 330)] [TestCase(1, 660)] public void HealPotion(byte level, int price) { this.CheckPrice(2, 40, 1, 1, 1, 14, 20, level, price); } /// /// Tests if the large heal potion price is calculated correctly. /// /// The level. /// The price. [TestCase(0, 1500)] [TestCase(1, 3000)] public void LargeHealPotion(byte level, int price) { this.CheckPrice(3, 40, 1, 1, 1, 14, 30, level, price); } /// /// Tests if the small shield potion price is calculated correctly. /// [Test] public void SmallShieldPotion() { this.CheckPrice(35, 40, 1, 1, 1, 14, 50, 0, 2000); } /// /// Tests if the shield potion price is calculated correctly. /// [Test] public void ShieldPotion() { this.CheckPrice(36, 40, 1, 1, 1, 14, 80, 0, 4000); } /// /// Tests if the shield potion price is calculated correctly. /// [Test] public void LargeShieldPotion() { this.CheckPrice(37, 40, 1, 1, 1, 14, 100, 0, 6000); } /// /// Tests if the bolt price is calculated correctly. /// /// The level. /// The price. [TestCase(0, 100)] [TestCase(1, 1400)] [TestCase(2, 2200)] public void Bolts(byte level, int price) { this.CheckPrice(7, 0, 255, 1, 1, 4, 0, level, price); } /// /// Tests if the arrow price is calculated correctly. /// /// The level. /// The price. [TestCase(0, 70)] [TestCase(1, 1200)] [TestCase(2, 2000)] public void Arrows(byte level, int price) { this.CheckPrice(15, 0, 255, 1, 1, 4, 0, level, price); } /// /// Tests if the price of the fireball scroll is calculated as 300. /// [Test] public void FireballScroll() { this.CheckPrice(3, 0, 1, 1, 1, 15, 300, 0, 300); } /// /// Tests if the price of the powerwave scroll is calculated as 1100. /// [Test] public void PowerwaveScroll() { this.CheckPrice(10, 0, 1, 1, 1, 15, 1100, 0, 1100); } /// /// Tests if the price of the lightning scroll is calculated as 3000. /// [Test] public void LightningScroll() { this.CheckPrice(2, 0, 1, 1, 1, 15, 3000, 0, 3000); } /// /// Tests if the price of the meteorite scroll is calculated as 11000. /// [Test] public void MeteoriteScroll() { this.CheckPrice(1, 0, 1, 1, 1, 15, 11000, 0, 11000); } /// /// Tests if the price of the teleport scroll is calculated as 5000. /// [Test] public void TeleportScroll() { this.CheckPrice(5, 0, 1, 1, 1, 15, 5000, 0, 5000); } /// /// Tests if the price of the ice scroll is calculated as 14000. /// [Test] public void IceScroll() { this.CheckPrice(6, 0, 1, 1, 1, 15, 14000, 0, 14000); } /// /// Tests if the price of the poison scroll is calculated as 17000. /// [Test] public void PoisonScroll() { this.CheckPrice(0, 0, 1, 1, 1, 15, 17000, 0, 17000); } /// /// Tests if the items of a pad set +0+4+Luck is calculated correctly. /// /// The group. /// The drop level. /// The maximum durability. /// The price. /// /// pad helm+0+4+l 480 /// armor 1400 /// pants 960 /// gloves 290 /// boots 370. /// [TestCase(7, 5, 28, 480, Description = "Pad Helm")] [TestCase(8, 10, 28, 1400, Description = "Pad Armor")] [TestCase(9, 8, 28, 960, Description = "Pad Pants")] [TestCase(10, 3, 28, 290, Description = "Pad Gloves")] [TestCase(11, 4, 28, 370, Description = "Pad Boots")] public void PadSetItem_0_4_Luck(byte group, byte dropLevel, byte maxDurability, long price) { this.CheckPrice(2, dropLevel, maxDurability, 2, 2, group, 0, 0, price, true, true); } /// /// Tests if the items of a bone set +2+4+Luck is calculated correctly. /// /// The group. /// The drop level. /// The maximum durability. /// The price. /// /// bone helm+2+4+l 9400 /// armor 13500 /// pants 11300 /// gloves 6200 /// boots 7700. /// [TestCase(7, 18, 30, 9400, Description = "Bone Helm")] [TestCase(8, 22, 30, 13500, Description = "Bone Armor")] [TestCase(9, 20, 30, 11300, Description = "Bone Pants")] [TestCase(10, 14, 30, 6200, Description = "Bone Gloves")] [TestCase(11, 16, 30, 7700, Description = "Bone Boots")] public void BoneSetItem_2_4_Luck(byte group, byte dropLevel, byte maxDurability, long price) { this.CheckPrice(4, dropLevel, maxDurability, 2, 2, group, 0, 2, price, true, true); } /// /// Tests if the items of a sphinx set +3+4+Luck is calculated correctly. /// /// The group. /// The drop level. /// The maximum durability. /// The price. /// /// sphinx helm+3+4+l 34200 /// armor 48200 /// pants 38500 /// gloves 26500 /// boots 30200. /// [TestCase(7, 32, 36, 34200, Description = "Sphinx Mask")] [TestCase(8, 38, 36, 48200, Description = "Sphinx Armor")] [TestCase(9, 34, 36, 38500, Description = "Sphinx Pants")] [TestCase(10, 28, 36, 26500, Description = "Sphinx Gloves")] [TestCase(11, 30, 36, 30200, Description = "Sphinx Boots")] public void SphinxSetItem_3_4_Luck(byte group, byte dropLevel, byte maxDurability, long price) { this.CheckPrice(7, dropLevel, maxDurability, 2, 2, group, 0, 3, price, true, true); } /// /// Tests the price calculations of some staffs. /// /// The identifier. /// The level. /// The drop level. /// The maximum durability. /// The width. /// The heigth. /// The price. /// /// skull+0+4+l 480 /// angelic+2+4+l 9400 /// serpent+3+4+l 30200 /// thunder+3+4+l 59300. /// [TestCase(0, 0, 6, 20, 1, 3, 480, Description = "skull+0+4+l")] [TestCase(1, 2, 18, 38, 2, 3, 9400, Description = "angelic+2+4+l")] [TestCase(2, 3, 30, 50, 2, 3, 30200, Description = "serpent+3+4+l")] [TestCase(3, 3, 42, 60, 2, 4, 59300, Description = "thunder+3+4+l")] public void Staffs(byte id, byte level, byte dropLevel, byte maxDurability, byte width, byte heigth, long price) { this.CheckPrice(id, dropLevel, maxDurability, heigth, width, 5, 0, level, price, true, true); } /// /// Tests the price calculations of some shields. /// /// The identifier. /// The level. /// The drop level. /// The maximum durability. /// The width. /// The heigth. /// if set to true [skill]. /// The price. /// /// small shield+0+5+l 230 /// buckler+1+5+s+l 2300 /// horn+2+5+l 2600 /// kite+3+5+l 5500 /// skull+3+5+s+l 18800. /// [TestCase(0, 0, 3, 22, 2, 2, false, 230, Description = "small shield+0+5+l")] [TestCase(4, 1, 6, 24, 2, 2, true, 2300, Description = "buckler+1+5+s+l")] [TestCase(1, 2, 9, 28, 2, 2, false, 2600, Description = "horn+2+5+l")] [TestCase(2, 3, 12, 32, 2, 2, false, 5500, Description = "kite+3+5+l")] [TestCase(6, 3, 15, 34, 2, 2, true, 18800, Description = "skull+3+5+s+l")] public void Shields(byte id, byte level, byte dropLevel, byte maxDurability, byte width, byte heigth, bool skill, long price) { this.CheckPrice(id, dropLevel, maxDurability, heigth, width, 6, 0, level, price, true, true, skill); } /// /// Tests the price calculation of a small shield. /// /// The level. /// The price. [TestCase(0, 110)] [TestCase(1, 240)] [TestCase(2, 470)] [TestCase(3, 820)] [TestCase(4, 1300)] [TestCase(5, 3000)] [TestCase(6, 6900)] [TestCase(7, 21400)] [TestCase(8, 58100)] [TestCase(9, 121900)] [TestCase(10, 275300)] [TestCase(11, 617000)] [TestCase(12, 1324700)] [TestCase(13, 2693500)] [TestCase(14, 4777500)] [TestCase(15, 7726800)] public void SmallShield(byte level, long price) { this.CheckPrice(0, 3, 22, 2, 2, 6, 0, level, price); } /// /// Tests the price calculations of some swords. /// /// The identifier. /// The level. /// The drop level. /// The maximum durability. /// The width. /// The heigth. /// if set to true [skill]. /// The price. /// /// short sword+0+4+l 230 /// hand axe+1+4+l 610 /// kris+2+4+l 1600 /// mace+2+4+l 1900 /// rapier+2+4+l 2600 /// double+2+4+s+l 12400 /// blade+3+4+s+l 86400. /// [TestCase(1, 0, 3, 22, 1, 2, false, 230, Description = "short sword+0+4+l")] [TestCase(0, 2, 6, 20, 1, 2, false, 1600, Description = "kris+2+4+l")] [TestCase(2, 2, 9, 23, 1, 3, false, 2600, Description = "rapier+2+4+l")] [TestCase(5, 3, 36, 39, 1, 3, true, 86400, Description = "blade+3+4+s+l")] public void Swords(byte id, byte level, byte dropLevel, byte maxDurability, byte width, byte heigth, bool skill, long price) { this.CheckPrice(id, dropLevel, maxDurability, heigth, width, 0, 0, level, price, true, true, skill); } private void CheckPrice(byte id, byte dropLevel, byte maxDurability, byte height, byte width, byte group, int value, byte level, long price, bool luck = false, bool option = false, bool skill = false) { var itemDefinitionMock = new Mock(); itemDefinitionMock.SetupAllProperties(); itemDefinitionMock.Setup(d => d.BasePowerUpAttributes).Returns(new List()); var itemDefinition = itemDefinitionMock.Object; itemDefinition.DropLevel = dropLevel; itemDefinition.Durability = maxDurability; itemDefinition.Height = height; itemDefinition.Width = width; itemDefinition.Group = group; itemDefinition.Value = value; itemDefinition.Number = id; if (group <= 11) { itemDefinition.ItemSlot = new ItemSlotType(); } if (group < 6) { // weapons should have an attack speed attribute itemDefinition.BasePowerUpAttributes.Add(new ItemBasePowerUpDefinition { TargetAttribute = Stats.AttackSpeedByWeapon }); } var itemMock = new Mock(); itemMock.SetupAllProperties(); itemMock.Setup(i => i.ItemOptions).Returns(new List()); itemMock.Setup(i => i.ItemSetGroups).Returns(new List()); var item = itemMock.Object; item.Definition = itemDefinition; item.Level = level; item.Durability = Math.Max(item.GetMaximumDurabilityOfOnePiece(), maxDurability); if (luck) { var optionLink = new ItemOptionLink { ItemOption = new IncreasableItemOption { OptionType = ItemOptionTypes.Luck, }, }; item.ItemOptions.Add(optionLink); } if (option) { var optionLink = new ItemOptionLink { ItemOption = new IncreasableItemOption { OptionType = ItemOptionTypes.Option, }, Level = 1, }; item.ItemOptions.Add(optionLink); } if (skill) { item.HasSkill = true; } var buyingPrice = this._calculator.CalculateFinalBuyingPrice(item); Assert.That(buyingPrice, Is.EqualTo(price)); } }