diff --git a/Maple2.File.Parser/Maple2.File.Parser.csproj b/Maple2.File.Parser/Maple2.File.Parser.csproj
index 73d6e43..45eca3a 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.31
+ 2.4.32
net8.0
README.md
enable
diff --git a/Maple2.File.Parser/ServerTableParser.cs b/Maple2.File.Parser/ServerTableParser.cs
index 3b5cecc..2a1e101 100644
--- a/Maple2.File.Parser/ServerTableParser.cs
+++ b/Maple2.File.Parser/ServerTableParser.cs
@@ -43,6 +43,7 @@ public class ServerTableParser {
private readonly XmlSerializer spawnNpcSerializer;
private readonly XmlSerializer spawnInteractObjectSerializer;
private readonly XmlSerializer groupSpawnSerializer;
+ private readonly XmlSerializer shadowExpeditionDropSerializer;
private readonly XmlSerializer fishSerializer;
private readonly XmlSerializer fishingSpotSerializer;
private readonly XmlSerializer fishLureSerializer;
@@ -91,6 +92,7 @@ public ServerTableParser(M2dReader xmlReader) {
spawnNpcSerializer = new XmlSerializer(typeof(SpawnNpcRoot));
spawnInteractObjectSerializer = new XmlSerializer(typeof(SpawnInteractObjectRoot));
groupSpawnSerializer = new XmlSerializer(typeof(GroupSpawnRoot));
+ shadowExpeditionDropSerializer = new XmlSerializer(typeof(ShadowExpeditionDropRoot));
fishSerializer = new XmlSerializer(typeof(FishRoot));
fishingSpotSerializer = new XmlSerializer(typeof(FishingSpotRoot));
fishLureSerializer = new XmlSerializer(typeof(FishLureRoot));
@@ -511,6 +513,17 @@ public ServerTableParser(M2dReader xmlReader) {
}
}
+ public IEnumerable ParseShadowExpeditionDrop() {
+ string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry("table/Server/shadowExpeditionDrop.xml")));
+ var reader = XmlReader.Create(new StringReader(xml));
+ var data = shadowExpeditionDropSerializer.Deserialize(reader) as ShadowExpeditionDropRoot;
+ Debug.Assert(data != null);
+
+ foreach (ShadowExpeditionDrop drop in data.shadowExpeditionDrop) {
+ yield return drop;
+ }
+ }
+
public IEnumerable<(int Id, Fish Fish)> ParseFish() {
string xml = Sanitizer.RemoveEmpty(xmlReader.GetString(xmlReader.GetEntry("table/Server/fish.xml")));
var reader = XmlReader.Create(new StringReader(xml));
diff --git a/Maple2.File.Parser/Xml/Table/Server/ShadowExpeditionDrop.cs b/Maple2.File.Parser/Xml/Table/Server/ShadowExpeditionDrop.cs
new file mode 100644
index 0000000..cf8d135
--- /dev/null
+++ b/Maple2.File.Parser/Xml/Table/Server/ShadowExpeditionDrop.cs
@@ -0,0 +1,17 @@
+using System.Xml.Serialization;
+using M2dXmlGenerator;
+
+namespace Maple2.File.Parser.Xml.Table.Server;
+
+// ./data/server/table/Server/shadowExpeditionDrop.xml
+[XmlRoot("ms2")]
+public class ShadowExpeditionDropRoot {
+ [XmlElement] public List shadowExpeditionDrop;
+}
+
+public partial class ShadowExpeditionDrop {
+ [XmlAttribute] public int step;
+ // The killed NPC's basic class: 1, 3 or 6, the classes whose npc rankIcon is c, b and a (normal, elite, boss).
+ [XmlAttribute("class")] public int @class;
+ [M2dArray] public int[] dropBoxId = Array.Empty();
+}
diff --git a/Maple2.File.Tests/ServerTableParserTest.cs b/Maple2.File.Tests/ServerTableParserTest.cs
index 5a84fd0..979f80e 100644
--- a/Maple2.File.Tests/ServerTableParserTest.cs
+++ b/Maple2.File.Tests/ServerTableParserTest.cs
@@ -265,6 +265,30 @@ public void TestGroupSpawn() {
}
}
+ [TestMethod]
+ public void TestShadowExpeditionDrop() {
+ var parser = new ServerTableParser(TestUtils.ServerReader);
+
+ List drops = parser.ParseShadowExpeditionDrop().ToList();
+ Assert.AreEqual(102, drops.Count);
+
+ //
+ Assert.AreEqual(1, drops[0].step);
+ Assert.AreEqual(1, drops[0].@class);
+ CollectionAssert.AreEqual(new[] { 920001001 }, drops[0].dropBoxId);
+
+ //
+ Assert.AreEqual(1, drops[1].step);
+ Assert.AreEqual(3, drops[1].@class);
+ CollectionAssert.AreEqual(new[] { 920001002, 920003001 }, drops[1].dropBoxId);
+
+ //
+ ShadowExpeditionDrop last = drops[^1];
+ Assert.AreEqual(34, last.step);
+ Assert.AreEqual(6, last.@class);
+ CollectionAssert.AreEqual(new[] { 920001002, 920006034, 920000034, 820000034 }, last.dropBoxId);
+ }
+
[TestMethod]
public void TestSpawnInteractObject() {
var parser = new ServerTableParser(TestUtils.ServerReader);