2025-05-13 19:22:01 +08:00

1350 lines
32 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text.RegularExpressions;
using Godot;
using Godot.Bridge;
using Godot.Collections;
using Godot.NativeInterop;
[ScriptPath("res://Scripts/Common/TextSystem.cs")]
public partial class TextSystem : NinePatchRect
{
public partial class MiniText
{
public RichTextLabel textObj;
public string text;
public string portraitSprite;
public AnimatedSprite2D portraitObj;
public Vector2 pos = miniDefault;
public Vector2 startP;
public float time;
public const float defaultTime = 10f;
}
[Signal]
public delegate void DiagEndEventHandler();
[Export(PropertyHint.None, "")]
public AnimatedSprite2D portrait;
[Export(PropertyHint.None, "")]
public RichTextLabel text;
[Export(PropertyHint.None, "")]
public RichTextLabel[] promptText;
[Export(PropertyHint.None, "")]
public Sprite2D soul;
public static TextSystem instance;
public static Callable callable;
public static string[] replacers;
public static StringName[] redirects;
public static int lastPrompt;
public static Entity caller;
private static int currentPrompt;
private static int wait;
private static int currentIndex;
private static bool inPrompt;
public static bool overridePlayer = true;
public static bool slow;
public static bool firstFrame;
private static SavePrompt savePrompt;
private List<MiniText> miniTexts = new List<MiniText>();
private static readonly Vector2 promptOffset = new Vector2(-8f, 8f);
private static readonly Vector2 textDefaultPos = new Vector2(12f, 10f);
private static readonly Vector2 textDefaultSize = new Vector2(276f, 63f);
private static readonly Vector2 textDiagPos = new Vector2(73f, 10f);
private static readonly Vector2 textDiagSize = new Vector2(218f, 63f);
private static readonly Vector2 miniDefault = new Vector2(195f, 57f);
private static List<Texts.TextBlock> current;
private static readonly Texture2D dwTex = GD.Load<Texture2D>("res://Sprites/Menus/dwbox.png");
private static readonly Texture2D lwTex = GD.Load<Texture2D>("res://Sprites/Menus/utbox.png");
private const float topY = -115f;
private const float bottomY = 40f;
private const float promptDefaultY = 27f;
private const float promptBigY = 10f;
private static readonly System.Collections.Generic.Dictionary<string, object[]> bleeps = new System.Collections.Generic.Dictionary<string, object[]>
{
{
"Kanako",
new object[3]
{
GD.Load<AudioStream>("res://Audio/Bleeps/kanakoTalk.wav"),
0.85f,
0.5f
}
},
{
"KanaFB",
new object[4]
{
GD.Load<AudioStream>("res://Audio/Bleeps/kanakoTalk.wav"),
1f,
0.5f,
"Reverb"
}
},
{
"Warden",
new object[2]
{
GD.Load<AudioStream>("res://Audio/Bleeps/edTalk.wav"),
0.85f
}
},
{
"Bearing",
new object[2]
{
GD.Load<AudioStream>("res://Audio/Bleeps/aceTalk.wav"),
0.85f
}
},
{
"Ceroba",
new object[2]
{
GD.Load<AudioStream>("res://Audio/Bleeps/cerobaTalk.wav"),
1f
}
},
{
"Necklace",
new object[3]
{
GD.Load<AudioStream>("res://Audio/Bleeps/cerobaTalk.wav"),
0.85f,
0.75f
}
},
{
"Chujin",
new object[2]
{
GD.Load<AudioStream>("res://Audio/Bleeps/chujinTalk.wav"),
1f
}
},
{
"Dalv",
new object[2]
{
GD.Load<AudioStream>("res://Audio/Bleeps/dalvTalk.wav"),
1f
}
},
{
"Axis",
new object[2]
{
GD.Load<AudioStream>("res://Audio/Bleeps/axisTalk.wav"),
1f
}
},
{
"June",
new object[2]
{
GD.Load<AudioStream>("res://Audio/Bleeps/juneTalk.wav"),
1f
}
},
{
"Martlet",
new object[2]
{
GD.Load<AudioStream>("res://Audio/Bleeps/martletTalk.wav"),
1f
}
},
{
"Starlo",
new object[2]
{
GD.Load<AudioStream>("res://Audio/Bleeps/starloTalk.wav"),
1f
}
},
{
"Melody",
new object[2]
{
GD.Load<AudioStream>("res://Audio/Bleeps/melodyTalk.wav"),
1f
}
},
{
"Ace",
new object[2]
{
GD.Load<AudioStream>("res://Audio/Bleeps/aceTalk.wav"),
1f
}
},
{
"Mooch",
new object[2]
{
GD.Load<AudioStream>("res://Audio/Bleeps/moochTalk.wav"),
1f
}
},
{
"Moray",
new object[2]
{
GD.Load<AudioStream>("res://Audio/Bleeps/morayTalk.wav"),
1f
}
},
{
"Ed",
new object[2]
{
GD.Load<AudioStream>("res://Audio/Bleeps/edTalk.wav"),
1f
}
},
{
"System",
new object[2]
{
GD.Load<AudioStream>("res://Audio/Bleeps/SND_TXT2.wav"),
1f
}
},
{
"Toast",
new object[3]
{
GD.Load<AudioStream>("res://Audio/Bleeps/snd_mtt6.wav"),
1f,
1f
}
}
};
public static AudioStreamPlayer bleepPlayer;
public static AudioStreamPlayer extraSound;
private static readonly StringName dropShadowColor = "font_shadow_color";
private static readonly Color shadowColor = new Color(0f, 0f, 0.25f);
public static readonly AudioStream defaultBleep = GD.Load<AudioStream>("res://Audio/Bleeps/snd_text.wav");
public static readonly AudioStream defaultBleep2 = GD.Load<AudioStream>("res://Audio/Bleeps/SND_TXT2.wav");
private static char[] punctuation = new char[4] { '.', ',', '?', '!' };
private static readonly PackedScene miniTextObj = GD.Load<PackedScene>("res://Objects/UI/MiniText.tscn");
private static readonly System.Collections.Generic.Dictionary<StringName, string> regex = new System.Collections.Generic.Dictionary<StringName, string>
{
{ "money", "@(m)(\\d+)" },
{ "var", "@(v)(\\d+)" }
};
public static void LoadText(in string filename, ref System.Collections.Generic.Dictionary<string, Texts.TextBlock[]> dictionary)
{
dictionary.Clear();
using FileAccess fileAccess = FileAccess.Open(Texts.textFolder + "/" + filename, FileAccess.ModeFlags.Read);
string[] array = fileAccess.GetAsText(skipCr: true).Split('\n');
bool flag = false;
for (int i = 0; i < array.Length; i++)
{
flag = false;
if (array[i].Length <= 0 || array[i][0] != '@')
{
continue;
}
List<Texts.TextBlock> list = new List<Texts.TextBlock>();
string text = array[i].Remove(0, 1);
Texts.TextBlock textBlock = new Texts.TextBlock();
if (flag)
{
textBlock.top = true;
}
for (int j = i + 1; j < array.Length; j++)
{
if (array[j] == "END")
{
list.Add(textBlock);
break;
}
if (array[j].Length <= 0)
{
continue;
}
if (array[j][0] == '.')
{
list.Add(textBlock);
textBlock = new Texts.TextBlock();
if (flag)
{
textBlock.top = true;
}
}
else if (array[j][0] == '>')
{
string[] array2 = array[j].Remove(0, 1).Split(':');
switch (array2[0].ToLower())
{
case "setflag":
case "flag":
{
textBlock.setFlags = new Array<SaveFile.Flags>();
for (int l = 1; l < array2.Length; l++)
{
textBlock.setFlags.Add((SaveFile.Flags)Enum.Parse(typeof(SaveFile.Flags), array2[l]));
}
break;
}
case "talkanim":
textBlock.talkAnim = array2[1];
break;
case "endanim":
textBlock.endAnim = array2[1];
break;
case "bleep":
textBlock.bleep = array2[1];
break;
case "portrait":
case "p":
textBlock.portrait = array2[1];
break;
case "setvalue":
case "value":
textBlock.setValue.Add(new int[3]
{
Convert.ToInt32(array2[1]),
Convert.ToInt32(array2[2]),
(array2.Length > 3) ? Convert.ToInt32(array2[3]) : 0
});
break;
case "anim":
textBlock.anims.Add(new StringName[2]
{
array2[1],
array2[2]
});
break;
case "save":
case "callsave":
textBlock.callSave = true;
break;
case "additem":
case "item":
textBlock.addItem.Add(new object[3]
{
(Items.Type)Enum.Parse(typeof(Items.Type), array2[1]),
(Items.IDs)Enum.Parse(typeof(Items.IDs), array2[2]),
(array2.Length <= 3) ? 1 : Convert.ToInt32(array2[3])
});
break;
case "heal":
textBlock.heal = true;
break;
case "mini":
textBlock.mini.Add(new MiniText
{
text = array2[2],
portraitSprite = array2[1]
});
if (array2.Length > 3)
{
List<MiniText> mini = textBlock.mini;
mini[mini.Count - 1].pos = new Vector2(Convert.ToSingle(array2[3]), Convert.ToSingle(array2[4]));
}
break;
case "changehp":
textBlock.changeHP = Convert.ToInt32(array2[1]);
break;
case "redirect":
if (array2.Length == 2)
{
textBlock.redirectOnFlag.Add(new object[2]
{
SaveFile.Flags.None,
array2[1]
});
}
else
{
textBlock.redirectOnFlag.Add(new object[2]
{
(SaveFile.Flags)Enum.Parse(typeof(SaveFile.Flags), array2[1]),
array2[2]
});
}
break;
case "prompts":
case "prompt":
{
textBlock.prompts = new string[array2.Length - 1];
for (int num2 = 0; num2 < array2.Length - 1; num2++)
{
textBlock.prompts[num2] = array2[num2 + 1].Replace("@", "\n");
}
break;
}
case "presult":
case "predirect":
case "promptredirect":
case "promptresult":
{
textBlock.redirects = new StringName[array2.Length - 1];
for (int num = 0; num < array2.Length - 1; num++)
{
textBlock.redirects[num] = array2[num + 1];
}
break;
}
case "promptneed":
{
textBlock.promptReq = new Array<SaveFile.Flags>();
for (int n = 0; n < array2.Length - 1; n++)
{
if (array2[n].Length > 2 && Enum.TryParse<SaveFile.Flags>(array2[n + 1], ignoreCase: true, out var result2))
{
textBlock.promptReq.Add(result2);
}
else
{
textBlock.promptReq.Add(SaveFile.Flags.None);
}
}
break;
}
case "promptlimit":
{
textBlock.promptLimit = new Array<SaveFile.Flags>();
for (int m = 0; m < array2.Length - 1; m++)
{
if (array2[m].Length > 2 && Enum.TryParse<SaveFile.Flags>(array2[m + 1], ignoreCase: true, out var result))
{
textBlock.promptLimit.Add(result);
}
else
{
textBlock.promptLimit.Add(SaveFile.Flags.None);
}
}
break;
}
case "hide":
textBlock.hide = true;
break;
case "hidebg":
textBlock.noBG = true;
break;
case "slow":
textBlock.delay = ((array2.Length == 1) ? 3 : Convert.ToInt32(array2[1]));
break;
case "event":
case "callevent":
textBlock.commonEvent = array2[1];
break;
case "instant":
textBlock.instant = true;
break;
case "instend":
textBlock.instEnd = true;
break;
case "sound":
case "soundstart":
textBlock.soundStart = array2[1];
if (array2.Length > 2 && array2[2] == "wait")
{
textBlock.waitSound = true;
}
break;
case "soundend":
textBlock.soundEnd = array2[1];
if (array2.Length > 2 && array2[2] == "wait")
{
textBlock.waitSound = true;
}
break;
case "tc":
textBlock.getTalker = "caller";
break;
case "talk":
textBlock.getTalker = array2[1];
break;
case "top":
textBlock.top = true;
if (array2.Length > 1 && array2[1] == "lock")
{
flag = true;
}
break;
case "mapflag":
case "setmapflag":
case "setmap":
{
for (int k = 1; k < array2.Length; k++)
{
textBlock.setMapFlag.Add(array2[k]);
}
break;
}
case "redirectmap":
textBlock.redirectOnMapFlag = new string[2]
{
array2[1],
array2[2]
};
break;
}
}
else
{
string text2 = array[j].Replace("[shake]", "[shake level=6 rate=7]");
int num3 = 0;
for (int num4 = j + 1; num4 < array.Length && array[num4].Length > 0 && array[num4][0] != '.' && array[num4][0] != '>' && array[num4] != "END"; num4++)
{
text2 = text2 + "\n" + array[num4];
num3++;
}
textBlock.text = text2;
j += num3;
}
}
if (!dictionary.ContainsKey(text))
{
dictionary.Add(text, list.ToArray());
continue;
}
GD.Print("Text key " + text + " from file " + filename + " already registered before in Main.txt");
}
}
public override void _EnterTree()
{
instance = this;
if (!GodotObject.IsInstanceValid(bleepPlayer))
{
AudioStreamPlayer node = new AudioStreamPlayer
{
Bus = "Sound"
};
bleepPlayer = node;
AddChild(node, forceReadableName: false, InternalMode.Disabled);
}
}
public override void _Process(double delta)
{
if (savePrompt != null)
{
if (!GodotObject.IsInstanceValid(savePrompt))
{
savePrompt = null;
base.Modulate = Main.colorWhite;
End();
}
}
else
{
if (!base.Visible)
{
return;
}
soul.Visible = inPrompt;
if (inPrompt)
{
text.VisibleCharacters = int.MaxValue;
if (currentPrompt > -1)
{
soul.Position = promptText[currentPrompt].Position + promptOffset;
}
for (int i = 0; i < 4; i++)
{
if (i == currentPrompt)
{
promptText[i].Modulate = Main.colorYellow;
}
else
{
promptText[i].Modulate = Main.colorWhite;
}
}
if (Input.IsActionJustPressed(Main.keys[4]) && currentPrompt > -1)
{
Audio.PlaySound(Audio.commonSounds[2]);
inPrompt = false;
lastPrompt = currentPrompt;
for (int j = 0; j < 4; j++)
{
promptText[j].Visible = false;
}
StringName[] array = redirects;
if (array != null && array.Length != 0)
{
GetText(current[0].redirects[lastPrompt]);
}
else
{
End();
}
return;
}
if (Input.IsActionJustPressed(Main.keys[0]) && current[0].prompts.Length >= 3)
{
string obj = current[0].prompts[2];
if (obj != null && obj.Length > 0 && promptText[2].Visible)
{
currentPrompt = 2;
Audio.PlaySound(Audio.commonSounds[0]);
return;
}
}
if (Input.IsActionJustPressed(Main.keys[1]) && current[0].prompts.Length >= 4)
{
string obj2 = current[0].prompts[3];
if (obj2 != null && obj2.Length > 0 && promptText[3].Visible)
{
currentPrompt = 3;
Audio.PlaySound(Audio.commonSounds[0]);
return;
}
}
if (Input.IsActionJustPressed(Main.keys[2]))
{
currentPrompt = 0;
Audio.PlaySound(Audio.commonSounds[0]);
}
else if (Input.IsActionJustPressed(Main.keys[3]))
{
currentPrompt = 1;
Audio.PlaySound(Audio.commonSounds[0]);
}
return;
}
if (text.VisibleRatio < 1f)
{
if (Input.IsActionPressed(Main.keys[7]))
{
text.VisibleRatio = 9999f;
return;
}
if (wait > 0)
{
wait--;
}
else
{
if (!bleepPlayer.Playing)
{
bleepPlayer.Play();
}
do
{
currentIndex++;
if (currentIndex < text.Text.Length && text.Text[currentIndex] == '[')
{
for (int k = currentIndex + 1; k < text.Text.Length; k++)
{
currentIndex++;
if (text.Text[k] == ']')
{
break;
}
}
}
text.VisibleCharacters++;
}
while (text.VisibleCharacters < text.Text.Length && currentIndex < text.Text.Length && !char.IsLetterOrDigit(text.Text[currentIndex]) && !punctuation.Contains(text.Text[currentIndex - 1]));
if (currentIndex < text.Text.Length && punctuation.Contains(text.Text[currentIndex - 1]))
{
wait = 10;
bleepPlayer.Stop();
}
else if (slow)
{
wait = 3;
}
else
{
wait = current[0].delay;
}
}
}
else
{
TalkerIdle();
portrait.Stop();
if (bleepPlayer.Playing)
{
string soundEnd = current[0].soundEnd;
if (soundEnd != null && soundEnd.Length > 1)
{
extraSound = Audio.PlaySound(current[0].soundEnd);
}
}
bleepPlayer.Stop();
DoMiniText();
}
if (GodotObject.IsInstanceValid(extraSound) && extraSound.Playing && current[0].waitSound)
{
return;
}
if (Input.IsActionJustPressed(Main.keys[6]))
{
text.VisibleRatio = 999f;
}
if (firstFrame && (Input.IsActionJustPressed(Main.keys[4]) || Input.IsActionJustPressed(Main.keys[5]) || current[0].instEnd || Input.IsActionPressed(Main.keys[7])))
{
if (text.VisibleRatio >= 1f)
{
if (current.Count > 1)
{
current.RemoveAt(0);
DoText();
return;
}
if (current[0].callSave)
{
base.Modulate = Main.colorClear;
CameraController.instance.AddChild(savePrompt = GD.Load<PackedScene>("res://Objects/UI/SavePrompt.tscn").Instantiate<SavePrompt>(PackedScene.GenEditState.Disabled), forceReadableName: false, InternalMode.Disabled);
if (bleepPlayer.Playing)
{
bleepPlayer.Stop();
}
}
else if (current[0].prompts != null)
{
DestroyMiniText();
if (Player.instance.controlling.id == Entity.IDs.Kanako)
{
instance.soul.RotationDegrees = 180f;
instance.soul.Modulate = Main.colorWhite;
}
else
{
instance.soul.RotationDegrees = 0f;
instance.soul.Modulate = Main.colorYellow;
}
bleepPlayer.Stop();
inPrompt = true;
currentPrompt = -1;
soul.Position = new Vector2(149f, 39f);
redirects = current[0].redirects;
portrait.Visible = portrait.Visible && current[0].keepTextOnPrompt;
if (!current[0].keepTextOnPrompt)
{
text.Text = "";
}
for (int l = 0; l < 4; l++)
{
promptText[l].Visible = l < current[0].prompts.Length;
if (!promptText[l].Visible)
{
continue;
}
Array<SaveFile.Flags> promptReq = current[0].promptReq;
if (promptReq == null || promptReq.Count <= 0)
{
Array<SaveFile.Flags> promptLimit = current[0].promptLimit;
if (promptLimit == null || promptLimit.Count <= 0)
{
goto IL_084c;
}
}
Array<SaveFile.Flags> spawn = ((current[0].promptReq == null) ? null : new Array<SaveFile.Flags> { current[0].promptReq[l] });
Array<SaveFile.Flags> despawn = ((current[0].promptLimit == null) ? null : new Array<SaveFile.Flags> { current[0].promptReq[l] });
if (!SaveFile.CanDo(spawn, despawn))
{
promptText[l].Visible = false;
continue;
}
goto IL_084c;
IL_084c:
promptText[l].Text = current[0].prompts[l];
if (l < 2)
{
if (promptText[l].GetLineCount() > 2)
{
promptText[l].Position = new Vector2(promptText[l].Position.X, 10f);
}
else
{
promptText[l].Position = new Vector2(promptText[l].Position.X, 27f);
}
}
}
}
else
{
StringName next = current[0].next;
if ((object)next != null && next.ToString().Length > 1)
{
if (SaveFile.CanDo(current[0].nextFlags, current[0].nextLimitFlags))
{
GetText(current[0].next);
return;
}
End();
}
else
{
End();
}
}
}
else if (text.VisibleRatio > 0.1f)
{
text.VisibleRatio = 999f;
}
}
firstFrame = true;
}
}
private static void TalkerIdle()
{
Entity talking = current[0].talking;
if (talking != null)
{
AnimationPlayer anim = talking.anim;
string idleOverride = current[0].talking.idleOverride;
anim.Play((idleOverride != null && idleOverride.Length > 0) ? ((StringName)current[0].talking.idleOverride) : current[0].endAnim);
}
}
private static void DoMiniText()
{
List<MiniText> mini = current[0].mini;
if (mini == null || mini.Count <= 0)
{
return;
}
if (instance.miniTexts.Count == 0)
{
for (int i = 0; i < current[0].mini.Count; i++)
{
AnimatedSprite2D animatedSprite2D = miniTextObj.Instantiate<AnimatedSprite2D>(PackedScene.GenEditState.Disabled);
instance.AddChild(animatedSprite2D, forceReadableName: false, InternalMode.Disabled);
instance.miniTexts.Add(new MiniText
{
portraitObj = animatedSprite2D,
textObj = animatedSprite2D.GetChild<RichTextLabel>(0),
startP = current[0].mini[i].pos + Vector2.Right * 10f,
pos = current[0].mini[i].pos
});
List<MiniText> list = instance.miniTexts;
list[list.Count - 1].textObj.Text = current[0].mini[i].text;
animatedSprite2D.Play(current[0].mini[i].portraitSprite);
animatedSprite2D.Stop();
List<MiniText> list2 = instance.miniTexts;
animatedSprite2D.Position = list2[list2.Count - 1].startP;
animatedSprite2D.Modulate = Main.colorClear;
}
}
for (int j = 0; j < current[0].mini.Count; j++)
{
if (instance.miniTexts[j].time < 10f)
{
instance.miniTexts[j].time += Main.deltaTime;
}
instance.miniTexts[j].portraitObj.Position = instance.miniTexts[j].startP.Lerp(instance.miniTexts[j].pos, Mathf.Min(instance.miniTexts[j].time / 10f, 1f));
instance.miniTexts[j].portraitObj.Modulate = instance.miniTexts[j].portraitObj.Modulate.Lerp(Main.colorWhite, Main.deltaTime * 0.1f);
}
}
private static void DestroyMiniText()
{
List<MiniText> list = instance.miniTexts;
if (list != null && list.Count > 0)
{
for (int i = 0; i < instance.miniTexts.Count; i++)
{
instance.miniTexts[i].portraitObj.QueueFree();
}
instance.miniTexts.Clear();
}
}
public static void GetText(string key)
{
current = new List<Texts.TextBlock>(Texts.FindDiag(in key));
DoText();
}
public static void End()
{
if (current[0].callEvent != null)
{
Room.current.DoEvent((int)current[0].callEvent[0], (string)current[0].callEvent[1]);
}
TalkerIdle();
for (int i = 0; i < instance.promptText.Length; i++)
{
instance.promptText[i].Modulate = Main.colorWhite;
}
caller = null;
if (Main.inEvent == null || Main.inEvent.done)
{
Player.instance.EndInteraction();
}
instance.Visible = false;
instance.EmitSignal(SignalName.DiagEnd);
Room room = Room.current;
if (room != null && room.stopOnDiag?.Length > 0)
{
for (int j = 0; j < Room.current.stopOnDiag.Length; j++)
{
Room.current.stopOnDiag[j].ProcessMode = ProcessModeEnum.Inherit;
}
}
instance.soul.Visible = false;
bleepPlayer.Stop();
bleepPlayer.PitchScale = 1f;
bleepPlayer.VolumeDb = Mathf.LinearToDb(1f);
overridePlayer = true;
}
private static void DoText()
{
firstFrame = false;
currentIndex = 0;
List<object[]> redirectOnFlag = current[0].redirectOnFlag;
if (redirectOnFlag != null && redirectOnFlag.Count > 0)
{
for (int i = 0; i < current[0].redirectOnFlag.Count; i++)
{
if ((SaveFile.Flags)current[0].redirectOnFlag[i][0] == SaveFile.Flags.None || SaveFile.HasFlag((SaveFile.Flags)current[0].redirectOnFlag[i][0]))
{
GetText((string)current[0].redirectOnFlag[i][1]);
DoText();
return;
}
}
}
if (current[0].redirectOnMapFlag != null && Room.current.tempFlags.Contains(current[0].redirectOnMapFlag[0]))
{
GetText(current[0].redirectOnMapFlag[1]);
DoText();
return;
}
Room room = Room.current;
if (room != null && room.entities?.Count > 0)
{
List<StringName[]> anims = current[0].anims;
if (anims != null && anims.Count > 0)
{
for (int j = 0; j < current[0].anims.Count; j++)
{
Entity entity = Room.GetEntity(current[0].anims[j][0], removeNull: true);
if (entity != null)
{
if (current[0].anims[j][1] == (StringName)"force")
{
entity.UpdateAnim(force: true);
}
else
{
entity.anim.Play(current[0].anims[j][1]);
}
}
}
}
}
DestroyMiniText();
if (BattleDR.current == null)
{
DWMenu.instance.showHP = 0f;
}
string input = current[0].text;
foreach (StringName key in regex.Keys)
{
MatchCollection matchCollection = Regex.Matches(input, regex[key]);
for (int k = 0; k < matchCollection.Count; k++)
{
string text = key;
if (text == "money" || text == "var")
{
int num = SaveFile.current.values[Convert.ToInt32(matchCollection[k].Groups[2].Value)];
input = current[0].text.Replace(matchCollection[k].Value, num.ToString());
if (key == (StringName)"money")
{
SaveFile.current.dollars = Mathf.Clamp(SaveFile.current.dollars + num, 0, 9999);
}
}
}
}
List<int[]> setValue = current[0].setValue;
if (setValue != null && setValue.Count > 0)
{
for (int l = 0; l < current[0].setValue.Count; l++)
{
switch (current[0].setValue[l][2])
{
case 0:
if (current[0].setValue[l][0] == -1)
{
SaveFile.current.dollars += current[0].setValue[l][1];
}
else
{
SaveFile.current.values[current[0].setValue[l][0]] += current[0].setValue[l][1];
}
break;
case 1:
if (current[0].setValue[l][0] == -1)
{
SaveFile.current.dollars -= current[0].setValue[l][1];
}
else
{
SaveFile.current.values[current[0].setValue[l][0]] -= current[0].setValue[l][1];
}
break;
case 2:
if (current[0].setValue[l][0] == -1)
{
SaveFile.current.dollars = current[0].setValue[l][1];
}
else
{
SaveFile.current.values[current[0].setValue[l][0]] = current[0].setValue[l][1];
}
break;
}
}
}
List<object[]> addItem = current[0].addItem;
if (addItem != null && addItem.Count > 0)
{
bool flag = false;
for (int m = 0; m < current[0].addItem.Count; m++)
{
for (int n = 0; n < Mathf.Abs((int)current[0].addItem[m][2]); n++)
{
if ((int)current[0].addItem[m][2] > 0)
{
switch ((Items.Type)current[0].addItem[m][0])
{
case Items.Type.Equip:
SaveFile.current.dwArmor.Add((Items.IDs)current[0].addItem[m][1]);
break;
case Items.Type.Weapon:
SaveFile.current.dwWeapon.Add((Items.IDs)current[0].addItem[m][1]);
break;
case Items.Type.Normal:
SaveFile.current.dwItems.Add((Items.IDs)current[0].addItem[m][1]);
break;
case Items.Type.Key:
SaveFile.current.dwKey.Add((Items.IDs)current[0].addItem[m][1]);
break;
case Items.Type.LightWorld:
SaveFile.current.lwItems.Add((Items.IDs)current[0].addItem[m][1]);
break;
}
flag = true;
}
else
{
switch ((Items.Type)current[0].addItem[m][0])
{
case Items.Type.Equip:
SaveFile.current.dwArmor.Remove((Items.IDs)current[0].addItem[m][1]);
break;
case Items.Type.Weapon:
SaveFile.current.dwWeapon.Remove((Items.IDs)current[0].addItem[m][1]);
break;
case Items.Type.Normal:
SaveFile.current.dwItems.Remove((Items.IDs)current[0].addItem[m][1]);
break;
case Items.Type.Key:
SaveFile.current.dwKey.Remove((Items.IDs)current[0].addItem[m][1]);
break;
case Items.Type.LightWorld:
SaveFile.current.lwItems.Remove((Items.IDs)current[0].addItem[m][1]);
break;
}
}
}
}
if (flag)
{
Audio.PlaySound("snd_item_ch1.wav");
}
}
instance.text.Text = input;
if ((current[0].instant && current[0].instEnd) || current[0].hide)
{
instance.Position = new Vector2(999f, 999f);
}
else if (current[0].top)
{
instance.Position = new Vector2(-149f, -115f);
}
else
{
instance.Position = new Vector2(-149f, 40f);
}
string soundStart = current[0].soundStart;
if (soundStart != null && soundStart.Length > 1)
{
if (current[0].soundStart.Contains("RoomMusic"))
{
Room.current.DoMusic(Convert.ToInt32(current[0].soundStart.Replace("RoomMusic", "")));
}
else if (current[0].soundStart == "StopMusic")
{
Audio.music.Stop();
}
else
{
extraSound = Audio.PlaySound(current[0].soundStart);
}
}
instance.text.VisibleRatio = (current[0].instant ? 1 : 0);
int num2;
if (!SaveFile.current.flags.Contains(SaveFile.Flags.IsInDW))
{
Player player = Player.instance;
num2 = ((player != null && player.animMod == Entity.AnimMods.DW) ? 1 : 0);
}
else
{
num2 = 1;
}
bool flag2 = (byte)num2 != 0;
instance.text.AddThemeColorOverride(dropShadowColor, flag2 ? shadowColor : Main.colorClear);
instance.Texture = (flag2 ? dwTex : lwTex);
instance.Visible = true;
string getTalker = current[0].getTalker;
if (getTalker != null && getTalker.Length > 1)
{
if (current[0].getTalker.ToLower() == "caller")
{
current[0].talking = caller;
}
else
{
Room.current.entities.RemoveWhere((Entity x) => !GodotObject.IsInstanceValid(x));
current[0].talking = Room.current?.entities?.FirstOrDefault((Entity x) => x.Name == (StringName)current[0].getTalker);
}
}
if (overridePlayer)
{
Player.instance.StopMoving(Entity.Animations.Idle);
}
Player.instance.canInput = false;
if (current[0].heal)
{
Party.Heal();
}
Array<SaveFile.Flags> setFlags = current[0].setFlags;
if (setFlags != null && setFlags.Count > 0)
{
for (int num3 = 0; num3 < current[0].setFlags.Count; num3++)
{
SaveFile.AddFlag(current[0].setFlags[num3]);
}
}
List<StringName> setMapFlag = current[0].setMapFlag;
if (setMapFlag != null && setMapFlag.Count > 0)
{
for (int num4 = 0; num4 < current[0].setMapFlag.Count; num4++)
{
Room.current.tempFlags.Add(current[0].setMapFlag[num4]);
}
}
if (current[0].changeHP != 0)
{
for (int num5 = 0; num5 < SaveFile.current.activeParty.Count; num5++)
{
Party.party[SaveFile.current.activeParty[num5]].HP = Mathf.Clamp(current[0].changeHP + Party.party[SaveFile.current.activeParty[num5]].HP, 0, Party.party[SaveFile.current.activeParty[num5]].MAXHP);
}
}
float volume = 1f;
Texts.TextBlock textBlock = current[0];
if (textBlock != null && textBlock.portrait?.ToString()?.Length > 1)
{
if (current[0].portrait != (StringName)"KEEP")
{
instance.portrait.Play(current[0].portrait);
string bleep = current[0].bleep;
if (bleep != null && bleep.Length > 1)
{
AssignBleep(current[0].bleep, ref volume);
}
else
{
AssignBleep(current[0].portrait, ref volume);
}
}
else
{
volume = -1f;
}
instance.portrait.Visible = true;
instance.portrait.Play();
}
else
{
string bleep2 = current[0].bleep;
if (bleep2 != null && bleep2.Length > 1)
{
AssignBleep(current[0].bleep, ref volume);
}
else
{
bleepPlayer.Bus = "Sound";
bleepPlayer.Stream = defaultBleep;
bleepPlayer.PitchScale = 1f;
}
instance.portrait.Visible = false;
}
if (volume != -1f)
{
bleepPlayer.VolumeDb = Mathf.LinearToDb(volume);
}
bleepPlayer.Play();
if (current[0].talking?.anim != null)
{
string talkOverride = current[0].talking.talkOverride;
string text2 = ((talkOverride != null && talkOverride.Length > 0) ? current[0].talking.talkOverride : ((string?)current[0].talkAnim));
if (current[0].talking.anim.HasAnimation(text2))
{
current[0].talking.anim.Play(text2);
}
}
Room room2 = Room.current;
if (room2 != null && room2.stopOnDiag?.Length > 0)
{
for (int num6 = 0; num6 < Room.current.stopOnDiag.Length; num6++)
{
Room.current.stopOnDiag[num6].ProcessMode = ProcessModeEnum.Disabled;
}
}
if (instance.portrait.Visible)
{
instance.text.Size = textDiagSize;
instance.text.Position = textDiagPos;
}
else
{
instance.text.Size = textDefaultSize;
instance.text.Position = textDefaultPos;
}
if (current[0].noBG)
{
instance.SelfModulate = Main.colorClear;
}
else
{
instance.SelfModulate = Main.colorWhite;
}
if (Main.inEvent == null)
{
Player.instance.CallDeferred(Player.MethodName.PartyStop);
}
}
public static void AssignBleep(string name, ref float volume)
{
bool flag = false;
bleepPlayer.Bus = "Sound";
if (name != null && name.Length > 0)
{
foreach (string key in bleeps.Keys)
{
if (name.Contains(key))
{
flag = true;
object[] array = bleeps[key];
bleepPlayer.Stream = (AudioStream)array[0];
bleepPlayer.PitchScale = (float)array[1];
if (array.Length > 2)
{
volume = (float)array[2];
}
if (array.Length > 3)
{
bleepPlayer.Bus = (string)array[3];
}
break;
}
}
}
if (!flag)
{
bleepPlayer.Stream = defaultBleep;
bleepPlayer.PitchScale = 1f;
}
}
public static void SingleText(Texts.TextBlock[] texts)
{
current = new List<Texts.TextBlock>(texts);
DoText();
}
public static void SingleText(string text, string portrait = null, string next = null, string[] prompts = null)
{
current = new List<Texts.TextBlock>
{
new Texts.TextBlock
{
text = text,
portrait = portrait,
next = next,
prompts = prompts
}
};
DoText();
}
public static void TextBlock(Texts.TextBlock[] blocks)
{
current = new List<Texts.TextBlock>(blocks);
DoText();
}
}