|
|
using System;
|
|
|
using System.Text.RegularExpressions;
|
|
|
using System.Linq;
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using Encompass;
|
|
|
using Ink.Runtime;
|
|
|
using TraceryNet;
|
|
|
|
|
|
using isometricparkfna.Messages;
|
|
|
using isometricparkfna.Components;
|
|
|
using isometricparkfna.Spawners;
|
|
|
|
|
|
namespace isometricparkfna.Engines
|
|
|
{
|
|
|
|
|
|
[Receives(typeof(SetDialogMessage),
|
|
|
typeof(DialogChoiceMessage))]
|
|
|
[Reads(typeof(DialogComponent),
|
|
|
typeof(OptionsComponent)) ]
|
|
|
[Writes(typeof(DialogComponent),
|
|
|
typeof(ImageComponent))]
|
|
|
class DialogEngine : Engine
|
|
|
{
|
|
|
public static Dictionary<string, string> replacements = new Dictionary<string,string> {{"Damn", "Drat"},
|
|
|
{"Fucking hell", "Flipping heck"},
|
|
|
{"Fucking", "flipping"},
|
|
|
{"Fuck", "Fork"}, //Ty michael shur
|
|
|
{"Motherfucker", "Motherforker"},
|
|
|
{"Hellifiknow", "Heckifiknow"},
|
|
|
{"Shitheel", "Slimewheel"}, //idk
|
|
|
{"Shit!", "Shitake mushrooms!"}, //depends on context
|
|
|
{"Shit", "Shitake mushroom"},
|
|
|
{"Hell", "Heck"},
|
|
|
{"Oh my God", "Oh my Glob"}, //Ty Pendleton Ward
|
|
|
{"Goddammit", "Glob drat it"},
|
|
|
{"Bloody hell", "Blimey"},
|
|
|
{"Goddamm", "Goshdarn"},
|
|
|
{"Megadick", "Megadunce"},
|
|
|
{"Dickhead", "Dunderhead"},
|
|
|
{"Bastard", "Bollocks"},
|
|
|
{"Cuntforsaken", "Clodforsaken"},
|
|
|
{"Godforsaken", "Globforsaken"},
|
|
|
{"Piss-eared", "Paste-eared"},
|
|
|
{"Asshole", "Bumhead"} //i guess
|
|
|
};
|
|
|
|
|
|
public static Dictionary<string, string> replacements_lower;
|
|
|
public Story Story;
|
|
|
public Grammar Grammar;
|
|
|
|
|
|
Random Random;
|
|
|
|
|
|
public DialogEngine(Story story, Grammar grammar)
|
|
|
{
|
|
|
this.Story = story;
|
|
|
this.Grammar = grammar;
|
|
|
|
|
|
this.Random = new Random();
|
|
|
|
|
|
DialogEngine.replacements_lower = DialogEngine.replacements.Select((i) => (i.Key.ToLower(), i.Value.ToLower())).ToDictionary(i => i.Item1, i => i.Item2);
|
|
|
|
|
|
}
|
|
|
|
|
|
public string BleepString(string s, ProfanityLevel setting)
|
|
|
{
|
|
|
switch (setting)
|
|
|
{
|
|
|
case ProfanityLevel.Uncensored:
|
|
|
return s;
|
|
|
case ProfanityLevel.Minced:
|
|
|
foreach (var item in DialogEngine.replacements)
|
|
|
{
|
|
|
s = s.Replace(item.Key, item.Value);
|
|
|
}
|
|
|
foreach (var item in DialogEngine.replacements_lower)
|
|
|
{
|
|
|
s = s.Replace(item.Key, item.Value);
|
|
|
}
|
|
|
return s;
|
|
|
case ProfanityLevel.Removed:
|
|
|
return Regex.Replace(s, "(?i)((?<=d)amn|(?<=f)uck|(?<=c)unt|(?<=D)amn|(?<=F)uck|(?<=S)hit|(?<=Motherf)ucker|(?<=megad)ick|(?<=C)unt)", "------");
|
|
|
}
|
|
|
return s;
|
|
|
}
|
|
|
|
|
|
public string BleepAndFlatten(string s, ProfanityLevel setting)
|
|
|
{
|
|
|
return this.BleepString(this.Grammar.Flatten(s), setting);
|
|
|
}
|
|
|
|
|
|
public override void Update(double dt)
|
|
|
{
|
|
|
|
|
|
ProfanityLevel profanity_setting = default;
|
|
|
|
|
|
foreach (ref readonly var entity in ReadEntities<OptionsComponent>())
|
|
|
{
|
|
|
var option_component = GetComponent<OptionsComponent>(entity);
|
|
|
|
|
|
profanity_setting = option_component.ProfanitySetting;
|
|
|
}
|
|
|
|
|
|
foreach (ref readonly var dialogMessage in ReadMessages<SetDialogMessage>())
|
|
|
{
|
|
|
if (dialogMessage.newOption != null)
|
|
|
{
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
Destroy(dialogMessage.Entity);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
foreach (ref readonly var choiceMessage in ReadMessages<DialogChoiceMessage>())
|
|
|
{
|
|
|
|
|
|
if (Story.currentChoices.Count > 0
|
|
|
| Story.canContinue)
|
|
|
{
|
|
|
//Advance the story
|
|
|
|
|
|
if (Story.currentChoices.Count > 0)
|
|
|
{
|
|
|
Logging.Debug("Advancing story (choice).");
|
|
|
Story.ChooseChoiceIndex(choiceMessage.Choice);
|
|
|
}
|
|
|
else {
|
|
|
Logging.Debug("Advancing story (continuation).");
|
|
|
}
|
|
|
|
|
|
//Update the dialog component with the new speaker, dialog, and options:
|
|
|
var continuation = BleepAndFlatten(this.Story.ContinueMaximally(), profanity_setting);
|
|
|
var parts = Regex.Split(continuation, ":", 0);
|
|
|
var speaker = (parts.Length == 2) ? BleepAndFlatten(parts[0], profanity_setting) : "Dialog";
|
|
|
var dialog = (parts.Length == 2) ? BleepAndFlatten(parts[1], profanity_setting) : continuation;
|
|
|
|
|
|
SetComponent(choiceMessage.Entity, new DialogComponent {
|
|
|
CurrentDialog = dialog,
|
|
|
CurrentSpeaker = speaker.Trim(),
|
|
|
Options = this.Story.currentChoices
|
|
|
.Select(option => BleepAndFlatten(option.text,
|
|
|
profanity_setting))
|
|
|
.ToList()
|
|
|
});
|
|
|
|
|
|
var index = DialogSpawner.GetSpeakerImageIndex(this.Grammar, this.Random, speaker);
|
|
|
|
|
|
SetComponent(choiceMessage.Entity, new ImageComponent {
|
|
|
ImageIndex = index
|
|
|
});
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
Logging.Debug(String.Format("Destroying Dialog (Entity ID {0}).", choiceMessage.Entity.ID));
|
|
|
Destroy(choiceMessage.Entity);
|
|
|
|
|
|
var lowestID = Int32.MaxValue;
|
|
|
Entity lowestEntity = default;
|
|
|
|
|
|
|
|
|
foreach(ref var entity in ReadEntities<DialogComponent>())
|
|
|
{
|
|
|
if ((entity.ID < lowestID)
|
|
|
//Don't try to use entity we just destroyed:
|
|
|
&& (entity.ID != choiceMessage.Entity.ID)
|
|
|
|
|
|
&& (!GetComponent<DialogComponent>(entity).Hydrated))
|
|
|
{
|
|
|
lowestID = entity.ID;
|
|
|
lowestEntity = entity;
|
|
|
Logging.Spy(lowestID, "ID");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (lowestID != Int32.MaxValue
|
|
|
&& EntityExists(lowestEntity))
|
|
|
{
|
|
|
Logging.Debug("Hydrating Dialog.");
|
|
|
|
|
|
|
|
|
var Knot = GetComponent<DialogComponent>(lowestEntity).Knot;
|
|
|
|
|
|
Story.ChoosePathString(Knot);
|
|
|
var continuation = this.Story.ContinueMaximally();
|
|
|
var parts = Regex.Split(continuation, ":", 0);
|
|
|
var speaker = (parts.Length == 2) ? BleepAndFlatten(parts[0], profanity_setting) : "Dialog";
|
|
|
var dialog = (parts.Length == 2) ? BleepAndFlatten(parts[1], profanity_setting) : continuation;
|
|
|
SetComponent(lowestEntity, new DialogComponent {
|
|
|
Knot = Knot,
|
|
|
CurrentDialog = dialog,
|
|
|
CurrentSpeaker = speaker.Trim(),
|
|
|
Options = this.Story.currentChoices
|
|
|
.Select(option => BleepAndFlatten(option.text,
|
|
|
profanity_setting ))
|
|
|
.ToList()
|
|
|
});
|
|
|
|
|
|
var index = DialogSpawner.GetSpeakerImageIndex(this.Grammar, this.Random, speaker);
|
|
|
|
|
|
SetComponent(lowestEntity, new ImageComponent {
|
|
|
ImageIndex = index
|
|
|
});
|
|
|
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|