163 lines
5.8 KiB
C#
163 lines
5.8 KiB
C#
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using UnityEngine;
|
|
|
|
namespace TKS
|
|
{
|
|
/// <summary>
|
|
/// 시나리오 이벤트 표(2026-11-12 PD 「스테이지 선택 때 전장 설명 · 보스 등장 포커스 + 대사 + 등장 연출」 · 개발 요청서 C1·C2).
|
|
/// SOT = 조직 레포 `공유/기획팀_산출물/삼국지슬링샷/tables/` → 사본 `Assets/Resources/Scenario/*.csv`(utf-8-sig · 고친 뒤 기획 tables 도 같이).
|
|
/// stage_story.csv = n_chapter,n_stage,s_desc_ko,Memo · boss_intro.csv = n_chapter,n_stage,n_order,s_boss_id,s_title_ko,s_line_ko,Memo ·
|
|
/// boss_intro_config.csv = s_key,f_value,Memo — 값은 전부 표에서 읽는다(C45 · 코드에 값 없음).
|
|
/// </summary>
|
|
public static class ScenarioData
|
|
{
|
|
public const string Root = "Scenario/";
|
|
|
|
public class BossLine
|
|
{
|
|
public int chapter;
|
|
public int stage;
|
|
public int order;
|
|
public string id;
|
|
public string title;
|
|
public string line;
|
|
}
|
|
|
|
static bool loaded;
|
|
static readonly Dictionary<long, string> desc = new Dictionary<long, string>();
|
|
static readonly List<BossLine> bosses = new List<BossLine>();
|
|
static readonly Dictionary<string, float> cfg = new Dictionary<string, float>();
|
|
static readonly HashSet<string> missingReported = new HashSet<string>();
|
|
|
|
/// <summary>읽기 오류(형식 · 빠진 칸 · 없는 키) — 데이터 검사 테스트가 0 인지 본다.</summary>
|
|
public static readonly List<string> Errors = new List<string>();
|
|
|
|
public static void Reload()
|
|
{
|
|
loaded = false;
|
|
Load();
|
|
}
|
|
|
|
static void Load()
|
|
{
|
|
if (loaded) return;
|
|
loaded = true;
|
|
desc.Clear();
|
|
bosses.Clear();
|
|
cfg.Clear();
|
|
Errors.Clear();
|
|
missingReported.Clear();
|
|
|
|
foreach (var r in Rows("stage_story"))
|
|
{
|
|
int c = Int(r, "n_chapter", "stage_story"), s = Int(r, "n_stage", "stage_story");
|
|
desc[Key(c, s)] = Get(r, "s_desc_ko");
|
|
}
|
|
foreach (var r in Rows("boss_intro"))
|
|
{
|
|
bosses.Add(new BossLine
|
|
{
|
|
chapter = Int(r, "n_chapter", "boss_intro"),
|
|
stage = Int(r, "n_stage", "boss_intro"),
|
|
order = Int(r, "n_order", "boss_intro"),
|
|
id = Get(r, "s_boss_id"),
|
|
title = Get(r, "s_title_ko"),
|
|
line = Get(r, "s_line_ko"),
|
|
});
|
|
}
|
|
bosses.Sort((a, b) => a.chapter != b.chapter ? a.chapter.CompareTo(b.chapter) : a.stage != b.stage ? a.stage.CompareTo(b.stage) : a.order.CompareTo(b.order));
|
|
foreach (var r in Rows("boss_intro_config"))
|
|
{
|
|
float v;
|
|
if (float.TryParse(Get(r, "f_value"), NumberStyles.Float, CultureInfo.InvariantCulture, out v)) cfg[Get(r, "s_key")] = v;
|
|
else Errors.Add("boss_intro_config.csv 행 " + Get(r, "#") + ": f_value 숫자 아님");
|
|
}
|
|
foreach (var e in Errors) Debug.LogError("[TKS] 시나리오 표 " + e);
|
|
}
|
|
|
|
static List<Dictionary<string, string>> Rows(string file)
|
|
{
|
|
var ta = Resources.Load<TextAsset>(Root + file);
|
|
if (ta == null)
|
|
{
|
|
Errors.Add("Resources/" + Root + file + ".csv 없음");
|
|
return new List<Dictionary<string, string>>();
|
|
}
|
|
return StageTable.ReadCsv(ta.text, file + ".csv", Errors);
|
|
}
|
|
|
|
static long Key(int chapter, int stage)
|
|
{
|
|
return chapter * 1000L + stage;
|
|
}
|
|
|
|
static string Get(Dictionary<string, string> r, string k)
|
|
{
|
|
string v;
|
|
return r.TryGetValue(k, out v) ? v : "";
|
|
}
|
|
|
|
static int Int(Dictionary<string, string> r, string k, string file)
|
|
{
|
|
int v;
|
|
if (int.TryParse(Get(r, k), NumberStyles.Integer, CultureInfo.InvariantCulture, out v)) return v;
|
|
Errors.Add(file + ".csv 행 " + Get(r, "#") + ": " + k + " 정수 아님");
|
|
return 0;
|
|
}
|
|
|
|
/// <summary>스테이지 선택 팝업의 전장 설명(없으면 "").</summary>
|
|
public static string Desc(int chapter, int stage)
|
|
{
|
|
Load();
|
|
string s;
|
|
return desc.TryGetValue(Key(chapter, stage), out s) ? s : "";
|
|
}
|
|
|
|
/// <summary>그 스테이지의 보스 등장 행(n_order 순 · 없으면 빈 목록).</summary>
|
|
public static List<BossLine> Bosses(int chapter, int stage)
|
|
{
|
|
Load();
|
|
return bosses.FindAll(b => b.chapter == chapter && b.stage == stage);
|
|
}
|
|
|
|
public static IList<BossLine> AllBosses
|
|
{
|
|
get
|
|
{
|
|
Load();
|
|
return bosses;
|
|
}
|
|
}
|
|
|
|
public static IEnumerable<KeyValuePair<long, string>> AllDesc
|
|
{
|
|
get
|
|
{
|
|
Load();
|
|
return desc;
|
|
}
|
|
}
|
|
|
|
/// <summary>연출 값(boss_intro_config.csv) — 키가 없으면 콘솔 오류 1회 + 0.</summary>
|
|
public static float Cfg(string key)
|
|
{
|
|
Load();
|
|
float v;
|
|
if (cfg.TryGetValue(key, out v)) return v;
|
|
if (missingReported.Add(key))
|
|
{
|
|
Errors.Add("boss_intro_config.csv 에 키 없음: " + key);
|
|
Debug.LogError("[TKS] boss_intro_config.csv 에 키 없음: " + key);
|
|
}
|
|
return 0f;
|
|
}
|
|
|
|
public static bool HasCfg(string key)
|
|
{
|
|
Load();
|
|
return cfg.ContainsKey(key);
|
|
}
|
|
}
|
|
}
|