剧情
This commit is contained in:
@@ -24,7 +24,7 @@ namespace Ichni.Story
|
||||
|
||||
public Dictionary<string, List<string>> functionDictionary;
|
||||
public Dictionary<string, List<DialogSentence>> dialogDictionary;
|
||||
public Dictionary<string, List<Choice>> choiceDictionary;
|
||||
public Dictionary<string, ChoiceGroup> choiceDictionary;
|
||||
public Dictionary<string, List<Condition>> conditionDictionary;
|
||||
|
||||
private string currentLoadingDialog;
|
||||
@@ -41,32 +41,32 @@ namespace Ichni.Story
|
||||
|
||||
public void SetDialog(string dialogName)
|
||||
{
|
||||
TextAsset dialog = Resources.Load<TextAsset>("Dialogs/" + dialogName);
|
||||
SetDialog(new List<TextAsset> { dialog }, "Entry");
|
||||
string chapter = StoryManager.instance.currentChapter;
|
||||
TextAsset dialog = Resources.Load<TextAsset>("Story/" + chapter + "/Dialogs/" + dialogName);
|
||||
SetDialog(new List<TextAsset> { dialog });
|
||||
}
|
||||
|
||||
public void SetDialog(List<TextAsset> dialogFiles, string dialogParagraphName)
|
||||
public void SetDialog(List<TextAsset> dialogFiles, string dialogParagraphName = "")
|
||||
{
|
||||
dialogUIPage.FadeIn();
|
||||
|
||||
currentDialog = "NULL";
|
||||
isPlayingDialog = true;
|
||||
LoadDialog(dialogFiles);
|
||||
|
||||
if (!string.IsNullOrEmpty(dialogParagraphName))
|
||||
{
|
||||
currentDialog = dialogParagraphName;
|
||||
}
|
||||
|
||||
PlayNextDialogParagraph(currentDialog);
|
||||
currentDialog = "NULL";
|
||||
LoadDialog(dialogFiles, out string firstHeader);
|
||||
|
||||
Debug.Log($"Loaded dialog, first header: {firstHeader}");
|
||||
currentDialog = dialogParagraphName == "" ? firstHeader : dialogParagraphName;
|
||||
|
||||
Debug.Log($"Setting dialog to: {currentDialog}");
|
||||
}
|
||||
|
||||
public void PlayNextDialogParagraph(string nextDialog)
|
||||
public void PlayNextDialogParagraph(string nextDialog, bool invokeFunctions = true)
|
||||
{
|
||||
currentDialog = nextDialog;
|
||||
currentDialogSentenceIndex = 0;
|
||||
|
||||
if (functionDictionary.TryGetValue(currentDialog, out List<string> functionList))
|
||||
if (invokeFunctions && functionDictionary.TryGetValue(currentDialog, out List<string> functionList))
|
||||
{
|
||||
functionList.ForEach(x => StoryInterpreters.FunctionInterpreter.Eval(x));
|
||||
}
|
||||
@@ -83,11 +83,8 @@ namespace Ichni.Story
|
||||
{
|
||||
currentFinalType = "None";
|
||||
}
|
||||
|
||||
PlayDialog();
|
||||
}
|
||||
|
||||
[Button("Test Play")]
|
||||
public void PlayDialog()
|
||||
{
|
||||
if(currentDialog == "NULL")
|
||||
@@ -95,11 +92,10 @@ namespace Ichni.Story
|
||||
throw new Exception("Current dialog is NULL");
|
||||
}
|
||||
|
||||
/*if (dialogInterface.dialogTextFrame.isPlayingSentence)
|
||||
if (isPlayingChoice)
|
||||
{
|
||||
dialogInterface.dialogTextFrame.FinishSentence();
|
||||
return;
|
||||
}*/
|
||||
}
|
||||
|
||||
if (dialogDictionary[currentDialog].Count > 0 && currentDialogSentenceIndex < dialogDictionary[currentDialog].Count)
|
||||
{
|
||||
@@ -107,7 +103,7 @@ namespace Ichni.Story
|
||||
|
||||
string interpretedContent = currentSentence.GetInterpretedContent();
|
||||
|
||||
dialogUIPage.textFrame.PlaySentence(currentSentence.characterName, interpretedContent);
|
||||
dialogUIPage.dialogContentFrame.PlaySentence(currentSentence.characterName, interpretedContent);
|
||||
currentDialogSentenceIndex++;
|
||||
|
||||
if (currentDialogSentenceIndex <= dialogDictionary[currentDialog].Count)
|
||||
@@ -121,7 +117,7 @@ namespace Ichni.Story
|
||||
if (currentFinalType == "Choice")
|
||||
{
|
||||
isPlayingChoice = true;
|
||||
dialogUIPage.choiceFrame.PlayChoice(choiceDictionary[currentDialog]);
|
||||
dialogUIPage.dialogContentFrame.PlayChoice(choiceDictionary[currentDialog]);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -140,21 +136,65 @@ namespace Ichni.Story
|
||||
|
||||
if (currentFinalType == "None" && currentDialogSentenceIndex >= dialogDictionary[currentDialog].Count)
|
||||
{
|
||||
dialogUIPage.FadeOut();
|
||||
dialogUIPage.choiceFrame.gameObject.SetActive(false);
|
||||
//currentDialogNPC.priorStoryTexts.Remove(dialogTextAsset);
|
||||
//currentDialogNPC = null;
|
||||
StoryManager.instance.storyline.currentBlock.state = StoryBlockState.Completed;
|
||||
isPlayingDialog = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void RevealDialog()
|
||||
{
|
||||
string finalType;
|
||||
int max = 0;
|
||||
|
||||
do
|
||||
{
|
||||
finalType = currentFinalType;
|
||||
currentDialogSentenceIndex = 0;
|
||||
|
||||
foreach (DialogSentence sentence in dialogDictionary[currentDialog])
|
||||
{
|
||||
string interpretedContent = sentence.GetInterpretedContent();
|
||||
dialogUIPage.dialogContentFrame.PlaySentence(sentence.characterName, interpretedContent);
|
||||
currentDialogSentenceIndex++;
|
||||
}
|
||||
|
||||
if (finalType == "Choice")
|
||||
{
|
||||
ChoiceGroup choiceGroup = choiceDictionary[currentDialog];
|
||||
int choiceIndex = GameSaveManager.instance.StorySaveModule.selectedChoices[choiceGroup.choiceName];
|
||||
dialogUIPage.dialogContentFrame.SelectChoice(choiceGroup, choiceIndex);
|
||||
}
|
||||
|
||||
if (finalType == "Condition")
|
||||
{
|
||||
foreach (var condition in conditionDictionary[currentDialog])
|
||||
{
|
||||
if (condition.GetConditionResult())
|
||||
{
|
||||
PlayNextDialogParagraph(condition.nextDialogName, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
max++;
|
||||
|
||||
if (max > 1024)
|
||||
{
|
||||
throw new Exception("An infinite loop may detected in dialog parsing. Please check the dialog structure.");
|
||||
}
|
||||
|
||||
} while (finalType != "None");
|
||||
}
|
||||
}
|
||||
|
||||
public partial class DialogManager
|
||||
{
|
||||
public void LoadDialog(List<TextAsset> dialogFiles)
|
||||
public void LoadDialog(List<TextAsset> dialogFiles, out string firstHeader)
|
||||
{
|
||||
ClearDictionaries();
|
||||
|
||||
firstHeader = string.Empty;
|
||||
|
||||
dialogTextAssets = dialogFiles;
|
||||
List<string> dialogLines = new List<string>();
|
||||
|
||||
@@ -165,20 +205,34 @@ namespace Ichni.Story
|
||||
|
||||
dialogLines.RemoveAll(line => line.Trim() == "");
|
||||
|
||||
dialogLines.ForEach(Debug.Log);
|
||||
//dialogLines.ForEach(Debug.Log);
|
||||
|
||||
foreach (var line in from line in dialogLines
|
||||
where !ParseHeader(line)
|
||||
where !ParseChoiceModule(line)
|
||||
where !ParseConditionModule(line)
|
||||
where !ParseDialogSentence(line)
|
||||
select line)
|
||||
foreach (string line in dialogLines)
|
||||
{
|
||||
throw new Exception($"Invalid dialog line: {line}"); // 抛出异常,提示不合法的对话行
|
||||
if (!ParseHeader(line))
|
||||
{
|
||||
if (!ParseChoiceModule(line))
|
||||
{
|
||||
if (!ParseConditionModule(line))
|
||||
{
|
||||
if (!ParseDialogSentence(line))
|
||||
{
|
||||
throw new Exception($"Invalid dialog line: {line}"); // 抛出异常,提示不合法的对话行
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (firstHeader == string.Empty)
|
||||
{
|
||||
firstHeader = currentDialog;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//dialogDictionary.RemoveWhere((header, sentences) => sentences == null || sentences.Count == 0);
|
||||
choiceDictionary.RemoveWhere((header, choices) => choices == null || choices.Count == 0);
|
||||
choiceDictionary.RemoveWhere((header, choices) => choices == null || choices.choices.Count == 0);
|
||||
conditionDictionary.RemoveWhere((header, conditions) => conditions == null || conditions.Count == 0);
|
||||
}
|
||||
|
||||
@@ -244,7 +298,7 @@ namespace Ichni.Story
|
||||
currentLoadingDialog = dialogTitle.Replace("[", "").Replace("]", "");
|
||||
|
||||
dialogDictionary.Add(currentLoadingDialog, new List<DialogSentence>());
|
||||
choiceDictionary.Add(currentLoadingDialog, new List<Choice>());
|
||||
//choiceDictionary.Add(currentLoadingDialog, new ChoiceGroup("Error"));
|
||||
conditionDictionary.Add(currentLoadingDialog, new List<Condition>());
|
||||
|
||||
if (currentDialog == "NULL")
|
||||
@@ -278,7 +332,7 @@ namespace Ichni.Story
|
||||
|
||||
public bool ParseDialogSentence(string line)
|
||||
{
|
||||
//speakerName(emotion):sentence
|
||||
//speakerName:sentence
|
||||
|
||||
string[] sentenceData;
|
||||
if (line.Contains(":"))
|
||||
@@ -291,30 +345,14 @@ namespace Ichni.Story
|
||||
}
|
||||
|
||||
string character = sentenceData[0];
|
||||
|
||||
string speakerName = character;
|
||||
string emotion = "Default";
|
||||
|
||||
|
||||
if (character.Contains("("))
|
||||
{
|
||||
emotion = character.Split("(")[1].Replace(")", "");
|
||||
speakerName = character.Split("(")[0];
|
||||
}
|
||||
else if (character.Contains("("))
|
||||
{
|
||||
emotion = character.Split("(")[1].Replace(")", "");
|
||||
speakerName = character.Split("(")[0];
|
||||
}
|
||||
|
||||
DialogSentence dialogSentence = new DialogSentence
|
||||
{
|
||||
characterName = speakerName,
|
||||
characterEmotion = emotion,
|
||||
content = sentenceData[1]
|
||||
characterName = speakerName.Trim(),
|
||||
content = sentenceData[1].Trim()
|
||||
};
|
||||
|
||||
|
||||
dialogDictionary[currentLoadingDialog].Add(dialogSentence);
|
||||
|
||||
return true;
|
||||
@@ -322,9 +360,9 @@ namespace Ichni.Story
|
||||
|
||||
public bool ParseChoiceModule(string line)
|
||||
{
|
||||
//$Choice{
|
||||
//choiceText0(Hint0)->[nextDialogName0];
|
||||
//choiceText1(Hint1)->[nextDialogName1];
|
||||
//$Choice(ChoiceName){
|
||||
//choiceText0->[nextDialogName0];
|
||||
//choiceText1->[nextDialogName1];
|
||||
//}
|
||||
|
||||
line = line.Trim();
|
||||
@@ -333,23 +371,21 @@ namespace Ichni.Story
|
||||
{
|
||||
string[] choiceModuleData = line.Split('{');
|
||||
|
||||
List<Choice> choices = new List<Choice>();
|
||||
string choiceName = choiceModuleData[0].Split('(')[1].Replace(")", "").Trim();
|
||||
ChoiceGroup choiceGroup = new ChoiceGroup(choiceName);
|
||||
|
||||
string[] choiceData = choiceModuleData[1].Split(';');
|
||||
|
||||
for (var index = 0; index < choiceData.Length - 1; index++)
|
||||
{
|
||||
Choice choice = new Choice
|
||||
{
|
||||
choiceText = choiceData[index].Split("->")[0].Split("(")[0].Trim(),
|
||||
hint = choiceData[index].Split("->")[0].Split("(")[1].Replace(")", "").Trim(),
|
||||
nextDialogName = choiceData[index].Split("->[")[1].Replace("]", "").Trim(),
|
||||
};
|
||||
choiceData[index] = choiceData[index].Replace(" ", "").Replace("\n", "").Replace("\r", "").Trim();
|
||||
|
||||
string choiceText = choiceData[index].Split("->[")[0].Trim();
|
||||
string nextDialogName = choiceData[index].Split("->[")[1].Replace("]", "").Trim();
|
||||
|
||||
choices.Add(choice);
|
||||
choiceGroup.choices.Add(new Choice(choiceText, nextDialogName));
|
||||
}
|
||||
|
||||
choiceDictionary[currentLoadingDialog] = choices;
|
||||
choiceDictionary[currentLoadingDialog] = choiceGroup;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user