- 任务推进与结算:执行阶段按任务类型用属性权重计算进度、考虑角色/学科匹配、状态衰减与难度缩放,回合结束统一扣 Deadline、判定完成/失败并派发事件,同时记录署名贡献度 scripts/Core/GameSystems.cs - 经济结算:接收任务事件发奖惩,学术探索根据难度生成论文卡;回合结束统一扣工资并结息(经济学学科触发基础利率)scripts/Core/GameSystems.cs - 羁绊层数与效果:统计人群画像/职能分工堆叠,激活层级并聚合为全局 ModifierBundle 给数值解析器使用 scripts/Core/GameSystems.cs, scripts/Models/GameState.cs - 事件与数值解析支撑:新增领域事件与统一属性合成器,兼容羁绊/学科/特质/装备的叠加 scripts/Core/DomainEvents.cs, scripts/Core/StatResolver.cs - 回合结算入口调整:Review 阶段改由系统处理并发布回合结束事件 scripts/GameManager.cs
161 lines
4.5 KiB
C#
161 lines
4.5 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()
|
||
{
|
||
Session.Systems.Task.ResolveEndOfTurn();
|
||
Session.Events.Publish(new TurnEndedEvent(CurrentTurn));
|
||
|
||
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");
|
||
}
|
||
}
|