// Copyright (c) 2023 Dominic Masters // // This software is released under the MIT License. // https://opensource.org/licenses/MIT #include "VNSceneGen.hpp" using namespace Dawn; void VNSceneGen::test( std::string eventName, struct VNSceneEvent *event, int32_t *eventIndex, std::vector *eventInit, std::vector *eventChain, std::vector *includes ) { std::string initType = ""; std::string toInclude = ""; std::string initArgs = ""; std::vector eventInitAfter; switch(event->type) { case VN_SCENE_EVENT_TYPE_TEXT: initType = "VNTextEvent"; toInclude = "games/vn/events/VNTextEvent.hpp"; line(&eventInitAfter, eventName + "->" + "text = " + event->text.texts.begin()->text + ";", ""); break; case VN_SCENE_EVENT_TYPE_POSITION: initType = "VNPositionEvent"; toInclude = "games/vn/events/VNPositionEvent.hpp"; line(&eventInitAfter, eventName + "->item = " + event->position.item + ";", ""); if(event->position.x != "") line(&eventInitAfter, eventName + "->" + "to.x = " + event->position.x + ";", ""); if(event->position.y != "") line(&eventInitAfter, eventName + "->" + "to.y = " + event->position.y + ";", ""); if(event->position.z != "") line(&eventInitAfter, eventName + "->" + "to.z = " + event->position.z + ";", ""); break; case VN_SCENE_EVENT_TYPE_SET: initType = "VNSetEvent<" + event->set.type + ">"; toInclude = "games/vn/events/VNSetEvent.hpp"; line(&eventInitAfter, eventName + "->modifies = &" + event->set.property + ";", ""); line(&eventInitAfter, eventName + "->value = " + event->set.to + ";", ""); break; case VN_SCENE_EVENT_TYPE_WAIT: initType = "VNWaitEvent"; toInclude = "games/vn/events/VNWaitEvent.hpp"; line(&eventInitAfter, eventName + "->duration = " + event->wait.duration + ";", ""); break; case VN_SCENE_EVENT_TYPE_PARALLEL: { initType = "VNParallelEvent"; toInclude = "games/vn/events/VNParallelEvent.hpp"; auto itParallel = event->parallel.events.events.begin(); while(itParallel != event->parallel.events.events.end()) { std::string pEventName = "pEvent" + std::to_string((*eventIndex)++); VNSceneGen::test( pEventName, &(*itParallel), eventIndex, eventInit, eventChain, includes ); line(&eventInitAfter, eventName + "->events.push_back(" + pEventName + ");", ""); line(&eventInitAfter, "", ""); ++itParallel; } break; } case VN_SCENE_EVENT_TYPE_MARKER: initType = "VNDummyEvent"; toInclude = "games/vn/events/VNDummyEvent.hpp"; line(&eventInitAfter, "auto marker_" + event->marker.name + " = " + eventName + ";", ""); break; case VN_SCENE_EVENT_TYPE_GOTO_MARKER: initType = "VNDummyEvent"; toInclude = "games/vn/events/VNDummyEvent.hpp"; line(eventChain, eventName + "->then(marker_" + event->gotoMarker.name + ");", ""); break; case VN_SCENE_EVENT_TYPE_CHOICES: { initType = "VNChoiceEvent"; toInclude = "games/vn/events/VNChoiceEvent.hpp"; line(&eventInitAfter, eventName + "->key = \"" + event->choices.key+ "\";", ""); line(&eventInitAfter, eventName + "->text = " + event->choices.titles.begin()->text + ";", ""); auto itChoices = event->choices.choices.begin(); while(itChoices != event->choices.choices.end()) { line(&eventInitAfter, 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(&eventInitAfter, eventName + "->key = \"" + event->choiceSet.key + "\";", ""); line(&eventInitAfter, eventName + "->value = \"" + event->choiceSet.value + "\";", ""); break; case VN_SCENE_EVENT_TYPE_IF: { initType = "VNIfEvent"; toInclude = "games/vn/events/VNIfEvent.hpp"; line(&eventInitAfter, eventName + "->key = \"" + event->ifEvent.key + "\";", ""); line(&eventInitAfter, eventName + "->value = \"" + event->ifEvent.value + "\";", ""); std::string ifPrevious = ""; std::string ifFirst = ""; auto itIf = event->ifEvent.events.events.begin(); while(itIf != event->ifEvent.events.events.end()) { std::string ifEventName = "ifEvent" + std::to_string((*eventIndex)++); VNSceneGen::test( ifEventName, &(*itIf), eventIndex, eventInit, eventChain, includes ); if(!ifPrevious.empty()) line(eventChain, ifPrevious + "->then(" + ifEventName + ");", ""); ifPrevious = ifEventName; if(ifFirst == "") ifFirst = ifEventName; ++itIf; } if(ifFirst == "" || ifPrevious == "") { std::cout << "If event must have at least one event" << std::endl; assertUnreachable("VNSCeneGen::test: If event must have at least one event"); } line(eventChain, eventName + "->ifTrue = " + ifFirst + ";", ""); line(eventChain, eventName + "->ifEnd = " + ifPrevious + ";", ""); break; } case VN_SCENE_EVENT_TYPE_SCENE_CHANGE: { initType = "VNSceneChangeEvent<" + event->sceneChange.scene + ">"; toInclude = "games/vn/events/VNSceneChangeEvent.hpp"; includes->push_back(event->sceneChange.include); break; } case VN_SCENE_EVENT_SET_DEFAULT_FONT: { initType = "VNSetDefaultFontEvent"; toInclude = "games/vn/events/VNSetDefaultFontEvent.hpp"; std::string strFont = "setDefaultFont; if(!sdf.font.empty()) strFont += "font=" + stringParser(sdf.font, NULL); if(!sdf.fontSize.empty()) strFont += " size=\"" + floatParser(sdf.fontSize, NULL) + "\""; if(!sdf.color.empty()) strFont += " color=\"" + colorParser(sdf.color, NULL) + "\""; if(!sdf.style.empty()) strFont += " style=" + stringParser(sdf.style, NULL); strFont += ">{{ text }}"; line(&eventInitAfter, eventName + "->font = " + stringParser(strFont, NULL) + ";", ""); break; } default: std::cout << "Unknown event type: " << event->type << std::endl; assertUnreachable("VNSceneGen::test: Unknown event type"); } if(!toInclude.empty()) includes->push_back(toInclude); line(eventInit, "auto " + eventName + " = vnManager->createEvent<" + initType + ">(" + initArgs + ");", ""); lines(eventInit, eventInitAfter, ""); } void VNSceneGen::generate( std::vector *out, struct VNScene *scene, std::string tabs ) { struct ClassGenInfo classInfo; struct MethodGenInfo methodAssets; struct MethodGenInfo methodInit; // Load Scene SceneGenerator::generate( &scene->scene, classInfo, methodAssets, methodInit ); // Events classInfo.includes.push_back("games/vn/events/VNDummyEvent.hpp"); line(&methodInit.body, "assertNotNull(vnManager, \"VNSceneGenInit - VN Manager is null?\");", ""); line(&methodInit.body, "VNEvent *previous = vnManager->createEvent();", ""); line(&methodInit.body, "auto eventStart = previous;", ""); int32_t eventIndex = 0; auto itEvents = scene->events.events.begin(); std::string previous = "eventStart"; std::vector eventInit; std::vector eventChain; while(itEvents != scene->events.events.end()) { line(&eventInit, "", ""); std::string eventName = "event" + std::to_string(eventIndex++); VNSceneGen::test( eventName, &(*itEvents), &eventIndex, &eventInit, &eventChain, &classInfo.includes ); if(!previous.empty()) line(&eventChain, previous + "->then(" + eventName + ");", ""); previous = eventName; if(itEvents->type == VN_SCENE_EVENT_TYPE_GOTO_MARKER) previous = ""; ++itEvents; } lines(&methodInit.body, eventInit, ""); lines(&methodInit.body, eventChain, ""); line(&methodInit.body, "vnManager->setEvent(eventStart);", ""); // Add in methods CodeGen::methodGen(&classInfo.publicCode, methodAssets); line(&classInfo.publicCode, "", ""); CodeGen::methodGen(&classInfo.publicCode, methodInit); CodeGen::classGen(out, classInfo); }