|
|
@@ -56,6 +56,7 @@ class WeaponConfigManager:
|
|
|
'射速': float,
|
|
|
'射程': int,
|
|
|
'子弹速度': int,
|
|
|
+ '稀有度伤害倍率': str, # 逗号分隔的数组字符串
|
|
|
# 方块价格配置字段
|
|
|
'基础每格成本': int,
|
|
|
'I形状成本': int,
|
|
|
@@ -72,6 +73,7 @@ class WeaponConfigManager:
|
|
|
'fireRate': float,
|
|
|
'range': int,
|
|
|
'bulletSpeed': int,
|
|
|
+ 'rarityDamageMultipliers': str, # 逗号分隔的数组字符串
|
|
|
'baseCost': int,
|
|
|
'I_shape_cost': int,
|
|
|
'HI_shape_cost': int,
|
|
|
@@ -163,6 +165,9 @@ class WeaponConfigManager:
|
|
|
if block_shape_sheet is not None:
|
|
|
weapons_config['blockSizes'] = self._parse_block_shape_data(block_shape_sheet)
|
|
|
|
|
|
+ # 注意:稀有度权重配置和稀有度伤害倍率配置现在已经移到武器基础配置表中
|
|
|
+ # 不再需要单独的工作表解析
|
|
|
+
|
|
|
return weapons_config
|
|
|
|
|
|
except Exception as e:
|
|
|
@@ -201,9 +206,27 @@ class WeaponConfigManager:
|
|
|
elif param_type == float:
|
|
|
item[col_name] = float(value)
|
|
|
else:
|
|
|
- item[col_name] = str(value).strip()
|
|
|
+ # 特殊处理稀有度伤害倍率字段
|
|
|
+ if col_name in ['稀有度伤害倍率', 'rarityDamageMultipliers']:
|
|
|
+ # 将逗号分隔的字符串转换为浮点数数组
|
|
|
+ multipliers_str = str(value).strip()
|
|
|
+ if multipliers_str:
|
|
|
+ try:
|
|
|
+ multipliers = [float(x.strip()) for x in multipliers_str.split(',') if x.strip()]
|
|
|
+ item[col_name] = multipliers
|
|
|
+ except ValueError:
|
|
|
+ # 如果解析失败,使用默认值
|
|
|
+ item[col_name] = [1.0, 1.5, 2.25, 8.0]
|
|
|
+ else:
|
|
|
+ item[col_name] = [1.0, 1.5, 2.25, 8.0]
|
|
|
+ else:
|
|
|
+ item[col_name] = str(value).strip()
|
|
|
except (ValueError, TypeError):
|
|
|
- item[col_name] = str(value).strip()
|
|
|
+ # 特殊处理稀有度伤害倍率字段的异常情况
|
|
|
+ if col_name in ['稀有度伤害倍率', 'rarityDamageMultipliers']:
|
|
|
+ item[col_name] = [1.0, 1.5, 2.25, 8.0]
|
|
|
+ else:
|
|
|
+ item[col_name] = str(value).strip()
|
|
|
|
|
|
# 检查是否有有效的武器ID
|
|
|
weapon_id = item.get('ID') or item.get('id') or item.get('武器ID')
|
|
|
@@ -547,6 +570,203 @@ class WeaponConfigManager:
|
|
|
print(f"解析形状矩阵失败: {e}, 使用默认矩阵")
|
|
|
return [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
|
|
|
|
|
|
+ def _parse_rarity_weights_data(self, rarity_weights_sheet):
|
|
|
+ """解析稀有度权重配置数据"""
|
|
|
+ try:
|
|
|
+ print(f"开始处理稀有度权重配置,工作表行数: {len(rarity_weights_sheet)}")
|
|
|
+ rarity_weights = {}
|
|
|
+
|
|
|
+ # 检查第一行是否为表头
|
|
|
+ first_row = rarity_weights_sheet.iloc[0] if len(rarity_weights_sheet) > 0 else None
|
|
|
+ is_header = False
|
|
|
+ if first_row is not None:
|
|
|
+ first_cell = str(first_row.iloc[0]).strip() if len(first_row) > 0 else ""
|
|
|
+ if first_cell in ['稀有度', 'Rarity', 'rarity', '等级']:
|
|
|
+ is_header = True
|
|
|
+ print(f"检测到表头行,第一列内容: {first_cell}")
|
|
|
+
|
|
|
+ for index, row in rarity_weights_sheet.iterrows():
|
|
|
+ if is_header and index == 0: # 跳过表头
|
|
|
+ continue
|
|
|
+
|
|
|
+ # 获取稀有度名称
|
|
|
+ rarity_name = None
|
|
|
+ for field in ['稀有度', 'Rarity', 'rarity', '等级']:
|
|
|
+ if field in row and pd.notna(row[field]):
|
|
|
+ rarity_name = str(row[field]).strip().lower()
|
|
|
+ break
|
|
|
+
|
|
|
+ if rarity_name is None and len(row) > 0:
|
|
|
+ rarity_name = str(row.iloc[0]).strip().lower() if pd.notna(row.iloc[0]) else None
|
|
|
+
|
|
|
+ # 获取权重值
|
|
|
+ weight = None
|
|
|
+ for field in ['权重', 'Weight', 'weight', '值']:
|
|
|
+ if field in row and pd.notna(row[field]):
|
|
|
+ try:
|
|
|
+ weight = int(float(row[field]))
|
|
|
+ break
|
|
|
+ except (ValueError, TypeError):
|
|
|
+ pass
|
|
|
+
|
|
|
+ if weight is None and len(row) > 1:
|
|
|
+ try:
|
|
|
+ weight = int(float(row.iloc[1])) if pd.notna(row.iloc[1]) else None
|
|
|
+ except (ValueError, TypeError):
|
|
|
+ pass
|
|
|
+
|
|
|
+ # 映射中文稀有度名称到英文
|
|
|
+ rarity_mapping = {
|
|
|
+ '普通': 'common',
|
|
|
+ '稀有': 'uncommon',
|
|
|
+ '史诗': 'rare',
|
|
|
+ '传说': 'epic',
|
|
|
+ 'common': 'common',
|
|
|
+ 'uncommon': 'uncommon',
|
|
|
+ 'rare': 'rare',
|
|
|
+ 'epic': 'epic'
|
|
|
+ }
|
|
|
+
|
|
|
+ if rarity_name and weight is not None:
|
|
|
+ mapped_rarity = rarity_mapping.get(rarity_name, rarity_name)
|
|
|
+ rarity_weights[mapped_rarity] = weight
|
|
|
+ print(f"✓ 添加稀有度权重配置: {mapped_rarity} = {weight}")
|
|
|
+
|
|
|
+ return rarity_weights
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ print(f"解析稀有度权重配置失败: {e}")
|
|
|
+ return {}
|
|
|
+
|
|
|
+ def _parse_rarity_damage_multipliers_data(self, rarity_damage_multipliers_sheet):
|
|
|
+ """解析稀有度伤害倍率配置数据"""
|
|
|
+ try:
|
|
|
+ print(f"开始处理稀有度伤害倍率配置,工作表行数: {len(rarity_damage_multipliers_sheet)}")
|
|
|
+ damage_multipliers = []
|
|
|
+
|
|
|
+ # 检查第一行是否为表头
|
|
|
+ first_row = rarity_damage_multipliers_sheet.iloc[0] if len(rarity_damage_multipliers_sheet) > 0 else None
|
|
|
+ is_header = False
|
|
|
+ if first_row is not None:
|
|
|
+ first_cell = str(first_row.iloc[0]).strip() if len(first_row) > 0 else ""
|
|
|
+ if first_cell in ['配置项', 'Config Item', 'config_item', '等级', 'Level', 'level', '稀有度等级']:
|
|
|
+ is_header = True
|
|
|
+ print(f"检测到表头行,第一列内容: {first_cell}")
|
|
|
+
|
|
|
+ for index, row in rarity_damage_multipliers_sheet.iterrows():
|
|
|
+ if is_header and index == 0: # 跳过表头
|
|
|
+ continue
|
|
|
+
|
|
|
+ # 获取配置项名称
|
|
|
+ config_item = None
|
|
|
+ for field in ['配置项', 'Config Item', 'config_item']:
|
|
|
+ if field in row and pd.notna(row[field]):
|
|
|
+ config_item = str(row[field]).strip()
|
|
|
+ break
|
|
|
+
|
|
|
+ if config_item is None and len(row) > 0:
|
|
|
+ config_item = str(row.iloc[0]).strip() if pd.notna(row.iloc[0]) else None
|
|
|
+
|
|
|
+ # 如果找到rarityDamageMultipliers配置项
|
|
|
+ if config_item == 'rarityDamageMultipliers':
|
|
|
+ # 获取值字段
|
|
|
+ multipliers_str = None
|
|
|
+ for field in ['值', 'Value', 'value']:
|
|
|
+ if field in row and pd.notna(row[field]):
|
|
|
+ multipliers_str = str(row[field]).strip()
|
|
|
+ break
|
|
|
+
|
|
|
+ if multipliers_str is None and len(row) > 1:
|
|
|
+ multipliers_str = str(row.iloc[1]).strip() if pd.notna(row.iloc[1]) else None
|
|
|
+
|
|
|
+ if multipliers_str:
|
|
|
+ try:
|
|
|
+ # 解析逗号分隔的数组字符串
|
|
|
+ multipliers_list = [float(x.strip()) for x in multipliers_str.split(',')]
|
|
|
+ damage_multipliers = multipliers_list
|
|
|
+ print(f"✓ 解析稀有度伤害倍率配置: {damage_multipliers}")
|
|
|
+ break
|
|
|
+ except (ValueError, TypeError) as e:
|
|
|
+ print(f"解析倍率数组失败: {e}, 字符串: {multipliers_str}")
|
|
|
+
|
|
|
+ # 如果没有找到配置或解析失败,尝试旧格式解析
|
|
|
+ if not damage_multipliers:
|
|
|
+ print("未找到新格式配置,尝试解析旧格式...")
|
|
|
+ level_multipliers = {}
|
|
|
+
|
|
|
+ for index, row in rarity_damage_multipliers_sheet.iterrows():
|
|
|
+ if is_header and index == 0: # 跳过表头
|
|
|
+ continue
|
|
|
+
|
|
|
+ # 获取稀有度等级
|
|
|
+ level = None
|
|
|
+ for field in ['等级', 'Level', 'level', '稀有度等级']:
|
|
|
+ if field in row and pd.notna(row[field]):
|
|
|
+ try:
|
|
|
+ level_str = str(row[field]).strip()
|
|
|
+ if level_str.startswith('等级'):
|
|
|
+ level = int(level_str.replace('等级', ''))
|
|
|
+ else:
|
|
|
+ level = int(float(row[field]))
|
|
|
+ break
|
|
|
+ except (ValueError, TypeError):
|
|
|
+ pass
|
|
|
+
|
|
|
+ if level is None and len(row) > 0:
|
|
|
+ try:
|
|
|
+ first_cell = str(row.iloc[0]).strip()
|
|
|
+ if first_cell.startswith('等级'):
|
|
|
+ level = int(first_cell.replace('等级', ''))
|
|
|
+ else:
|
|
|
+ level = int(float(row.iloc[0])) if pd.notna(row.iloc[0]) else None
|
|
|
+ except (ValueError, TypeError):
|
|
|
+ pass
|
|
|
+
|
|
|
+ # 获取伤害倍率
|
|
|
+ multiplier = None
|
|
|
+ for field in ['伤害倍率', 'Damage Multiplier', 'multiplier', '倍率', '值', 'Value', 'value']:
|
|
|
+ if field in row and pd.notna(row[field]):
|
|
|
+ try:
|
|
|
+ multiplier = float(row[field])
|
|
|
+ break
|
|
|
+ except (ValueError, TypeError):
|
|
|
+ pass
|
|
|
+
|
|
|
+ if multiplier is None and len(row) > 1:
|
|
|
+ try:
|
|
|
+ multiplier = float(row.iloc[1]) if pd.notna(row.iloc[1]) else None
|
|
|
+ except (ValueError, TypeError):
|
|
|
+ pass
|
|
|
+
|
|
|
+ if level is not None and multiplier is not None:
|
|
|
+ level_multipliers[level] = multiplier
|
|
|
+ print(f"✓ 添加稀有度伤害倍率配置: 等级{level} = {multiplier}倍")
|
|
|
+
|
|
|
+ # 将字典转换为按等级排序的数组
|
|
|
+ if level_multipliers:
|
|
|
+ max_level = max(level_multipliers.keys())
|
|
|
+ for i in range(max_level + 1):
|
|
|
+ if i in level_multipliers:
|
|
|
+ damage_multipliers.append(level_multipliers[i])
|
|
|
+ else:
|
|
|
+ # 使用默认值
|
|
|
+ default_multipliers = [1, 1.5, 2.25, 8]
|
|
|
+ if i < len(default_multipliers):
|
|
|
+ damage_multipliers.append(default_multipliers[i])
|
|
|
+ else:
|
|
|
+ damage_multipliers.append(1)
|
|
|
+
|
|
|
+ # 如果仍然没有数据,使用默认值
|
|
|
+ if not damage_multipliers:
|
|
|
+ damage_multipliers = [1, 1.5, 2.25, 8]
|
|
|
+ print("使用默认稀有度伤害倍率配置")
|
|
|
+
|
|
|
+ return damage_multipliers
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ print(f"解析稀有度伤害倍率配置失败: {e}")
|
|
|
+ return [1, 1.5, 2.25, 8] # 返回默认值
|
|
|
+
|
|
|
def merge_weapon_configs(self, existing_config, excel_config):
|
|
|
"""合并现有JSON配置和Excel配置"""
|
|
|
try:
|
|
|
@@ -595,6 +815,13 @@ class WeaponConfigManager:
|
|
|
merged_config['blockSizes'] = excel_config['blockSizes']
|
|
|
print(f"✓ 更新方块形状配置,共{len(excel_config['blockSizes'])}个形状")
|
|
|
|
|
|
+ # 保留重要的全局配置字段
|
|
|
+ global_config_fields = ['rarityWeights', 'rarityDamageMultipliers']
|
|
|
+ for field in global_config_fields:
|
|
|
+ if field in existing_config:
|
|
|
+ merged_config[field] = existing_config[field]
|
|
|
+ print(f"✓ 保留全局配置: {field}")
|
|
|
+
|
|
|
print(f"合并完成,最终武器数量: {len(merged_weapons)}")
|
|
|
return merged_config
|
|
|
|
|
|
@@ -621,6 +848,12 @@ class WeaponConfigManager:
|
|
|
weapon_type = item.get('type', item.get('类型', ''))
|
|
|
weight = item.get('weight', item.get('权重', 1))
|
|
|
|
|
|
+ # 获取稀有度伤害倍率
|
|
|
+ rarity_damage_multipliers = item.get('rarityDamageMultipliers', item.get('稀有度伤害倍率', [1.0, 1.5, 2.25, 8.0]))
|
|
|
+ # 确保是数组格式
|
|
|
+ if not isinstance(rarity_damage_multipliers, list):
|
|
|
+ rarity_damage_multipliers = [1.0, 1.5, 2.25, 8.0]
|
|
|
+
|
|
|
# 推断武器类型(如果为空)
|
|
|
if not weapon_type:
|
|
|
weapon_type = self._infer_weapon_type(weapon_id)
|
|
|
@@ -635,6 +868,7 @@ class WeaponConfigManager:
|
|
|
'name': weapon_name,
|
|
|
'type': weapon_type,
|
|
|
'weight': weight,
|
|
|
+ 'rarityDamageMultipliers': rarity_damage_multipliers,
|
|
|
'stats': {
|
|
|
'damage': damage,
|
|
|
'fireRate': fire_rate,
|