319 lines
11 KiB
C#
319 lines
11 KiB
C#
using Godot;
|
|
|
|
namespace TheGame
|
|
{
|
|
public partial class AdvancedSaveDialog : AcceptDialog
|
|
{
|
|
private LineEdit _nameInput;
|
|
private CheckBox _newInstanceCheck;
|
|
private Label _infoLabel;
|
|
private Game _gameController;
|
|
private SaveData _existingSaveData;
|
|
|
|
public override void _Ready()
|
|
{
|
|
// Sätt process mode så att dialogen fungerar när spelet är pausat
|
|
ProcessMode = ProcessModeEnum.WhenPaused;
|
|
|
|
var loc = LocalizationManager.Instance;
|
|
Title = loc.GetText("save_dialog_title");
|
|
|
|
// Kontrollera om det finns befintlig save för denna seed
|
|
var saveManager = new SaveManager();
|
|
if (GameState.CurrentGameSeed != null)
|
|
{
|
|
_existingSaveData = saveManager.FindSaveDataBySeed(GameState.CurrentGameSeed);
|
|
}
|
|
|
|
CreateDialogContent();
|
|
|
|
// Sätt process mode på alla child nodes
|
|
SetProcessModeRecursive(this, ProcessModeEnum.WhenPaused);
|
|
}
|
|
|
|
private void CreateDialogContent()
|
|
{
|
|
var vbox = new VBoxContainer();
|
|
|
|
if (_existingSaveData == null || _existingSaveData.Instances.Count == 0)
|
|
{
|
|
// Första gången man sparar detta spel - bara namn input
|
|
CreateFirstTimeSaveUI(vbox);
|
|
}
|
|
else
|
|
{
|
|
// Det finns befintliga saves - visa alternativ
|
|
CreateExistingSaveUI(vbox);
|
|
}
|
|
|
|
AddChild(vbox);
|
|
}
|
|
|
|
private void CreateFirstTimeSaveUI(VBoxContainer vbox)
|
|
{
|
|
var loc = LocalizationManager.Instance;
|
|
|
|
var infoLabel = new Label();
|
|
infoLabel.Text = "This is your first save for this game.";
|
|
infoLabel.AutowrapMode = TextServer.AutowrapMode.WordSmart;
|
|
vbox.AddChild(infoLabel);
|
|
|
|
var separator = new HSeparator();
|
|
vbox.AddChild(separator);
|
|
|
|
// Save name input
|
|
var nameLabel = new Label();
|
|
nameLabel.Text = loc.GetText("save_dialog_enter_name");
|
|
vbox.AddChild(nameLabel);
|
|
|
|
_nameInput = new LineEdit();
|
|
_nameInput.PlaceholderText = loc.GetText("save_dialog_placeholder");
|
|
_nameInput.Text = $"Save {System.DateTime.Now:HH:mm:ss}";
|
|
vbox.AddChild(_nameInput);
|
|
|
|
// Anslut signaler
|
|
Confirmed += OnSaveConfirmed;
|
|
|
|
// Fokusera på text input - skjut upp till nästa frame
|
|
CallDeferred(nameof(FocusNameInput));
|
|
}
|
|
|
|
private void CreateExistingSaveUI(VBoxContainer vbox)
|
|
{
|
|
var latestInstance = _existingSaveData.GetLatestInstance();
|
|
|
|
var infoLabel = new Label();
|
|
infoLabel.Text = $"Game Seed: {_existingSaveData.GameSeed.ToString()}\nExisting saves: {_existingSaveData.Instances.Count}\nLatest: {latestInstance.DisplayName} ({latestInstance.GetFormattedGameTime()})";
|
|
infoLabel.AutowrapMode = TextServer.AutowrapMode.WordSmart;
|
|
vbox.AddChild(infoLabel);
|
|
|
|
var separator = new HSeparator();
|
|
vbox.AddChild(separator);
|
|
|
|
// Button för att skriva över senaste save
|
|
var overwriteButton = new Button();
|
|
overwriteButton.Text = "Save over the last save point";
|
|
overwriteButton.CustomMinimumSize = new Vector2(0, 40);
|
|
overwriteButton.Pressed += OnOverwriteLatestPressed;
|
|
vbox.AddChild(overwriteButton);
|
|
|
|
// Button för att skapa ny save point
|
|
var newSaveButton = new Button();
|
|
newSaveButton.Text = "Save a new save point";
|
|
newSaveButton.CustomMinimumSize = new Vector2(0, 40);
|
|
newSaveButton.Pressed += OnNewSavePressed;
|
|
vbox.AddChild(newSaveButton);
|
|
|
|
// Dölj standard OK-knappen
|
|
GetOkButton().Visible = false;
|
|
}
|
|
|
|
public void Initialize(Game gameController)
|
|
{
|
|
_gameController = gameController;
|
|
}
|
|
|
|
private void ShowErrorDialog(string message)
|
|
{
|
|
var errorDialog = new AcceptDialog();
|
|
errorDialog.DialogText = message;
|
|
errorDialog.Title = "Save Error";
|
|
errorDialog.ProcessMode = ProcessModeEnum.WhenPaused;
|
|
GetTree().Root.AddChild(errorDialog);
|
|
errorDialog.PopupCentered();
|
|
}
|
|
|
|
private void OnOverwriteLatestPressed()
|
|
{
|
|
// Skriv över senaste save utan att fråga om namn
|
|
if (_gameController != null)
|
|
{
|
|
var saveManager = new SaveManager();
|
|
float currentTime = _gameController.GetGameTime();
|
|
|
|
bool saveSuccess = saveManager.SaveGame(currentTime, "", GameState.CurrentGameSeed, true); // overwriteLatest = true
|
|
|
|
if (saveSuccess)
|
|
{
|
|
GameState.MarkProgressAsSaved(currentTime);
|
|
_gameController.TogglePause();
|
|
}
|
|
else
|
|
{
|
|
ShowErrorDialog("Failed to save the game. Please try again.");
|
|
return;
|
|
}
|
|
}
|
|
|
|
QueueFree();
|
|
}
|
|
|
|
private void OnNewSavePressed()
|
|
{
|
|
// Visa namn-input dialog för ny save point
|
|
ShowNameInputDialog();
|
|
}
|
|
|
|
private void ShowNameInputDialog()
|
|
{
|
|
// Rensa nuvarande innehåll
|
|
foreach (Node child in GetChildren())
|
|
{
|
|
if (child != GetOkButton())
|
|
{
|
|
child.QueueFree();
|
|
}
|
|
}
|
|
|
|
var vbox = new VBoxContainer();
|
|
|
|
var loc = LocalizationManager.Instance;
|
|
|
|
var nameLabel = new Label();
|
|
nameLabel.Text = loc.GetText("save_dialog_enter_name");
|
|
vbox.AddChild(nameLabel);
|
|
|
|
_nameInput = new LineEdit();
|
|
_nameInput.PlaceholderText = loc.GetText("save_dialog_placeholder");
|
|
_nameInput.Text = $"Save {System.DateTime.Now:HH:mm:ss}";
|
|
vbox.AddChild(_nameInput);
|
|
|
|
AddChild(vbox);
|
|
|
|
// Visa OK-knappen igen och anslut till ny save
|
|
GetOkButton().Visible = true;
|
|
|
|
// Ta bort tidigare signaler och lägg till ny
|
|
if (IsConnected("confirmed", new Callable(this, nameof(OnSaveConfirmed))))
|
|
{
|
|
Disconnect("confirmed", new Callable(this, nameof(OnSaveConfirmed)));
|
|
}
|
|
Confirmed += OnNewSaveConfirmed;
|
|
|
|
// Fokusera på text input
|
|
_nameInput.GrabFocus();
|
|
_nameInput.SelectAll();
|
|
}
|
|
|
|
private void OnNewSaveConfirmed()
|
|
{
|
|
if (_gameController != null)
|
|
{
|
|
string saveName = _nameInput.Text.Trim();
|
|
if (string.IsNullOrEmpty(saveName))
|
|
{
|
|
saveName = $"Save {System.DateTime.Now:HH:mm:ss}";
|
|
}
|
|
|
|
var saveManager = new SaveManager();
|
|
float currentTime = _gameController.GetGameTime();
|
|
|
|
bool saveSuccess = saveManager.SaveGame(currentTime, saveName, GameState.CurrentGameSeed, false); // overwriteLatest = false (ny instans)
|
|
|
|
if (saveSuccess)
|
|
{
|
|
GameState.MarkProgressAsSaved(currentTime);
|
|
_gameController.TogglePause();
|
|
}
|
|
else
|
|
{
|
|
ShowErrorDialog("Failed to save the game. Please try again.");
|
|
return;
|
|
}
|
|
}
|
|
|
|
QueueFree();
|
|
}
|
|
|
|
private void OnSaveConfirmed()
|
|
{
|
|
// För första gången man sparar
|
|
if (_gameController != null)
|
|
{
|
|
string saveName = _nameInput.Text.Trim();
|
|
if (string.IsNullOrEmpty(saveName))
|
|
{
|
|
saveName = $"Save {System.DateTime.Now:HH:mm:ss}";
|
|
}
|
|
|
|
var saveManager = new SaveManager();
|
|
float currentTime = _gameController.GetGameTime();
|
|
|
|
bool saveSuccess = saveManager.SaveGame(currentTime, saveName, GameState.CurrentGameSeed, false); // Första save är alltid ny instans
|
|
|
|
if (saveSuccess)
|
|
{
|
|
GameState.MarkProgressAsSaved(currentTime);
|
|
_gameController.TogglePause();
|
|
}
|
|
else
|
|
{
|
|
ShowErrorDialog("Failed to save the game. Please try again.");
|
|
return;
|
|
}
|
|
}
|
|
|
|
QueueFree();
|
|
}
|
|
|
|
private void SetProcessModeRecursive(Node node, ProcessModeEnum mode)
|
|
{
|
|
if (node is Control control)
|
|
{
|
|
control.ProcessMode = mode;
|
|
}
|
|
|
|
foreach (Node child in node.GetChildren())
|
|
{
|
|
SetProcessModeRecursive(child, mode);
|
|
}
|
|
}
|
|
|
|
public override void _Input(InputEvent @event)
|
|
{
|
|
if (!IsInsideTree())
|
|
return;
|
|
|
|
if (@event is InputEventKey keyEvent && keyEvent.Pressed)
|
|
{
|
|
if (keyEvent.Keycode == Key.Enter || keyEvent.Keycode == Key.KpEnter)
|
|
{
|
|
// Hantera Enter baserat på nuvarande state
|
|
if (_nameInput != null && _nameInput.Visible)
|
|
{
|
|
if (IsConnected("confirmed", new Callable(this, nameof(OnNewSaveConfirmed))))
|
|
{
|
|
OnNewSaveConfirmed();
|
|
}
|
|
else
|
|
{
|
|
OnSaveConfirmed();
|
|
}
|
|
}
|
|
if (IsInsideTree())
|
|
{
|
|
GetViewport().SetInputAsHandled();
|
|
}
|
|
}
|
|
else if (keyEvent.Keycode == Key.Escape)
|
|
{
|
|
Hide();
|
|
QueueFree();
|
|
if (IsInsideTree())
|
|
{
|
|
GetViewport().SetInputAsHandled();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void FocusNameInput()
|
|
{
|
|
if (_nameInput != null && IsInsideTree())
|
|
{
|
|
_nameInput.GrabFocus();
|
|
_nameInput.SelectAll();
|
|
}
|
|
}
|
|
}
|
|
} |