From a3a640c73c8bbe83479edb4e9c768845c765a61d Mon Sep 17 00:00:00 2001
From: Zin <62830952+Zintixx@users.noreply.github.com>
Date: Thu, 30 Apr 2026 20:40:03 -0700
Subject: [PATCH] AI Parsing Fix
---
Maple2.File.Parser/AiParser.cs | 12 ++++++++----
Maple2.File.Parser/Maple2.File.Parser.csproj | 2 +-
Maple2.File.Parser/Xml/AI/NpcAi.cs | 16 ++++++++++++++--
Maple2.File.Tests/AiParserTest.cs | 8 ++++----
4 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/Maple2.File.Parser/AiParser.cs b/Maple2.File.Parser/AiParser.cs
index 962bc8d..cee615d 100644
--- a/Maple2.File.Parser/AiParser.cs
+++ b/Maple2.File.Parser/AiParser.cs
@@ -40,27 +40,31 @@ public AiParser(M2dReader xmlReader, bool includeComments = false) {
}
XmlNode? battleNode = document.SelectSingleNode("npcAi/battle");
if (battleNode != null) {
+ ai.Battle.startAni = battleNode.Attributes?["startAni"]?.Value ?? string.Empty;
+ ai.Battle.endAni = battleNode.Attributes?["endAni"]?.Value ?? string.Empty;
+ ai.Battle.isBattle = battleNode.Attributes?["isBattle"]?.Value == "true";
XmlNode? commentNode = battleNode.PreviousSibling;
while (includeComments && commentNode is XmlComment { Value: not null } comment) {
commentNode = commentNode.PreviousSibling;
if (comment.Value.Trim() == "전투") continue; // Redundant comment
- ai.Battle.Insert(0, new Comment {
+ ai.Battle.Entries.Insert(0, new Comment {
Value = comment.Value,
});
}
- ai.Battle.AddRange(ParseChildren(battleNode));
+ ai.Battle.Entries.AddRange(ParseChildren(battleNode));
}
XmlNode? battleEndNode = document.SelectSingleNode("npcAi/battleEnd");
if (battleEndNode != null) {
+ ai.BattleEnd.onlyDead = battleEndNode.Attributes?["onlyDead"]?.Value == "true";
XmlNode? commentNode = battleEndNode.PreviousSibling;
while (includeComments && commentNode is XmlComment { Value: not null } comment) {
commentNode = commentNode.PreviousSibling;
- ai.BattleEnd.Insert(0, new Comment {
+ ai.BattleEnd.Entries.Insert(0, new Comment {
Value = comment.Value,
});
}
- ai.BattleEnd.AddRange(ParseChildren(battleEndNode));
+ ai.BattleEnd.Entries.AddRange(ParseChildren(battleEndNode));
}
XmlNode? aiPresetsNode = document.SelectSingleNode("npcAi/aiPresets");
if (aiPresetsNode != null) {
diff --git a/Maple2.File.Parser/Maple2.File.Parser.csproj b/Maple2.File.Parser/Maple2.File.Parser.csproj
index 4817e7e..3b64879 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.5
+ 2.4.6
net8.0
README.md
enable
diff --git a/Maple2.File.Parser/Xml/AI/NpcAi.cs b/Maple2.File.Parser/Xml/AI/NpcAi.cs
index 6973f67..fc53877 100644
--- a/Maple2.File.Parser/Xml/AI/NpcAi.cs
+++ b/Maple2.File.Parser/Xml/AI/NpcAi.cs
@@ -3,7 +3,19 @@
// ./data/server/ai/**/%s.xml
public class NpcAi {
public List Reserved = new();
- public List Battle = new();
- public List BattleEnd = new();
+ public Battle Battle = new();
+ public BattleEnd BattleEnd = new();
public List AiPresets = new();
}
+
+public class Battle {
+ public string startAni = string.Empty;
+ public string endAni = string.Empty;
+ public bool isBattle;
+ public List Entries = [];
+}
+
+public class BattleEnd {
+ public bool onlyDead;
+ public List Entries = [];
+}
diff --git a/Maple2.File.Tests/AiParserTest.cs b/Maple2.File.Tests/AiParserTest.cs
index ac58670..51ad8a6 100644
--- a/Maple2.File.Tests/AiParserTest.cs
+++ b/Maple2.File.Tests/AiParserTest.cs
@@ -61,8 +61,8 @@ public void TestAiParser() {
HashSet definedPresets = new();
bool hasReserved = data.Reserved.Count > 0;
- bool hasBattle = data.Battle.Count > 0;
- bool hasBattleEnd = data.BattleEnd.Count > 0;
+ bool hasBattle = data.Battle.Entries.Count > 0;
+ bool hasBattleEnd = data.BattleEnd.Entries.Count > 0;
bool hasAiPresets = data.AiPresets.Count > 0;
bool hasAnyNodes = hasReserved || hasBattle || hasBattleEnd || hasAiPresets;
bool hasAnySubNodes = false;
@@ -81,13 +81,13 @@ public void TestAiParser() {
hasAnySubNodes = true;
}
- foreach (Entry entry in data.Battle) {
+ foreach (Entry entry in data.Battle.Entries) {
TestEntry(entry, definedPresets);
hasAnySubNodes = true;
}
- foreach (Entry entry in data.BattleEnd) {
+ foreach (Entry entry in data.BattleEnd.Entries) {
TestEntry(entry, definedPresets);
hasAnySubNodes = true;