diff --git a/Maple2.File.Parser/Maple2.File.Parser.csproj b/Maple2.File.Parser/Maple2.File.Parser.csproj
index 4fafe91..1aa9baf 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.10
+ 2.4.11
net8.0
README.md
enable
diff --git a/Maple2.File.Parser/ServerTableParser.cs b/Maple2.File.Parser/ServerTableParser.cs
index 972419b..12569fd 100644
--- a/Maple2.File.Parser/ServerTableParser.cs
+++ b/Maple2.File.Parser/ServerTableParser.cs
@@ -60,6 +60,7 @@ public class ServerTableParser {
private readonly XmlSerializer itemOptionRandomSerializer;
private readonly XmlSerializer constantsSerializer;
private readonly XmlSerializer npcStatFactorByPlayerCountSerializer;
+ private readonly XmlSerializer npcStatFactorByLevelSerializer;
public ServerTableParser(M2dReader xmlReader) {
this.xmlReader = xmlReader;
@@ -103,6 +104,7 @@ public ServerTableParser(M2dReader xmlReader) {
itemOptionRandomSerializer = new XmlSerializer(typeof(ItemOptionRandomRoot));
constantsSerializer = new XmlSerializer(typeof(Constants));
npcStatFactorByPlayerCountSerializer = new XmlSerializer(typeof(NpcStatFactorByPlayerCountRoot));
+ npcStatFactorByLevelSerializer = new XmlSerializer(typeof(NpcStatFactorByLevelRoot));
// var seen = new HashSet();
// this.bankTypeSerializer.UnknownAttribute += (sender, args) => {
@@ -712,7 +714,18 @@ public IEnumerable ParseNpcStatFactorByPlayerCount()
Debug.Assert(data != null);
foreach (NpcStatFactorByPlayerCount entry in data.PlayerCountFactor) {
- yield return (entry);
+ yield return entry;
+ }
+ }
+
+ public IEnumerable ParseNpcStatFactorByLevel() {
+ string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry("table/Server/npcStatFactorByLevel.xml")));
+ var reader = XmlReader.Create(new StringReader(xml));
+ var data = npcStatFactorByLevelSerializer.Deserialize(reader) as NpcStatFactorByLevelRoot;
+ Debug.Assert(data != null);
+
+ foreach (NpcStatFactorByLevel entry in data.levelFactor) {
+ yield return entry;
}
}
}
diff --git a/Maple2.File.Parser/TableParser.cs b/Maple2.File.Parser/TableParser.cs
index 94c0208..5bf91ff 100644
--- a/Maple2.File.Parser/TableParser.cs
+++ b/Maple2.File.Parser/TableParser.cs
@@ -110,6 +110,7 @@ public class TableParser {
private readonly XmlSerializer questGroupSerializer;
private readonly XmlSerializer darkStreamSerializer;
private readonly XmlSerializer clubBuffSerializer;
+ private readonly XmlSerializer characterCreateSelectSerializer;
private readonly string locale;
private readonly string language;
@@ -214,6 +215,7 @@ public TableParser(M2dReader xmlReader, string language) {
questGroupSerializer = new XmlSerializer(typeof(QuestGroupRoot));
darkStreamSerializer = new XmlSerializer(typeof(DarkStreamRoot));
clubBuffSerializer = new XmlSerializer(typeof(ClubBuffRoot));
+ characterCreateSelectSerializer = new XmlSerializer(typeof(CharacterCreateSelect));
locale = FeatureLocaleFilter.Locale.ToLower();
this.language = language;
@@ -1649,4 +1651,15 @@ public IEnumerable ParseJobTableNew() {
yield return (entry.id, entry);
}
}
+
+ public IEnumerable<(string Name, CharacterCreateSelectGroup Group)> ParseCharacterCreateSelect() {
+ string xml = Sanitizer.RemoveSpaces(xmlReader.GetString(xmlReader.GetEntry($"table/charactercreateselect.xml")));
+ var reader = XmlReader.Create(new StringReader(xml));
+ var data = characterCreateSelectSerializer.Deserialize(reader) as CharacterCreateSelect;
+ Debug.Assert(data != null);
+
+ foreach (CharacterCreateSelectGroup entry in data.group) {
+ yield return (entry.name, entry);
+ }
+ }
}
diff --git a/Maple2.File.Parser/Xml/Table/CharacterCreateSelect.cs b/Maple2.File.Parser/Xml/Table/CharacterCreateSelect.cs
new file mode 100644
index 0000000..a2878e5
--- /dev/null
+++ b/Maple2.File.Parser/Xml/Table/CharacterCreateSelect.cs
@@ -0,0 +1,26 @@
+using System.Xml.Serialization;
+using M2dXmlGenerator;
+
+namespace Maple2.File.Parser.Xml.Table;
+
+// ./data/xml/table/charactercreateselect.xml
+[XmlRoot("ms2")]
+public partial class CharacterCreateSelect {
+ [M2dFeatureLocale(Selector = "name")] private IList _group;
+}
+
+public partial class CharacterCreateSelectGroup : IFeatureLocale {
+ [XmlAttribute] public string name = string.Empty;
+ [M2dFeatureLocale(Selector = "jobCode")] private IList _list;
+}
+
+public partial class CharacterCreateSelectList : IFeatureLocale {
+ [XmlAttribute] public int jobCode;
+ [XmlAttribute] public string movie = string.Empty;
+ [XmlAttribute] public int descKey;
+
+ [M2dArray] public int[] order = Array.Empty();
+ [M2dArray] public int[] disableJobCode = Array.Empty();
+ [M2dArray] public int[] selectJobCode = Array.Empty();
+ [M2dArray] public int[] randomselectJobCode = Array.Empty();
+}
diff --git a/Maple2.File.Parser/Xml/Table/Server/NpcStatFactorByLevel.cs b/Maple2.File.Parser/Xml/Table/Server/NpcStatFactorByLevel.cs
new file mode 100644
index 0000000..c0113a8
--- /dev/null
+++ b/Maple2.File.Parser/Xml/Table/Server/NpcStatFactorByLevel.cs
@@ -0,0 +1,19 @@
+using System.Xml.Serialization;
+
+namespace Maple2.File.Parser.Xml.Table.Server;
+
+// ./data/server/table/Server/npcStatFactorByLevel.xml
+[XmlRoot("ms2")]
+public class NpcStatFactorByLevelRoot {
+ [XmlElement] public List levelFactor;
+}
+
+public partial class NpcStatFactorByLevel {
+ [XmlAttribute] public int level;
+ [XmlAttribute] public int @class;
+ [XmlAttribute] public float hp;
+ [XmlAttribute] public float pap;
+ [XmlAttribute] public float map;
+ [XmlAttribute] public float ndd;
+ [XmlAttribute] public float cap;
+}
diff --git a/Maple2.File.Parser/Xml/Table/Server/NpcStatFactorByPlayerCount.cs b/Maple2.File.Parser/Xml/Table/Server/NpcStatFactorByPlayerCount.cs
index a0b3a55..d62c556 100644
--- a/Maple2.File.Parser/Xml/Table/Server/NpcStatFactorByPlayerCount.cs
+++ b/Maple2.File.Parser/Xml/Table/Server/NpcStatFactorByPlayerCount.cs
@@ -13,6 +13,7 @@ public partial class NpcStatFactorByPlayerCount {
[XmlAttribute] public int @class;
[XmlAttribute] public int playerCount;
[XmlAttribute] public float hpRate;
+ [XmlAttribute] public int hpValue;
[XmlAttribute] public float papRate;
[XmlAttribute] public int papValue;
[XmlAttribute] public float mapRate;
diff --git a/Maple2.File.Tests/ServerTableParserTest.cs b/Maple2.File.Tests/ServerTableParserTest.cs
index c7d3814..3692d91 100644
--- a/Maple2.File.Tests/ServerTableParserTest.cs
+++ b/Maple2.File.Tests/ServerTableParserTest.cs
@@ -455,5 +455,14 @@ public void TestNpcStatFactorByPlayerCount() {
continue;
}
}
+
+ [TestMethod]
+ public void TestNpcStatFactorByLevel() {
+ var parser = new ServerTableParser(TestUtils.ServerReader);
+
+ foreach (NpcStatFactorByLevel _ in parser.ParseNpcStatFactorByLevel()) {
+ continue;
+ }
+ }
}
diff --git a/Maple2.File.Tests/TableParserTest.cs b/Maple2.File.Tests/TableParserTest.cs
index 5548065..7614fa0 100644
--- a/Maple2.File.Tests/TableParserTest.cs
+++ b/Maple2.File.Tests/TableParserTest.cs
@@ -794,4 +794,11 @@ public void TestDungeonRewardCoupon() {
continue;
}
}
+
+ [TestMethod]
+ public void TestCharacterCreateSelect() {
+ foreach ((_, _) in _parser.ParseCharacterCreateSelect()) {
+ continue;
+ }
+ }
}