extends Node class_name CharacterData ## 角色数据模型 ## 定义角色数据结构和验证函数 # 角色数据字段 const FIELD_ID = "id" const FIELD_NAME = "name" const FIELD_OWNER_ID = "owner_id" const FIELD_POSITION = "position" const FIELD_IS_ONLINE = "is_online" const FIELD_APPEARANCE = "appearance" const FIELD_CREATED_AT = "created_at" const FIELD_LAST_SEEN = "last_seen" # 个性化字段 const FIELD_PERSONALITY = "personality" const FIELD_STATUS = "status" const FIELD_MOOD = "mood" const FIELD_ATTRIBUTES = "attributes" const FIELD_SKILLS = "skills" const FIELD_ACHIEVEMENTS = "achievements" const FIELD_LEVEL = "level" const FIELD_EXPERIENCE = "experience" # 名称验证规则 const MIN_NAME_LENGTH = 2 const MAX_NAME_LENGTH = 20 ## 生成唯一角色 ID static func generate_id() -> String: """ 生成唯一的角色 ID(使用时间戳 + 随机数) @return: 唯一 ID 字符串 """ var timestamp = Time.get_unix_time_from_system() var random_part = randi() return "char_%d_%d" % [timestamp, random_part] ## 创建角色数据 static func create(char_name: String, owner_id: String, position: Vector2 = Vector2.ZERO) -> Dictionary: """ 创建新的角色数据 @param char_name: 角色名称 @param owner_id: 所有者 ID @param position: 初始位置 @return: 角色数据字典 """ var now = Time.get_unix_time_from_system() return { FIELD_ID: generate_id(), FIELD_NAME: char_name, FIELD_OWNER_ID: owner_id, FIELD_POSITION: { "x": position.x, "y": position.y }, FIELD_IS_ONLINE: true, FIELD_APPEARANCE: { "sprite": "character_01", "color": "#FFFFFF", "body_color": "#4A90E2", "head_color": "#F5E6D3", "hair_color": "#8B4513", "clothing_color": "#2E8B57" }, FIELD_PERSONALITY: { "traits": ["friendly", "curious"], "bio": "", "favorite_activity": "exploring" }, FIELD_STATUS: "active", # active, busy, away, offline FIELD_MOOD: "neutral", # happy, sad, excited, tired, neutral FIELD_ATTRIBUTES: { "charisma": 5, "intelligence": 5, "creativity": 5, "energy": 5 }, FIELD_SKILLS: { "communication": 1, "problem_solving": 1, "leadership": 1, "collaboration": 1 }, FIELD_ACHIEVEMENTS: [], FIELD_LEVEL: 1, FIELD_EXPERIENCE: 0, FIELD_CREATED_AT: now, FIELD_LAST_SEEN: now } ## 验证角色名称 static func validate_name(char_name: String) -> bool: """ 验证角色名称是否有效 @param char_name: 角色名称 @return: 是否有效 """ # 检查是否为空或仅包含空白字符 if char_name.strip_edges().is_empty(): return false # 检查长度 var trimmed_name = char_name.strip_edges() if trimmed_name.length() < MIN_NAME_LENGTH or trimmed_name.length() > MAX_NAME_LENGTH: return false return true ## 验证角色数据完整性 static func validate(data: Dictionary) -> bool: """ 验证角色数据是否完整且有效 @param data: 角色数据字典 @return: 是否有效 """ # 检查必需字段 if not data.has(FIELD_ID) or not data[FIELD_ID] is String: return false if not data.has(FIELD_NAME) or not data[FIELD_NAME] is String: return false if not data.has(FIELD_OWNER_ID) or not data[FIELD_OWNER_ID] is String: return false if not data.has(FIELD_POSITION) or not data[FIELD_POSITION] is Dictionary: return false if not data.has(FIELD_IS_ONLINE) or not data[FIELD_IS_ONLINE] is bool: return false # 验证名称 if not validate_name(data[FIELD_NAME]): return false # 验证位置数据 var pos = data[FIELD_POSITION] if not pos.has("x") or not pos.has("y"): return false return true ## 从字典创建 Vector2 位置 static func get_position(data: Dictionary) -> Vector2: """ 从角色数据中提取位置 @param data: 角色数据字典 @return: Vector2 位置 """ if data.has(FIELD_POSITION): var pos = data[FIELD_POSITION] return Vector2(pos.get("x", 0), pos.get("y", 0)) return Vector2.ZERO ## 更新角色位置 static func set_position(data: Dictionary, position: Vector2) -> void: """ 更新角色数据中的位置 @param data: 角色数据字典 @param position: 新位置 """ data[FIELD_POSITION] = { "x": position.x, "y": position.y } ## 更新在线状态 static func set_online_status(data: Dictionary, is_online: bool) -> void: """ 更新角色在线状态 @param data: 角色数据字典 @param is_online: 是否在线 """ data[FIELD_IS_ONLINE] = is_online data[FIELD_LAST_SEEN] = Time.get_unix_time_from_system() ## 序列化为 JSON static func to_json(data: Dictionary) -> String: """ 将角色数据序列化为 JSON @param data: 角色数据字典 @return: JSON 字符串 """ return JSON.stringify(data) ## 从 JSON 反序列化 static func from_json(json_string: String) -> Dictionary: """ 从 JSON 反序列化角色数据 @param json_string: JSON 字符串 @return: 角色数据字典,失败返回空字典 """ var json = JSON.new() var parse_result = json.parse(json_string) if parse_result == OK: var data = json.data if validate(data): return data else: push_error("Invalid character data in JSON") else: push_error("Failed to parse character JSON") return {} ## 克隆角色数据 static func clone(data: Dictionary) -> Dictionary: """ 深度克隆角色数据 @param data: 原始角色数据 @return: 克隆的角色数据 """ return from_json(to_json(data)) ## 个性化相关函数 ## 更新角色外观 static func set_appearance(data: Dictionary, appearance: Dictionary) -> void: """ 更新角色外观 @param data: 角色数据字典 @param appearance: 外观数据 """ if not data.has(FIELD_APPEARANCE): data[FIELD_APPEARANCE] = {} for key in appearance: data[FIELD_APPEARANCE][key] = appearance[key] ## 设置角色状态 static func set_status(data: Dictionary, status: String) -> void: """ 设置角色状态 @param data: 角色数据字典 @param status: 状态 (active, busy, away, offline) """ var valid_statuses = ["active", "busy", "away", "offline"] if status in valid_statuses: data[FIELD_STATUS] = status ## 设置角色心情 static func set_mood(data: Dictionary, mood: String) -> void: """ 设置角色心情 @param data: 角色数据字典 @param mood: 心情 (happy, sad, excited, tired, neutral) """ var valid_moods = ["happy", "sad", "excited", "tired", "neutral"] if mood in valid_moods: data[FIELD_MOOD] = mood ## 更新角色属性 static func set_attribute(data: Dictionary, attribute: String, value: int) -> void: """ 设置角色属性值 @param data: 角色数据字典 @param attribute: 属性名称 @param value: 属性值 (1-10) """ if not data.has(FIELD_ATTRIBUTES): data[FIELD_ATTRIBUTES] = {} # 限制属性值范围 value = clamp(value, 1, 10) data[FIELD_ATTRIBUTES][attribute] = value ## 更新角色技能 static func set_skill(data: Dictionary, skill: String, level: int) -> void: """ 设置角色技能等级 @param data: 角色数据字典 @param skill: 技能名称 @param level: 技能等级 (1-10) """ if not data.has(FIELD_SKILLS): data[FIELD_SKILLS] = {} # 限制技能等级范围 level = clamp(level, 1, 10) data[FIELD_SKILLS][skill] = level ## 添加成就 static func add_achievement(data: Dictionary, achievement: Dictionary) -> void: """ 添加成就 @param data: 角色数据字典 @param achievement: 成就数据 {id, name, description, earned_at} """ if not data.has(FIELD_ACHIEVEMENTS): data[FIELD_ACHIEVEMENTS] = [] # 检查是否已有此成就 for existing in data[FIELD_ACHIEVEMENTS]: if existing.get("id") == achievement.get("id"): return # 已有此成就 achievement["earned_at"] = Time.get_unix_time_from_system() data[FIELD_ACHIEVEMENTS].append(achievement) ## 增加经验值 static func add_experience(data: Dictionary, experience: int) -> bool: """ 增加经验值,如果升级返回 true @param data: 角色数据字典 @param experience: 经验值 @return: 是否升级 """ if not data.has(FIELD_EXPERIENCE): data[FIELD_EXPERIENCE] = 0 if not data.has(FIELD_LEVEL): data[FIELD_LEVEL] = 1 data[FIELD_EXPERIENCE] += experience # 检查是否升级 var current_level = data[FIELD_LEVEL] var required_exp = get_required_experience(current_level) if data[FIELD_EXPERIENCE] >= required_exp: data[FIELD_LEVEL] += 1 data[FIELD_EXPERIENCE] -= required_exp return true return false ## 获取升级所需经验值 static func get_required_experience(level: int) -> int: """ 获取升级到下一级所需的经验值 @param level: 当前等级 @return: 所需经验值 """ return level * 100 + (level - 1) * 50 # 递增的经验需求 ## 获取角色总体评分 static func get_character_score(data: Dictionary) -> int: """ 计算角色的总体评分 @param data: 角色数据字典 @return: 总体评分 """ var score = 0 # 等级贡献 score += data.get(FIELD_LEVEL, 1) * 10 # 属性贡献 var attributes = data.get(FIELD_ATTRIBUTES, {}) for value in attributes.values(): score += value # 技能贡献 var skills = data.get(FIELD_SKILLS, {}) for value in skills.values(): score += value * 2 # 成就贡献 var achievements = data.get(FIELD_ACHIEVEMENTS, []) score += achievements.size() * 5 return score ## 获取个性化数据摘要 static func get_personality_summary(data: Dictionary) -> String: """ 获取角色个性化数据的摘要 @param data: 角色数据字典 @return: 个性化摘要文本 """ var summary = [] # 等级和经验 var level = data.get(FIELD_LEVEL, 1) var experience = data.get(FIELD_EXPERIENCE, 0) summary.append("等级 %d (%d 经验)" % [level, experience]) # 状态和心情 var status = data.get(FIELD_STATUS, "active") var mood = data.get(FIELD_MOOD, "neutral") summary.append("状态: %s, 心情: %s" % [status, mood]) # 成就数量 var achievements = data.get(FIELD_ACHIEVEMENTS, []) if achievements.size() > 0: summary.append("%d 个成就" % achievements.size()) return " | ".join(summary)