# point_reset_system.gd # 40250 官方 1:1 属性点/技能重置洗点与两阶段确认系统 # 对照: uipointreset.py, questiondialog2.py, char.cpp, cmd_general.cpp class_name PointResetSystem extends RefCounted const RESET_COST_YANG: int = 500 # 40250 官方四职业初始属性基准值 [CON, INT, STR, DEX] const START_STAT: Dictionary = { 0: [4, 3, 6, 3], # WARRIOR (战士) 1: [3, 3, 4, 6], # ASSASSIN (刺客) 2: [3, 5, 5, 3], # SURA (修罗) 3: [4, 6, 3, 3] # SHAMAN (萨满) } # 状态枚举 enum DialogState { CLOSED = 0, INITIAL_PROMPT = 1, CONFIRMATION = 2 } var state: DialogState = DialogState.CLOSED var player_job: int = 0 var player_gold: int = 0 var current_stats: Dictionary = {"CON": 4, "INT": 3, "STR": 6, "DEX": 3} var unallocated_stat_points: int = 0 # 技能重置支持 var player_level: int = 1 var current_skill_tree: int = 0 # 0=未选, 1=分支A, 2=分支B var unallocated_skill_points: int = 0 var active_skills: Dictionary = {} var last_packet_sent: String = "" signal dialog_opened(cost: int) signal confirm_dialog_opened(warning_text: String) signal dialog_closed() signal reset_completed(new_stats: Dictionary, refund_points: int, remaining_gold: int) signal reset_failed(reason: String) func init_player_data(job: int, level: int, gold: int, stats: Dictionary, stat_pts: int, skill_tree: int, skill_pts: int, skills: Dictionary) -> void: player_job = job player_level = level player_gold = gold current_stats = stats.duplicate() unallocated_stat_points = stat_pts current_skill_tree = skill_tree unallocated_skill_points = skill_pts active_skills = skills.duplicate() func open_dialog() -> void: state = DialogState.INITIAL_PROMPT dialog_opened.emit(RESET_COST_YANG) func open_confirm_dialog() -> bool: if state != DialogState.INITIAL_PROMPT: return false # 检查金币是否满足 500 Yang if player_gold < RESET_COST_YANG: reset_failed.emit("NOT_ENOUGH_MONEY") close_dialog() return false state = DialogState.CONFIRMATION var warning_msg = "重置后所有属性点将被重置!确定继续吗?" confirm_dialog_opened.emit(warning_msg) return true func accept_reset() -> bool: if state != DialogState.CONFIRMATION: return false if player_gold < RESET_COST_YANG: reset_failed.emit("NOT_ENOUGH_MONEY") close_dialog() return false # 扣除 500 金币 player_gold -= RESET_COST_YANG last_packet_sent = "/pointreset" # 回退属性点 var base_stat = START_STAT.get(player_job, [4, 3, 6, 3]) var refund_con = maxi(0, current_stats["CON"] - base_stat[0]) var refund_int = maxi(0, current_stats["INT"] - base_stat[1]) var refund_str = maxi(0, current_stats["STR"] - base_stat[2]) var refund_dex = maxi(0, current_stats["DEX"] - base_stat[3]) var total_refund = refund_con + refund_int + refund_str + refund_dex unallocated_stat_points += total_refund current_stats["CON"] = base_stat[0] current_stats["INT"] = base_stat[1] current_stats["STR"] = base_stat[2] current_stats["DEX"] = base_stat[3] reset_completed.emit(current_stats, total_refund, player_gold) close_dialog() return true # 官方 30 级以下老妇人技能树重洗 (Old Woman Skill Reset) func reset_skills_at_old_woman() -> bool: if player_level > 30: reset_failed.emit("LEVEL_TOO_HIGH") return false # 40250 老妇人洗技能费用公式: level * 1000 + 2000 Yang var cost = player_level * 1000 + 2000 if player_gold < cost: reset_failed.emit("NOT_ENOUGH_MONEY") return false player_gold -= cost var total_skill_pts = 0 for sk_id in active_skills: total_skill_pts += active_skills[sk_id] active_skills.clear() unallocated_skill_points += total_skill_pts current_skill_tree = 0 # 允许重新转职选择专精分支 return true func close_dialog() -> void: state = DialogState.CLOSED dialog_closed.emit()