165 lines
4.2 KiB
C#
165 lines
4.2 KiB
C#
using Godot;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using Models;
|
|
|
|
public partial class GameManager : Node
|
|
{
|
|
/// <summary>
|
|
/// Indicates if the game is currently in tutorial mode.
|
|
/// </summary>
|
|
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; }
|
|
public List<StudentModel> Students { get; private set; } = new List<StudentModel>();
|
|
public List<Task> ActiveTasks { get; private set; } = new List<Task>();
|
|
|
|
// --- 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
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 结束筹备阶段,开始执行
|
|
/// </summary>
|
|
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)
|
|
}
|
|
|
|
/// <summary>
|
|
/// 结束执行阶段(通常由时间耗尽或玩家手动触发),进入结算
|
|
/// </summary>
|
|
public void EndExecution()
|
|
{
|
|
if (CurrentPhase != GamePhase.Execution) return;
|
|
|
|
CurrentPhase = GamePhase.Review;
|
|
EmitSignal(SignalName.PhaseChanged, (int)CurrentPhase);
|
|
GD.Print("Phase Changed: Review");
|
|
|
|
PerformReview();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 执行结算逻辑,并准备下一回合
|
|
/// </summary>
|
|
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.");
|
|
}
|
|
|
|
/// <summary>
|
|
/// 开始新的回合
|
|
/// </summary>
|
|
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");
|
|
}
|
|
}
|