138 lines
5.9 KiB
GDScript
138 lines
5.9 KiB
GDScript
## 弟子数据模型(纯数据,不挂在场景树上)。
|
||
## 生成时决定的属性(姓名/资质/灵根)不可变,成长属性(境界)由 D5 修炼系统推进。
|
||
class_name Disciple # 全局类名:全项目可直接用 Disciple.new()
|
||
extends Resource # Resource = 轻量纯数据对象,可序列化(D8 存档用)
|
||
|
||
## 资质四类(入宗分流结果)。
|
||
enum Aptitude { ORDINARY, MEDIUM, SUPERIOR, HEAVENLY } # 下品/中品/上品/天骄
|
||
|
||
## 灵根五行。
|
||
enum SpiritRoot { GOLD, WOOD, WATER, FIRE, EARTH }
|
||
|
||
# —— 常量表:枚举值 → 显示文本(按索引一一对应)——
|
||
const APTITUDE_NAMES: Array[String] = ["下品", "中品", "上品", "天骄"]
|
||
const ROOT_NAMES: Array[String] = ["金", "木", "水", "火", "土"]
|
||
const REALM_NAMES: Array[String] = ["练气", "筑基", "金丹", "元婴", "化神"] # 按 realm_index 索引
|
||
|
||
# —— 修炼数值一律读 GameConfig(资质倍率/天灵根加成/速度等)——
|
||
|
||
# —— 实例字段 ——
|
||
var id: int = 0 # 唯一编号(DiscipleManager 分配)
|
||
var name: String = ""
|
||
var age: int = 0
|
||
var aptitude: Aptitude = Aptitude.ORDINARY # 资质(入宗分流结果)
|
||
var roots: Array[SpiritRoot] = [] # 普通弟子 1~5 根;天灵根固定 1 根
|
||
var is_heavenly: bool = false # 天灵根标记(仅天骄资质,概率见配置)
|
||
var join_year: int = 0 # 入宗年份(0 = 未入宗/候选),accept 时快照
|
||
var join_month: int = 0 # 入宗月份
|
||
var join_day: int = 0 # 入宗日
|
||
var realm_index: int = 0 # 大境界索引(0=练气)
|
||
var sub_realm_index: int = 0 # 小境界索引(练气层数-1)
|
||
var cultivation_exp: float = 0.0 # 修为(float 可积累小数,D5 每日结算)
|
||
var hunger_days: int = 0 # 断粮累计天数(≥阈值离宗,方案 B)
|
||
|
||
# —— 辅助函数:把数据翻译成给人看的文本 ——
|
||
func get_aptitude_name() -> String:
|
||
return APTITUDE_NAMES[aptitude]
|
||
|
||
## 灵根显示文本,如 "金、木"。
|
||
func get_roots_text() -> String:
|
||
var names: Array[String] = []
|
||
for root in roots:
|
||
names.append(ROOT_NAMES[root])
|
||
return "、".join(names)
|
||
|
||
## 灵根数量灵气容量倍率(根数越少灵气越纯、修炼越快,D5 修炼循环消费)。
|
||
## 容量规则:单灵根 1 单位灵气充满,双灵根只充 1/2,三灵根 1/3,以此类推(容量 = 1 ÷ 根数)。
|
||
## 无灵根无法练气,容量为 0(体修路线未来另行结算,暂不生成)。
|
||
func get_root_count_capacity() -> float:
|
||
if roots.is_empty():
|
||
return 0.0
|
||
return 1.0 / roots.size()
|
||
|
||
## 境界显示文本,如 "练气5层"、"筑基初期"。
|
||
func get_realm_text() -> String:
|
||
if realm_index == 0:
|
||
return "%s%d层" % [REALM_NAMES[realm_index], sub_realm_index + 1]
|
||
return "%s%s" % [REALM_NAMES[realm_index], ["初期", "中期", "后期", "圆满"][sub_realm_index]]
|
||
|
||
## 入宗时间文本,如 "1年2月3日";未入宗返回空串。
|
||
func get_join_date_text() -> String:
|
||
if join_year <= 0:
|
||
return ""
|
||
return "%d年%d月%d日" % [join_year, join_month, join_day]
|
||
|
||
## 序列化为字典(D8 存档用,枚举转 int)。
|
||
func to_dict() -> Dictionary:
|
||
var roots_data: Array[int] = []
|
||
for r in roots:
|
||
roots_data.append(int(r))
|
||
return {
|
||
"id": id,
|
||
"name": name,
|
||
"age": age,
|
||
"aptitude": int(aptitude),
|
||
"roots": roots_data,
|
||
"is_heavenly": is_heavenly,
|
||
"join_year": join_year,
|
||
"join_month": join_month,
|
||
"join_day": join_day,
|
||
"realm_index": realm_index,
|
||
"sub_realm_index": sub_realm_index,
|
||
"cultivation_exp": cultivation_exp,
|
||
"hunger_days": hunger_days,
|
||
}
|
||
|
||
## 从字典还原(D8 读档用)。
|
||
## @param data: to_dict 产生的字典
|
||
static func from_dict(data: Dictionary) -> Disciple:
|
||
var d := Disciple.new()
|
||
d.id = int(data["id"])
|
||
d.name = str(data["name"])
|
||
d.age = int(data["age"])
|
||
d.aptitude = int(data["aptitude"]) as Aptitude
|
||
d.roots = []
|
||
for r in data["roots"]:
|
||
d.roots.append(int(r) as SpiritRoot)
|
||
d.is_heavenly = bool(data["is_heavenly"])
|
||
d.join_year = int(data["join_year"])
|
||
d.join_month = int(data["join_month"])
|
||
d.join_day = int(data["join_day"])
|
||
d.realm_index = int(data["realm_index"])
|
||
d.sub_realm_index = int(data["sub_realm_index"])
|
||
d.cultivation_exp = float(data["cultivation_exp"])
|
||
d.hunger_days = int(data["hunger_days"])
|
||
return d
|
||
|
||
## 本层修炼进度文本,如 "1234 / 2000"(当前修为 / 本层门槛)。
|
||
## 练气圆满(13 层)返回"练气圆满";筑基及以上返回 "1234 / 6000"(小境门槛),圆满返回"筑基圆满"。
|
||
func get_cultivation_progress_text() -> String:
|
||
if realm_index == 0:
|
||
if sub_realm_index >= GameConfig.level_thresholds.size():
|
||
return "练气圆满"
|
||
return "%d / %d" % [int(cultivation_exp), int(GameConfig.level_thresholds[sub_realm_index])]
|
||
if sub_realm_index >= GameConfig.realm_sub_thresholds.size():
|
||
return REALM_NAMES[realm_index] + "圆满"
|
||
return "%d / %d" % [int(cultivation_exp), int(GameConfig.realm_sub_thresholds[sub_realm_index])]
|
||
|
||
## 当前大境界是否修为圆满(练气 = 13 层;筑基及以上 = 4 小境修满)。
|
||
## 圆满后解锁"大境界突破"(玩家手动花费灵石)。
|
||
func is_realm_peak() -> bool:
|
||
if realm_index == 0:
|
||
return sub_realm_index >= GameConfig.level_thresholds.size()
|
||
return sub_realm_index >= GameConfig.realm_sub_thresholds.size() \
|
||
and cultivation_exp >= GameConfig.realm_sub_thresholds[GameConfig.realm_sub_thresholds.size() - 1]
|
||
|
||
## 目标大境界索引(realm_index+1);化神圆满(最高)返回 -1 表示无可突破。
|
||
func get_next_realm_index() -> int:
|
||
if realm_index + 1 >= REALM_NAMES.size():
|
||
return -1
|
||
return realm_index + 1
|
||
|
||
## 大境界突破所需灵石(按目标大境界索引读配置);无可突破返回 -1。
|
||
func get_realm_breakthrough_cost() -> int:
|
||
var next := get_next_realm_index()
|
||
if next < 0:
|
||
return -1
|
||
return GameConfig.realm_breakthrough_costs[next - 1]
|