Files
aibis-dream/Assets/Scripts/Game Loop/ChapterController.cs
T

145 lines
4.4 KiB
C#

using System.Collections.Generic;
using System.IO;
using System.Linq;
using AibisDream.Kit;
using AibisDream.Utility;
using UnityEngine;
namespace AibisDream
{
public class ChapterController : Singleton<ChapterController>
{
private ChapterData ChapterData => GlobalDataContainer.Instance.GetData<ChapterData>();
/// <summary>
/// 获取章节列表用于显示
/// </summary>
/// <returns>章节列表</returns>
public List<ChapterVo> GetChapterList()
{
// 获取存档并提取章节信息
var cacheChapter = string.Empty;
if (ChapterData.TryGetSaveFilePath(out var saveFilePath))
{
cacheChapter = ParseChapterTitle(saveFilePath);
}
var sourceList = GameManager.Instance.GetAllSceneSos();
// 拼接章节列表
var chapterList = sourceList
.Where(item => ChapterData.unlockedChapterList.Contains(item.name))
.Select(chapterSo => new ChapterVo
{
chapterSo = chapterSo,
title = chapterSo.title,
chapter = chapterSo.chapter,
desc = chapterSo.description,
pic = chapterSo.coverPic,
hasSaveFile = cacheChapter == chapterSo.name
})
.ToList();
return chapterList;
}
private static string ParseChapterTitle(string filePath)
{
var fileName = Path.GetFileNameWithoutExtension(filePath);
var parts = fileName.Split('_');
// 文件名格式: yyyyMMdd-HHmmss_{sceneSoName}_{gameStage}
// sceneSoName 可能包含下划线,但时间戳(第0段)和游戏阶段(最后1段)不会
if (parts.Length < 3)
{
Debug.LogWarning($"存档文件名格式异常: {fileName}");
return string.Empty;
}
var sceneSoName = string.Join("_", parts, 1, parts.Length - 2);
Debug.Log($"ParseChapterTitle: 从 {fileName} 解析出章节名 = {sceneSoName}");
return sceneSoName;
}
public void StartWithChapter(ChapterVo chapterVo)
{
GameManager.Instance.StartWithLevel(chapterVo.chapterSo);
}
public void StartWithSaveFile()
{
// 获取当前存档
if (!ChapterData.TryGetSaveFilePath(out var saveFilePath))
{
Debug.LogError("未找到存档");
}
else
{
GameManager.Instance.StartWithSaveFile(saveFilePath);
}
}
public void UnlockChapter(TalkSceneSO chapterSo)
{
if (chapterSo.name == "GeneralEnd")
{
return;
}
if (!ChapterData.unlockedChapterList.Contains(chapterSo.name))
{
ChapterData.unlockedChapterList.Add(chapterSo.name);
ChapterData.SaveUnloadChapters();
}
}
}
[GlobalData]
public class ChapterData
{
public List<string> unlockedChapterList;
public ChapterData()
{
Directory.CreateDirectory(ConstRef.SaveFilePath);
LoadUnlockChapters();
}
private void LoadUnlockChapters()
{
unlockedChapterList = File.Exists(ConstRef.ChapterProgressPath)
? JsonUtil.ReadBeanArray<string>(ConstRef.ChapterProgressPath).ToList()
: new List<string> { GameManager.Instance.firstTalkSo.name };
}
public void SaveUnloadChapters()
{
JsonUtil.SaveArray(unlockedChapterList.ToArray(), ConstRef.ChapterProgressPath);
}
public bool TryGetSaveFilePath(out string saveFilePath)
{
var files = Directory.GetFiles(ConstRef.SaveFilePath, "*.json")
.OrderByDescending(fileName => fileName)
.ToArray();
if (files.Length <= 0)
{
saveFilePath = string.Empty;
return false;
}
saveFilePath = files[0];
return true;
}
}
public struct ChapterVo
{
public string title;
public string chapter;
public string desc;
public Sprite pic;
public bool hasSaveFile;
public TalkSceneSO chapterSo;
}
}