修复初始编队生成:对入参建可写副本再补发 id

- Disciple.create 强制要求 data 含 id,且 INITIAL_ROSTER 为 const 常量:
  原实现先 create 后补 id 导致 5 人全部创建失败
- 改为 duplicate() 副本上写入 _master_id 发号,避免污染常量
- INITIAL_ROSTER 补手写 id 占位字段(实际以发号器为准)
This commit is contained in:
2026-09-10 00:27:40 +08:00
parent f38bcfd210
commit 050c8116ad
2 changed files with 62 additions and 60 deletions
+61 -60
View File
@@ -1,6 +1,4 @@
# 初始版本不提供添加弟子的接口 # 初始版本不提供添加弟子的接口
class_name DiscipleManager class_name DiscipleManager
extends Node extends Node
@@ -14,6 +12,7 @@ const INITIAL_ROSTER := [
# 1 玄真(宗主):修士·炼气9层,五行全高,炼丹3级 # 1 玄真(宗主):修士·炼气9层,五行全高,炼丹3级
{ {
"name": "玄真", "name": "玄真",
"id" : 1,
"metal": 45, "wood": 38, "water": 22, "fire": 31, "earth": 19, "metal": 45, "wood": 38, "water": 22, "fire": 31, "earth": 19,
"efficiency": 85, "efficiency": 85,
"realm_level": 1, "sub_realm_level": 9, "realm_level": 1, "sub_realm_level": 9,
@@ -23,6 +22,7 @@ const INITIAL_ROSTER := [
# 2 凌霄:修士·炼气4层,金火旺 # 2 凌霄:修士·炼气4层,金火旺
{ {
"name": "凌霄", "name": "凌霄",
"id" : 2,
"metal": 62, "wood": 12, "water": 15, "fire": 44, "earth": 20, "metal": 62, "wood": 12, "water": 15, "fire": 44, "earth": 20,
"efficiency": 76, "efficiency": 76,
"realm_level": 1, "sub_realm_level": 4, "realm_level": 1, "sub_realm_level": 4,
@@ -32,6 +32,7 @@ const INITIAL_ROSTER := [
# 3 青禾:凡人带灵根(木47≥20 可修炼破境),药草天赋 # 3 青禾:凡人带灵根(木47≥20 可修炼破境),药草天赋
{ {
"name": "青禾", "name": "青禾",
"id" : 3,
"metal": 8, "wood": 47, "water": 25, "fire": 12, "earth": 10, "metal": 8, "wood": 47, "water": 25, "fire": 12, "earth": 10,
"efficiency": 68, "efficiency": 68,
"realm_level": 0, "sub_realm_level": 1, "realm_level": 0, "sub_realm_level": 1,
@@ -41,6 +42,7 @@ const INITIAL_ROSTER := [
# 4 阿福:凡人杂役(无灵根,五行均<20) # 4 阿福:凡人杂役(无灵根,五行均<20)
{ {
"name": "阿福", "name": "阿福",
"id" : 4,
"metal": 5, "wood": 12, "water": 8, "fire": 9, "earth": 10, "metal": 5, "wood": 12, "water": 8, "fire": 9, "earth": 10,
"efficiency": 41, "efficiency": 41,
"realm_level": 0, "sub_realm_level": 1, "realm_level": 0, "sub_realm_level": 1,
@@ -50,6 +52,7 @@ const INITIAL_ROSTER := [
# 5 阿禄:凡人杂役(无灵根) # 5 阿禄:凡人杂役(无灵根)
{ {
"name": "阿禄", "name": "阿禄",
"id" : 5,
"metal": 3, "wood": 6, "water": 5, "fire": 8, "earth": 15, "metal": 3, "wood": 6, "water": 5, "fire": 8, "earth": 15,
"efficiency": 35, "efficiency": 35,
"realm_level": 0, "sub_realm_level": 1, "realm_level": 0, "sub_realm_level": 1,
@@ -61,103 +64,101 @@ const INITIAL_ROSTER := [
var _disciples: Array[Disciple] = [] # 弟子列表 var _disciples: Array[Disciple] = [] # 弟子列表
var _master_id: int = 0 # 管理器的发号计数,id 的唯一来源 var _master_id: int = 0 # 管理器的发号计数,id 的唯一来源
# ---- 工厂 ---- func _enter_tree() -> void:
pass
# ---- 工厂 ----
# 初始编队(复用 _create_from_data # 初始编队(复用 _create_from_data
func spawn_initial_roster() -> Array[Disciple]: func spawn_initial_roster() -> void:
for data in INITIAL_ROSTER: for data in INITIAL_ROSTER:
var disciple = _create_from_data(data) var disciple = _create_from_data(data)
if disciple != null: if disciple != null:
add_disciple(disciple) add_disciple(disciple)
# _disciples.append(disciple) else:
# emit_signal("disciple_added", disciple) push_error("Failed to spawn disciple from data: %s" % data)
else: pass
push_error("Failed to spawn disciple from data: %s" % data)
pass
# 补 id → Disciple.create() # 补 id → Disciple.create()
# 从数据字典创建 Disciple 实例,若失败返回 null # 从数据字典创建 Disciple 实例,若失败返回 null
func _create_from_data(data: Dictionary) -> Disciple: func _create_from_data(data: Dictionary) -> Disciple:
var disciple := Disciple.create(data) var copy := data.duplicate() # 可写副本(浅拷贝,顶层加键足够)
if disciple == null: copy["id"] = _master_id
push_error("Failed to create disciple from data: %s" % data) _master_id += 1
return null var disciple := Disciple.create(copy)
disciple.id = _master_id if disciple == null:
_master_id += 1 push_error("Failed to create disciple from data: %s" % data)
return disciple return null
pass return disciple
# ---- 仓储 ---- # ---- 仓储 ----
# 公开接口:添加弟子 # 公开接口:添加弟子
func add_disciple(d : Disciple) -> void: func add_disciple(d : Disciple) -> void:
if d == null: if d == null:
push_error("Cannot add null disciple.") push_error("Cannot add null disciple.")
return return
_disciples.append(d) _disciples.append(d)
emit_signal("disciple_added", d) emit_signal("disciple_added", d)
# 移除弟子 # 移除弟子
func remove_disciple(d : Disciple) -> bool: func remove_disciple(d : Disciple) -> bool:
if d != null and _disciples.has(d): if d != null and _disciples.has(d):
_disciples.erase(d) _disciples.erase(d)
emit_signal("disciple_removed", d) emit_signal("disciple_removed", d)
return true return true
return false return false
# 公开接口:通过id获取弟子 # 公开接口:通过id获取弟子
func get_disciple(id : int) -> Disciple: func get_disciple(id : int) -> Disciple:
for d in _disciples: for d in _disciples:
if d.id == id: if d.id == id:
return d return d
return null return null
# 公开接口:获取所有弟子(返回副本,避免外部修改原数组) # 公开接口:获取所有弟子(返回副本,避免外部修改原数组)
func get_all() -> Array[Disciple]: func get_all() -> Array[Disciple]:
return _disciples.duplicate() # 返回副本,避免外部修改原数组 return _disciples.duplicate() # 返回副本,避免外部修改原数组
# ---- 修改唯一入口 ---- # ---- 修改唯一入口 ----
# 调 d.set_attr + 发信号(name 特判) # 调 d.set_attr + 发信号(name 特判)
func set_attr(d :Disciple, attr: String, value: Variant) -> bool: func set_attr(d :Disciple, attr: String, value: Variant) -> bool:
if _disciples.has(d): if _disciples.has(d):
var old_value = d.get_attr(attr) var old_value = d.get_attr(attr)
if d.set_attr(attr, value): if d.set_attr(attr, value):
emit_signal("disciple_attr_changed", d, attr, old_value, value) emit_signal("disciple_attr_changed", d, attr, old_value, value)
return true return true
return false return false
# ---- 经验晋级(领域操作)---- # ---- 经验晋级(领域操作)----
# 跨小境界继承循环;跨大境界清零;满级不涨;无灵根拒绝 # 跨小境界继承循环;跨大境界清零;满级不涨;无灵根拒绝
func add_cultivation_exp(d : Disciple, amount : int) -> void: func add_cultivation_exp(d : Disciple, amount : int) -> void:
if _disciples.has(d): if _disciples.has(d):
var old_realm = d.realm_level var old_realm = d.realm_level
var old_sub_realm = d.sub_realm_level var old_sub_realm = d.sub_realm_level
d.add_cultivation_exp(amount) d.add_cultivation_exp(amount)
if d.realm_level != old_realm or d.sub_realm_level != old_sub_realm: if d.realm_level != old_realm or d.sub_realm_level != old_sub_realm:
emit_signal("disciple_attr_changed", d, "realm_level", old_realm, d.realm_level) emit_signal("disciple_attr_changed", d, "realm_level", old_realm, d.realm_level)
emit_signal("disciple_attr_changed", d, "sub_realm_level", old_sub_realm, d.sub_realm_level) emit_signal("disciple_attr_changed", d, "sub_realm_level", old_sub_realm, d.sub_realm_level)
# skill∈{farming,herb,alchemy},查 SKILL_EXP_CAPS,溢出继承至满级 # skill∈{farming,herb,alchemy},查 SKILL_EXP_CAPS,溢出继承至满级
func add_skill_exp(d : Disciple, skill: String, amount : int) -> void: func add_skill_exp(d : Disciple, skill: String, amount : int) -> void:
if _disciples.has(d): if _disciples.has(d):
var old_level = d.get_skill_level(skill) var old_level = d.get_skill_level(skill)
d.add_skill_exp(skill, amount) d.add_skill_exp(skill, amount)
var new_level = d.get_skill_level(skill) var new_level = d.get_skill_level(skill)
if new_level != old_level: if new_level != old_level:
emit_signal("disciple_attr_changed", d, skill + "_level", old_level, new_level) emit_signal("disciple_attr_changed", d, skill + "_level", old_level, new_level)
# ---- 月度结算(预留)---- # ---- 月度结算(预留)----
# 月收益 = f(efficiency),依赖经济扣灵石 —— 取决于下列问题 # 月收益 = f(efficiency),依赖经济扣灵石 —— 取决于下列问题
func settle_month() -> void: func settle_month() -> void:
pass pass
# ---- 存档 ---- # ---- 存档 ----
func to_dict(): func to_dict():
pass pass
func load_from_dict(): func load_from_dict():
pass pass
+1
View File
@@ -0,0 +1 @@
uid://bstiea1nx61b8