# intro_create_phase.gd —— 40250 3D 角色塑形创建系统 1:1 # 严格对照: # Client/Eternexus/root/introcreate.py (CreateCharacterWindow) # ClientVS22/source/UserInterface/InstanceBaseTransform.cpp # metin2/src/server/game/src/player.cpp extends RefCounted const JOB_WARRIOR := 0 const JOB_ASSASSIN := 1 const JOB_SURA := 2 const JOB_SHAMAN := 3 const GENDER_MALE := 0 # MAN const GENDER_FEMALE := 1 # WOMAN const SHAPE_0 := 0 # 经典外观 1 (SHAPE0) const SHAPE_1 := 1 # 经典外观 2 (SHAPE1) # 40250 官方职业初始四维属性分配表 (CON, INT, STR, DEX) # 对应 introcreate.py: START_STAT const START_STAT_TABLE := { JOB_WARRIOR: { "con": 4, "int": 3, "str": 6, "dex": 3 }, # 战士 JOB_ASSASSIN: { "con": 3, "int": 3, "str": 4, "dex": 6 }, # 刺客 JOB_SURA: { "con": 3, "int": 5, "str": 5, "dex": 3 }, # 修罗 JOB_SHAMAN: { "con": 4, "int": 6, "str": 3, "dex": 3 }, # 萨满 } # 违禁词简易过滤器 const BANNED_NAME_PATTERNS := ["[GM]", "admin", "null", "fuck", "shit"] # 当前创建器状态 var selected_job: int = JOB_WARRIOR var selected_gender: int = GENDER_MALE var selected_shape: int = SHAPE_0 var turntable_rotation_deg: float = 0.0 # 360° 转盘旋转角度 func _init(p_job: int = JOB_WARRIOR, p_gender: int = GENDER_MALE) -> void: selected_job = p_job selected_gender = p_gender selected_shape = SHAPE_0 turntable_rotation_deg = 0.0 # 1. 切换职业与属性联动 func select_job(job_id: int) -> bool: if not START_STAT_TABLE.has(job_id): return false selected_job = job_id return true # 2. 切换性别 func select_gender(gender_id: int) -> bool: if gender_id != GENDER_MALE and gender_id != GENDER_FEMALE: return false selected_gender = gender_id return true # 3. 切换外观 (Shape 0 / Shape 1) func select_shape(shape_id: int) -> bool: if shape_id != SHAPE_0 and shape_id != SHAPE_1: return false selected_shape = shape_id return true # 4. 旋转展示台 (360 度循环) func rotate_turntable(delta_deg: float) -> float: turntable_rotation_deg = fposmod(turntable_rotation_deg + delta_deg, 360.0) return turntable_rotation_deg # 5. 获取当前职业的基础四维属性 func get_current_stats() -> Dictionary: return START_STAT_TABLE.get(selected_job, { "con": 4, "int": 3, "str": 6, "dex": 3 }) # 6. 角色名称合规性校验 func validate_character_name(name_str: String) -> Dictionary: var res := { "valid": false, "error_code": "OK", "message": "" } if name_str.is_empty(): res["error_code"] = "EMPTY_NAME" res["message"] = "角色名称不能为空。" return res var length := name_str.length() if length < 2 or length > 12: res["error_code"] = "INVALID_NAME_LENGTH" res["message"] = "角色名称长度需在 2 到 12 字符之间。" return res if name_str.contains(" ") or name_str.contains("\t"): res["error_code"] = "NAME_CONTAINS_SPACE" res["message"] = "角色名称中不能包含空格。" return res var lower_name := name_str.to_lower() for banned in BANNED_NAME_PATTERNS: if lower_name.contains(banned.to_lower()): res["error_code"] = "NAME_CONTAINS_BANNED_WORD" res["message"] = "角色名称中包含非法或保留字符。" return res res["valid"] = true return res # 7. 确认创建角色并打包角色初始数据 func create_character(name_str: String, empire_id: int = 1) -> Dictionary: var val = validate_character_name(name_str) if not val["valid"]: return { "success": false, "error_code": val["error_code"], "message": val["message"] } var stats: Dictionary = get_current_stats() var char_data := { "name": name_str, "empire": empire_id, "level": 1, "exp": 0, "job": selected_job, "gender": selected_gender, "shape": selected_shape, "cur_hp": 1000, "max_hp": 1000, "cur_sp": 500, "max_sp": 500, "stats": stats, "horse_level": 0, "playtime_min": 0, "delete_code": "1234567" # 默认 7 位删除安全码 } return { "success": true, "character": char_data, "message": "角色 %s 创建成功!" % name_str }