525 lines
13 KiB
C#
525 lines
13 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using Godot;
|
|
using Godot.Bridge;
|
|
using Godot.NativeInterop;
|
|
using Newtonsoft.Json;
|
|
|
|
[ScriptPath("res://Scripts/UI/MainMenu.cs")]
|
|
public partial class MainMenu : Control
|
|
{
|
|
[Export(PropertyHint.None, "")]
|
|
private NinePatchRect[] files;
|
|
|
|
[Export(PropertyHint.None, "")]
|
|
private RichTextLabel[] fileText;
|
|
|
|
[Export(PropertyHint.None, "")]
|
|
private RichTextLabel[] opt;
|
|
|
|
[Export(PropertyHint.None, "")]
|
|
private NinePatchRect settingsBox;
|
|
|
|
[Export(PropertyHint.None, "")]
|
|
private RichTextLabel top;
|
|
|
|
[Export(PropertyHint.None, "")]
|
|
private Sprite2D soul;
|
|
|
|
[Export(PropertyHint.None, "")]
|
|
private Sprite2D logo;
|
|
|
|
[Export(PropertyHint.None, "")]
|
|
private Control fileMenu;
|
|
|
|
private string[][] langs;
|
|
|
|
public int option;
|
|
|
|
public int maxOption = 6;
|
|
|
|
public int current;
|
|
|
|
public int subOption;
|
|
|
|
public int copySlot = -1;
|
|
|
|
public int file;
|
|
|
|
private float sec;
|
|
|
|
private static SaveFile[] saves = new SaveFile[3];
|
|
|
|
private static bool firstLoad;
|
|
|
|
public static string lastLang = null;
|
|
|
|
public static MainMenu instance;
|
|
|
|
public static int forceReload = -1;
|
|
|
|
private Settings settings;
|
|
|
|
private Coroutine delay;
|
|
|
|
private GenericList langList;
|
|
|
|
private AudioStreamPlayer introsound;
|
|
|
|
private static readonly AudioStream music = GD.Load<AudioStream>("res://Audio/Music/AUDIO_STORY.ogg");
|
|
|
|
private static readonly Vector2[] optPos = new Vector2[6]
|
|
{
|
|
new Vector2(-124f, -65f),
|
|
new Vector2(-124f, -4f),
|
|
new Vector2(-124f, 57f),
|
|
new Vector2(-102f, 98f),
|
|
new Vector2(-30f, 98f),
|
|
new Vector2(42f, 98f)
|
|
};
|
|
|
|
private string[] mes;
|
|
|
|
private static readonly StringName intronoise = "AUDIO_INTRONOISE.ogg";
|
|
|
|
public override void _EnterTree()
|
|
{
|
|
if (instance == null)
|
|
{
|
|
instance = this;
|
|
}
|
|
base.Visible = true;
|
|
if (saves == null)
|
|
{
|
|
saves = new SaveFile[3];
|
|
}
|
|
if (lastLang != null)
|
|
{
|
|
Settings.file.lang = lastLang;
|
|
}
|
|
SetMes();
|
|
for (int i = 0; i < saves.Length; i++)
|
|
{
|
|
if (FileAccess.FileExists("user://Save" + i + ".dat"))
|
|
{
|
|
using FileAccess fileAccess = FileAccess.Open("user://Save" + i + ".dat", FileAccess.ModeFlags.Read);
|
|
saves[i] = JsonConvert.DeserializeObject<SaveFile>(fileAccess.GetAsText());
|
|
fileAccess.Close();
|
|
files[i].Modulate = Main.colorWhite;
|
|
}
|
|
else
|
|
{
|
|
saves[i] = null;
|
|
}
|
|
SetFileText(in i);
|
|
}
|
|
if (forceReload > -1)
|
|
{
|
|
base.Modulate = Main.colorClear;
|
|
current = -1;
|
|
Coroutine.Start(LoadFile(forceReload, skip: true));
|
|
forceReload = -1;
|
|
return;
|
|
}
|
|
if (current != -1 && !firstLoad && DirAccess.DirExistsAbsolute("user://Text/"))
|
|
{
|
|
string[] directoriesAt = DirAccess.GetDirectoriesAt("user://Text/");
|
|
if (directoriesAt.Length != 0)
|
|
{
|
|
List<string> list = new List<string>();
|
|
langs = new string[directoriesAt.Length + 1][];
|
|
langs[0] = FileAccess.Open("res://Data/Text_EnUS/LangInfo.txt", FileAccess.ModeFlags.Read).GetAsText().Split('\n');
|
|
langs[0][2] = "EnUS";
|
|
list.Add(langs[0][1]);
|
|
for (int j = 1; j < langs.Length; j++)
|
|
{
|
|
langs[j] = FileAccess.Open("user://Text/" + directoriesAt[j - 1] + "/LangInfo.txt", FileAccess.ModeFlags.Read).GetAsText().Split('\n');
|
|
langs[j][2] = directoriesAt[j - 1].Split('_', 2)[1];
|
|
list.Add(langs[j][1]);
|
|
}
|
|
current = -2;
|
|
AddChild(langList = GD.Load<PackedScene>("res://Objects/UI/GenericList.tscn").Instantiate<GenericList>(PackedScene.GenEditState.Disabled), forceReadableName: false, InternalMode.Disabled);
|
|
langList.options = list.ToArray();
|
|
langList.Scrolled += UpdateLangHeader;
|
|
langList.Selected += LangSelected;
|
|
langList.Position = new Vector2(-74f, -70f);
|
|
UpdateLangHeader();
|
|
logo.ProcessMode = ProcessModeEnum.Disabled;
|
|
}
|
|
}
|
|
if (current != -2 && current <= 0)
|
|
{
|
|
introsound = Audio.PlaySound(intronoise);
|
|
}
|
|
firstLoad = true;
|
|
}
|
|
|
|
private void SetFileText(in int i)
|
|
{
|
|
if (saves[i] != null)
|
|
{
|
|
fileText[i].Text = "[center]" + Texts.common[28].ToUpper() + "\t\t\t\t" + Texts.common[91] + " " + saves[i].love + "\t\t\t\t" + Texts.common[92] + " " + saves[i].lv + "\n" + SaveFile.GetRoomName(saves[i].room) + "\n" + saves[i].time[2].ToString().PadLeft(3, '0') + ":" + saves[i].time[1].ToString().PadLeft(2, '0');
|
|
}
|
|
else
|
|
{
|
|
fileText[i].Text = "\n[center]" + Texts.common[89];
|
|
}
|
|
}
|
|
|
|
private void SetMes()
|
|
{
|
|
mes = new string[9]
|
|
{
|
|
"[center]" + Texts.common[77],
|
|
"\t\t" + Texts.common[78],
|
|
"",
|
|
"[center]" + Texts.common[78],
|
|
"\t\t" + Texts.common[79] + "\t\t\t\t[color=#202020]" + Texts.common[80] + "\t\t\t\t" + Texts.common[81],
|
|
"[center]" + Texts.common[82],
|
|
"[center][color=red]" + Texts.common[83],
|
|
"",
|
|
"[center]" + Texts.common[86]
|
|
};
|
|
}
|
|
|
|
private void UpdateLangHeader()
|
|
{
|
|
langList.label.Text = "[center]" + langs[langList.current][0];
|
|
}
|
|
|
|
private void LangSelected()
|
|
{
|
|
Settings.file.lang = langs[langList.current][2];
|
|
Texts.LoadText();
|
|
SetMes();
|
|
_Ready();
|
|
lastLang = Settings.file.lang;
|
|
for (int i = 0; i < saves.Length; i++)
|
|
{
|
|
SetFileText(in i);
|
|
}
|
|
langList.QueueFree();
|
|
}
|
|
|
|
public override void _Ready()
|
|
{
|
|
opt[0].Text = mes[1];
|
|
opt[1].Text = "";
|
|
opt[2].Text = "";
|
|
top.Text = mes[0];
|
|
}
|
|
|
|
private void SetOpt()
|
|
{
|
|
opt[0].Text = "\t\t" + Texts.common[79];
|
|
opt[1].Text = ((saves[file] == null) ? "[color=#202020]" : "") + "\t\t" + Texts.common[80];
|
|
opt[2].Text = ((saves[file] == null) ? "[color=#202020]" : "") + "\t\t" + Texts.common[81];
|
|
}
|
|
|
|
public override void _Process(double delta)
|
|
{
|
|
if (delay != null)
|
|
{
|
|
return;
|
|
}
|
|
switch (current)
|
|
{
|
|
case -2:
|
|
if (!GodotObject.IsInstanceValid(langList))
|
|
{
|
|
introsound = Audio.PlaySound(intronoise);
|
|
current = 0;
|
|
logo.ProcessMode = ProcessModeEnum.Inherit;
|
|
}
|
|
break;
|
|
case -1:
|
|
base.Modulate = base.Modulate.Lerp(Main.colorClear, 0.1f * Main.deltaTime);
|
|
break;
|
|
case 0:
|
|
if (sec < 630f)
|
|
{
|
|
sec += Main.deltaTime;
|
|
if (Input.IsActionJustPressed(Main.keys[4]))
|
|
{
|
|
current = 1;
|
|
sec = 0f;
|
|
Audio.FadeSound(introsound, 2f);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
current = 2;
|
|
}
|
|
break;
|
|
case 1:
|
|
if (sec < 60f)
|
|
{
|
|
sec += Main.deltaTime;
|
|
logo.Modulate = Main.colorWhite.Lerp(Main.colorClear, sec / 60f);
|
|
}
|
|
else
|
|
{
|
|
current = 2;
|
|
}
|
|
break;
|
|
case 2:
|
|
if (!Audio.music.Playing)
|
|
{
|
|
Audio.ChangeMusic(music);
|
|
}
|
|
soul.Position = optPos[option];
|
|
fileMenu.Modulate = fileMenu.Modulate.Lerp(Main.colorWhite, 0.1f * Main.deltaTime);
|
|
if (Input.IsActionJustPressed(Main.keys[0]) || Input.IsActionJustPressed(Main.keys[2]))
|
|
{
|
|
option = (int)Main.Repeat(option - 1, (subOption == 0) ? 4 : 3);
|
|
Audio.PlaySound(Audio.commonSounds[0]);
|
|
}
|
|
else if (Input.IsActionJustPressed(Main.keys[1]) || Input.IsActionJustPressed(Main.keys[3]))
|
|
{
|
|
option = (int)Main.Repeat(option + 1, (subOption == 0) ? 4 : 3);
|
|
Audio.PlaySound(Audio.commonSounds[0]);
|
|
}
|
|
else if (Input.IsActionJustPressed(Main.keys[4]))
|
|
{
|
|
if (option != 3)
|
|
{
|
|
if (subOption == 0)
|
|
{
|
|
Audio.PlaySound(Audio.commonSounds[2]);
|
|
file = option;
|
|
option = 0;
|
|
current = 4;
|
|
SetOpt();
|
|
top.Text = "[center]" + Texts.common[87].Replace("@", (file + 1).ToString());
|
|
}
|
|
else if (file == option)
|
|
{
|
|
Audio.PlaySound(Audio.commonSounds[1]);
|
|
}
|
|
else
|
|
{
|
|
FileCopy();
|
|
Audio.PlaySound(Audio.commonSounds[2]);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Audio.PlaySound(Audio.commonSounds[2]);
|
|
fileMenu.Visible = false;
|
|
settingsBox.AddChild(settings = GD.Load<PackedScene>("res://Objects/UI/Settings.tscn").Instantiate<Settings>(PackedScene.GenEditState.Disabled), forceReadableName: false, InternalMode.Disabled);
|
|
settings.Position = new Vector2(27f, 14f);
|
|
current = 3;
|
|
settingsBox.Visible = true;
|
|
}
|
|
}
|
|
else if (Input.IsActionJustPressed(Main.keys[5]) && subOption > 0)
|
|
{
|
|
Cancel();
|
|
}
|
|
break;
|
|
case 3:
|
|
if (!GodotObject.IsInstanceValid(settings))
|
|
{
|
|
settings = null;
|
|
current = 2;
|
|
settingsBox.Visible = false;
|
|
fileMenu.Visible = true;
|
|
}
|
|
break;
|
|
case 4:
|
|
soul.Position = optPos[3 + option];
|
|
if (Input.IsActionJustPressed(Main.keys[0]) || Input.IsActionJustPressed(Main.keys[2]))
|
|
{
|
|
option = (int)Main.Repeat(option - 1, (subOption == 0) ? 3 : 2);
|
|
Audio.PlaySound(Audio.commonSounds[0]);
|
|
}
|
|
else if (Input.IsActionJustPressed(Main.keys[1]) || Input.IsActionJustPressed(Main.keys[3]))
|
|
{
|
|
option = (int)Main.Repeat(option + 1, (subOption == 0) ? 3 : 2);
|
|
Audio.PlaySound(Audio.commonSounds[0]);
|
|
}
|
|
else if (Input.IsActionJustPressed(Main.keys[4]))
|
|
{
|
|
if (subOption == 1)
|
|
{
|
|
if (option == 0)
|
|
{
|
|
subOption = 0;
|
|
opt[0].Text = "\t\t" + Texts.common[79];
|
|
opt[1].Text = "\t\t" + Texts.common[80];
|
|
opt[2].Text = "\t\t" + Texts.common[81];
|
|
top.Text = mes[0];
|
|
option = 2;
|
|
}
|
|
else
|
|
{
|
|
FileDelete();
|
|
}
|
|
Audio.PlaySound(Audio.commonSounds[2]);
|
|
}
|
|
else
|
|
{
|
|
if (subOption != 0)
|
|
{
|
|
break;
|
|
}
|
|
if (saves[file] == null && option != 0)
|
|
{
|
|
Audio.PlaySound(Audio.commonSounds[1]);
|
|
break;
|
|
}
|
|
Audio.PlaySound(Audio.commonSounds[2]);
|
|
switch (option)
|
|
{
|
|
case 0:
|
|
Main.inEvent = Coroutine.Start(LoadFile(file));
|
|
current = -1;
|
|
break;
|
|
case 1:
|
|
subOption = 2;
|
|
top.Text = mes[5];
|
|
opt[0].Text = "";
|
|
opt[1].Text = "";
|
|
opt[2].Text = "";
|
|
option = file;
|
|
current = 2;
|
|
files[file].Modulate = Main.colorYellow;
|
|
break;
|
|
case 2:
|
|
subOption = 1;
|
|
opt[0].Text = "\t\t" + Texts.common[84];
|
|
opt[1].Text = "\t\t[color=red]" + Texts.common[85];
|
|
opt[2].Text = "";
|
|
top.Text = mes[6];
|
|
option = 0;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else if (Input.IsActionJustPressed(Main.keys[5]))
|
|
{
|
|
Cancel();
|
|
}
|
|
break;
|
|
case 5:
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void Cancel()
|
|
{
|
|
subOption = 0;
|
|
current = 2;
|
|
option = file;
|
|
_Ready();
|
|
for (int i = 0; i < files.Length; i++)
|
|
{
|
|
files[i].Modulate = Main.colorWhite;
|
|
}
|
|
}
|
|
|
|
private void FileCopy()
|
|
{
|
|
using FileAccess fileAccess = FileAccess.Open("user://Save" + option + ".dat", FileAccess.ModeFlags.Write);
|
|
fileAccess.StoreString(JsonConvert.SerializeObject(saves[file]));
|
|
fileAccess.Close();
|
|
Cancel();
|
|
_EnterTree();
|
|
top.Text = mes[8];
|
|
}
|
|
|
|
private void FileDelete()
|
|
{
|
|
Error error = DirAccess.RemoveAbsolute("user://Save" + file + ".dat");
|
|
saves = null;
|
|
current = 2;
|
|
option = file;
|
|
subOption = 0;
|
|
_Ready();
|
|
_EnterTree();
|
|
if (error == Error.Ok)
|
|
{
|
|
Audio.PlaySound("AUDIO_APPEARANCE.wav");
|
|
}
|
|
else
|
|
{
|
|
Audio.PlaySound("snd_error.wav");
|
|
}
|
|
top.Text = ((error == Error.Ok) ? mes[8] : ("[center][color=red]" + Texts.common[88]));
|
|
delay = null;
|
|
}
|
|
|
|
public static IEnumerator LoadFile(int id, bool skip = false)
|
|
{
|
|
Audio.ChangeMusic(null);
|
|
if (!skip)
|
|
{
|
|
for (float a = 0f; a < 30f; a += Main.deltaTime)
|
|
{
|
|
instance.Modulate = Main.colorWhite.Lerp(Main.colorClear, a / 30f);
|
|
yield return null;
|
|
}
|
|
for (float a = 0f; a < 30f; a += Main.deltaTime)
|
|
{
|
|
yield return null;
|
|
}
|
|
}
|
|
instance.QueueFree();
|
|
instance = null;
|
|
if (saves[id] == null)
|
|
{
|
|
SaveFile.current.time = new int[3];
|
|
CameraController.instance.AddChild(GD.Load<PackedScene>("res://Objects/Events/Intro.tscn").Instantiate(PackedScene.GenEditState.Disabled), forceReadableName: false, InternalMode.Disabled);
|
|
}
|
|
else
|
|
{
|
|
SaveFile.current = saves[id];
|
|
SaveFile.current.LoadStats();
|
|
if (SaveFile.HasFlag(SaveFile.Flags.JuneRecessDay2))
|
|
{
|
|
SaveFile.AddFlag(SaveFile.Flags.SchoolRecessDay2);
|
|
}
|
|
CameraController.Transition(Main.colorBlack);
|
|
yield return null;
|
|
Room.LoadRoom(SaveFile.current.room);
|
|
yield return null;
|
|
SetPlayer();
|
|
yield return null;
|
|
Player.instance.GlobalPosition = SaveFile.current.position;
|
|
CameraController.instance.GlobalPosition = Player.instance.GlobalPosition + CameraController.instance.offset;
|
|
Player.instance.UpdateAnim(force: true);
|
|
yield return null;
|
|
Player.instance.FollowerSetUp();
|
|
CameraController.Transition(Main.colorClearB, 30f);
|
|
Room.current.DoMusic();
|
|
yield return null;
|
|
Room.SpawnFollowers();
|
|
Player.instance.GetParent().MoveChild(Player.instance, Player.instance.GetParent().GetChildCount() - 1);
|
|
yield return null;
|
|
while (true)
|
|
{
|
|
Coroutine transitionRoutine = CameraController.transitionRoutine;
|
|
if (transitionRoutine == null || transitionRoutine.done)
|
|
{
|
|
break;
|
|
}
|
|
yield return null;
|
|
}
|
|
Player.instance.canInput = true;
|
|
Party.UpdateStats();
|
|
}
|
|
SaveFile.current.slot = id;
|
|
}
|
|
|
|
public static Entity SetPlayer()
|
|
{
|
|
Entity en;
|
|
Room.current.AddChild(en = GD.Load<PackedScene>("res://Objects/Characters/Clover.tscn").Instantiate<Entity>(PackedScene.GenEditState.Disabled), forceReadableName: false, InternalMode.Disabled);
|
|
Common.SwapType<Entity, Player>(ref en, "Entities/");
|
|
en._EnterTree();
|
|
return en;
|
|
}
|
|
|
|
}
|