ThreeKingdomsSlingshot/Assets/Scripts/OutGame/OutGameCaptureDriverC.cs

165 lines
6.8 KiB
C#
Raw Permalink Normal View History

아웃게임 2차(PD #1093 세션 C) — 내정(훈련·순찰·개발) · 보물(수집품·세트·상자) · 연무장(탑·일일 던전·투기장·적장 토벌) · 거래 상자 탭 + 영웅 56명 확장(PD #1096 · 신규 effect_key 4) - 데이터: C 표 10장(training · training_ranks · patrol · dev_tree · treasures · treasure_sets · chests(+iron/buy 열) · tower · dungeons(+reward_amount) · arena(+상점 키)) + economy.csv C 키 24 → 임포트 18 자산(OutGameTables.C.cs 검증: 행·연속 Lv/랭크/층·참조·확률 합 1·선행 노드·효과 키 처리기·카운터 키 · 오류 시 자산 불변) - 영웅 56명: heroes 71 · skills 112 · hero_gear 1344 · gacha_pool 71 재복사 · 신규 키 4(team_dmg_pct_turn · cooldown_add · charm · heal_self_pct) + 기존 키 조건 열(받는 피해 p2 HP 임계/보스/근접 · p3 출전 인원 아군 전원 · 최대 HP·반격 아군 전원 · 피해 % 발동 턴) · 대장군 키는 표 미사용(처리기 유지) - 내정: 훈련(병종 5 · 3항목 Lv · cost_mult · 랭크 승급 · train_bonus → §3-2 항목별) · 순찰(챕터 행 × 시간 · 오프라인 · 상한 12h + 농업 · 소수점 이월 · 광고 2배 스텁 · 즉시 수확 보옥) · 개발(갈래 3 · 선행 · 골드·도면 비용 · 효과 키 → 군량·보상·상점·순찰·상자 적용 지점 · 초기화 보옥 + 도면 환급) - 보물: 보유 중(4열 · 등급 색 · 상세·강화) · 세트(단계 효과) · 상자(포인트 → 명장 · 확률 · 중복 조각) · 효과 hp/atk/def → HeroRules · crit/range/splash → BattleManager.SideEffectsProvider → SkillMods · 조건 카운터 8종 = Runtime/BattleEvents(전투 코드 Raise 1줄씩 · 아군만) · 스테이지 청동 상자 10 % - 연무장: BattleManager.StartMode(BattleMode = 적 편성·제한 턴·onExit) · 탑 100층(입장권·층 배율·보상·10층 상자) · 던전 3(요일·2/일·보상) · 투기장(샘플 10 · EnemyAI 방어 · 메달·주간 순위·조각 상점) · 적장 토벌(주간 순환·hp ×20·5턴·누적 피해·명장 상자·천기) · 결과 패널 → 탭 = 연무장 - 거래: 상자 탭(구매 = 골드/보옥/포인트 · 거래 할인) · 패스·월정액·챕터 팩·첫 결제 팩 = 준비 중 스텁 · 스킬서 임시 판매 제거(사당 던전) - 테스트 87/87(기존 73 유지 · 갱신 3 = 로비 탭 · 표 키 목록 · 상점 스킬서 칸 / 신규 14 = OutGameCTests 12 + 확장 키 2) · console error 0 · 캡처 = DataImporter.CaptureC Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 15:22:54 +00:00
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
namespace TKS.OutGame
{
/// <summary>
/// 아웃게임 2차 화면 검증 캡처(PD #1093 C · 에디터 DataImporter.CaptureC 가 SessionState 로 출력 폴더를 넘기면 생성 · 세이브 = 메모리 전용 신규 유저).
/// 캡처용 재화·진행을 넣은 뒤 훈련 · 순찰 · 개발 · 보물 보유/세트/상자 · 탑 · 던전 · 투기장 · 도감 10장 + log · 끝나면 스스로 종료.
/// </summary>
public class OutGameCaptureDriverC : MonoBehaviour
{
public const string DirKey = "TKS_OUTGAME_C_CAPTURE_DIR";
public string OutputDir;
public int Width = 720;
public int Height = 1280;
readonly List<string> log = new List<string>();
int shot = 1;
#if UNITY_EDITOR
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
static void AutoSpawn()
{
string dir = UnityEditor.SessionState.GetString(DirKey, "");
if (string.IsNullOrEmpty(dir)) return;
UnityEditor.SessionState.EraseString(DirKey);
var d = new GameObject("OutGameCaptureDriverC").AddComponent<OutGameCaptureDriverC>();
d.OutputDir = dir;
}
#endif
IEnumerator Start()
{
Directory.CreateDirectory(OutputDir);
yield return null;
yield return null;
var root = OutGameRoot.Instance;
var cam = Camera.main;
if (root == null || cam == null)
{
Log("FAIL: OutGameRoot 또는 카메라 없음");
Finish(1);
yield break;
}
var s = root.Session;
var db = s.Db;
var d = s.Save;
Log("memoryOnly=" + SaveStore.MemoryOnly + " newUser=" + s.IsNewUser + " heroes(db)=" + db.Heroes.heroes.Count + " treasures(db)=" + db.Treasures.items.Count);
// 캡처용 진행(메모리 세이브만): 재화 · 훈련(보병 HP·공 Max · 방 9) · 순찰 7시간 · 개발 일부 · 상자 열기로 보물 · 상자 보유 · 포인트
d.gold = 120000;
d.gem = 3000;
d.inv.blueprint = 30;
d.inv.iron = 300;
var inf = UnitType.Infantry;
for (int i = 0; i < db.Training.MaxLevel; i++)
{
TrainingRules.Level(db, d, inf, 0);
TrainingRules.Level(db, d, inf, 1);
if (i < db.Training.MaxLevel - 1) TrainingRules.Level(db, d, inf, 2);
}
d.patrol.startAt = SaveStore.Iso(s.Now.AddHours(-7));
var first = db.Dev.InBranch(db.Dev.Branches[0]);
for (int i = 0; i < first[0].lvMax; i++) DevRules.Upgrade(db, d, first[0].id);
for (int i = 0; i < 4 && first.Count > 1; i++) DevRules.Upgrade(db, d, first[1].id);
var rng = new System.Random(1093);
Counts.Set(d.inv.chests, "gold", 6);
Counts.Set(d.inv.chests, "silver", 10);
for (int i = 0; i < 6; i++) TreasureRules.Open(db, d, "gold", rng);
for (int i = 0; i < 10; i++) TreasureRules.Open(db, d, "silver", rng);
foreach (var t in d.inv.treasures)
if (t.star == 0 && rng.NextDouble() < 0.6) t.star = 1 + rng.Next(3);
Counts.Set(d.inv.chests, "bronze", 4);
Counts.Set(d.inv.chests, "silver", 18);
Counts.Set(d.inv.chests, "gold", 3);
Counts.Set(d.inv.chests, "general", 1);
d.inv.chestPoints = 35;
TreasureRules.AddCount(d, BattleEvents.Battles, 45);
s.Commit();
Log("seed: gold=" + d.gold + " treasures=" + d.inv.treasures.Count + " infantry rank=" + TrainingRules.Rank(d, inf) + " dev=" + DevRules.TotalLevels(d));
root.Show(root.Domestic);
root.Domestic.SetTrainType(inf);
root.Domestic.SetPage(0);
yield return Shot(cam, "domestic_training");
root.Domestic.SetPage(1);
var y = PatrolRules.Preview(db, d, PatrolRules.Hours(db, d, s.Now), 1f);
Log("patrol hours=" + PatrolRules.Hours(db, d, s.Now).ToString("0.00") + " gold=" + y.gold + " exp=" + y.exp + " gear=" + y.gear + " chests=" + y.chests);
yield return Shot(cam, "domestic_patrol");
root.Domestic.SetPage(2);
root.Domestic.SetBranch(0);
Log("dev nodes(branch 0)=" + root.Domestic.NodeCount + " gold_gain=" + DevRules.Mod(db, d, DevRules.GoldGain));
yield return Shot(cam, "domestic_dev");
root.Show(root.Treasures);
root.Treasures.SetPage(0);
Log("treasure grid=" + root.Treasures.GridCount + " owned=" + d.inv.treasures.Count + " atk%=" + TreasureRules.StatPct(db, d, "atk").ToString("0.##"));
yield return Shot(cam, "treasure_owned");
root.Treasures.SetPage(1);
yield return Shot(cam, "treasure_sets");
root.Treasures.SetPage(2);
root.Treasures.SelectChest("gem");
yield return Shot(cam, "treasure_chests");
root.Arena.SetPage(0);
root.Show(root.Arena);
yield return Wait();
root.Arena.SetPage(1);
Log("tower next=" + ArenaRules.TowerNext(db, d) + " tickets=" + d.arena.towerTickets);
yield return Shot(cam, "arena_tower");
root.Arena.SetPage(2);
yield return Shot(cam, "arena_dungeons");
root.Arena.SetPage(3);
Log("arena samples=" + d.arena.samples.Count + " rank=" + ArenaRules.Rank(d));
yield return Shot(cam, "arena_pvp");
root.Show(root.HeroList);
HeroDetailScreen.ShowCodex(root);
Log("codex heroes=" + db.Heroes.heroes.Count);
yield return Shot(cam, "hero_codex");
Finish(0);
}
static IEnumerator Wait()
{
yield return null;
yield return new WaitForSecondsRealtime(0.3f);
}
IEnumerator Shot(Camera cam, string name)
{
yield return Wait();
string file = Path.Combine(OutputDir, shot.ToString("00") + "_" + name + ".png");
shot++;
yield return CaptureUtil.Capture(cam, Width, Height, file);
Log("shot " + file);
}
void Log(string s)
{
log.Add(s);
Debug.Log("[OutGameCaptureC] " + s);
try
{
File.WriteAllLines(Path.Combine(OutputDir, "capture_log.txt"), log.ToArray());
}
catch
{
}
}
void Finish(int code)
{
Log("finish code=" + code);
#if UNITY_EDITOR
UnityEditor.EditorApplication.Exit(code);
#else
Application.Quit(code);
#endif
}
}
}