//
// 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));
}
}