using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
namespace TKS.EditorTools
{
///
/// 지형 기믹 표(Assets/Data/Gimmicks/{gimmicks,stage_gimmicks,tutorial_tips}.csv · 기획 tables/ 사본 · PD #1097) + 적 AI 가중치(Assets/Data/AI/ai_weights.csv · PD #1098)
/// → Resources/Gimmicks/GimmickDb · StageGimmickTable · Resources/AI/AiWeights. 메뉴 TKS/Import Gimmicks 또는
/// CLI: Unity.exe -batchmode -nographics -projectPath <proj> -executeMethod TKS.EditorTools.GimmickImporter.Import -quit
/// 형식·참조 오류(정의 id · 스테이지 · 모양 · params · 가중치 키)가 하나라도 있으면 자산을 건드리지 않는다.
///
public static class GimmickImporter
{
public const string AssetFolder = "Assets/Resources/Gimmicks";
public const string AiFolder = "Assets/Resources/AI";
[MenuItem("TKS/Import Gimmicks (기믹 임포트)")]
public static void Import()
{
ImportAll();
}
public static string[] ReadFiles()
{
var dir = Path.Combine(Application.dataPath, GimmickTables.Folder);
var texts = new string[GimmickTables.Files.Length];
for (int i = 0; i < texts.Length; i++)
{
var p = Path.Combine(dir, GimmickTables.Files[i]);
texts[i] = File.Exists(p) ? File.ReadAllText(p, Encoding.UTF8) : null;
}
return texts;
}
public static bool ImportAll()
{
var cfg = AssetDatabase.LoadAssetAtPath(ProjectSetup.ConfigPath);
System.Func exists = null;
if (cfg != null && cfg.stages != null && cfg.stages.Length > 0)
{
exists = (ch, st) =>
{
foreach (var s in cfg.stages)
{
if (s.chapter == ch && s.stage == st) return true;
}
return false;
};
}
var r = GimmickTables.Parse(ReadFiles(), exists);
var aiPath = Path.Combine(Application.dataPath, AiWeights.CsvPath);
var aiEntries = AiWeights.Parse(File.Exists(aiPath) ? File.ReadAllText(aiPath, Encoding.UTF8) : null, r.errors);
if (r.errors.Count > 0)
{
foreach (var e in r.errors) Debug.LogError("[TKS] 기믹 표 오류 · " + e);
Debug.LogError("[TKS] 기믹 임포트 중단(오류 " + r.errors.Count + ") · 자산 변경 없음");
return false;
}
EnsureFolder("Assets/Resources");
EnsureFolder(AssetFolder);
EnsureFolder(AiFolder);
var db = Load(AssetFolder + "/GimmickDb.asset");
db.defs = new List(r.defs);
EditorUtility.SetDirty(db);
var table = Load(AssetFolder + "/StageGimmickTable.asset");
table.rows = new List(r.rows);
table.tips = new List(r.tips);
EditorUtility.SetDirty(table);
var w = Load(AiFolder + "/AiWeights.asset");
w.entries = aiEntries;
EditorUtility.SetDirty(w);
AssetDatabase.SaveAssets();
GimmickTables.Invalidate();
AiWeights.Invalidate();
Debug.Log("[TKS] 기믹 임포트 완료 · 정의 " + r.defs.Count + " · 배치 " + r.rows.Count + " · 팁 " + r.tips.Count + " · AI 가중치 " + aiEntries.Count + " · " + AssetFolder);
return true;
}
static T Load(string path) where T : ScriptableObject
{
var a = AssetDatabase.LoadAssetAtPath(path);
if (a != null) return a;
a = ScriptableObject.CreateInstance();
AssetDatabase.CreateAsset(a, path);
return a;
}
static void EnsureFolder(string path)
{
if (AssetDatabase.IsValidFolder(path)) return;
var parent = Path.GetDirectoryName(path).Replace('\\', '/');
AssetDatabase.CreateFolder(parent, Path.GetFileName(path));
}
///
/// 기믹 검증 캡처(GUI 에디터 · 사본 프로젝트 권장 · 세이브 = 메모리 전용 · PD #1097):
/// Unity.exe -projectPath <copy> -executeMethod TKS.EditorTools.GimmickImporter.Capture -gimmickDir <dir>
/// 샘플 5 스테이지 1턴씩 + 조준선 반응 2장 + AI 함정 쪽 튕겨내기 1장 PNG + log · 끝나면 스스로 종료.
/// -gimmickStages 1-10,2-10,… 을 주면 그 스테이지들의 시작 화면(전장 전체)만 찍는다(145 배치 확인).
///
public static void Capture()
{
string dir = GetArg("-gimmickDir");
if (string.IsNullOrEmpty(dir)) dir = Path.Combine(Directory.GetCurrentDirectory(), "Logs", "gimmick_capture");
ImportAll();
EditorSceneManager.OpenScene(ProjectSetup.ScenePath, OpenSceneMode.Single);
SessionState.SetBool(OutGame.SaveStore.MemoryFlagKey, true);
SessionState.SetString(GimmickCaptureDriver.DirKey, dir);
SessionState.SetString(GimmickCaptureDriver.StagesKey, GetArg("-gimmickStages") ?? "");
Debug.Log("[TKS] 기믹 캡처 시작 → " + dir);
EditorApplication.EnterPlaymode();
}
static string GetArg(string name)
{
var args = System.Environment.GetCommandLineArgs();
for (int i = 0; i < args.Length - 1; i++)
if (args[i] == name) return args[i + 1];
return null;
}
}
}