# weather_daynight_system.gd —— Metin2 40250 单机本地天候昼夜交替与地图环境特效系统 1:1 # 对照 40250 客户端 PythonBackground.cpp, game.py, environment.h class_name WeatherDayNightSystem extends RefCounted signal phase_changed(old_phase: String, new_phase: String) signal weather_changed(old_weather: String, new_weather: String) signal lighting_updated(sun_color: Color, sun_energy: float, ambient_color: Color, fog_density: float) const PHASE_DAWN := "dawn" # 黎明晨曦 (05:00 ~ 08:00) const PHASE_NOON := "noon" # 正午晴空 (08:00 ~ 17:00) const PHASE_DUSK := "dusk" # 黄昏落日 (17:00 ~ 20:00) const PHASE_NIGHT := "night" # 寂静黑夜 (20:00 ~ 05:00) const WEATHER_CLEAR := "clear" # 晴朗明净 const WEATHER_RAIN := "rain" # 潇潇细雨 const WEATHER_SNOW := "snow" # 冰山暴雪 (Mount Sohan) const WEATHER_SANDSTORM := "sandstorm" # 狂沙飞舞 (Yongbi Desert) const WEATHER_CINDERS := "cinders" # 烈焰余烬 (Doyyumhwan) const SECONDS_PER_DAY: float = 86400.0 const DEFAULT_TIME_SCALE: float = 60.0 # 默认 1 秒流逝 60 秒游戏时间 (24 分钟一昼夜) const MAP_DEFAULT_WEATHER: Dictionary = { "village": WEATHER_CLEAR, "sohan": WEATHER_SNOW, "desert": WEATHER_SANDSTORM, "flame": WEATHER_CINDERS, "temple": WEATHER_CLEAR, "catacomb": WEATHER_CLEAR } var time_of_day: float = 43200.0 # 默认正午 12:00:00 (12 * 3600) var time_scale: float = DEFAULT_TIME_SCALE var is_frozen: bool = false var current_phase: String = PHASE_NOON var current_weather: String = WEATHER_CLEAR var current_map: String = "village" # 光影参数 var sun_color: Color = Color(1.0, 0.98, 0.9) var sun_energy: float = 1.2 var ambient_color: Color = Color(0.9, 0.9, 0.95) var fog_density: float = 0.001 func _init() -> void: _update_phase_and_lighting() # 帧心跳更新天候流逝 func update(delta: float) -> void: if not is_frozen: time_of_day = fmod(time_of_day + delta * time_scale, SECONDS_PER_DAY) if time_of_day < 0.0: time_of_day += SECONDS_PER_DAY _update_phase_and_lighting() # 手动设置指定时间 (小时 0~24,分钟 0~60) func set_time_of_day(hour: float, minute: float = 0.0) -> void: var clamped_h = clampf(hour, 0.0, 23.99) var clamped_m = clampf(minute, 0.0, 59.99) time_of_day = clamped_h * 3600.0 + clamped_m * 60.0 _update_phase_and_lighting() # 直接快速切换至指定时相 func set_phase(target_phase: String) -> void: match target_phase: PHASE_DAWN: set_time_of_day(6.0, 0.0) PHASE_NOON: set_time_of_day(12.0, 0.0) PHASE_DUSK: set_time_of_day(18.5, 0.0) PHASE_NIGHT: set_time_of_day(23.0, 0.0) # 设置天气模式 func set_weather(weather_type: String) -> Dictionary: var valid_weathers = [WEATHER_CLEAR, WEATHER_RAIN, WEATHER_SNOW, WEATHER_SANDSTORM, WEATHER_CINDERS] if not (weather_type in valid_weathers): return {"ok": false, "reason": "INVALID_WEATHER_TYPE"} if current_weather != weather_type: var old = current_weather current_weather = weather_type weather_changed.emit(old, weather_type) _update_phase_and_lighting() return {"ok": true, "weather": current_weather} # 设置当前地图并自动匹配环境天气 func set_map_environment(map_name: String) -> void: current_map = map_name var def_weather = MAP_DEFAULT_WEATHER.get(map_name, WEATHER_CLEAR) set_weather(def_weather) # 核心昼夜时相与光照参数计算 func _update_phase_and_lighting() -> void: var hours = time_of_day / 3600.0 var new_phase = PHASE_NOON if hours >= 5.0 and hours < 8.0: new_phase = PHASE_DAWN sun_color = Color(1.0, 0.8, 0.6) # 晨曦暖金 sun_energy = 0.75 ambient_color = Color(0.85, 0.75, 0.65) fog_density = 0.002 elif hours >= 8.0 and hours < 17.0: new_phase = PHASE_NOON sun_color = Color(1.0, 0.98, 0.92) # 正午白炽日光 sun_energy = 1.2 ambient_color = Color(0.9, 0.9, 0.95) fog_density = 0.001 elif hours >= 17.0 and hours < 20.0: new_phase = PHASE_DUSK sun_color = Color(0.95, 0.45, 0.3) # 晚霞橙红 sun_energy = 0.65 ambient_color = Color(0.7, 0.45, 0.4) fog_density = 0.003 else: new_phase = PHASE_NIGHT sun_color = Color(0.3, 0.4, 0.7) # 冷冽月光 sun_energy = 0.25 ambient_color = Color(0.15, 0.2, 0.35) fog_density = 0.004 # 天气修正 match current_weather: WEATHER_RAIN: sun_energy *= 0.6 fog_density += 0.003 WEATHER_SNOW: sun_color = sun_color.lerp(Color(0.85, 0.9, 1.0), 0.5) fog_density += 0.002 WEATHER_SANDSTORM: sun_color = sun_color.lerp(Color(0.85, 0.7, 0.4), 0.6) fog_density += 0.008 WEATHER_CINDERS: sun_color = sun_color.lerp(Color(1.0, 0.35, 0.2), 0.5) fog_density += 0.004 if current_phase != new_phase: var old = current_phase current_phase = new_phase phase_changed.emit(old, new_phase) lighting_updated.emit(sun_color, sun_energy, ambient_color, fog_density) # 获取格式化时间字符串 "HH:MM:SS" func get_time_string() -> String: var total_sec = int(time_of_day) var h = int(total_sec / 3600) var m = int((total_sec % 3600) / 60) var s = total_sec % 60 return "%02d:%02d:%02d" % [h, m, s] # 获取当前光照参数字典 func get_current_lighting() -> Dictionary: return { "phase": current_phase, "weather": current_weather, "time_string": get_time_string(), "sun_color": sun_color, "sun_energy": sun_energy, "ambient_color": ambient_color, "fog_density": fog_density }