using Godot; using System; using System.Collections.Generic; using Models; public partial class GameManager : Node { /// /// Indicates if the game is currently in tutorial mode. /// 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"); // --- Core Loop Definitions --- public enum GamePhase { Planning, // 筹备阶段:时间暂停,分配任务,购买设施 Execution, // 执行阶段:时间流动,学生工作 Review, // 结算阶段:回合结束,发工资,结算成果 } [Export] public int MaxTurns = 30; // --- Global State --- public static GamePhase CurrentPhase { get; private set; } = GamePhase.Planning; public static int CurrentTurn { get; private set; } = 1; // --- Domain Model --- public MentorModel Mentor { get; private set; } = new MentorModel(); public List Students { get; private set; } = new List(); public List ActiveTasks { get; private set; } = new List(); // --- 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() { CurrentTurn = 1; CurrentPhase = GamePhase.Planning; // MVP: Add a test student var s1 = new StudentModel("张三"); Students.Add(s1); // MVP: Add a test task var t1 = new Task("深度学习导论", TaskType.Paper, 1000f, 3); 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 } } /// /// 结束筹备阶段,开始执行 /// public void StartExecution() { if (CurrentPhase != GamePhase.Planning) return; CurrentPhase = GamePhase.Execution; 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; CurrentPhase = GamePhase.Review; EmitSignal(SignalName.PhaseChanged, (int)CurrentPhase); GD.Print("Phase Changed: Review"); PerformReview(); } /// /// 执行结算逻辑,并准备下一回合 /// private void PerformReview() { // 1. Task progress check foreach (var task in ActiveTasks) { task.Deadline--; if (task.IsCompleted) { GD.Print($"Task {task.Name} Completed!"); Mentor.Reputation += task.RewardReputation; Mentor.Money += task.RewardMoney; } else if (task.IsFailed) { GD.Print($"Task {task.Name} Failed!"); Mentor.Reputation -= 10; // Penalty } } // 2. Student status update (Salary, etc.) foreach (var student in Students) { // Deduct salary? Restore some stamina? } GD.Print("Review Complete. Waiting for Next Turn confirmation."); } /// /// 开始新的回合 /// public void StartNextTurn() { if (CurrentPhase != GamePhase.Review) return; CurrentTurn++; if (CurrentTurn > MaxTurns) { GD.Print("Game Over!"); // Handle Game Over return; } CurrentPhase = GamePhase.Planning; EmitSignal(SignalName.TurnChanged, CurrentTurn); EmitSignal(SignalName.PhaseChanged, (int)CurrentPhase); // Refresh resources/AP Mentor.Energy.Current = Mentor.Energy.UpperThreshold; GD.Print($"Turn {CurrentTurn} Started. Phase: Planning"); } }