- 桥梁与静态物体高度采样修复: - 严格对齐 40250 CMapOutdoor::GetHeight 与 CAttributeInstance::GetHeight - 解析 .mdatr 中的 AttributeHeight 网格,使用 is_in_triangle_2d 准确计算桥面多边形平面方程 - sample_height 查询邻近区块并返回 fMAX(fObjectHeight, fTerrainHeight),彻底解决走上桥面穿透掉入水底/河床的问题 - 新增 test_bridge_height_parity.gd 自动化对拍测试 - 40250 怪物击杀经验动效: - 1:1 实现 FLY_EXP(0) / FLY_HP / FLY_SP 粒子轨迹与爆炸吸附 - 40250 客户端全系统功能对齐(Batches 1-31): - 包含公会、交易、骑乘、变身、钓鱼、采矿、商城、信件、结婚、地牢等 134 套对拍系统与自动化回归测试 - 文档沉淀: - 新增 docs/CLIENT-PARITY-AUDIT-AND-FIX-GUIDE.md 客户端对拍缺陷发现与修复工程指南
102 lines
3.0 KiB
GDScript
102 lines
3.0 KiB
GDScript
# bgm_jukebox_system.gd —— 40250 客户端 BGM 点唱机与地图音乐配置系统 1:1
|
|
# 严格对照:
|
|
# Client/Eternexus/root/uiselectmusic.py (SelectMusicWindow)
|
|
# Client/Eternexus/root/musicinfo.py
|
|
# ClientVS22/source/UserInterface/PythonSoundManagerModule.cpp
|
|
extends RefCounted
|
|
|
|
const DEFAULT_THEME_TRACK := "enter_the_east.mp3"
|
|
|
|
# 40250 官方标准曲目清单 (musicinfo.py)
|
|
const CANONICAL_TRACKS := [
|
|
"enter_the_east.mp3",
|
|
"open_the_gate.mp3",
|
|
"characterselect.mp3",
|
|
"wedding.mp3",
|
|
"desert.mp3",
|
|
"mountain.mp3",
|
|
"temple.mp3",
|
|
"monkey_dungeon.mp3",
|
|
"flame_dungeon.mp3",
|
|
"catacomb.mp3",
|
|
"save_the_world.mp3",
|
|
"peaceful_valley.mp3",
|
|
"wonderland.mp3"
|
|
]
|
|
|
|
# 各大地图官方默认 BGM 映射表
|
|
const DEFAULT_MAP_BGM_MAP := {
|
|
"intro_login": "enter_the_east.mp3",
|
|
"intro_select": "characterselect.mp3",
|
|
"metin2_map_a1": "open_the_gate.mp3",
|
|
"metin2_map_b1": "open_the_gate.mp3",
|
|
"metin2_map_c1": "open_the_gate.mp3",
|
|
"metin2_map_n_desert_01": "desert.mp3",
|
|
"metin2_map_n_snowm_01": "mountain.mp3",
|
|
"metin2_map_milgyo": "temple.mp3",
|
|
"metin2_map_deviltower": "catacomb.mp3",
|
|
"metin2_map_wedding_01": "wedding.mp3",
|
|
}
|
|
|
|
# 播放器运行时状态
|
|
var current_track: String = ""
|
|
var is_playing: bool = false
|
|
var loop_enabled: bool = true
|
|
var volume: float = 0.8 # 0.0 ~ 1.0 (默认 80%)
|
|
|
|
# 自定义地图偏好覆写: map_id -> track_name
|
|
var custom_map_overrides: Dictionary = {}
|
|
|
|
func _init() -> void:
|
|
current_track = ""
|
|
is_playing = false
|
|
loop_enabled = true
|
|
volume = 0.8
|
|
custom_map_overrides.clear()
|
|
|
|
# 1. 播放指定曲目 (1:1 snd.PlayBGM)
|
|
func play_bgm(track_name: String, loop: bool = true) -> bool:
|
|
if not CANONICAL_TRACKS.has(track_name):
|
|
return false
|
|
current_track = track_name
|
|
is_playing = true
|
|
loop_enabled = loop
|
|
return true
|
|
|
|
# 2. 停止背景音乐 (1:1 snd.StopBGM)
|
|
func stop_bgm() -> void:
|
|
is_playing = false
|
|
current_track = ""
|
|
|
|
# 3. 调节音量 (1:1 snd.SetBGMVolume)
|
|
func set_volume(vol_pct: float) -> void:
|
|
volume = clamp(vol_pct, 0.0, 1.0)
|
|
|
|
# 4. 获取指定地图应当播放的背景音乐 (自定义优先,其次默认)
|
|
func get_effective_map_bgm(map_id: String) -> String:
|
|
if custom_map_overrides.has(map_id):
|
|
return custom_map_overrides[map_id]
|
|
return DEFAULT_MAP_BGM_MAP.get(map_id, DEFAULT_THEME_TRACK)
|
|
|
|
# 5. 进入地图自动切换音乐
|
|
func on_enter_map(map_id: String) -> String:
|
|
var target_track = get_effective_map_bgm(map_id)
|
|
if target_track != current_track or not is_playing:
|
|
play_bgm(target_track, true)
|
|
return target_track
|
|
|
|
# 6. 点唱机自定义地图专属曲目 (uiselectmusic.py: SelectMusic)
|
|
func set_custom_map_bgm(map_id: String, track_name: String) -> bool:
|
|
if not CANONICAL_TRACKS.has(track_name):
|
|
return false
|
|
custom_map_overrides[map_id] = track_name
|
|
return true
|
|
|
|
# 7. 恢复地图默认曲目
|
|
func reset_custom_map_bgm(map_id: String) -> void:
|
|
if custom_map_overrides.has(map_id):
|
|
custom_map_overrides.erase(map_id)
|
|
|
|
func clear_all_custom_overrides() -> void:
|
|
custom_map_overrides.clear()
|