596 lines
20 KiB
Python
596 lines
20 KiB
Python
"""
|
||
环境效果系统
|
||
负责管理天气和季节对环境的影响效果
|
||
"""
|
||
|
||
import time
|
||
from typing import Dict, Any, Tuple
|
||
import math
|
||
|
||
class EnvironmentEffects:
|
||
"""
|
||
环境效果系统
|
||
负责管理天气和季节对环境的影响,包括光照、雾效、风效等
|
||
"""
|
||
|
||
def __init__(self, plugin):
|
||
"""
|
||
初始化环境效果系统
|
||
|
||
Args:
|
||
plugin: 天气和季节系统插件实例
|
||
"""
|
||
self.plugin = plugin
|
||
self.enabled = False
|
||
self.initialized = False
|
||
|
||
# 光照效果配置
|
||
self.lighting_config = {
|
||
'sun_color': (1.0, 1.0, 1.0),
|
||
'sun_intensity': 1.0,
|
||
'ambient_color': (0.3, 0.3, 0.3),
|
||
'ambient_intensity': 0.3,
|
||
'shadow_strength': 1.0,
|
||
'light_temperature': 6500.0 # 色温(K)
|
||
}
|
||
|
||
# 雾效配置
|
||
self.fog_config = {
|
||
'fog_color': (0.5, 0.5, 0.5),
|
||
'fog_density': 0.0,
|
||
'fog_start': 100.0,
|
||
'fog_end': 1000.0,
|
||
'fog_mode': 'linear' # 'linear', 'exp', 'exp2'
|
||
}
|
||
|
||
# 风效配置
|
||
self.wind_config = {
|
||
'wind_direction': (1.0, 0.0, 0.0),
|
||
'wind_speed': 0.0,
|
||
'wind_turbulence': 0.1,
|
||
'wind_gust_strength': 0.0,
|
||
'wind_gust_frequency': 0.1
|
||
}
|
||
|
||
# 后处理效果配置
|
||
self.post_processing_config = {
|
||
'exposure': 1.0,
|
||
'saturation': 1.0,
|
||
'contrast': 1.0,
|
||
'brightness': 0.0,
|
||
'bloom_intensity': 0.5,
|
||
'lens_flare': 0.0
|
||
}
|
||
|
||
# 时间配置
|
||
self.time_config = {
|
||
'day_time': 12.0, # 当前时间(小时)
|
||
'day_speed': 1.0, # 时间流逝速度
|
||
'latitude': 0.0, # 纬度(影响日照)
|
||
'longitude': 0.0 # 经度
|
||
}
|
||
|
||
# 当前效果状态
|
||
self.current_effects = {
|
||
'lighting': self.lighting_config.copy(),
|
||
'fog': self.fog_config.copy(),
|
||
'wind': self.wind_config.copy(),
|
||
'post_processing': self.post_processing_config.copy()
|
||
}
|
||
|
||
# 效果更新配置
|
||
self.update_interval = 0.1 # 更新间隔(秒)
|
||
self.last_update_time = 0.0
|
||
|
||
# 统计信息
|
||
self.stats = {
|
||
'effects_updated': 0,
|
||
'lighting_updates': 0,
|
||
'fog_updates': 0,
|
||
'wind_updates': 0
|
||
}
|
||
|
||
print("✓ 环境效果系统已创建")
|
||
|
||
def initialize(self) -> bool:
|
||
"""
|
||
初始化环境效果系统
|
||
|
||
Returns:
|
||
是否初始化成功
|
||
"""
|
||
try:
|
||
self.initialized = True
|
||
print("✓ 环境效果系统初始化完成")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 环境效果系统初始化失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
|
||
def enable(self) -> bool:
|
||
"""
|
||
启用环境效果系统
|
||
|
||
Returns:
|
||
是否启用成功
|
||
"""
|
||
try:
|
||
if not self.initialized:
|
||
print("✗ 环境效果系统未初始化")
|
||
return False
|
||
|
||
self.enabled = True
|
||
print("✓ 环境效果系统已启用")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 环境效果系统启用失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
|
||
def disable(self):
|
||
"""禁用环境效果系统"""
|
||
try:
|
||
self.enabled = False
|
||
print("✓ 环境效果系统已禁用")
|
||
|
||
except Exception as e:
|
||
print(f"✗ 环境效果系统禁用失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
|
||
def finalize(self):
|
||
"""清理环境效果系统资源"""
|
||
try:
|
||
self.disable()
|
||
self.initialized = False
|
||
print("✓ 环境效果系统资源已清理")
|
||
|
||
except Exception as e:
|
||
print(f"✗ 环境效果系统资源清理失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
|
||
def update(self, dt: float):
|
||
"""
|
||
更新环境效果系统状态
|
||
|
||
Args:
|
||
dt: 时间增量
|
||
"""
|
||
try:
|
||
if not self.enabled:
|
||
return
|
||
|
||
# 检查是否需要更新
|
||
self.last_update_time += dt
|
||
if self.last_update_time < self.update_interval:
|
||
return
|
||
|
||
# 重置更新计时器
|
||
self.last_update_time = 0.0
|
||
|
||
# 更新各种环境效果
|
||
self._update_lighting_effects()
|
||
self._update_fog_effects()
|
||
self._update_wind_effects()
|
||
self._update_post_processing_effects()
|
||
|
||
# 更新统计信息
|
||
self.stats['effects_updated'] += 1
|
||
|
||
except Exception as e:
|
||
print(f"✗ 环境效果系统更新失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
|
||
def _update_lighting_effects(self):
|
||
"""更新光照效果"""
|
||
try:
|
||
# 获取当前环境参数
|
||
if self.plugin.weather_manager:
|
||
env_params = self.plugin.weather_manager.get_current_environment_params()
|
||
else:
|
||
env_params = {
|
||
'temperature': 20.0,
|
||
'humidity': 50.0,
|
||
'wind_speed': 3.0,
|
||
'visibility': 1.0
|
||
}
|
||
|
||
# 获取当前季节参数
|
||
if self.plugin.season_manager:
|
||
season_params = self.plugin.season_manager.get_interpolated_season_params()
|
||
else:
|
||
season_params = {
|
||
'temperature': 15.0,
|
||
'humidity': 60.0,
|
||
'day_length': 12.5,
|
||
'color_tint': (1.0, 1.0, 0.8)
|
||
}
|
||
|
||
# 获取当前天气参数
|
||
if self.plugin.weather_manager:
|
||
weather_params = self.plugin.weather_manager.get_interpolated_weather_params()
|
||
else:
|
||
weather_params = {
|
||
'cloud_cover': 0.1,
|
||
'light_intensity': 1.0,
|
||
'temperature_modifier': 0.0,
|
||
'humidity_modifier': 0.0
|
||
}
|
||
|
||
# 计算太阳颜色(基于时间、天气和季节)
|
||
sun_color = self._calculate_sun_color(
|
||
self.time_config['day_time'],
|
||
weather_params['cloud_cover'],
|
||
season_params['color_tint']
|
||
)
|
||
|
||
# 计算光照强度(基于时间、天气)
|
||
sun_intensity = self._calculate_sun_intensity(
|
||
self.time_config['day_time'],
|
||
weather_params['light_intensity'],
|
||
season_params['day_length']
|
||
)
|
||
|
||
# 计算环境光
|
||
ambient_intensity = 0.3 * weather_params['light_intensity']
|
||
|
||
# 更新光照配置
|
||
self.current_effects['lighting']['sun_color'] = sun_color
|
||
self.current_effects['lighting']['sun_intensity'] = sun_intensity
|
||
self.current_effects['lighting']['ambient_intensity'] = ambient_intensity
|
||
|
||
# 更新统计信息
|
||
self.stats['lighting_updates'] += 1
|
||
|
||
except Exception as e:
|
||
print(f"✗ 光照效果更新失败: {e}")
|
||
|
||
def _calculate_sun_color(self, time_of_day: float, cloud_cover: float, season_tint: Tuple[float, float, float]) -> Tuple[float, float, float]:
|
||
"""
|
||
计算太阳颜色
|
||
|
||
Args:
|
||
time_of_day: 当前时间(小时)
|
||
cloud_cover: 云层覆盖率
|
||
season_tint: 季节色调
|
||
|
||
Returns:
|
||
太阳颜色(RGB)
|
||
"""
|
||
try:
|
||
# 基础太阳颜色(根据时间变化)
|
||
if 6 <= time_of_day <= 18: # 白天
|
||
# 正午最白,早晚偏黄
|
||
hour_offset = abs(time_of_day - 12)
|
||
warmth = max(0.0, 1.0 - hour_offset / 6.0) # 12点最暖(1.0),6点和18点最冷(0.0)
|
||
base_color = (
|
||
1.0,
|
||
0.9 + 0.1 * warmth, # 绿色分量
|
||
0.8 + 0.2 * warmth # 蓝色分量
|
||
)
|
||
else: # 夜晚
|
||
base_color = (0.3, 0.3, 0.5) # 夜晚偏蓝
|
||
|
||
# 应用云层影响
|
||
cloud_factor = 1.0 - cloud_cover * 0.7 # 云层使颜色变暗
|
||
colored_sun = tuple(c * cloud_factor for c in base_color)
|
||
|
||
# 应用季节色调
|
||
final_color = tuple(colored_sun[i] * season_tint[i] for i in range(3))
|
||
|
||
return final_color
|
||
|
||
except Exception as e:
|
||
print(f"✗ 太阳颜色计算失败: {e}")
|
||
return (1.0, 1.0, 1.0)
|
||
|
||
def _calculate_sun_intensity(self, time_of_day: float, weather_intensity: float, day_length: float) -> float:
|
||
"""
|
||
计算太阳强度
|
||
|
||
Args:
|
||
time_of_day: 当前时间(小时)
|
||
weather_intensity: 天气光照强度
|
||
day_length: 日照时长(小时)
|
||
|
||
Returns:
|
||
太阳强度
|
||
"""
|
||
try:
|
||
# 计算日出和日落时间
|
||
sunrise = 12.0 - day_length / 2.0
|
||
sunset = 12.0 + day_length / 2.0
|
||
|
||
# 夜晚强度为0
|
||
if time_of_day < sunrise or time_of_day > sunset:
|
||
return 0.0
|
||
|
||
# 白天计算强度(正弦曲线)
|
||
day_progress = (time_of_day - sunrise) / (sunset - sunrise)
|
||
angle = day_progress * math.pi
|
||
base_intensity = math.sin(angle)
|
||
|
||
# 应用天气影响
|
||
final_intensity = base_intensity * weather_intensity
|
||
|
||
return max(0.0, final_intensity)
|
||
|
||
except Exception as e:
|
||
print(f"✗ 太阳强度计算失败: {e}")
|
||
return 1.0
|
||
|
||
def _update_fog_effects(self):
|
||
"""更新雾效"""
|
||
try:
|
||
# 获取当前天气参数
|
||
if self.plugin.weather_manager:
|
||
weather_params = self.plugin.weather_manager.get_interpolated_weather_params()
|
||
else:
|
||
weather_params = {
|
||
'visibility': 1.0,
|
||
'precipitation': 0.0
|
||
}
|
||
|
||
# 根据能见度计算雾密度
|
||
visibility = weather_params['visibility']
|
||
fog_density = (1.0 - visibility) * 0.1
|
||
|
||
# 根据降水增加雾密度
|
||
precipitation = weather_params['precipitation']
|
||
fog_density += precipitation * 0.05
|
||
|
||
# 更新雾效配置
|
||
self.current_effects['fog']['fog_density'] = fog_density
|
||
|
||
# 根据能见度调整雾的起始和结束距离
|
||
self.current_effects['fog']['fog_start'] = 50.0 * visibility
|
||
self.current_effects['fog']['fog_end'] = 500.0 * visibility
|
||
|
||
# 更新统计信息
|
||
self.stats['fog_updates'] += 1
|
||
|
||
except Exception as e:
|
||
print(f"✗ 雾效更新失败: {e}")
|
||
|
||
def _update_wind_effects(self):
|
||
"""更新风效"""
|
||
try:
|
||
# 获取当前环境参数
|
||
if self.plugin.weather_manager:
|
||
env_params = self.plugin.weather_manager.get_current_environment_params()
|
||
else:
|
||
env_params = {
|
||
'wind_speed': 3.0
|
||
}
|
||
|
||
# 获取当前天气参数
|
||
if self.plugin.weather_manager:
|
||
weather_params = self.plugin.weather_manager.get_interpolated_weather_params()
|
||
else:
|
||
weather_params = {
|
||
'wind_speed': 2.0
|
||
}
|
||
|
||
# 结合环境和天气风速
|
||
wind_speed = env_params['wind_speed'] * weather_params['wind_speed'] / 2.0
|
||
|
||
# 添加一些随机扰动
|
||
turbulence = 0.1 + random.uniform(-0.05, 0.05)
|
||
|
||
# 更新风效配置
|
||
self.current_effects['wind']['wind_speed'] = wind_speed
|
||
self.current_effects['wind']['wind_turbulence'] = turbulence
|
||
|
||
# 更新统计信息
|
||
self.stats['wind_updates'] += 1
|
||
|
||
except Exception as e:
|
||
print(f"✗ 风效更新失败: {e}")
|
||
|
||
def _update_post_processing_effects(self):
|
||
"""更新后处理效果"""
|
||
try:
|
||
# 获取当前天气参数
|
||
if self.plugin.weather_manager:
|
||
weather_params = self.plugin.weather_manager.get_interpolated_weather_params()
|
||
else:
|
||
weather_params = {
|
||
'light_intensity': 1.0,
|
||
'visibility': 1.0
|
||
}
|
||
|
||
# 获取当前季节参数
|
||
if self.plugin.season_manager:
|
||
season_params = self.plugin.season_manager.get_interpolated_season_params()
|
||
else:
|
||
season_params = {
|
||
'color_tint': (1.0, 1.0, 0.8)
|
||
}
|
||
|
||
# 根据光照强度调整曝光
|
||
light_intensity = weather_params['light_intensity']
|
||
exposure = 0.5 + 0.5 * light_intensity
|
||
|
||
# 根据能见度调整对比度和饱和度
|
||
visibility = weather_params['visibility']
|
||
contrast = 0.8 + 0.2 * visibility
|
||
saturation = 0.7 + 0.3 * visibility
|
||
|
||
# 根据季节色调调整颜色
|
||
color_tint = season_params['color_tint']
|
||
|
||
# 更新后处理配置
|
||
self.current_effects['post_processing']['exposure'] = exposure
|
||
self.current_effects['post_processing']['contrast'] = contrast
|
||
self.current_effects['post_processing']['saturation'] = saturation
|
||
|
||
# 根据天气类型调整辉光效果
|
||
current_weather = self.plugin.weather_manager.get_current_weather() if self.plugin.weather_manager else 'clear'
|
||
if current_weather in ['clear', 'cloudy']:
|
||
bloom = 0.5 * light_intensity
|
||
else:
|
||
bloom = 0.2 * light_intensity
|
||
|
||
self.current_effects['post_processing']['bloom_intensity'] = bloom
|
||
|
||
except Exception as e:
|
||
print(f"✗ 后处理效果更新失败: {e}")
|
||
|
||
def get_current_effects(self) -> Dict[str, Any]:
|
||
"""
|
||
获取当前环境效果
|
||
|
||
Returns:
|
||
当前环境效果字典
|
||
"""
|
||
return self.current_effects.copy()
|
||
|
||
def get_lighting_effects(self) -> Dict[str, Any]:
|
||
"""
|
||
获取当前光照效果
|
||
|
||
Returns:
|
||
当前光照效果字典
|
||
"""
|
||
return self.current_effects['lighting'].copy()
|
||
|
||
def get_fog_effects(self) -> Dict[str, Any]:
|
||
"""
|
||
获取当前雾效
|
||
|
||
Returns:
|
||
当前雾效字典
|
||
"""
|
||
return self.current_effects['fog'].copy()
|
||
|
||
def get_wind_effects(self) -> Dict[str, Any]:
|
||
"""
|
||
获取当前风效
|
||
|
||
Returns:
|
||
当前风效字典
|
||
"""
|
||
return self.current_effects['wind'].copy()
|
||
|
||
def get_post_processing_effects(self) -> Dict[str, Any]:
|
||
"""
|
||
获取当前后处理效果
|
||
|
||
Returns:
|
||
当前后处理效果字典
|
||
"""
|
||
return self.current_effects['post_processing'].copy()
|
||
|
||
def set_time(self, hour: float):
|
||
"""
|
||
设置当前时间
|
||
|
||
Args:
|
||
hour: 小时(0-24)
|
||
"""
|
||
self.time_config['day_time'] = max(0.0, min(24.0, hour))
|
||
print(f"✓ 当前时间设置为: {hour:.1f} 小时")
|
||
|
||
def set_day_speed(self, speed: float):
|
||
"""
|
||
设置时间流逝速度
|
||
|
||
Args:
|
||
speed: 时间流逝速度倍数
|
||
"""
|
||
self.time_config['day_speed'] = max(0.0, speed)
|
||
print(f"✓ 时间流逝速度设置为: {speed}x")
|
||
|
||
def set_location(self, latitude: float, longitude: float):
|
||
"""
|
||
设置地理位置
|
||
|
||
Args:
|
||
latitude: 纬度
|
||
longitude: 经度
|
||
"""
|
||
self.time_config['latitude'] = latitude
|
||
self.time_config['longitude'] = longitude
|
||
print(f"✓ 地理位置设置为: ({latitude}, {longitude})")
|
||
|
||
def apply_immediate_effects(self):
|
||
"""立即应用所有环境效果"""
|
||
try:
|
||
self._update_lighting_effects()
|
||
self._update_fog_effects()
|
||
self._update_wind_effects()
|
||
self._update_post_processing_effects()
|
||
print("✓ 环境效果已立即更新")
|
||
except Exception as e:
|
||
print(f"✗ 环境效果立即应用失败: {e}")
|
||
|
||
def get_stats(self) -> Dict[str, Any]:
|
||
"""
|
||
获取统计信息
|
||
|
||
Returns:
|
||
统计信息字典
|
||
"""
|
||
return self.stats.copy()
|
||
|
||
def reset_stats(self):
|
||
"""重置统计信息"""
|
||
self.stats = {
|
||
'effects_updated': 0,
|
||
'lighting_updates': 0,
|
||
'fog_updates': 0,
|
||
'wind_updates': 0
|
||
}
|
||
print("✓ 环境效果系统统计信息已重置")
|
||
|
||
def set_update_interval(self, interval: float):
|
||
"""
|
||
设置更新间隔
|
||
|
||
Args:
|
||
interval: 更新间隔(秒)
|
||
"""
|
||
self.update_interval = max(0.01, interval)
|
||
print(f"✓ 环境效果更新间隔设置为: {interval} 秒")
|
||
|
||
def get_effect_parameters(self, effect_type: str) -> Dict[str, Any]:
|
||
"""
|
||
获取特定效果类型的参数
|
||
|
||
Args:
|
||
effect_type: 效果类型('lighting', 'fog', 'wind', 'post_processing')
|
||
|
||
Returns:
|
||
效果参数字典
|
||
"""
|
||
if effect_type in self.current_effects:
|
||
return self.current_effects[effect_type].copy()
|
||
return {}
|
||
|
||
def set_effect_parameter(self, effect_type: str, parameter: str, value: Any):
|
||
"""
|
||
设置特定效果参数
|
||
|
||
Args:
|
||
effect_type: 效果类型
|
||
parameter: 参数名称
|
||
value: 参数值
|
||
"""
|
||
try:
|
||
if effect_type in self.current_effects:
|
||
if parameter in self.current_effects[effect_type]:
|
||
self.current_effects[effect_type][parameter] = value
|
||
print(f"✓ {effect_type}.{parameter} 设置为: {value}")
|
||
else:
|
||
print(f"✗ 无效的参数: {parameter}")
|
||
else:
|
||
print(f"✗ 无效的效果类型: {effect_type}")
|
||
except Exception as e:
|
||
print(f"✗ 效果参数设置失败: {e}") |