refactor: enhance GameStateStore integration and improve skill management
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using Godot;
|
||||
using Godot.Collections;
|
||||
using Mr.BrickAdventures.scripts;
|
||||
using Mr.BrickAdventures.scripts.State;
|
||||
|
||||
namespace Mr.BrickAdventures.Autoloads;
|
||||
|
||||
@@ -24,14 +25,14 @@ public partial class GhostManager : Node
|
||||
public void StartRecording(int levelIndex)
|
||||
{
|
||||
if (!IsPlaybackEnabled) return;
|
||||
|
||||
|
||||
_currentLevelIndex = levelIndex;
|
||||
_currentRecording.Clear();
|
||||
_startTime = Time.GetTicksMsec() / 1000.0;
|
||||
IsRecording = true;
|
||||
GD.Print("Ghost recording started.");
|
||||
}
|
||||
|
||||
|
||||
public void StopRecording(bool levelCompleted, double finalTime)
|
||||
{
|
||||
if (!IsRecording) return;
|
||||
@@ -48,23 +49,22 @@ public partial class GhostManager : Node
|
||||
}
|
||||
_currentRecording.Clear();
|
||||
}
|
||||
|
||||
|
||||
public void RecordFrame(Vector2 position)
|
||||
{
|
||||
if (!IsRecording) return;
|
||||
|
||||
var frame = new GhostFrame
|
||||
_currentRecording.Add(new GhostFrame
|
||||
{
|
||||
Timestamp = (Time.GetTicksMsec() / 1000.0) - _startTime,
|
||||
Position = position
|
||||
};
|
||||
_currentRecording.Add(frame);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void SpawnGhostPlayer(int levelIndex, Node parent)
|
||||
{
|
||||
if (!IsPlaybackEnabled || GhostPlayerScene == null) return;
|
||||
|
||||
|
||||
var ghostData = LoadGhostData(levelIndex);
|
||||
if (ghostData.Count > 0)
|
||||
{
|
||||
@@ -74,44 +74,63 @@ public partial class GhostManager : Node
|
||||
GD.Print($"Ghost player spawned for level {levelIndex}.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void SaveGhostData(int levelIndex, double time)
|
||||
{
|
||||
var path = $"user://ghost_level_{levelIndex}.dat";
|
||||
using var file = FileAccess.Open(path, FileAccess.ModeFlags.Write);
|
||||
|
||||
var dataToSave = new Godot.Collections.Dictionary
|
||||
var path = $"user://ghost_level_{levelIndex}.json";
|
||||
var saveData = new GhostSaveData { BestTime = time };
|
||||
foreach (var frame in _currentRecording)
|
||||
saveData.Frames.Add(new GhostFrameDto { Timestamp = frame.Timestamp, X = frame.Position.X, Y = frame.Position.Y });
|
||||
|
||||
try
|
||||
{
|
||||
{ "time", time },
|
||||
{ "frames", _currentRecording.ToArray() }
|
||||
};
|
||||
file.StoreVar(dataToSave);
|
||||
var json = JsonSerializer.Serialize(saveData, SaveSystem.JsonOptions);
|
||||
using var file = FileAccess.Open(path, FileAccess.ModeFlags.Write);
|
||||
file.StoreString(json);
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
GD.PrintErr($"GhostManager: Failed to save ghost data: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private List<GhostFrame> LoadGhostData(int levelIndex)
|
||||
{
|
||||
var path = $"user://ghost_level_{levelIndex}.dat";
|
||||
var path = $"user://ghost_level_{levelIndex}.json";
|
||||
if (!FileAccess.FileExists(path)) return [];
|
||||
|
||||
using var file = FileAccess.Open(path, FileAccess.ModeFlags.Read);
|
||||
var savedData = (Dictionary)file.GetVar();
|
||||
var framesArray = (Array)savedData["frames"];
|
||||
|
||||
var frames = new List<GhostFrame>();
|
||||
foreach (var obj in framesArray)
|
||||
try
|
||||
{
|
||||
frames.Add((GhostFrame)obj);
|
||||
using var file = FileAccess.Open(path, FileAccess.ModeFlags.Read);
|
||||
var saveData = JsonSerializer.Deserialize<GhostSaveData>(file.GetAsText(), SaveSystem.JsonOptions);
|
||||
if (saveData == null) return [];
|
||||
|
||||
var frames = new List<GhostFrame>();
|
||||
foreach (var dto in saveData.Frames)
|
||||
frames.Add(new GhostFrame { Timestamp = dto.Timestamp, Position = new Vector2(dto.X, dto.Y) });
|
||||
return frames;
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
GD.PrintErr($"GhostManager: Failed to load ghost data: {e.Message}");
|
||||
return [];
|
||||
}
|
||||
return frames;
|
||||
}
|
||||
|
||||
|
||||
private double LoadBestTime(int levelIndex)
|
||||
{
|
||||
var path = $"user://ghost_level_{levelIndex}.dat";
|
||||
var path = $"user://ghost_level_{levelIndex}.json";
|
||||
if (!FileAccess.FileExists(path)) return double.MaxValue;
|
||||
|
||||
using var file = FileAccess.Open(path, FileAccess.ModeFlags.Read);
|
||||
var data = (Dictionary)file.GetVar();
|
||||
return (double)data["time"];
|
||||
try
|
||||
{
|
||||
using var file = FileAccess.Open(path, FileAccess.ModeFlags.Read);
|
||||
var saveData = JsonSerializer.Deserialize<GhostSaveData>(file.GetAsText(), SaveSystem.JsonOptions);
|
||||
return saveData?.BestTime ?? double.MaxValue;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return double.MaxValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user