diff --git a/Maple2.File.Parser/Maple2.File.Parser.csproj b/Maple2.File.Parser/Maple2.File.Parser.csproj index 985a1a1..2a37cf9 100644 --- a/Maple2.File.Parser/Maple2.File.Parser.csproj +++ b/Maple2.File.Parser/Maple2.File.Parser.csproj @@ -13,7 +13,7 @@ MapleStory2, File, Parser, m2d, xml true - 2.4.28 + 2.4.29 net8.0 README.md enable diff --git a/Maple2.File.Parser/ServerTableParser.cs b/Maple2.File.Parser/ServerTableParser.cs index 0e84ba4..3b5cecc 100644 --- a/Maple2.File.Parser/ServerTableParser.cs +++ b/Maple2.File.Parser/ServerTableParser.cs @@ -66,6 +66,7 @@ public class ServerTableParser { private readonly XmlSerializer maidGradeInfoSerializer; private readonly XmlSerializer maidRecipeSerializer; private readonly XmlSerializer defaultCharacterInfoSerializer; + private readonly XmlSerializer dungeonScaleStatSerializer; public ServerTableParser(M2dReader xmlReader) { this.xmlReader = xmlReader; @@ -113,6 +114,7 @@ public ServerTableParser(M2dReader xmlReader) { maidGradeInfoSerializer = new XmlSerializer(typeof(MaidGradeInfoRoot)); maidRecipeSerializer = new XmlSerializer(typeof(MaidRecipeRoot)); defaultCharacterInfoSerializer = new XmlSerializer(typeof(DefaultCharacterInfoRoot)); + dungeonScaleStatSerializer = new XmlSerializer(typeof(DungeonScaleStatRoot)); // var seen = new HashSet(); // this.bankTypeSerializer.UnknownAttribute += (sender, args) => { @@ -768,4 +770,14 @@ public IEnumerable ParseNpcStatFactorByLevel() { yield return (info.value, info); } } + + public IEnumerable<(int Id, DungeonScaleStat ScaleStat)> ParseDungeonScaleStat() { + XmlReader reader = xmlReader.GetXmlReader(xmlReader.GetEntry("table/Server/DungeonScaleStat.xml")); + var data = dungeonScaleStatSerializer.Deserialize(reader) as DungeonScaleStatRoot; + Debug.Assert(data != null); + + foreach (DungeonScaleStat entry in data.DungeonScaleStat) { + yield return (entry.dungeonScaleStatID, entry); + } + } } diff --git a/Maple2.File.Parser/Xml/Table/Server/DungeonScaleStat.cs b/Maple2.File.Parser/Xml/Table/Server/DungeonScaleStat.cs new file mode 100644 index 0000000..54509b3 --- /dev/null +++ b/Maple2.File.Parser/Xml/Table/Server/DungeonScaleStat.cs @@ -0,0 +1,18 @@ +using System.Xml.Serialization; + +namespace Maple2.File.Parser.Xml.Table.Server; + +// ./data/server/table/Server/DungeonScaleStat.xml +// Per-dungeon counterpart of the scale* attributes in npc Stat. No dungeonroom column references it. +[XmlRoot("ms2")] +public class DungeonScaleStatRoot { + [XmlElement] public List DungeonScaleStat; +} + +public partial class DungeonScaleStat { + [XmlAttribute] public int dungeonScaleStatID; + [XmlAttribute] public float scaleStatRate; + [XmlAttribute] public long scaleBaseTap; + [XmlAttribute] public long scaleBaseDef; + [XmlAttribute] public float scaleBaseSpaRate; +} diff --git a/Maple2.File.Tests/ServerTableParserTest.cs b/Maple2.File.Tests/ServerTableParserTest.cs index d2b415c..5a84fd0 100644 --- a/Maple2.File.Tests/ServerTableParserTest.cs +++ b/Maple2.File.Tests/ServerTableParserTest.cs @@ -513,5 +513,21 @@ public void TestDefaultCharacterInfo() { Assert.AreNotEqual(Vector3.Zero, hair.controls.control[0].position); Assert.AreNotEqual(Vector3.Zero, hair.controls.control[0].rotation); } + + [TestMethod] + public void TestDungeonScaleStat() { + var parser = new ServerTableParser(TestUtils.ServerReader); + + Dictionary scaleStats = parser.ParseDungeonScaleStat() + .ToDictionary(entry => entry.Id, entry => entry.ScaleStat); + + // Retail row: + DungeonScaleStat row = scaleStats[6001]; + Assert.AreEqual(8.0f, row.scaleStatRate); + Assert.AreEqual(1911810L, row.scaleBaseTap); + Assert.AreEqual(2552L, row.scaleBaseDef); + Assert.AreEqual(0.35f, row.scaleBaseSpaRate); + } }