- 组合式单位与数值基础重构:scripts/Models/UnitModel.cs, scripts/Models/UnitComponents.cs, scripts/Models/StudentModel.cs, scripts/Models/MentorModel.cs, scripts/Models/StaffModel.cs, scripts/Models/PropertyValue.cs, scripts/Models/StatusValue.cs - 任务与运行时状态骨架:scripts/Models/Task.cs, scripts/Models/TaskDefinitions.cs, scripts/Models/GameState.cs - 配置与规则定义骨架:scripts/Models/DefinitionSupport.cs, scripts/Models/DomainEnums.cs, scripts/Models/Modifiers.cs, scripts/Models/DisciplineDefinitions.cs, scripts/Models/SynergyDefinitions.cs, scripts/Models/ItemDefinitions.cs, scripts/Models/PaperDefinitions.cs, scripts/Models/RogueliteDefinitions.cs, scripts/Models/GameContentDatabase.cs, scripts/Models/CoreIds.cs - MVC/会话/系统/i18n/Mod 支撑:scripts/Core/GameSession.cs, scripts/Core/GameSystems.cs, scripts/Core/GameController.cs, scripts/Core/Mvc.cs, scripts/Core/LocalizationService.cs, scripts/Core/ContentRegistry.cs, scripts/Core/ModManifest.cs, scripts/Core/EventBus.cs - 主控流程衔接:scripts/GameManager.cs
181 lines
4.9 KiB
C#
181 lines
4.9 KiB
C#
using Godot;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using Models;
|
||
using Core;
|
||
|
||
/// <summary>
|
||
/// 游戏主控制节点(MVC 的桥接层)
|
||
/// 设计说明:
|
||
/// 1) 负责初始化 GameSession,并把输入/信号转交给 Controller/System。
|
||
/// 2) 仅做“流程调度”,不直接计算复杂数值,避免逻辑堆积。
|
||
/// 注意事项:
|
||
/// - View 与 Model 的绑定应逐步迁移到独立 View 脚本,避免在此类膨胀。
|
||
/// 未来扩展:
|
||
/// - 可拆分为 SceneRoot + UIController + DebugController,分层管理。
|
||
/// </summary>
|
||
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");
|
||
|
||
[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<StudentModel> Students => State?.Roster.Students;
|
||
public List<TaskModel> 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);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 结束筹备阶段,开始执行
|
||
/// </summary>
|
||
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)
|
||
}
|
||
|
||
/// <summary>
|
||
/// 结束执行阶段(通常由时间耗尽或玩家手动触发),进入结算
|
||
/// </summary>
|
||
public void EndExecution()
|
||
{
|
||
if (CurrentPhase != GamePhase.Execution) return;
|
||
|
||
Controller.EndExecution();
|
||
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.Runtime.RemainingTurns--;
|
||
if (task.IsCompleted)
|
||
{
|
||
GD.Print($"Task {task.Name} Completed!");
|
||
Economy.Reputation += task.Reward.Reputation;
|
||
Economy.Money += task.Reward.Money;
|
||
}
|
||
else if (task.IsFailed)
|
||
{
|
||
GD.Print($"Task {task.Name} Failed!");
|
||
Economy.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;
|
||
|
||
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");
|
||
}
|
||
}
|