supervisor-simulator/scripts/Player.cs
2026-01-18 20:05:23 +08:00

171 lines
5.5 KiB
C#

using System;
using System.Collections.Generic;
using Godot;
/// <summary>
/// 玩家数据管理类
/// </summary>
public partial class Player : Node {
/// <summary>
/// 时间轴实例
/// </summary>
public static readonly TimelineType Timeline = new(DateOnly.Parse("2024/11/17"));
/// <summary>
/// 预算实例
/// </summary>
public static BudgetType Budget { get; set; } = new();
/// <summary>
/// 名字
/// </summary>
public static string PlayerName { get; set; }
/// <summary>
/// 年龄
/// </summary>
public static uint Age { get; set; }
/// <summary>
/// 日期
/// </summary>
public static DateOnly Date { get; set; }
// Called when the node enters the scene tree for the first time.
/// <summary>
/// 场景加载完成时调用
/// </summary>
public override void _Ready() { }
// Called every frame. 'delta' is the elapsed time since the previous frame.
/// <summary>
/// 每帧更新
/// </summary>
/// <param name="delta">帧间隔</param>
public override void _Process(double delta) { }
/// <summary>
/// 预算类型,用于记录项目预算的不同类别费用。
/// </summary>
public class BudgetType {
/// <summary>
/// 设备费:用于购买设备,升级实验室是指在项目实施过程中购置或试制专用仪
/// 器设备,对现有仪器设备进行升级改造,以及租赁外单位仪器设备而发生的费
/// 用。计算类仪器设备和软件工具可在设备费科目列支。应当严格控制设备购
/// 置,鼓励开放共享、自主研制、租赁专用仪器设备以及对现有仪器设备进行升
/// 级改造,避免重复购置。
/// </summary>
public int Facility { get; set; }
/// <summary>
/// 业务费:是指项目实施过程中消耗的各种材料、辅助材料等低值易耗品的采
/// 购、运输、装卸、整理等费用,发生的测试化验加工、燃料动力、出版/文献/
/// 信息传播/知识产权事务、会议/差旅/国际合作交流等费用,以及其他相关支
/// 出。
/// </summary>
public int Operational { get; set; }
/// <summary>
/// 劳务费:是指在项目实施过程中支付给参与项目研究的研究生、博士后、访问学
/// 者以及项目聘用的研究人员、科研辅助人员等的劳务性费用,以及支付给临时聘
/// 请的咨询专家的费用等。
/// </summary>
public int Labor { get; set; }
/// <summary>
/// 总预算
/// </summary>
public int Total => Facility + Operational + Labor;
}
/// <summary>
/// 时间轴类型
/// </summary>
public class TimelineType {
/// <summary>
/// 日期变更委托
/// </summary>
public delegate void DayChangedEventHandler(DateOnly date);
/// <summary>
/// 事件触发委托
/// </summary>
public delegate void EventTriggeredEventHandler(DateOnly date, Guid eventUuid);
private Dictionary<DateOnly, HashSet<Guid>> _events;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="startDate">开始日期</param>
public TimelineType(DateOnly startDate) {
InternalDate = startDate;
}
/// <summary>
/// 内部日期
/// </summary>
public DateOnly InternalDate { get; set; }
/// <summary>
/// 订阅事件
/// </summary>
/// <param name="date">日期</param>
/// <param name="eventUuid">事件UUID</param>
public void Subscribe(DateOnly date, Guid eventUuid) {
_events ??= new Dictionary<DateOnly, HashSet<Guid>>();
if (!_events.ContainsKey(date)) _events[date] = new HashSet<Guid>();
_events[date].Add(eventUuid);
}
/// <summary>
/// 取消订阅事件
/// </summary>
/// <param name="date">日期</param>
/// <param name="eventUuid">事件UUID</param>
public void Unsubscribe(DateOnly date, Guid eventUuid) {
if (_events == null) return;
if (!_events.ContainsKey(date)) return;
_events[date].Remove(eventUuid);
}
/// <summary>
/// 进入下一天
/// </summary>
private void NextDay() {
if (_events == null) return;
_events.Remove(InternalDate);
InternalDate = InternalDate.AddDays(1);
OnDayChanged?.Invoke(InternalDate);
GD.Print("Today is: " + InternalDate.ToString("yyyy-MM-dd"));
if (_events.ContainsKey(InternalDate)) {
var events = _events[InternalDate];
foreach (var eventUuid in events) {
// TODO: Trigger event
OnEventTriggered?.Invoke(InternalDate, eventUuid);
GD.Print("event triggered! eventUUID: " + eventUuid);
}
}
}
/// <summary>
/// 附加计时器
/// </summary>
/// <param name="ticker">计时器</param>
public void Attach(Timer ticker) {
ticker.Timeout += NextDay;
}
/// <summary>
/// 事件触发事件
/// </summary>
public event EventTriggeredEventHandler OnEventTriggered;
/// <summary>
/// 日期变更事件
/// </summary>
public event DayChangedEventHandler OnDayChanged;
}
}