diff --git a/assets/games/liminal/test.xml b/assets/games/liminal/test.xml
index f70a0f40..c48ccfde 100644
--- a/assets/games/liminal/test.xml
+++ b/assets/games/liminal/test.xml
@@ -1,16 +1,21 @@
-
-
+
+
+
+
+
-
+
+
+
+
-
-
-
+
+
-
+
@@ -18,9 +23,7 @@
-
-
-
+
Hi, I'm Craig.
@@ -31,14 +34,67 @@
at the same time. This will make craig exit screen left.
-->
-
-
+
+
-
+
-
+
+
+
+
+ Do you think Craig is cool?
+
+
+ Yes
+
+
+ No
+
+
+ Maybe
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/dawntools/vnscenetool/VNSceneGen.cpp b/src/dawntools/vnscenetool/VNSceneGen.cpp
index e1327c40..c8b9bd22 100644
--- a/src/dawntools/vnscenetool/VNSceneGen.cpp
+++ b/src/dawntools/vnscenetool/VNSceneGen.cpp
@@ -83,6 +83,25 @@ void VNSceneGen::test(
line(&afterLines, eventName + "->then(marker_" + event->gotoMarker.name + ");", "");
break;
+ case VN_SCENE_EVENT_TYPE_CHOICES: {
+ initType = "VNChoiceEvent";
+ toInclude = "games/vn/events/VNChoiceEvent.hpp";
+ line(&afterLines, eventName + "->key = \"" + event->choices.key+ "\";", "");
+ line(&afterLines, eventName + "->text = \"" + event->choices.titles.begin()->text + "\";", "");
+ auto itChoices = event->choices.choices.begin();
+ while(itChoices != event->choices.choices.end()) {
+ line(&afterLines, eventName + "->choices[\"" + itChoices->value + "\"] = \"" + itChoices->texts.begin()->text + "\";", "");
+ ++itChoices;
+ }
+ break;
+ }
+
+ case VN_SCENE_EVENT_TYPE_CHOICE_SET:
+ initType = "VNChoiceSetEvent";
+ toInclude = "games/vn/events/VNChoiceSetEvent.hpp";
+ line(&afterLines, eventName + "->key = \"" + event->choiceSet.key + "\";", "");
+ line(&afterLines, eventName + "->value = \"" + event->choiceSet.value + "\";", "");
+ break;
default:
std::cout << "Unknown event type: " << event->type << std::endl;
diff --git a/src/dawntools/vnscenetool/events/CMakeLists.txt b/src/dawntools/vnscenetool/events/CMakeLists.txt
index 6689ff35..166bf999 100644
--- a/src/dawntools/vnscenetool/events/CMakeLists.txt
+++ b/src/dawntools/vnscenetool/events/CMakeLists.txt
@@ -14,4 +14,6 @@ target_sources(vnscenetool
VNWaitEventParser.cpp
VNParallelEventParser.cpp
VNGoToMarkerEventParser.cpp
+ VNChoiceEventParser.cpp
+ VNChoiceSetEventParser.cpp
)
\ No newline at end of file
diff --git a/src/dawntools/vnscenetool/events/VNChoiceEventParser.cpp b/src/dawntools/vnscenetool/events/VNChoiceEventParser.cpp
new file mode 100644
index 00000000..470f9f51
--- /dev/null
+++ b/src/dawntools/vnscenetool/events/VNChoiceEventParser.cpp
@@ -0,0 +1,95 @@
+// Copyright (c) 2023 Dominic Masters
+//
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#include "VNChoiceEventParser.hpp"
+
+using namespace Dawn;
+
+std::vector VNChoiceParser::getRequiredAttributes() {
+ return { "value" };
+}
+
+std::map VNChoiceParser::getOptionalAttributes() {
+ return { };
+}
+
+int32_t VNChoiceParser::onParse(
+ Xml *node,
+ std::map values,
+ struct VNChoice *out,
+ std::string *error
+) {
+ int32_t ret;
+ auto itChildren = node->children.begin();
+ while(itChildren != node->children.end()) {
+ Xml *child = *itChildren;
+
+ // Parse strings
+ if(child->node == "string") {
+ VNText text;
+ ret = (VNTextParser()).parse(child, &text, error);
+ if(ret != 0) return ret;
+ out->texts.push_back(text);
+ } else {
+ *error = "Unknown child node '" + child->node + "'";
+ return -1;
+ }
+
+ itChildren++;
+ }
+
+ out->value = values["value"];
+ return 0;
+}
+
+// // // // // // // // // // // // // // // // // // // // // // // // // // //
+
+std::vector VNChoicesEventParser::getRequiredAttributes() {
+ return { "key" };
+}
+
+std::map VNChoicesEventParser::getOptionalAttributes() {
+ return { };
+}
+
+int32_t VNChoicesEventParser::onParse(
+ Xml *node,
+ std::map values,
+ struct VNChoiceEvent *out,
+ std::string *error
+) {
+ int32_t ret;
+ auto itChildren = node->children.begin();
+ while(itChildren != node->children.end()) {
+ Xml *child = *itChildren;
+
+ // Parse strings
+ if(child->node == "title") {
+ auto itChildren2 = child->children.begin();
+ while(itChildren2 != child->children.end()) {
+ VNText text;
+ ret = (VNTextParser()).parse(*itChildren2, &text, error);
+ if(ret != 0) return ret;
+ out->titles.push_back(text);
+ ++itChildren2;
+ }
+
+ } else if(child->node == "choice") {
+ VNChoice choice;
+ ret = (VNChoiceParser()).parse(child, &choice, error);
+ if(ret != 0) return ret;
+ out->choices.push_back(choice);
+
+ } else {
+ *error = "Unknown child node '" + child->node + "'";
+ return -1;
+ }
+
+ itChildren++;
+ }
+
+ out->key = values["key"];
+ return 0;
+}
\ No newline at end of file
diff --git a/src/dawntools/vnscenetool/events/VNChoiceEventParser.hpp b/src/dawntools/vnscenetool/events/VNChoiceEventParser.hpp
new file mode 100644
index 00000000..f06d9d63
--- /dev/null
+++ b/src/dawntools/vnscenetool/events/VNChoiceEventParser.hpp
@@ -0,0 +1,44 @@
+// Copyright (c) 2023 Dominic Masters
+//
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#pragma once
+#include "VNTextEventParser.hpp"
+
+namespace Dawn {
+ struct VNChoice {
+ std::vector texts;
+ std::string value;
+ };
+
+ struct VNChoiceEvent {
+ std::vector titles;
+ std::vector choices;
+ std::string key;
+ };
+
+ class VNChoiceParser : public XmlParser {
+ protected:
+ std::vector getRequiredAttributes() override;
+ std::map getOptionalAttributes() override;
+ int32_t onParse(
+ Xml *node,
+ std::map values,
+ struct VNChoice *out,
+ std::string *error
+ ) override;
+ };
+
+ class VNChoicesEventParser : public XmlParser {
+ protected:
+ std::vector getRequiredAttributes() override;
+ std::map getOptionalAttributes() override;
+ int32_t onParse(
+ Xml *node,
+ std::map values,
+ struct VNChoiceEvent *out,
+ std::string *error
+ ) override;
+ };
+}
\ No newline at end of file
diff --git a/src/dawntools/vnscenetool/events/VNChoiceSetEventParser.cpp b/src/dawntools/vnscenetool/events/VNChoiceSetEventParser.cpp
new file mode 100644
index 00000000..14a78383
--- /dev/null
+++ b/src/dawntools/vnscenetool/events/VNChoiceSetEventParser.cpp
@@ -0,0 +1,27 @@
+// Copyright (c) 2023 Dominic Masters
+//
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#include "VNChoiceSetEventParser.hpp"
+
+using namespace Dawn;
+
+std::vector VNChoiceSetEventParser::getRequiredAttributes() {
+ return { "key", "value" };
+}
+
+std::map VNChoiceSetEventParser::getOptionalAttributes() {
+ return {};
+}
+
+int32_t VNChoiceSetEventParser::onParse(
+ Xml *node,
+ std::map values,
+ struct VNChoiceSetEvent *out,
+ std::string *error
+) {
+ out->key = values["key"];
+ out->value = values["value"];
+ return 0;
+}
\ No newline at end of file
diff --git a/src/dawntools/vnscenetool/events/VNChoiceSetEventParser.hpp b/src/dawntools/vnscenetool/events/VNChoiceSetEventParser.hpp
new file mode 100644
index 00000000..0691c9b5
--- /dev/null
+++ b/src/dawntools/vnscenetool/events/VNChoiceSetEventParser.hpp
@@ -0,0 +1,26 @@
+// Copyright (c) 2023 Dominic Masters
+//
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#pragma once
+#include "util/XmlParser.hpp"
+
+namespace Dawn {
+ struct VNChoiceSetEvent {
+ std::string key;
+ std::string value;
+ };
+
+ class VNChoiceSetEventParser : public XmlParser {
+ protected:
+ std::vector getRequiredAttributes() override;
+ std::map getOptionalAttributes() override;
+ int32_t onParse(
+ Xml *node,
+ std::map values,
+ struct VNChoiceSetEvent *out,
+ std::string *error
+ ) override;
+ };
+}
\ No newline at end of file
diff --git a/src/dawntools/vnscenetool/events/VNSceneEventsParser.cpp b/src/dawntools/vnscenetool/events/VNSceneEventsParser.cpp
index ba3ebeb1..9fbb79e8 100644
--- a/src/dawntools/vnscenetool/events/VNSceneEventsParser.cpp
+++ b/src/dawntools/vnscenetool/events/VNSceneEventsParser.cpp
@@ -65,6 +65,16 @@ int32_t VNSceneEventsParser::onParse(
ret = (VNGoToMarkerEventParser()).parse(child, &event.gotoMarker, error);
if(ret != 0) return ret;
+ } else if(child->node == "choices") {
+ event.type = VN_SCENE_EVENT_TYPE_CHOICES;
+ ret = (VNChoicesEventParser()).parse(child, &event.choices, error);
+ if(ret != 0) return ret;
+
+ } else if(child->node == "choice-set") {
+ event.type = VN_SCENE_EVENT_TYPE_CHOICE_SET;
+ ret = (VNChoiceSetEventParser()).parse(child, &event.choiceSet, error);
+ if(ret != 0) return ret;
+
} else {
*error = "Unknown child node '" + child->node + "'";
return -1;
diff --git a/src/dawntools/vnscenetool/events/VNSceneEventsParser.hpp b/src/dawntools/vnscenetool/events/VNSceneEventsParser.hpp
index 38e9d31f..5ec10dcd 100644
--- a/src/dawntools/vnscenetool/events/VNSceneEventsParser.hpp
+++ b/src/dawntools/vnscenetool/events/VNSceneEventsParser.hpp
@@ -11,6 +11,8 @@
#include "VNParallelEventParser.hpp"
#include "VNMarkerParser.hpp"
#include "VNGoToMarkerEventParser.hpp"
+#include "VNChoiceEventParser.hpp"
+#include "VNChoiceSetEventParser.hpp"
namespace Dawn {
struct VNSceneEvent;
@@ -26,7 +28,9 @@ namespace Dawn {
VN_SCENE_EVENT_TYPE_WAIT,
VN_SCENE_EVENT_TYPE_PARALLEL,
VN_SCENE_EVENT_TYPE_MARKER,
- VN_SCENE_EVENT_TYPE_GOTO_MARKER
+ VN_SCENE_EVENT_TYPE_GOTO_MARKER,
+ VN_SCENE_EVENT_TYPE_CHOICES,
+ VN_SCENE_EVENT_TYPE_CHOICE_SET
};
struct VNParallelEvent {
@@ -43,6 +47,8 @@ namespace Dawn {
struct VNParallelEvent parallel;
struct VNMarker marker;
struct VNGoToMarkerEvent gotoMarker;
+ struct VNChoiceEvent choices;
+ struct VNChoiceSetEvent choiceSet;
};
class VNSceneEventsParser : public XmlParser {
diff --git a/src/dawntools/vnscenetool/events/VNTextEventParser.cpp b/src/dawntools/vnscenetool/events/VNTextEventParser.cpp
index 65d79ad3..caadf738 100644
--- a/src/dawntools/vnscenetool/events/VNTextEventParser.cpp
+++ b/src/dawntools/vnscenetool/events/VNTextEventParser.cpp
@@ -7,6 +7,27 @@
using namespace Dawn;
+std::vector VNTextParser::getRequiredAttributes() {
+ return { "lang" };
+}
+
+std::map VNTextParser::getOptionalAttributes() {
+ return { };
+}
+
+int32_t VNTextParser::onParse(
+ Xml *node,
+ std::map values,
+ struct VNText *out,
+ std::string *error
+) {
+ out->language = values["lang"];
+ out->text = node->value;
+ return 0;
+}
+
+// // // // // // // // // // // // // // // // // // // // // // // // // // //
+
std::vector VNTextEventParser::getRequiredAttributes() {
return { };
}
@@ -21,6 +42,7 @@ int32_t VNTextEventParser::onParse(
struct VNTextEvent *out,
std::string *error
) {
+ int32_t ret;
auto itChildren = node->children.begin();
while(itChildren != node->children.end()) {
Xml *child = *itChildren;
@@ -28,8 +50,8 @@ int32_t VNTextEventParser::onParse(
// Parse strings
if(child->node == "string") {
VNText text;
- text.language = child->attributes["lang"];
- text.text = child->value;
+ ret = (VNTextParser()).parse(child, &text, error);
+ if(ret != 0) return ret;
out->texts.push_back(text);
} else {
*error = "Unknown child node '" + child->node + "'";
diff --git a/src/dawntools/vnscenetool/events/VNTextEventParser.hpp b/src/dawntools/vnscenetool/events/VNTextEventParser.hpp
index d351896b..a28570b8 100644
--- a/src/dawntools/vnscenetool/events/VNTextEventParser.hpp
+++ b/src/dawntools/vnscenetool/events/VNTextEventParser.hpp
@@ -16,6 +16,18 @@ namespace Dawn {
std::vector texts;
};
+ class VNTextParser : public XmlParser {
+ protected:
+ std::vector getRequiredAttributes() override;
+ std::map getOptionalAttributes() override;
+ int32_t onParse(
+ Xml *node,
+ std::map values,
+ struct VNText *out,
+ std::string *error
+ ) override;
+ };
+
class VNTextEventParser : public XmlParser {
protected:
std::vector getRequiredAttributes() override;