using Godot; using System; using System.Collections.Generic; using Models; using Core; /// /// 游戏主控制节点(MVC 的桥接层) /// 设计说明: /// 1) 负责初始化 GameSession,并把输入/信号转交给 Controller/System。 /// 2) 仅做“流程调度”,不直接计算复杂数值,避免逻辑堆积。 /// 注意事项: /// - View 与 Model 的绑定应逐步迁移到独立 View 脚本,避免在此类膨胀。 /// 未来扩展: /// - 可拆分为 SceneRoot + UIController + DebugController,分层管理。 /// public partial class GameManager : Node { /// /// 指示当前是否处于教程模式 /// public static bool IsTutorial { get; private set; } /// /// 下一个场景的路径 /// public static string NextScene { get; set; } = null; /// /// 双倍大小的箭头光标资源 /// public static readonly Resource Arrow2X = ResourceLoader.Load("res://temp_res/kenney_ui-pack-space-expansion/PNG/Extra/Double/cursor_f.png"); /// /// 最大回合数 /// [Export] public int MaxTurns = 30; // --- Global State --- /// /// 游戏会话实例 /// public GameSession Session { get; private set; } /// /// 当前游戏状态 /// public GameState State => Session?.State; /// /// 游戏控制器 /// public GameController Controller { get; private set; } /// /// 当前游戏阶段 /// public GamePhase CurrentPhase => State?.Turn.Phase ?? GamePhase.Planning; /// /// 当前回合数 /// public int CurrentTurn => State?.Turn.CurrentTurn ?? 1; // --- Domain Model --- /// /// 导师模型 /// public MentorModel Mentor => State?.Roster.Mentor; /// /// 学生列表 /// public List Students => State?.Roster.Students; /// /// 当前活动任务列表 /// public List ActiveTasks => State?.Tasks.ActiveTasks; /// /// 经济状态 /// public EconomyState Economy => State?.Economy; // --- Signals --- /// /// 阶段变更信号 /// /// 阶段枚举的整数值 [Signal] public delegate void PhaseChangedEventHandler(int phase); // int cast of GamePhase /// /// 回合变更信号 /// /// 当前回合数 [Signal] public delegate void TurnChangedEventHandler(int turn); // Singleton instance access (if needed, though Godot uses node paths) /// /// 单例实例 /// public static GameManager Instance { get; private set; } /// /// 进入场景树时调用 /// public override void _EnterTree() { Instance = this; } /// /// 准备就绪时调用 /// public override void _Ready() { Input.SetCustomMouseCursor(Arrow2X); // MVP Initialization InitializeGame(); } /// /// 初始化游戏数据 /// private void InitializeGame() { Session = GameSession.CreateDefault(); Controller = new GameController(); Controller.Initialize(Session); State.Turn.MaxTurns = MaxTurns; State.Turn.CurrentTurn = 1; State.Turn.Phase = GamePhase.Planning; // MVP: Add a test student var s1 = new StudentModel("张三"); Students.Add(s1); // MVP: Add a test task var t1 = new TaskModel("深度学习导论", TaskKind.AcademicExploration, 1000f, 3); t1.Reward.Money = 1000; t1.Reward.Reputation = 5; ActiveTasks.Add(t1); GD.Print("Game Initialized. Phase: Planning, Turn: 1"); } // Called every frame. 'delta' is the elapsed time since the previous frame. /// /// 每帧调用 /// /// 距离上一帧的时间间隔 public override void _Process(double delta) { if (CurrentPhase == GamePhase.Execution) { // Update game logic (timers, etc.) // In a real implementation, this might manage the global timer for the day/week } Session?.Tick((float)delta); } /// /// 结束筹备阶段,开始执行 /// public void StartExecution() { if (CurrentPhase != GamePhase.Planning) return; Controller.StartExecution(); EmitSignal(SignalName.PhaseChanged, (int)CurrentPhase); GD.Print("Phase Changed: Execution"); // Notify all agents to start working (this would be handled by a system listening to the signal) } /// /// 结束执行阶段(通常由时间耗尽或玩家手动触发),进入结算 /// public void EndExecution() { if (CurrentPhase != GamePhase.Execution) return; Controller.EndExecution(); EmitSignal(SignalName.PhaseChanged, (int)CurrentPhase); GD.Print("Phase Changed: Review"); PerformReview(); } /// /// 执行结算逻辑,并准备下一回合 /// private void PerformReview() { Session.Systems.Task.ResolveEndOfTurn(); Session.Events.Publish(new TurnEndedEvent(CurrentTurn)); GD.Print("Review Complete. Waiting for Next Turn confirmation."); } /// /// 开始新的回合 /// public void StartNextTurn() { if (CurrentPhase != GamePhase.Review) return; Controller.StartNextTurn(); if (CurrentTurn > State.Turn.MaxTurns) { GD.Print("Game Over!"); // Handle Game Over return; } State.Turn.Phase = GamePhase.Planning; EmitSignal(SignalName.TurnChanged, CurrentTurn); EmitSignal(SignalName.PhaseChanged, (int)CurrentPhase); // Refresh resources/AP Mentor.Resources.Energy.Current.Value = Mentor.Resources.Energy.UpperThreshold; GD.Print($"Turn {CurrentTurn} Started. Phase: Planning"); } }