Commit Description:
Avoid creating duplicate dialogs.
Commit Description:
Avoid creating duplicate dialogs.
File last commit:
Show/Diff file:
Action:
isometric-park-fna/Engines/Spawners/DialogSpawner.cs
142 lines | 4.6 KiB | text/x-csharp | CSharpLexer
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Linq;
using Microsoft.Xna.Framework;
using isometricparkfna.Messages;
using isometricparkfna.Components;
using static isometricparkfna.CellMap;
using isometricparkfna.UI;
using Encompass;
using TraceryNet;
using Ink.Runtime;
using JM.LinqFaster;
namespace isometricparkfna.Spawners {
[Reads(typeof(DialogComponent))]
[Receives(typeof(SpawnDialogMessage))]
[Sends(typeof(GameRateMessage))]
class DialogSpawner : Spawner<SpawnDialogMessage>
{
Story Story;
Grammar Grammar;
Random Random;
public static Dictionary<String, int> indexes;
public DialogSpawner(Story story, Grammar grammar)
{
this.Story = story;
this.Grammar = grammar;
this.Random = new Random();
if (DialogSpawner.indexes == null)
{
DialogSpawner.indexes = new Dictionary<String, int>();
}
}
public static int GetSpeakerImageIndex(Grammar grammar, Random random, String speakerRaw)
{
var index = 0;
String speaker = grammar.Flatten(speakerRaw.Trim());
if (DialogSpawner.indexes.ContainsKey(speaker)) {
index = DialogSpawner.indexes[speaker];
}
else {
Logging.Info(String.Format("Creating a new image for speaker {0}", speaker));
do
{
index = random.Next(0,7);
} while(DialogSpawner.indexes.ContainsValue(index));
DialogSpawner.indexes[speaker] = index;
}
return index;
}
protected override void Spawn(in SpawnDialogMessage message)
{
Logging.Info(String.Format("Count: {0}", this.Story.currentChoices.Count()));
Logging.Info(String.Format("Cancontinue: {0}", this.Story.canContinue));
var index = 0;
var path = message.Path;
var matching_dialog_entites = ReadEntities<DialogComponent>()
.SelectWhereF(e => GetComponent<DialogComponent>(e),
e => e.StartingKnot == path);
//If there are no existing dialog:
if(ReadEntities<DialogComponent>().Length == 0
&& this.Story.currentChoices.Count() == 0
&& !this.Story.canContinue)
{
Logging.Debug("Creating and hydrating new Dialog.");
//Jump to the specified part of the story:
Story.ChoosePathString(message.Path);
var newDialog = CreateEntity();
var continuation = this.Story.ContinueMaximally();
var parts = Regex.Split(continuation, ":", 0);
var speaker = (parts.Length == 2) ? parts[0] : "";
var dialog = (parts.Length == 2) ? parts[1] : continuation;
AddComponent(newDialog, new DialogComponent {
StartingKnot = message.Path,
Knot = message.Path,
CurrentDialog = this.Grammar.Flatten(dialog),
CurrentSpeaker = this.Grammar.Flatten(speaker).Trim(),
Options = this.Story.currentChoices
.Select(option => this.Grammar.Flatten(option.text))
.ToList()
});
AddComponent(newDialog, new WindowTypeComponent {
type = Window.Dialog
});
AddComponent(newDialog,
new VisibilityComponent { visible = true});
index = GetSpeakerImageIndex(this.Grammar, this.Random, speaker);
AddComponent(newDialog, new ImageComponent {
ImageIndex = index
});
Logging.Success("Spawned new dialog.");
SendMessage(new GameRateMessage { paused = true });
}
else if (matching_dialog_entites.Length == 0)
{
Logging.Debug("Creating new Dialog without hydrating.");
var newDialog = CreateEntity();
AddComponent(newDialog, new DialogComponent {
StartingKnot = message.Path,
Knot = message.Path
});
AddComponent(newDialog, new WindowTypeComponent {
type = Window.Dialog
});
AddComponent(newDialog,
new VisibilityComponent { visible = true});
}
}
}
}