""" 视觉效果系统 负责管理天气和季节的视觉效果,如粒子效果、光照变化等 """ import time import random from typing import Dict, Any, List, Optional import math class VisualEffects: """ 视觉效果系统 负责管理天气和季节的视觉效果,包括粒子效果、光照变化、材质变化等 """ def __init__(self, plugin): """ 初始化视觉效果系统 Args: plugin: 天气和季节系统插件实例 """ self.plugin = plugin self.enabled = False self.initialized = False # 粒子效果配置 self.particle_effects = { 'rain': { 'name': '雨滴', 'particle_count': 1000, 'particle_size': (0.1, 0.5), 'particle_speed': (5.0, 15.0), 'particle_lifetime': (0.5, 2.0), 'particle_color': (0.7, 0.7, 1.0, 0.8), 'emission_rate': 100, 'spread': (100.0, 50.0), # 水平和垂直扩散范围 'affected_by_wind': True }, 'snow': { 'name': '雪花', 'particle_count': 800, 'particle_size': (0.2, 1.0), 'particle_speed': (0.5, 3.0), 'particle_lifetime': (3.0, 8.0), 'particle_color': (1.0, 1.0, 1.0, 0.9), 'emission_rate': 80, 'spread': (100.0, 50.0), 'affected_by_wind': True }, 'storm': { 'name': '暴风雨', 'particle_count': 1500, 'particle_size': (0.1, 0.8), 'particle_speed': (8.0, 25.0), 'particle_lifetime': (0.3, 1.5), 'particle_color': (0.5, 0.5, 0.8, 0.7), 'emission_rate': 200, 'spread': (150.0, 80.0), 'affected_by_wind': True }, 'hail': { 'name': '冰雹', 'particle_count': 500, 'particle_size': (0.3, 1.5), 'particle_speed': (10.0, 20.0), 'particle_lifetime': (1.0, 3.0), 'particle_color': (0.9, 0.9, 1.0, 0.9), 'emission_rate': 50, 'spread': (80.0, 60.0), 'affected_by_wind': True }, 'light_fog': { 'name': '薄雾', 'particle_count': 200, 'particle_size': (5.0, 15.0), 'particle_speed': (0.1, 0.5), 'particle_lifetime': (5.0, 15.0), 'particle_color': (0.8, 0.8, 0.8, 0.3), 'emission_rate': 20, 'spread': (200.0, 100.0), 'affected_by_wind': True }, 'heavy_fog': { 'name': '浓雾', 'particle_count': 500, 'particle_size': (10.0, 30.0), 'particle_speed': (0.05, 0.3), 'particle_lifetime': (10.0, 30.0), 'particle_color': (0.7, 0.7, 0.7, 0.5), 'emission_rate': 50, 'spread': (300.0, 150.0), 'affected_by_wind': True }, 'wind_debris': { 'name': '风中碎片', 'particle_count': 100, 'particle_size': (0.5, 2.0), 'particle_speed': (2.0, 10.0), 'particle_lifetime': (1.0, 5.0), 'particle_color': (0.6, 0.5, 0.4, 0.7), 'emission_rate': 10, 'spread': (100.0, 30.0), 'affected_by_wind': True } } # 当前激活的视觉效果 self.active_effects = {} # 材质变化配置 self.material_effects = { 'wet_surface': { 'name': '湿润表面', 'roughness_multiplier': 0.7, 'metallic_multiplier': 1.2, 'specular_multiplier': 1.5, 'normal_strength': 0.8 }, 'snow_cover': { 'name': '积雪覆盖', 'roughness_multiplier': 1.3, 'metallic_multiplier': 0.8, 'specular_multiplier': 0.5, 'normal_strength': 1.2 } } # 光照效果配置 self.lighting_effects = { 'lightning': { 'name': '闪电', 'intensity': 5.0, 'color': (0.8, 0.8, 1.0), 'duration': 0.1, 'frequency': 0.05 # 每秒闪电概率 } } # 视觉效果更新配置 self.update_interval = 0.05 # 更新间隔(秒) self.last_update_time = 0.0 # 粒子系统配置 self.particle_system_config = { 'max_particles': 10000, 'particle_lod': 'medium', # 'low', 'medium', 'high' 'distance_fade': True, 'collision_detection': False } # 统计信息 self.stats = { 'effects_activated': 0, 'particles_generated': 0, 'effects_deactivated': 0, 'total_effect_time': 0.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 self._deactivate_all_effects() 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_active_effects(dt) # 根据当前天气激活相应的视觉效果 self._update_weather_effects() # 更新统计信息 self.stats['total_effect_time'] += dt except Exception as e: print(f"✗ 视觉效果系统更新失败: {e}") import traceback traceback.print_exc() def _update_active_effects(self, dt: float): """ 更新激活的视觉效果 Args: dt: 时间增量 """ try: effects_to_remove = [] for effect_name, effect_data in self.active_effects.items(): # 更新效果持续时间 effect_data['duration'] -= dt # 检查效果是否应该结束 if effect_data['duration'] <= 0 and not effect_data['persistent']: effects_to_remove.append(effect_name) # 移除过期的效果 for effect_name in effects_to_remove: self._deactivate_effect(effect_name) except Exception as e: print(f"✗ 激活效果更新失败: {e}") def _update_weather_effects(self): """根据当前天气更新视觉效果""" try: if not self.plugin.weather_manager: return current_weather = self.plugin.weather_manager.get_current_weather() weather_info = self.plugin.weather_manager.get_weather_info(current_weather) if not weather_info: return # 获取天气对应的粒子效果 particle_effect = weather_info.get('particle_effect') # 检查是否需要激活或更新粒子效果 if particle_effect and particle_effect in self.particle_effects: # 检查效果是否已经激活 if particle_effect not in self.active_effects: # 激活粒子效果 self._activate_particle_effect(particle_effect) else: # 更新现有效果的参数 self._update_particle_effect_parameters(particle_effect) else: # 检查是否需要停用粒子效果 active_particle_effects = [ name for name in self.active_effects.keys() if name in self.particle_effects ] for effect_name in active_particle_effects: self._deactivate_effect(effect_name) except Exception as e: print(f"✗ 天气效果更新失败: {e}") def _activate_particle_effect(self, effect_name: str): """ 激活粒子效果 Args: effect_name: 粒子效果名称 """ try: if effect_name not in self.particle_effects: return effect_config = self.particle_effects[effect_name] # 创建效果数据 effect_data = { 'name': effect_config['name'], 'type': 'particle', 'config': effect_config, 'start_time': time.time(), 'duration': float('inf'), # 持续到手动停用 'persistent': True, 'intensity': 1.0 } # 添加到激活效果列表 self.active_effects[effect_name] = effect_data # 更新统计信息 self.stats['effects_activated'] += 1 self.stats['particles_generated'] += effect_config['particle_count'] print(f"✓ 粒子效果已激活: {effect_config['name']}") except Exception as e: print(f"✗ 粒子效果激活失败: {e}") def _update_particle_effect_parameters(self, effect_name: str): """ 更新粒子效果参数 Args: effect_name: 粒子效果名称 """ try: if effect_name not in self.active_effects: return # 在实际实现中,这里会根据当前天气强度等因素更新粒子效果参数 # 例如:根据降水强度调整雨滴数量和速度 pass except Exception as e: print(f"✗ 粒子效果参数更新失败: {e}") def _deactivate_effect(self, effect_name: str): """ 停用视觉效果 Args: effect_name: 效果名称 """ try: if effect_name in self.active_effects: effect_data = self.active_effects.pop(effect_name) # 更新统计信息 self.stats['effects_deactivated'] += 1 print(f"✓ 视觉效果已停用: {effect_data['name']}") except Exception as e: print(f"✗ 视觉效果停用失败: {e}") def _deactivate_all_effects(self): """停用所有视觉效果""" try: effect_names = list(self.active_effects.keys()) for effect_name in effect_names: self._deactivate_effect(effect_name) except Exception as e: print(f"✗ 所有效果停用失败: {e}") def activate_effect(self, effect_name: str, duration: float = float('inf'), intensity: float = 1.0): """ 激活视觉效果 Args: effect_name: 效果名称 duration: 持续时间(秒),默认为无限 intensity: 效果强度(0-1) """ try: # 检查效果类型 if effect_name in self.particle_effects: self._activate_particle_effect(effect_name) else: # 创建通用效果数据 effect_data = { 'name': effect_name, 'type': 'generic', 'start_time': time.time(), 'duration': duration, 'persistent': duration == float('inf'), 'intensity': max(0.0, min(1.0, intensity)) } self.active_effects[effect_name] = effect_data self.stats['effects_activated'] += 1 print(f"✓ 视觉效果已激活: {effect_name}") except Exception as e: print(f"✗ 视觉效果激活失败: {e}") def deactivate_effect(self, effect_name: str): """ 停用视觉效果 Args: effect_name: 效果名称 """ self._deactivate_effect(effect_name) def set_effect_intensity(self, effect_name: str, intensity: float): """ 设置效果强度 Args: effect_name: 效果名称 intensity: 效果强度(0-1) """ try: if effect_name in self.active_effects: self.active_effects[effect_name]['intensity'] = max(0.0, min(1.0, intensity)) print(f"✓ 效果强度已设置: {effect_name} = {intensity}") else: print(f"✗ 效果未激活: {effect_name}") except Exception as e: print(f"✗ 效果强度设置失败: {e}") def get_active_effects(self) -> List[str]: """ 获取激活的视觉效果列表 Returns: 激活的效果名称列表 """ return list(self.active_effects.keys()) def get_effect_info(self, effect_name: str) -> Optional[Dict[str, Any]]: """ 获取效果信息 Args: effect_name: 效果名称 Returns: 效果信息字典或None """ try: # 检查粒子效果 if effect_name in self.particle_effects: return self.particle_effects[effect_name].copy() # 检查激活的效果 if effect_name in self.active_effects: return self.active_effects[effect_name].copy() return None except Exception as e: print(f"✗ 效果信息获取失败: {e}") return None def get_particle_effects_list(self) -> List[str]: """ 获取所有粒子效果列表 Returns: 粒子效果名称列表 """ return list(self.particle_effects.keys()) def get_material_effects_list(self) -> List[str]: """ 获取所有材质效果列表 Returns: 材质效果名称列表 """ return list(self.material_effects.keys()) def apply_material_effect(self, material_name: str, effect_name: str): """ 应用材质效果 Args: material_name: 材质名称 effect_name: 效果名称 """ try: if effect_name in self.material_effects: effect_config = self.material_effects[effect_name] # 在实际实现中,这里会应用材质效果到指定材质 print(f"✓ 材质效果已应用: {material_name} + {effect_config['name']}") else: print(f"✗ 无效的材质效果: {effect_name}") except Exception as e: print(f"✗ 材质效果应用失败: {e}") def remove_material_effect(self, material_name: str, effect_name: str): """ 移除材质效果 Args: material_name: 材质名称 effect_name: 效果名称 """ try: # 在实际实现中,这里会从指定材质移除效果 print(f"✓ 材质效果已移除: {material_name} - {effect_name}") except Exception as e: print(f"✗ 材质效果移除失败: {e}") def trigger_lighting_effect(self, effect_name: str): """ 触发瞬时光照效果 Args: effect_name: 光照效果名称 """ try: if effect_name in self.lighting_effects: effect_config = self.lighting_effects[effect_name] # 在实际实现中,这里会触发瞬时光照效果 print(f"✓ 光照效果已触发: {effect_config['name']}") else: print(f"✗ 无效的光照效果: {effect_name}") except Exception as e: print(f"✗ 光照效果触发失败: {e}") def set_particle_system_config(self, config: Dict[str, Any]): """ 设置粒子系统配置 Args: config: 配置字典 """ self.particle_system_config.update(config) print(f"✓ 粒子系统配置已更新: {self.particle_system_config}") def get_particle_system_config(self) -> Dict[str, Any]: """ 获取粒子系统配置 Returns: 粒子系统配置字典 """ return self.particle_system_config.copy() def get_stats(self) -> Dict[str, Any]: """ 获取统计信息 Returns: 统计信息字典 """ return self.stats.copy() def reset_stats(self): """重置统计信息""" self.stats = { 'effects_activated': 0, 'particles_generated': 0, 'effects_deactivated': 0, 'total_effect_time': 0.0 } print("✓ 视觉效果系统统计信息已重置") def set_update_interval(self, interval: float): """ 设置更新间隔 Args: interval: 更新间隔(秒) """ self.update_interval = max(0.01, interval) print(f"✓ 视觉效果更新间隔设置为: {interval} 秒") def is_effect_active(self, effect_name: str) -> bool: """ 检查效果是否激活 Args: effect_name: 效果名称 Returns: 效果是否激活 """ return effect_name in self.active_effects