"""
高度图生成器
负责生成程序化地形的高度图数据
"""

import numpy as np
from typing import Dict, Any
import math
import random

class HeightmapGenerator:
    """
    高度图生成器
    负责生成程序化地形的高度图数据，使用多种噪声算法和地形特征生成技术
    """
    
    def __init__(self, plugin):
        """
        初始化高度图生成器
        
        Args:
            plugin: 程序化地形生成插件实例
        """
        self.plugin = plugin
        self.enabled = False
        self.initialized = False
        
        # 生成器配置
        self.seed = plugin.config.get('seed', 12345)
        self.scale = 50.0
        self.octaves = 6
        self.persistence = 0.5
        self.lacunarity = 2.0
        self.height_multiplier = 1.0
        self.water_level = 0.8
        
        # 地形特征参数
        self.mountain_scale = 1.0
        self.hill_scale = 0.5
        self.plain_scale = 0.1
        self.valley_scale = 0.3
        
        # 地形类型权重
        self.terrain_weights = {
            'mountains': 0.3,
            'hills': 0.4,
            'plains': 0.2,
            'valleys': 0.1
        }
        
        # 噪声生成器引用
        self.noise_generator = None
        
        # 统计信息
        self.stats = {
            'generations_count': 0,
            'total_generation_time': 0.0,
            'average_generation_time': 0.0,
            'last_generation_time': 0.0
        }
        
        print("✓ 高度图生成器已创建")
        
    def initialize(self) -> bool:
        """
        初始化高度图生成器
        
        Returns:
            是否初始化成功
        """
        try:
            # 获取噪声生成器引用
            self.noise_generator = self.plugin.noise_generator
            
            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: 时间增量
        """
        # 处理更新逻辑
        pass
        
    def generate_heightmap(self, width: int, height: int, seed: int = None) -> np.ndarray:
        """
        生成高度图
        
        Args:
            width: 高度图宽度
            height: 高度图高度
            seed: 随机种子
            
        Returns:
            高度图数据
        """
        try:
            import time
            generation_start_time = time.time()
            
            if not self.enabled:
                print("✗ 高度图生成器未启用")
                return np.zeros((height, width), dtype=np.float32)
                
            # 更新种子
            if seed is not None:
                self.seed = seed
                
            # 设置随机种子
            random.seed(self.seed)
            np.random.seed(self.seed)
            
            print(f"✓ 开始生成 {width}x{height} 高度图...")
            
            # 创建高度图数组
            heightmap = np.zeros((height, width), dtype=np.float32)
            
            # 生成基础噪声
            print("  → 生成基础噪声...")
            base_noise = self._generate_base_noise(width, height)
            
            # 应用地形特征
            print("  → 应用地形特征...")
            terrain_features = self._apply_terrain_features(width, height)
            
            # 混合噪声和地形特征
            print("  → 混合地形数据...")
            heightmap = self._blend_terrain_data(base_noise, terrain_features)
            
            # 应用后处理
            print("  → 应用后处理...")
            heightmap = self._post_process_heightmap(heightmap)
            
            # 更新统计信息
            generation_time = time.time() - generation_start_time
            self.stats['generations_count'] += 1
            self.stats['total_generation_time'] += generation_time
            self.stats['average_generation_time'] = self.stats['total_generation_time'] / self.stats['generations_count']
            self.stats['last_generation_time'] = generation_time
            
            print(f"✓ 高度图生成完成，耗时: {generation_time:.2f}秒")
            return heightmap
            
        except Exception as e:
            print(f"✗ 高度图生成失败: {e}")
            import traceback
            traceback.print_exc()
            return np.zeros((height, width), dtype=np.float32)
            
    def _generate_base_noise(self, width: int, height: int) -> np.ndarray:
        """
        生成基础噪声
        
        Args:
            width: 噪声图宽度
            height: 噪声图高度
            
        Returns:
            基础噪声数据
        """
        try:
            if self.noise_generator is None:
                # 如果没有噪声生成器，生成简单的随机噪声
                print("⚠ 未找到噪声生成器，使用简化噪声生成")
                return np.random.rand(height, width).astype(np.float32)
                
            # 使用分形噪声生成基础地形
            noise_map = np.zeros((height, width), dtype=np.float32)
            
            # 生成多层噪声
            amplitude = 1.0
            frequency = 1.0
            max_value = 0.0
            
            for octave in range(self.octaves):
                # 计算当前层的频率和振幅
                current_frequency = frequency / self.scale
                current_amplitude = amplitude
                
                # 生成噪声层
                for y in range(height):
                    for x in range(width):
                        noise_value = self.noise_generator.generate_noise(
                            x * current_frequency,
                            y * current_frequency,
                            self.seed + octave
                        )
                        noise_map[y, x] += noise_value * current_amplitude
                        
                # 更新最大值用于归一化
                max_value += current_amplitude
                
                # 更新频率和振幅
                amplitude *= self.persistence
                frequency *= self.lacunarity
                
            # 归一化噪声值到0-1范围
            if max_value > 0:
                noise_map = (noise_map + 1) / 2  # 将[-1,1]转换为[0,1]
                
            return noise_map
            
        except Exception as e:
            print(f"✗ 基础噪声生成失败: {e}")
            return np.random.rand(height, width).astype(np.float32)
            
    def _apply_terrain_features(self, width: int, height: int) -> np.ndarray:
        """
        应用地形特征
        
        Args:
            width: 地形宽度
            height: 地形高度
            
        Returns:
            地形特征数据
        """
        try:
            features_map = np.zeros((height, width), dtype=np.float32)
            
            # 计算中心点
            center_x, center_y = width / 2.0, height / 2.0
            max_distance = math.sqrt(center_x**2 + center_y**2)
            
            # 生成不同的地形特征
            for y in range(height):
                for x in range(width):
                    # 计算到中心的距离
                    distance_x = x - center_x
                    distance_y = y - center_y
                    distance = math.sqrt(distance_x**2 + distance_y**2) / max_distance
                    
                    # 生成径向地形特征
                    radial_feature = math.sin(distance * math.pi * 4) * 0.1
                    
                    # 生成角度特征
                    angle = math.atan2(distance_y, distance_x)
                    angular_feature = math.sin(angle * 8) * 0.05
                    
                    # 组合特征
                    features_map[y, x] = radial_feature + angular_feature
                    
            return features_map
            
        except Exception as e:
            print(f"✗ 地形特征应用失败: {e}")
            return np.zeros((height, width), dtype=np.float32)
            
    def _blend_terrain_data(self, base_noise: np.ndarray, terrain_features: np.ndarray) -> np.ndarray:
        """
        混合地形数据
        
        Args:
            base_noise: 基础噪声数据
            terrain_features: 地形特征数据
            
        Returns:
            混合后的地形数据
        """
        try:
            height, width = base_noise.shape
            
            # 确保两个数组尺寸相同
            if terrain_features.shape != (height, width):
                # 调整地形特征尺寸
                terrain_features = np.resize(terrain_features, (height, width))
                
            # 混合数据
            blended_map = np.zeros((height, width), dtype=np.float32)
            
            # 获取地形权重
            mountain_weight = self.terrain_weights.get('mountains', 0.3)
            hill_weight = self.terrain_weights.get('hills', 0.4)
            plain_weight = self.terrain_weights.get('plains', 0.2)
            valley_weight = self.terrain_weights.get('valleys', 0.1)
            
            for y in range(height):
                for x in range(width):
                    # 基础噪声值
                    noise_value = base_noise[y, x]
                    
                    # 地形特征值
                    feature_value = terrain_features[y, x]
                    
                    # 根据权重混合
                    blended_value = (
                        noise_value * 0.7 +  # 主要使用噪声
                        feature_value * 0.3   # 添加部分特征
                    )
                    
                    # 应用高度乘数
                    blended_value *= self.height_multiplier
                    
                    # 确保值在0-1范围内
                    blended_value = max(0.0, min(1.0, blended_value))
                    
                    blended_map[y, x] = blended_value
                    
            return blended_map
            
        except Exception as e:
            print(f"✗ 地形数据混合失败: {e}")
            return base_noise
            
    def _post_process_heightmap(self, heightmap: np.ndarray) -> np.ndarray:
        """
        后处理高度图
        
        Args:
            heightmap: 原始高度图
            
        Returns:
            处理后的高度图
        """
        try:
            processed_map = heightmap.copy()
            height, width = processed_map.shape
            
            # 应用平滑滤波器
            processed_map = self._apply_smoothing_filter(processed_map)
            
            # 调整边缘值，使边缘更加平滑
            processed_map = self._smooth_edges(processed_map)
            
            # 应用高程调整
            processed_map = self._adjust_elevation(processed_map)
            
            # 确保所有值在0-1范围内
            processed_map = np.clip(processed_map, 0.0, 1.0)
            
            return processed_map
            
        except Exception as e:
            print(f"✗ 高度图后处理失败: {e}")
            return heightmap
            
    def _apply_smoothing_filter(self, heightmap: np.ndarray) -> np.ndarray:
        """
        应用平滑滤波器
        
        Args:
            heightmap: 高度图数据
            
        Returns:
            平滑后的高度图
        """
        try:
            smoothed = heightmap.copy()
            height, width = smoothed.shape
            
            # 简单的3x3平均滤波器
            for y in range(1, height - 1):
                for x in range(1, width - 1):
                    # 计算3x3邻域的平均值
                    avg_value = (
                        heightmap[y-1, x-1] + heightmap[y-1, x] + heightmap[y-1, x+1] +
                        heightmap[y, x-1] + heightmap[y, x] + heightmap[y, x+1] +
                        heightmap[y+1, x-1] + heightmap[y+1, x] + heightmap[y+1, x+1]
                    ) / 9.0
                    
                    smoothed[y, x] = avg_value
                    
            return smoothed
            
        except Exception as e:
            print(f"✗ 平滑滤波器应用失败: {e}")
            return heightmap
            
    def _smooth_edges(self, heightmap: np.ndarray) -> np.ndarray:
        """
        平滑地形边缘
        
        Args:
            heightmap: 高度图数据
            
        Returns:
            边缘平滑后的高度图
        """
        try:
            smoothed = heightmap.copy()
            height, width = smoothed.shape
            
            # 平滑边缘几行/列
            edge_width = min(10, width // 20)  # 边缘宽度为地形尺寸的5%或10像素
            
            # 平滑顶部和底部边缘
            for i in range(edge_width):
                factor = i / edge_width
                # 顶部边缘
                smoothed[i, :] *= factor
                # 底部边缘
                smoothed[height - 1 - i, :] *= factor
                
            # 平滑左侧和右侧边缘
            for i in range(edge_width):
                factor = i / edge_width
                # 左侧边缘
                smoothed[:, i] *= factor
                # 右侧边缘
                smoothed[:, width - 1 - i] *= factor
                
            return smoothed
            
        except Exception as e:
            print(f"✗ 边缘平滑处理失败: {e}")
            return heightmap
            
    def _adjust_elevation(self, heightmap: np.ndarray) -> np.ndarray:
        """
        调整地形高程
        
        Args:
            heightmap: 高度图数据
            
        Returns:
            高程调整后的高度图
        """
        try:
            adjusted = heightmap.copy()
            
            # 应用高程曲线调整，使低地更平缓，高地更陡峭
            adjusted = np.power(adjusted, 1.5)
            
            # 添加一些随机变化
            noise = np.random.rand(*adjusted.shape).astype(np.float32) * 0.02
            adjusted = adjusted + noise
            adjusted = np.clip(adjusted, 0.0, 1.0)
            
            return adjusted
            
        except Exception as e:
            print(f"✗ 高程调整失败: {e}")
            return heightmap
            
    def set_seed(self, seed: int):
        """
        设置随机种子
        
        Args:
            seed: 随机种子
        """
        self.seed = seed
        print(f"✓ 高度图生成器随机种子设置为: {seed}")
        
    def set_scale(self, scale: float):
        """
        设置噪声缩放
        
        Args:
            scale: 噪声缩放因子
        """
        self.scale = max(0.1, scale)
        print(f"✓ 噪声缩放设置为: {self.scale}")
        
    def set_octaves(self, octaves: int):
        """
        设置噪声八度数
        
        Args:
            octaves: 八度数
        """
        self.octaves = max(1, min(10, octaves))
        print(f"✓ 噪声八度数设置为: {self.octaves}")
        
    def set_persistence(self, persistence: float):
        """
        设置噪声持久性
        
        Args:
            persistence: 持久性值
        """
        self.persistence = max(0.0, min(1.0, persistence))
        print(f"✓ 噪声持久性设置为: {self.persistence}")
        
    def set_lacunarity(self, lacunarity: float):
        """
        设置噪声间隙性
        
        Args:
            lacunarity: 间隙性值
        """
        self.lacunarity = max(1.0, lacunarity)
        print(f"✓ 噪声间隙性设置为: {self.lacunarity}")
        
    def set_height_multiplier(self, multiplier: float):
        """
        设置高度乘数
        
        Args:
            multiplier: 高度乘数
        """
        self.height_multiplier = max(0.0, multiplier)
        print(f"✓ 高度乘数设置为: {self.height_multiplier}")
        
    def set_water_level(self, level: float):
        """
        设置水位
        
        Args:
            level: 水位值 (0.0-1.0)
        """
        self.water_level = max(0.0, min(1.0, level))
        print(f"✓ 水位设置为: {self.water_level}")
        
    def set_terrain_weights(self, weights: Dict[str, float]):
        """
        设置地形类型权重
        
        Args:
            weights: 地形权重字典
        """
        self.terrain_weights.update(weights)
        print(f"✓ 地形权重已更新: {self.terrain_weights}")
        
    def get_stats(self) -> Dict[str, Any]:
        """
        获取统计信息
        
        Returns:
            统计信息字典
        """
        return self.stats.copy()
        
    def generate_island_heightmap(self, width: int, height: int, seed: int = None) -> np.ndarray:
        """
        生成岛屿型高度图
        
        Args:
            width: 高度图宽度
            height: 高度图高度
            seed: 随机种子
            
        Returns:
            岛屿型高度图数据
        """
        try:
            if seed is not None:
                self.seed = seed
                
            # 设置随机种子
            random.seed(self.seed)
            np.random.seed(self.seed)
            
            # 创建高度图数组
            heightmap = np.zeros((height, width), dtype=np.float32)
            
            # 计算中心点
            center_x, center_y = width / 2.0, height / 2.0
            max_distance = math.sqrt(center_x**2 + center_y**2)
            
            # 生成岛屿形状
            for y in range(height):
                for x in range(width):
                    # 计算到中心的距离
                    distance_x = x - center_x
                    distance_y = y - center_y
                    distance = math.sqrt(distance_x**2 + distance_y**2)
                    normalized_distance = distance / max_distance
                    
                    # 岛屿衰减函数 (边缘为0，中心为1)
                    island_factor = max(0.0, 1.0 - normalized_distance**2)
                    
                    # 生成基础噪声
                    if self.noise_generator:
                        noise_value = self.noise_generator.generate_noise(
                            x / self.scale,
                            y / self.scale,
                            self.seed
                        )
                        noise_value = (noise_value + 1) / 2  # 转换到0-1范围
                    else:
                        noise_value = random.random()
                        
                    # 应用岛屿因子
                    heightmap[y, x] = noise_value * island_factor
                    
            # 应用后处理
            heightmap = self._post_process_heightmap(heightmap)
            
            return heightmap
            
        except Exception as e:
            print(f"✗ 岛屿型高度图生成失败: {e}")
            import traceback
            traceback.print_exc()
            return np.zeros((height, width), dtype=np.float32)
            
    def generate_mountain_heightmap(self, width: int, height: int, seed: int = None) -> np.ndarray:
        """
        生成山脉型高度图
        
        Args:
            width: 高度图宽度
            height: 高度图高度
            seed: 随机种子
            
        Returns:
            山脉型高度图数据
        """
        try:
            if seed is not None:
                self.seed = seed
                
            # 设置随机种子
            random.seed(self.seed)
            np.random.seed(self.seed)
            
            # 创建高度图数组
            heightmap = np.zeros((height, width), dtype=np.float32)
            
            # 生成多个山峰
            num_peaks = random.randint(3, 8)
            peaks = []
            for _ in range(num_peaks):
                peak_x = random.randint(0, width - 1)
                peak_y = random.randint(0, height - 1)
                peak_height = random.uniform(0.5, 1.0)
                peak_radius = random.randint(width // 10, width // 4)
                peaks.append((peak_x, peak_y, peak_height, peak_radius))
                
            # 根据山峰生成地形
            for y in range(height):
                for x in range(width):
                    height_value = 0.0
                    for peak_x, peak_y, peak_height, peak_radius in peaks:
                        # 计算到山峰的距离
                        distance = math.sqrt((x - peak_x)**2 + (y - peak_y)**2)
                        if distance <= peak_radius:
                            # 使用高斯函数生成山峰形状
                            distance_factor = 1.0 - (distance / peak_radius)
                            height_value += peak_height * math.exp(-distance_factor**2 / 0.1)
                            
                    heightmap[y, x] = min(1.0, height_value)
                    
            # 添加细节噪声
            if self.noise_generator:
                for y in range(height):
                    for x in range(width):
                        noise_value = self.noise_generator.generate_noise(
                            x / (self.scale / 2),
                            y / (self.scale / 2),
                            self.seed + 1000
                        )
                        noise_value = (noise_value + 1) / 2  # 转换到0-1范围
                        heightmap[y, x] = heightmap[y, x] * 0.8 + noise_value * 0.2
                        
            # 应用后处理
            heightmap = self._post_process_heightmap(heightmap)
            
            return heightmap
            
        except Exception as e:
            print(f"✗ 山脉型高度图生成失败: {e}")
            import traceback
            traceback.print_exc()
            return np.zeros((height, width), dtype=np.float32)
            
    def generate_plateau_heightmap(self, width: int, height: int, seed: int = None) -> np.ndarray:
        """
        生成高原型高度图
        
        Args:
            width: 高度图宽度
            height: 高度图高度
            seed: 随机种子
            
        Returns:
            高原型高度图数据
        """
        try:
            if seed is not None:
                self.seed = seed
                
            # 设置随机种子
            random.seed(self.seed)
            np.random.seed(self.seed)
            
            # 创建高度图数组
            heightmap = np.zeros((height, width), dtype=np.float32)
            
            # 生成基础高原高度
            plateau_height = random.uniform(0.4, 0.7)
            
            # 填充基础高原
            heightmap.fill(plateau_height)
            
            # 添加边缘斜坡
            slope_width = min(30, width // 10)
            for i in range(slope_width):
                factor = i / slope_width
                # 上边缘
                heightmap[i, :] *= factor
                # 下边缘
                heightmap[height - 1 - i, :] *= factor
                # 左边缘
                heightmap[:, i] *= factor
                # 右边缘
                heightmap[:, width - 1 - i] *= factor
                
            # 添加一些起伏
            if self.noise_generator:
                for y in range(height):
                    for x in range(width):
                        noise_value = self.noise_generator.generate_noise(
                            x / self.scale,
                            y / self.scale,
                            self.seed + 2000
                        )
                        noise_value = (noise_value + 1) / 2  # 转换到0-1范围
                        # 减少噪声影响，保持高原特征
                        heightmap[y, x] = heightmap[y, x] * 0.9 + noise_value * 0.1
                        
            # 应用后处理
            heightmap = self._post_process_heightmap(heightmap)
            
            return heightmap
            
        except Exception as e:
            print(f"✗ 高原型高度图生成失败: {e}")
            import traceback
            traceback.print_exc()
            return np.zeros((height, width), dtype=np.float32)
            
    def generate_valley_heightmap(self, width: int, height: int, seed: int = None) -> np.ndarray:
        """
        生成峡谷型高度图
        
        Args:
            width: 高度图宽度
            height: 高度图高度
            seed: 随机种子
            
        Returns:
            峡谷型高度图数据
        """
        try:
            if seed is not None:
                self.seed = seed
                
            # 设置随机种子
            random.seed(self.seed)
            np.random.seed(self.seed)
            
            # 创建高度图数组
            heightmap = np.zeros((height, width), dtype=np.float32)
            
            # 选择峡谷方向 (0=水平, 1=垂直, 2=对角线)
            valley_direction = random.randint(0, 2)
            
            # 生成峡谷
            for y in range(height):
                for x in range(width):
                    if valley_direction == 0:  # 水平峡谷
                        valley_factor = 1.0 - abs(y - height/2) / (height/2)
                    elif valley_direction == 1:  # 垂直峡谷
                        valley_factor = 1.0 - abs(x - width/2) / (width/2)
                    else:  # 对角线峡谷
                        valley_factor = 1.0 - abs((x - width/2) - (y - height/2)) / max(width, height)
                        
                    # 确保峡谷因子在合理范围内
                    valley_factor = max(0.0, min(1.0, valley_factor))
                    
                    # 生成周围地形
                    if self.noise_generator:
                        noise_value = self.noise_generator.generate_noise(
                            x / self.scale,
                            y / self.scale,
                            self.seed + 3000
                        )
                        noise_value = (noise_value + 1) / 2  # 转换到0-1范围
                    else:
                        noise_value = random.random()
                        
                    # 应用峡谷因子 (峡谷区域较低)
                    heightmap[y, x] = noise_value * (0.5 + valley_factor * 0.5)
                    
            # 应用后处理
            heightmap = self._post_process_heightmap(heightmap)
            
            return heightmap
            
        except Exception as e:
            print(f"✗ 峡谷型高度图生成失败: {e}")
            import traceback
            traceback.print_exc()
            return np.zeros((height, width), dtype=np.float32)
            
    def generate_crater_heightmap(self, width: int, height: int, seed: int = None) -> np.ndarray:
        """
        生成陨石坑型高度图
        
        Args:
            width: 高度图宽度
            height: 高度图高度
            seed: 随机种子
            
        Returns:
            陨石坑型高度图数据
        """
        try:
            if seed is not None:
                self.seed = seed
                
            # 设置随机种子
            random.seed(self.seed)
            np.random.seed(self.seed)
            
            # 创建高度图数组
            heightmap = np.zeros((height, width), dtype=np.float32)
            
            # 生成多个陨石坑
            num_craters = random.randint(1, 5)
            craters = []
            for _ in range(num_craters):
                crater_x = random.randint(width // 4, 3 * width // 4)
                crater_y = random.randint(height // 4, 3 * height // 4)
                crater_radius = random.randint(width // 20, width // 5)
                crater_depth = random.uniform(0.2, 0.6)
                craters.append((crater_x, crater_y, crater_radius, crater_depth))
                
            # 初始化为平坦地形
            heightmap.fill(0.8)
            
            # 根据陨石坑生成地形
            for y in range(height):
                for x in range(width):
                    for crater_x, crater_y, crater_radius, crater_depth in craters:
                        # 计算到陨石坑中心的距离
                        distance = math.sqrt((x - crater_x)**2 + (y - crater_y)**2)
                        if distance <= crater_radius:
                            # 陨石坑形状 (边缘高，中心低)
                            if distance < crater_radius * 0.8:  # 坑内
                                # 抛物线形坑底
                                normalized_distance = distance / (crater_radius * 0.8)
                                depth_factor = 1.0 - normalized_distance**2
                                heightmap[y, x] = min(heightmap[y, x], 0.8 - crater_depth * depth_factor)
                            else:  # 坑边缘
                                # 边缘隆起
                                edge_factor = (distance - crater_radius * 0.8) / (crater_radius * 0.2)
                                heightmap[y, x] = max(heightmap[y, x], 0.8 + crater_depth * 0.3 * (1.0 - edge_factor))
                                
            # 添加细节噪声
            if self.noise_generator:
                for y in range(height):
                    for x in range(width):
                        noise_value = self.noise_generator.generate_noise(
                            x / (self.scale / 3),
                            y / (self.scale / 3),
                            self.seed + 4000
                        )
                        noise_value = (noise_value + 1) / 2  # 转换到0-1范围
                        heightmap[y, x] = heightmap[y, x] * 0.9 + noise_value * 0.1
                        
            # 应用后处理
            heightmap = self._post_process_heightmap(heightmap)
            
            return heightmap
            
        except Exception as e:
            print(f"✗ 陨石坑型高度图生成失败: {e}")
            import traceback
            traceback.print_exc()
            return np.zeros((height, width), dtype=np.float32)
            
    def generate_terrain_with_zones(self, width: int, height: int, zones: Dict[str, Any], seed: int = None) -> np.ndarray:
        """
        根据区域定义生成地形
        
        Args:
            width: 高度图宽度
            height: 高度图高度
            zones: 区域定义字典
            seed: 随机种子
            
        Returns:
            区域化高度图数据
        """
        try:
            if seed is not None:
                self.seed = seed
                
            # 设置随机种子
            random.seed(self.seed)
            np.random.seed(self.seed)
            
            # 创建高度图数组
            heightmap = np.zeros((height, width), dtype=np.float32)
            
            # 为每个区域生成地形
            for zone_name, zone_params in zones.items():
                zone_type = zone_params.get('type', 'default')
                zone_position = zone_params.get('position', (0, 0))
                zone_size = zone_params.get('size', (width, height))
                zone_height = zone_params.get('height', 0.5)
                
                # 根据区域类型生成地形
                if zone_type == 'mountain':
                    # 在指定区域生成山脉
                    self._generate_zone_mountains(heightmap, zone_position, zone_size, zone_height)
                elif zone_type == 'valley':
                    # 在指定区域生成峡谷
                    self._generate_zone_valley(heightmap, zone_position, zone_size, zone_height)
                elif zone_type == 'plateau':
                    # 在指定区域生成高原
                    self._generate_zone_plateau(heightmap, zone_position, zone_size, zone_height)
                elif zone_type == 'water':
                    # 在指定区域生成水域
                    self._generate_zone_water(heightmap, zone_position, zone_size, zone_height)
                    
            # 应用后处理
            heightmap = self._post_process_heightmap(heightmap)
            
            return heightmap
            
        except Exception as e:
            print(f"✗ 区域化地形生成失败: {e}")
            import traceback
            traceback.print_exc()
            return np.zeros((height, width), dtype=np.float32)
            
    def _generate_zone_mountains(self, heightmap: np.ndarray, position: tuple, size: tuple, base_height: float):
        """在指定区域生成山脉"""
        try:
            x_start, y_start = position
            width, height = size
            map_height, map_width = heightmap.shape
            
            # 确保区域在地图范围内
            x_start = max(0, min(x_start, map_width - 1))
            y_start = max(0, min(y_start, map_height - 1))
            x_end = min(map_width, x_start + width)
            y_end = min(map_height, y_start + height)
            
            # 生成山脉
            for y in range(y_start, y_end):
                for x in range(x_start, x_end):
                    # 计算相对于区域的位置
                    rel_x = (x - x_start) / width
                    rel_y = (y - y_start) / height
                    
                    # 生成山峰
                    peak_influence = math.sin(rel_x * math.pi) * math.sin(rel_y * math.pi)
                    heightmap[y, x] = max(heightmap[y, x], base_height + peak_influence * 0.3)
                    
        except Exception as e:
            print(f"✗ 区域山脉生成失败: {e}")
            
    def _generate_zone_valley(self, heightmap: np.ndarray, position: tuple, size: tuple, base_height: float):
        """在指定区域生成峡谷"""
        try:
            x_start, y_start = position
            width, height = size
            map_height, map_width = heightmap.shape
            
            # 确保区域在地图范围内
            x_start = max(0, min(x_start, map_width - 1))
            y_start = max(0, min(y_start, map_height - 1))
            x_end = min(map_width, x_start + width)
            y_end = min(map_height, y_start + height)
            
            # 生成峡谷
            for y in range(y_start, y_end):
                for x in range(x_start, x_end):
                    # 计算相对于区域的位置
                    rel_x = (x - x_start) / width
                    rel_y = (y - y_start) / height
                    
                    # 生成峡谷形状 (中心低，边缘高)
                    valley_factor = 1.0 - math.sqrt((rel_x - 0.5)**2 + (rel_y - 0.5)**2) * 2
                    valley_factor = max(0.0, valley_factor)
                    heightmap[y, x] = min(heightmap[y, x], base_height - valley_factor * 0.4)
                    
        except Exception as e:
            print(f"✗ 区域峡谷生成失败: {e}")
            
    def _generate_zone_plateau(self, heightmap: np.ndarray, position: tuple, size: tuple, base_height: float):
        """在指定区域生成高原"""
        try:
            x_start, y_start = position
            width, height = size
            map_height, map_width = heightmap.shape
            
            # 确保区域在地图范围内
            x_start = max(0, min(x_start, map_width - 1))
            y_start = max(0, min(y_start, map_height - 1))
            x_end = min(map_width, x_start + width)
            y_end = min(map_height, y_start + height)
            
            # 生成高原
            for y in range(y_start, y_end):
                for x in range(x_start, x_end):
                    heightmap[y, x] = max(heightmap[y, x], base_height)
                    
        except Exception as e:
            print(f"✗ 区域高原生成失败: {e}")
            
    def _generate_zone_water(self, heightmap: np.ndarray, position: tuple, size: tuple, water_level: float):
        """在指定区域生成水域"""
        try:
            x_start, y_start = position
            width, height = size
            map_height, map_width = heightmap.shape
            
            # 确保区域在地图范围内
            x_start = max(0, min(x_start, map_width - 1))
            y_start = max(0, min(y_start, map_height - 1))
            x_end = min(map_width, x_start + width)
            y_end = min(map_height, y_start + height)
            
            # 生成平坦水域
            for y in range(y_start, y_end):
                for x in range(x_start, x_end):
                    heightmap[y, x] = min(heightmap[y, x], water_level)
                    
        except Exception as e:
            print(f"✗ 区域水域生成失败: {e}")
            
    def blend_heightmaps(self, heightmaps: List[np.ndarray], weights: List[float] = None) -> np.ndarray:
        """
        混合多个高度图
        
        Args:
            heightmaps: 高度图列表
            weights: 权重列表 (如果为None，则平均分配权重)
            
        Returns:
            混合后的高度图
        """
        try:
            if not heightmaps:
                return np.array([])
                
            if len(heightmaps) == 1:
                return heightmaps[0].copy()
                
            # 确保所有高度图尺寸相同
            base_shape = heightmaps[0].shape
            for hm in heightmaps:
                if hm.shape != base_shape:
                    raise ValueError("所有高度图必须具有相同的尺寸")
                    
            # 处理权重
            if weights is None:
                weights = [1.0 / len(heightmaps)] * len(heightmaps)
            elif len(weights) != len(heightmaps):
                raise ValueError("权重数量必须与高度图数量相同")
                
            # 归一化权重
            total_weight = sum(weights)
            if total_weight > 0:
                weights = [w / total_weight for w in weights]
                
            # 混合高度图
            blended = np.zeros(base_shape, dtype=np.float32)
            for i, (hm, weight) in enumerate(zip(heightmaps, weights)):
                blended += hm * weight
                
            # 确保值在0-1范围内
            blended = np.clip(blended, 0.0, 1.0)
            
            return blended
            
        except Exception as e:
            print(f"✗ 高度图混合失败: {e}")
            import traceback
            traceback.print_exc()
            # 返回第一个高度图的副本
            return heightmaps[0].copy() if heightmaps else np.array([])