The open source repository for the action RPG game in development by Sig Productions titled 'Adventures in Lestoria'!
https://forums.lestoria.net
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
198 lines
6.8 KiB
198 lines
6.8 KiB
1 year ago
|
#pragma region License
|
||
|
/*
|
||
|
License (OLC-3)
|
||
|
~~~~~~~~~~~~~~~
|
||
|
|
||
|
Copyright 2018 - 2023 OneLoneCoder.com
|
||
|
|
||
|
Redistribution and use in source and binary forms, with or without modification,
|
||
|
are permitted provided that the following conditions are met:
|
||
|
|
||
|
1. Redistributions or derivations of source code must retain the above copyright
|
||
|
notice, this list of conditions and the following disclaimer.
|
||
|
|
||
|
2. Redistributions or derivative works in binary form must reproduce the above
|
||
|
copyright notice. This list of conditions and the following disclaimer must be
|
||
|
reproduced in the documentation and/or other materials provided with the distribution.
|
||
|
|
||
|
3. Neither the name of the copyright holder nor the names of its contributors may
|
||
|
be used to endorse or promote products derived from this software without specific
|
||
|
prior written permission.
|
||
|
|
||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||
|
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||
|
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||
|
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||
|
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||
|
SUCH DAMAGE.
|
||
|
*/
|
||
|
#pragma endregion
|
||
|
#include "VisualNovel.h"
|
||
|
#include "GameState.h"
|
||
|
#include "Crawler.h"
|
||
|
#include <fstream>
|
||
|
|
||
|
VisualNovel VisualNovel::novel;
|
||
|
safemap<std::string,std::vector<std::unique_ptr<Command>>>VisualNovel::storyLevelData;
|
||
|
|
||
|
void VisualNovel::Initialize(){
|
||
|
for(int chapter=1;chapter<=6;chapter++){
|
||
|
std::string chapterFilename="story_directory"_S+"Chapter "+std::to_string(chapter)+".txt";
|
||
|
std::ifstream file(chapterFilename);
|
||
|
if(!file)ERR("Failed to open file "<<chapterFilename)
|
||
|
std::string line;
|
||
|
std::string currentStory;
|
||
|
while(file.good()){
|
||
|
|
||
|
auto trim=[](std::string line){
|
||
|
for(int counter=0;counter<line.length();counter++){
|
||
|
if(line[counter]!=' '&&line[counter]!='\t')return line.substr(counter);
|
||
|
}
|
||
|
return line;
|
||
|
};
|
||
|
auto ReadCSVArgs=[](std::string text){
|
||
|
std::vector<std::string>args;
|
||
|
size_t counter=0;
|
||
|
while(text.find(',',counter)!=std::string::npos){
|
||
|
std::string arg=text.substr(counter,text.find(',',counter)-counter);
|
||
|
counter=text.find(',',counter)+1;
|
||
|
if(arg.find(',')!=std::string::npos)ERR("Found an erraneous comma inside parsed arg "<<arg<<". Inside of main text: "<<text);
|
||
|
args.push_back(arg);
|
||
|
}
|
||
|
std::string arg=text.substr(counter);
|
||
|
args.push_back(arg);
|
||
|
return args;
|
||
|
};
|
||
|
std::getline(file,line);
|
||
|
line=trim(line);
|
||
|
if(line.length()==0)continue; //It's a blank line, so we skip it.
|
||
|
|
||
|
auto&data=storyLevelData.at(currentStory);
|
||
|
|
||
|
switch(line[0]){
|
||
|
case '=':{ //Initializes a new story section.
|
||
|
currentStory=line.substr(3,line.find('=',3)-3);
|
||
|
if(currentStory.find('=')!=std::string::npos)ERR("Story name "<<currentStory<<" is an invalid name! Failed to load story.");
|
||
|
storyLevelData[currentStory];
|
||
|
}break;
|
||
|
case '{':{ //Start of a command.
|
||
|
size_t spacePos=line.find(' ');
|
||
|
if(spacePos==std::string::npos)ERR("Cannot parse arguments from "<<line<<": No space found");
|
||
|
size_t endingBracePos=line.find('}',spacePos+1);
|
||
|
if(endingBracePos==std::string::npos)ERR("Cannot parse arguments from "<<line<<": No closing ending brace found")
|
||
|
std::string args=line.substr(spacePos+1,endingBracePos-(spacePos+1));
|
||
|
if(args.find(' ')!=std::string::npos||args.find('}')!=std::string::npos)ERR("Cannot parse args, found invalid tokens in "<<args)
|
||
|
std::vector<std::string>arguments=ReadCSVArgs(args);
|
||
|
|
||
|
if(line.find("{LOCATION")!=std::string::npos){//Location command
|
||
|
if(arguments.size()!=1)ERR("Arguments size is "<<arguments.size()<<". Expecting only 1 argument.")
|
||
|
data.push_back(std::make_unique<LocationCommand>(arguments[0]));
|
||
|
}else
|
||
|
if(line.find("{BACKGROUND")!=std::string::npos){//Background command
|
||
|
if(arguments.size()!=1)ERR("Arguments size is "<<arguments.size()<<". Expecting only 1 argument.")
|
||
|
data.push_back(std::make_unique<BackgroundCommand>(arguments[0]));
|
||
|
}else
|
||
|
if(line.find("{LEFT")!=std::string::npos){//Left command
|
||
|
data.push_back(std::make_unique<LeftCommand>(arguments));
|
||
|
}else
|
||
|
if(line.find("{RIGHT")!=std::string::npos){//Right command
|
||
|
data.push_back(std::make_unique<RightCommand>(arguments));
|
||
|
}else
|
||
|
if(line.find("{PAUSE")!=std::string::npos){//Pause command
|
||
|
if(arguments.size()!=0)ERR("Arguments size is "<<arguments.size()<<". Expecting no arguments.")
|
||
|
data.push_back(std::make_unique<PauseCommand>());
|
||
|
}else{
|
||
|
ERR("Unknown command "<<line<<". Could not parse!");
|
||
|
}
|
||
|
}break;
|
||
|
case '[':{
|
||
|
size_t endingBracePos=line.find(']');
|
||
|
if(endingBracePos==std::string::npos)ERR("Cannot parse arguments from "<<line<<": No closing ending bracket found")
|
||
|
std::string args=line.substr(1,endingBracePos-1);
|
||
|
if(args.find(']')!=std::string::npos)ERR("Cannot parse args, found invalid tokens in "<<args)
|
||
|
std::vector<std::string>arguments=ReadCSVArgs(args);
|
||
|
if(arguments.size()>2)ERR("Expecting a maximum of two arguments for parsed args in "<<args<<", got "<<arguments.size()<<" arguments instead.");
|
||
|
if(arguments.size()!=2){
|
||
|
data.push_back(std::make_unique<SpeakerCommand>(arguments[0]));
|
||
|
}else{
|
||
|
data.push_back(std::make_unique<SpeakerCommand>(arguments[0],arguments[1]));
|
||
|
}
|
||
|
}break;
|
||
|
default:{
|
||
|
data.push_back(std::make_unique<DialogCommand>(line));
|
||
|
}break;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
storyLevelData.SetInitialized();
|
||
|
};
|
||
|
void VisualNovel::LoadVisualNovel(std::string storyLevelName){
|
||
|
novel.storyLevel=storyLevelName;
|
||
|
GameState::ChangeState(States::STORY);
|
||
|
}
|
||
|
void VisualNovel::Update(){
|
||
|
|
||
|
}
|
||
|
void VisualNovel::Draw(){
|
||
|
|
||
|
}
|
||
|
|
||
|
Command::Command(){}
|
||
|
|
||
|
void LocationCommand::Execute(VisualNovel&vn){
|
||
|
|
||
|
}
|
||
|
LocationCommand::LocationCommand(std::string location){
|
||
|
|
||
|
}
|
||
|
|
||
|
void BackgroundCommand::Execute(VisualNovel&vn){
|
||
|
|
||
|
}
|
||
|
BackgroundCommand::BackgroundCommand(std::string backgroundFilename){
|
||
|
|
||
|
}
|
||
|
|
||
|
void LeftCommand::Execute(VisualNovel&vn){
|
||
|
|
||
|
}
|
||
|
LeftCommand::LeftCommand(std::vector<std::string>characters){
|
||
|
|
||
|
}
|
||
|
|
||
|
void RightCommand::Execute(VisualNovel&vn){
|
||
|
|
||
|
}
|
||
|
RightCommand::RightCommand(std::vector<std::string>characters){
|
||
|
|
||
|
}
|
||
|
|
||
|
void SpeakerCommand::Execute(VisualNovel&vn){
|
||
|
|
||
|
}
|
||
|
SpeakerCommand::SpeakerCommand(std::string speaker){
|
||
|
|
||
|
}
|
||
|
SpeakerCommand::SpeakerCommand(std::string displayedName,std::string speaker){
|
||
|
|
||
|
}
|
||
|
|
||
|
void DialogCommand::Execute(VisualNovel&vn){
|
||
|
|
||
|
}
|
||
|
DialogCommand::DialogCommand(std::string dialog){
|
||
|
|
||
|
}
|
||
|
|
||
|
void PauseCommand::Execute(VisualNovel&vn){
|
||
|
|
||
|
}
|
||
|
PauseCommand::PauseCommand(){
|
||
|
|
||
|
}
|