This commit is contained in:
SoulliesOfficial
2025-06-13 14:59:58 -04:00
parent 27529d44dc
commit b9e6a9ab25
143 changed files with 7254 additions and 1906 deletions

View File

@@ -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;
}