750 lines
26 KiB
Python
750 lines
26 KiB
Python
"""
|
||
动物模拟器
|
||
负责模拟动物种群行为和与植被的相互作用
|
||
"""
|
||
|
||
import time
|
||
from typing import Dict, Any, List, Optional
|
||
import math
|
||
import random
|
||
|
||
class AnimalSimulator:
|
||
"""
|
||
动物模拟器
|
||
负责模拟动物种群行为、繁殖、死亡和与植被的相互作用
|
||
"""
|
||
|
||
def __init__(self, plugin):
|
||
"""
|
||
初始化动物模拟器
|
||
|
||
Args:
|
||
plugin: 植被和生态系统插件实例
|
||
"""
|
||
self.plugin = plugin
|
||
self.enabled = False
|
||
self.initialized = False
|
||
|
||
# 动物种类定义
|
||
self.animal_species = {
|
||
'rabbit': {
|
||
'name': '兔子',
|
||
'description': '草食性小型哺乳动物,优秀的种子传播者',
|
||
'diet': 'herbivore',
|
||
'size': 'small',
|
||
'reproduction_rate': 0.3, # 每天繁殖率
|
||
'mortality_rate': 0.02, # 每天死亡率
|
||
'mobility': 0.8, # 移动能力
|
||
'preferred_food': ['grass', 'flower'],
|
||
'territory_size': 10.0,
|
||
'lifespan': 365, # 天
|
||
'max_population': 50,
|
||
'pollinator': False,
|
||
'seed_disperser': True
|
||
},
|
||
'deer': {
|
||
'name': '鹿',
|
||
'description': '草食性中型哺乳动物,重要的种子传播者',
|
||
'diet': 'herbivore',
|
||
'size': 'medium',
|
||
'reproduction_rate': 0.05,
|
||
'mortality_rate': 0.01,
|
||
'mobility': 0.9,
|
||
'preferred_food': ['bush', 'tree', 'grass'],
|
||
'territory_size': 50.0,
|
||
'lifespan': 2190, # 6年
|
||
'max_population': 20,
|
||
'pollinator': False,
|
||
'seed_disperser': True
|
||
},
|
||
'wolf': {
|
||
'name': '狼',
|
||
'description': '肉食性大型哺乳动物,顶级捕食者',
|
||
'diet': 'carnivore',
|
||
'size': 'large',
|
||
'reproduction_rate': 0.02,
|
||
'mortality_rate': 0.005,
|
||
'mobility': 0.95,
|
||
'preferred_food': ['rabbit', 'deer'],
|
||
'territory_size': 100.0,
|
||
'lifespan': 2555, # 7年
|
||
'max_population': 10,
|
||
'pollinator': False,
|
||
'seed_disperser': False
|
||
},
|
||
'fox': {
|
||
'name': '狐狸',
|
||
'description': '杂食性小型哺乳动物',
|
||
'diet': 'omnivore',
|
||
'size': 'small',
|
||
'reproduction_rate': 0.1,
|
||
'mortality_rate': 0.015,
|
||
'mobility': 0.85,
|
||
'preferred_food': ['rabbit', 'flower', 'berry'],
|
||
'territory_size': 30.0,
|
||
'lifespan': 1460, # 4年
|
||
'max_population': 15,
|
||
'pollinator': False,
|
||
'seed_disperser': True
|
||
},
|
||
'bird': {
|
||
'name': '鸟类',
|
||
'description': '飞行动物,重要的授粉者和种子传播者',
|
||
'diet': 'omnivore',
|
||
'size': 'small',
|
||
'reproduction_rate': 0.2,
|
||
'mortality_rate': 0.03,
|
||
'mobility': 1.0,
|
||
'preferred_food': ['flower', 'berry', 'insect'],
|
||
'territory_size': 200.0,
|
||
'lifespan': 1095, # 3年
|
||
'max_population': 30,
|
||
'pollinator': True,
|
||
'seed_disperser': True
|
||
},
|
||
'insect': {
|
||
'name': '昆虫',
|
||
'description': '小型无脊椎动物,主要授粉者',
|
||
'diet': 'omnivore',
|
||
'size': 'tiny',
|
||
'reproduction_rate': 0.5,
|
||
'mortality_rate': 0.1,
|
||
'mobility': 0.7,
|
||
'preferred_food': ['flower', 'fruit', 'decaying_matter'],
|
||
'territory_size': 1.0,
|
||
'lifespan': 30, # 1个月
|
||
'max_population': 500,
|
||
'pollinator': True,
|
||
'seed_disperser': False
|
||
}
|
||
}
|
||
|
||
# 动物种群
|
||
self.animal_populations = {}
|
||
self.population_counter = 0
|
||
|
||
# 动物行为配置
|
||
self.behavior_config = {
|
||
'feeding_efficiency': 0.8, # 进食效率
|
||
'energy_consumption': 0.1, # 能量消耗率
|
||
'migration_probability': 0.05, # 迁移概率
|
||
'social_behavior': 0.7, # 社会行为倾向
|
||
'fear_factor': 0.6, # 恐惧因子
|
||
'territory_awareness': 0.8 # 领域意识
|
||
}
|
||
|
||
# 环境影响因子
|
||
self.environment_factors = {
|
||
'temperature': 20.0,
|
||
'humidity': 60.0,
|
||
'vegetation_density': 0.5,
|
||
'water_availability': 0.7,
|
||
'predator_presence': 0.2
|
||
}
|
||
|
||
# 动物实例
|
||
self.animal_instances = {}
|
||
self.instance_counter = 0
|
||
|
||
# 动物状态跟踪
|
||
self.animal_states = {
|
||
'feeding': [], # 正在进食的动物
|
||
'moving': [], # 正在移动的动物
|
||
'resting': [], # 正在休息的动物
|
||
'mating': [] # 正在交配的动物
|
||
}
|
||
|
||
# 统计信息
|
||
self.stats = {
|
||
'total_animals': 0,
|
||
'animals_by_species': {},
|
||
'births': 0,
|
||
'deaths': 0,
|
||
'feedings': 0,
|
||
'movements': 0
|
||
}
|
||
|
||
print("✓ 动物模拟器已创建")
|
||
|
||
def initialize(self) -> bool:
|
||
"""
|
||
初始化动物模拟器
|
||
|
||
Returns:
|
||
是否初始化成功
|
||
"""
|
||
try:
|
||
# 初始化统计数据
|
||
self.stats['animals_by_species'] = {species: 0 for species in self.animal_species.keys()}
|
||
|
||
# 初始化一些动物种群
|
||
self._initialize_populations()
|
||
|
||
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.animal_populations.clear()
|
||
self.animal_instances.clear()
|
||
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._update_populations(dt)
|
||
|
||
# 更新动物实例
|
||
self._update_animal_instances(dt)
|
||
|
||
# 更新动物行为
|
||
self._update_animal_behaviors(dt)
|
||
|
||
except Exception as e:
|
||
print(f"✗ 动物模拟器更新失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
|
||
def _initialize_populations(self):
|
||
"""初始化动物种群"""
|
||
try:
|
||
# 为每种动物创建初始种群
|
||
for species_name in self.animal_species.keys():
|
||
population_id = self.population_counter
|
||
self.population_counter += 1
|
||
|
||
initial_size = max(2, int(self.animal_species[species_name]['max_population'] * 0.1))
|
||
|
||
population_data = {
|
||
'id': population_id,
|
||
'species': species_name,
|
||
'size': initial_size,
|
||
'health': 0.8,
|
||
'territory_center': (random.uniform(-50, 50), random.uniform(-50, 50)),
|
||
'last_update': time.time(),
|
||
'creation_time': time.time()
|
||
}
|
||
|
||
self.animal_populations[population_id] = population_data
|
||
|
||
# 更新统计数据
|
||
self.stats['animals_by_species'][species_name] += initial_size
|
||
self.stats['total_animals'] += initial_size
|
||
|
||
print(f"✓ {self.animal_species[species_name]['name']} 种群已初始化,大小: {initial_size}")
|
||
|
||
except Exception as e:
|
||
print(f"✗ 动物种群初始化失败: {e}")
|
||
|
||
def _update_populations(self, dt: float):
|
||
"""
|
||
更新动物种群
|
||
|
||
Args:
|
||
dt: 时间增量
|
||
"""
|
||
try:
|
||
populations_to_remove = []
|
||
|
||
for population_id, population in self.animal_populations.items():
|
||
species_name = population['species']
|
||
species_info = self.animal_species[species_name]
|
||
|
||
# 计算繁殖和死亡
|
||
current_size = population['size']
|
||
|
||
# 繁殖
|
||
reproduction_rate = species_info['reproduction_rate']
|
||
births = int(current_size * reproduction_rate * dt / 86400) # 转换为天
|
||
|
||
# 死亡
|
||
mortality_rate = species_info['mortality_rate']
|
||
deaths = int(current_size * mortality_rate * dt / 86400)
|
||
|
||
# 环境压力影响
|
||
environment_pressure = 1.0 - self._calculate_environment_suitability(species_name)
|
||
deaths += int(current_size * environment_pressure * 0.1)
|
||
|
||
# 更新种群大小
|
||
new_size = max(0, current_size + births - deaths)
|
||
population['size'] = min(new_size, species_info['max_population'])
|
||
|
||
# 更新统计数据
|
||
size_change = population['size'] - current_size
|
||
self.stats['total_animals'] += size_change
|
||
self.stats['animals_by_species'][species_name] += size_change
|
||
self.stats['births'] += births
|
||
self.stats['deaths'] += deaths
|
||
|
||
# 如果种群灭绝,标记移除
|
||
if population['size'] <= 0:
|
||
populations_to_remove.append(population_id)
|
||
|
||
# 移除灭绝的种群
|
||
for population_id in populations_to_remove:
|
||
population = self.animal_populations.pop(population_id)
|
||
species_name = population['species']
|
||
print(f"✓ {self.animal_species[species_name]['name']} 种群已灭绝")
|
||
self.stats['animals_by_species'][species_name] = 0
|
||
|
||
except Exception as e:
|
||
print(f"✗ 动物种群更新失败: {e}")
|
||
|
||
def _update_animal_instances(self, dt: float):
|
||
"""更新动物实例"""
|
||
try:
|
||
# 更新动物实例状态
|
||
for instance_id, instance in self.animal_instances.items():
|
||
if not instance['alive']:
|
||
continue
|
||
|
||
# 更新饥饿度
|
||
instance['hunger'] = min(1.0, instance['hunger'] + 0.001 * dt / 3600)
|
||
|
||
# 更新能量
|
||
instance['energy'] = max(0.0, instance['energy'] - 0.0005 * dt / 3600)
|
||
|
||
# 如果饥饿度太高或能量太低,健康度下降
|
||
if instance['hunger'] > 0.8 or instance['energy'] < 0.2:
|
||
self.update_animal_health(instance_id, -0.0001 * dt / 3600)
|
||
|
||
except Exception as e:
|
||
print(f"✗ 动物实例更新失败: {e}")
|
||
|
||
def _update_animal_behaviors(self, dt: float):
|
||
"""更新动物行为"""
|
||
try:
|
||
# 在实际实现中,这里会更新动物的行为状态
|
||
# 如决定是否进食、移动、休息或交配
|
||
pass
|
||
except Exception as e:
|
||
print(f"✗ 动物行为更新失败: {e}")
|
||
|
||
def _calculate_environment_suitability(self, species_name: str) -> float:
|
||
"""
|
||
计算环境适宜性
|
||
|
||
Args:
|
||
species_name: 动物种类名称
|
||
|
||
Returns:
|
||
适宜性评分 (0.0-1.0)
|
||
"""
|
||
try:
|
||
species_info = self.animal_species[species_name]
|
||
|
||
# 基于植被密度的适宜性
|
||
vegetation_suitability = self.environment_factors['vegetation_density']
|
||
|
||
# 基于水可用性的适宜性
|
||
water_suitability = self.environment_factors['water_availability']
|
||
|
||
# 基于温度的适宜性
|
||
temperature = self.environment_factors['temperature']
|
||
if species_name in ['rabbit', 'deer']:
|
||
# 草食动物适宜温度范围
|
||
temp_suitability = max(0.0, 1.0 - abs(temperature - 20.0) / 20.0)
|
||
elif species_name in ['wolf', 'fox']:
|
||
# 肉食动物适宜温度范围
|
||
temp_suitability = max(0.0, 1.0 - abs(temperature - 15.0) / 25.0)
|
||
else:
|
||
temp_suitability = 1.0
|
||
|
||
# 综合评分
|
||
overall_suitability = (
|
||
vegetation_suitability * 0.4 +
|
||
water_suitability * 0.3 +
|
||
temp_suitability * 0.3
|
||
)
|
||
|
||
return max(0.0, min(1.0, overall_suitability))
|
||
|
||
except Exception as e:
|
||
print(f"✗ 环境适宜性计算失败: {e}")
|
||
return 0.5
|
||
|
||
def get_animal_species(self) -> List[str]:
|
||
"""
|
||
获取所有动物种类
|
||
|
||
Returns:
|
||
动物种类列表
|
||
"""
|
||
return list(self.animal_species.keys())
|
||
|
||
def get_animal_info(self, species_name: str) -> Optional[Dict[str, Any]]:
|
||
"""
|
||
获取动物种类信息
|
||
|
||
Args:
|
||
species_name: 动物种类名称
|
||
|
||
Returns:
|
||
动物信息字典或None
|
||
"""
|
||
return self.animal_species.get(species_name)
|
||
|
||
def create_animal_instance(self, species_name: str, position: tuple,
|
||
initial_age: float = 0.0, initial_health: float = 1.0) -> int:
|
||
"""
|
||
创建动物实例
|
||
|
||
Args:
|
||
species_name: 动物种类名称
|
||
position: 位置坐标 (x, y, z)
|
||
initial_age: 初始年龄
|
||
initial_health: 初始健康度 (0.0-1.0)
|
||
|
||
Returns:
|
||
动物实例ID
|
||
"""
|
||
try:
|
||
if species_name not in self.animal_species:
|
||
print(f"✗ 无效的动物种类: {species_name}")
|
||
return -1
|
||
|
||
instance_id = self.instance_counter
|
||
self.instance_counter += 1
|
||
|
||
# 获取动物种类信息
|
||
animal_info = self.animal_species[species_name]
|
||
|
||
# 创建实例数据
|
||
instance_data = {
|
||
'id': instance_id,
|
||
'species': species_name,
|
||
'position': position,
|
||
'age': initial_age,
|
||
'health': initial_health,
|
||
'alive': True,
|
||
'hunger': 0.0,
|
||
'energy': 1.0,
|
||
'state': 'resting', # 初始状态为休息
|
||
'destination': None, # 移动目标
|
||
'creation_time': time.time(),
|
||
'last_update': time.time()
|
||
}
|
||
|
||
# 存储实例
|
||
self.animal_instances[instance_id] = instance_data
|
||
|
||
# 添加到状态跟踪
|
||
self.animal_states['resting'].append(instance_id)
|
||
|
||
print(f"✓ 动物实例已创建: {animal_info['name']} (ID: {instance_id})")
|
||
return instance_id
|
||
|
||
except Exception as e:
|
||
print(f"✗ 动物实例创建失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return -1
|
||
|
||
def remove_animal_instance(self, instance_id: int) -> bool:
|
||
"""
|
||
移除动物实例
|
||
|
||
Args:
|
||
instance_id: 动物实例ID
|
||
|
||
Returns:
|
||
是否移除成功
|
||
"""
|
||
try:
|
||
if instance_id not in self.animal_instances:
|
||
print(f"✗ 动物实例不存在: {instance_id}")
|
||
return False
|
||
|
||
# 从状态跟踪中移除
|
||
for state_list in self.animal_states.values():
|
||
if instance_id in state_list:
|
||
state_list.remove(instance_id)
|
||
|
||
# 移除实例
|
||
del self.animal_instances[instance_id]
|
||
|
||
print(f"✓ 动物实例已移除: ID {instance_id}")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 动物实例移除失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
|
||
def get_animal_instance(self, instance_id: int) -> Optional[Dict[str, Any]]:
|
||
"""
|
||
获取动物实例信息
|
||
|
||
Args:
|
||
instance_id: 动物实例ID
|
||
|
||
Returns:
|
||
动物实例信息或None
|
||
"""
|
||
return self.animal_instances.get(instance_id)
|
||
|
||
def get_all_animal_instances(self) -> Dict[int, Dict[str, Any]]:
|
||
"""
|
||
获取所有动物实例
|
||
|
||
Returns:
|
||
所有动物实例字典
|
||
"""
|
||
return self.animal_instances.copy()
|
||
|
||
def update_environment_factors(self, factors: Dict[str, float]):
|
||
"""
|
||
更新环境因子
|
||
|
||
Args:
|
||
factors: 环境因子字典
|
||
"""
|
||
self.environment_factors.update(factors)
|
||
print(f"✓ 环境因子已更新: {factors}")
|
||
|
||
def get_environment_factors(self) -> Dict[str, float]:
|
||
"""
|
||
获取环境因子
|
||
|
||
Returns:
|
||
环境因子字典
|
||
"""
|
||
return self.environment_factors.copy()
|
||
|
||
def get_population_data(self) -> Dict[int, Dict[str, Any]]:
|
||
"""
|
||
获取种群数据
|
||
|
||
Returns:
|
||
种群数据字典
|
||
"""
|
||
return self.animal_populations.copy()
|
||
|
||
def set_behavior_config(self, config: Dict[str, float]):
|
||
"""
|
||
设置行为配置
|
||
|
||
Args:
|
||
config: 行为配置字典
|
||
"""
|
||
self.behavior_config.update(config)
|
||
print(f"✓ 行为配置已更新: {self.behavior_config}")
|
||
|
||
def get_behavior_config(self) -> Dict[str, float]:
|
||
"""
|
||
获取行为配置
|
||
|
||
Returns:
|
||
行为配置字典
|
||
"""
|
||
return self.behavior_config.copy()
|
||
|
||
def simulate_feeding(self, animal_species: str, food_type: str, amount: float) -> float:
|
||
"""
|
||
模拟进食过程
|
||
|
||
Args:
|
||
animal_species: 动物种类
|
||
food_type: 食物类型
|
||
amount: 食物量
|
||
|
||
Returns:
|
||
实际消耗的食物量
|
||
"""
|
||
try:
|
||
if animal_species not in self.animal_species:
|
||
return 0.0
|
||
|
||
# 获取进食效率
|
||
efficiency = self.behavior_config['feeding_efficiency']
|
||
actual_consumption = amount * efficiency
|
||
|
||
# 更新统计信息
|
||
self.stats['feedings'] += 1
|
||
|
||
print(f"✓ {animal_species} 进食了 {actual_consumption:.2f} 单位的 {food_type}")
|
||
return actual_consumption
|
||
|
||
except Exception as e:
|
||
print(f"✗ 进食模拟失败: {e}")
|
||
return 0.0
|
||
|
||
def update_animal_health(self, instance_id: int, health_change: float):
|
||
"""
|
||
更新动物健康度
|
||
|
||
Args:
|
||
instance_id: 动物实例ID
|
||
health_change: 健康度变化值
|
||
"""
|
||
try:
|
||
if instance_id not in self.animal_instances:
|
||
return
|
||
|
||
instance = self.animal_instances[instance_id]
|
||
new_health = max(0.0, min(1.0, instance['health'] + health_change))
|
||
instance['health'] = new_health
|
||
|
||
# 如果健康度为0,动物死亡
|
||
if new_health <= 0.0:
|
||
instance['alive'] = False
|
||
print(f"✓ 动物实例死亡: ID {instance_id}")
|
||
|
||
except Exception as e:
|
||
print(f"✗ 动物健康度更新失败: {e}")
|
||
|
||
def get_animal_states(self) -> Dict[str, List[int]]:
|
||
"""
|
||
获取动物状态分布
|
||
|
||
Returns:
|
||
动物状态字典
|
||
"""
|
||
# 返回状态副本,避免外部修改
|
||
return {state: ids.copy() for state, ids in self.animal_states.items()}
|
||
|
||
def update_animal_state(self, instance_id: int, new_state: str) -> bool:
|
||
"""
|
||
更新动物状态
|
||
|
||
Args:
|
||
instance_id: 动物实例ID
|
||
new_state: 新状态
|
||
|
||
Returns:
|
||
是否更新成功
|
||
"""
|
||
try:
|
||
if instance_id not in self.animal_instances:
|
||
print(f"✗ 动物实例不存在: {instance_id}")
|
||
return False
|
||
|
||
if new_state not in self.animal_states:
|
||
print(f"✗ 无效的动物状态: {new_state}")
|
||
return False
|
||
|
||
# 从旧状态列表中移除
|
||
for state_list in self.animal_states.values():
|
||
if instance_id in state_list:
|
||
state_list.remove(instance_id)
|
||
|
||
# 添加到新状态列表
|
||
self.animal_states[new_state].append(instance_id)
|
||
|
||
# 更新实例状态
|
||
self.animal_instances[instance_id]['state'] = new_state
|
||
|
||
# 更新移动统计
|
||
if new_state == 'moving':
|
||
self.stats['movements'] += 1
|
||
|
||
print(f"✓ 动物状态已更新: ID {instance_id} -> {new_state}")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 动物状态更新失败: {e}")
|
||
return False
|
||
|
||
def get_stats(self) -> Dict[str, Any]:
|
||
"""
|
||
获取统计信息
|
||
|
||
Returns:
|
||
统计信息字典
|
||
"""
|
||
return self.stats.copy()
|
||
|
||
def reset_stats(self):
|
||
"""重置统计信息"""
|
||
self.stats = {
|
||
'total_animals': 0,
|
||
'animals_by_species': {species: 0 for species in self.animal_species.keys()},
|
||
'births': 0,
|
||
'deaths': 0,
|
||
'feedings': 0,
|
||
'movements': 0
|
||
}
|
||
print("✓ 动物模拟器统计信息已重置")
|
||
|
||
def get_species_ecological_role(self, species_name: str) -> Dict[str, bool]:
|
||
"""
|
||
获取物种的生态角色
|
||
|
||
Args:
|
||
species_name: 物种名称
|
||
|
||
Returns:
|
||
生态角色字典
|
||
"""
|
||
try:
|
||
if species_name not in self.animal_species:
|
||
return {}
|
||
|
||
species_info = self.animal_species[species_name]
|
||
return {
|
||
'pollinator': species_info.get('pollinator', False),
|
||
'seed_disperser': species_info.get('seed_disperser', False),
|
||
'predator': species_info['diet'] == 'carnivore',
|
||
'herbivore': species_info['diet'] in ['herbivore', 'omnivore']
|
||
}
|
||
except Exception as e:
|
||
print(f"✗ 生态角色获取失败: {e}")
|
||
return {} |