# system_setting_system.gd —— Metin2 40250 音频视听与战斗选项系统 1:1 # 对照 40250 服务端与客户端 PythonSystem.cpp, uisystemoption.py, uigameoption.py class_name SystemSettingSystem extends RefCounted signal setting_changed(setting_name: String, new_val: Variant) signal pk_mode_changed(new_mode: int, mode_name: String) enum PkMode { PEACE = 0, # 和平 REVENGE = 1, # 善恶 (仅可攻击负善恶红名) GUILD = 2, # 阵营 (公会战保护) FREE = 3 # 自由 (无限制) } # 音频设置 var bgm_volume: float = 0.8: set(v): bgm_volume = clampf(v, 0.0, 1.0) setting_changed.emit("bgm_volume", bgm_volume) var sfx_volume: float = 0.8: set(v): sfx_volume = clampf(v, 0.0, 1.0) setting_changed.emit("sfx_volume", sfx_volume) var is_muted: bool = false: set(v): is_muted = v setting_changed.emit("is_muted", is_muted) # 视距与画质设置 var camera_distance: float = 25.0: set(v): camera_distance = clampf(v, 15.0, 40.0) setting_changed.emit("camera_distance", camera_distance) var fog_level: int = 1: # 0: 无, 1: 近, 2: 远 set(v): fog_level = clampi(v, 0, 2) setting_changed.emit("fog_level", fog_level) var shadow_quality: int = 1: # 0: 关, 1: 地面, 2: 全部 set(v): shadow_quality = clampi(v, 0, 2) setting_changed.emit("shadow_quality", shadow_quality) # 战斗飘字与标签显示 var show_damage_dealt: bool = true var show_damage_received: bool = true var show_critical_hit: bool = true var show_monster_names: bool = true var show_player_names: bool = true # PK 模式 var current_pk_mode: int = PkMode.PEACE # 设置 PK 模式 func set_pk_mode(mode: int) -> Dictionary: if mode < PkMode.PEACE or mode > PkMode.FREE: return {"ok": false, "reason": "INVALID_PK_MODE", "msg": "无效的 PK 模式!"} current_pk_mode = mode var mname := get_pk_mode_name(mode) pk_mode_changed.emit(mode, mname) return { "ok": true, "mode": mode, "mode_name": mname, "msg": "PK 模式已切换为【%s】!" % mname } # 获取模式中文名称 func get_pk_mode_name(mode: int) -> String: match mode: PkMode.PEACE: return "和平模式" PkMode.REVENGE: return "善恶反击模式" PkMode.GUILD: return "阵营公会模式" PkMode.FREE: return "自由对决模式" _: return "未知模式" # 判定是否可以对指定目标发起攻击 (PK 判定状态机) func can_attack_target( target_is_player: bool, target_alignment: int = 0, target_guild_id: int = 0, my_guild_id: int = 0 ) -> bool: # 怪物/NPC 永远可以攻击 if not target_is_player: return true # 玩家间攻击依据 PK 模式判定 match current_pk_mode: PkMode.PEACE: # 和平模式:严禁攻击任何玩家 return false PkMode.REVENGE: # 善恶模式:只可攻击红名玩家 (善恶值 < 0) return target_alignment < 0 PkMode.GUILD: # 阵营模式:同公会玩家受到保护,禁止攻击 if my_guild_id > 0 and target_guild_id > 0 and my_guild_id == target_guild_id: return false return true PkMode.FREE: # 自由模式:可攻击任何玩家 return true _: return false # 导出配置项 func export_settings() -> Dictionary: return { "bgm_volume": bgm_volume, "sfx_volume": sfx_volume, "is_muted": is_muted, "camera_distance": camera_distance, "fog_level": fog_level, "shadow_quality": shadow_quality, "show_damage_dealt": show_damage_dealt, "show_damage_received": show_damage_received, "show_critical_hit": show_critical_hit, "show_monster_names": show_monster_names, "show_player_names": show_player_names, "current_pk_mode": current_pk_mode } # 导入配置项 func import_settings(cfg: Dictionary) -> void: if cfg.has("bgm_volume"): bgm_volume = float(cfg["bgm_volume"]) if cfg.has("sfx_volume"): sfx_volume = float(cfg["sfx_volume"]) if cfg.has("is_muted"): is_muted = bool(cfg["is_muted"]) if cfg.has("camera_distance"): camera_distance = float(cfg["camera_distance"]) if cfg.has("fog_level"): fog_level = int(cfg["fog_level"]) if cfg.has("shadow_quality"): shadow_quality = int(cfg["shadow_quality"]) if cfg.has("show_damage_dealt"): show_damage_dealt = bool(cfg["show_damage_dealt"]) if cfg.has("show_damage_received"): show_damage_received = bool(cfg["show_damage_received"]) if cfg.has("show_critical_hit"): show_critical_hit = bool(cfg["show_critical_hit"]) if cfg.has("show_monster_names"): show_monster_names = bool(cfg["show_monster_names"]) if cfg.has("show_player_names"): show_player_names = bool(cfg["show_player_names"]) if cfg.has("current_pk_mode"): set_pk_mode(int(cfg["current_pk_mode"]))