# 枪械六大核心属性通用计算公式文档
# 1. 基础强度 Firepower (范围: 0-100)
定义: 表示武器每秒能造成的伤害总量,反映持续火力强度。
计算公式:
Firepower = (Base_Damage × Shots_Per_Second) × (1 - 平均伤害衰减比例)基于YML配置的公式:
Firepower = ({Weapon.Damage.Base_Damage} × {Weapon.Shoot.Fully_Automatic_Shots_Per_Second}) × (1 - 平均伤害衰减比例)参数说明:
- Base_Damage: 武器基础伤害值
- Shots_Per_Second: 每秒射击次数(射速)
- 平均伤害衰减比例: 根据不同距离的伤害衰减计算得出的平均值
标准化处理:
标准化Firepower = MIN(100, MAX(0, Firepower))对于火箭发射器
基于火箭武器瞬时爆发、范围伤害和低射速的特点,设计了专用的Firepower定义和计算公式:
# 火箭武器专用 Firepower 定义 (范围: 0-100)
定义: 表示武器单次射击造成的等效秒伤(DPS),综合爆炸范围伤害、装填时间和范围效能,反映爆发火力强度。
计算公式:
math
Firepower = \frac{ (Base\_Damage + Base\_Explosion\_Damage \times Effective\_Targets) \times Damage\_Multipliers }{ Reload\_Time }基于YML配置的公式:
Firepower = (
({Weapon.Damage.Base_Damage} + {Weapon.Damage.Base_Explosion_Damage} × {Weapon.Explosion.Effective_Targets})
× (1 + {Weapon.Damage.Fire_Ticks} × 0.01)
) / {Weapon.Shoot.Reload_Time}参数说明:
| 参数 | 说明 |
|---|---|
Base_Damage | 直接命中伤害值 |
Base_Explosion_Damage | 爆炸基础伤害值 |
Effective_Targets | 爆炸有效目标数,根据爆炸半径计算:MIN(5, (Explosion_Radius² / 4)) |
Damage_Multipliers | 伤害增益系数,包含: - 燃烧增益: 1 + (Fire_Ticks × 0.01)- 负面效果增益(如眩晕/中毒):+0.1/效果 |
Reload_Time | 装填时间(秒),火箭武器核心参数 |
标准化处理:
标准化Firepower = MIN(100, MAX(0, Firepower))# 多发火箭系统扩展公式
定义: 单次触发发射多枚火箭时的聚合火力强度
计算公式:
math
Firepower = \frac{ Missile\_Count \times (Base\_Damage + Base\_Explosion\_Damage \times Effective\_Targets \times Spread\_Factor) \times Damage\_Multipliers }{ Cluster\_Reload\_Time }基于YML配置的公式:
Firepower = (
{Weapon.Shoot.Missile_Count}
× ({Weapon.Damage.Base_Damage} + {Weapon.Damage.Base_Explosion_Damage} × {Weapon.Explosion.Effective_Targets} × {Weapon.Explosion.Spread_Factor})
× (1 + {Weapon.Damage.Fire_Ticks} × 0.01)
) / {Weapon.Shoot.Cluster_Reload_Time}新增参数说明:
| 参数 | 说明 | 典型值 |
|---|---|---|
Missile_Count | 单次发射火箭数量 | 3(三联装), 6(蜂窝式) |
Spread_Factor | 散布补偿系数:0.7 + (0.3 / Missile_Count)解决多弹重叠伤害衰减 | 三联装:0.8 六联装:0.75 |
Cluster_Reload_Time | 集群装填时间:Base_Reload_Time × (0.5 + 0.5 × Missile_Count)反映多弹装填效率 | - |
# 2. 弹道精度 Accuracy (范围: 0-100)
定义: 反映射击时子弹散布控制程度,数值越高表示精度越好。
计算公式:
Accuracy = MAX(0, 100 - (Base_Spread × 精度系数))基于YML配置的公式:
Accuracy = MAX(0, 100 - ({Weapon.Shoot.Spread.Base_Spread} × 精度系数))参数说明:
- Base_Spread: 基础散布值
- 精度系数: 根据游戏平衡调整的倍数(建议范围10-20)
考虑不同状态下的精度修正:
最终Accuracy = Accuracy × (1 + 瞄准时精度加成 + 蹲伏时精度加成 - 跳跃时精度惩罚)# 3. 操控性能 Stability (范围: 0-100)
定义: 衡量后坐力累积和恢复的速度,决定连续射击中的可控性。
计算公式:
Stability = 100 - (Recoil_Accumulation × 累积系数 + Recoil_Speed × 速度系数)基于YML配置的公式:
Stability = 100 - ({Weapon.Shoot.Recoil.Max_Accumulation} × 累积系数 + {Weapon.Shoot.Recoil.Speed} × 速度系数)参数说明:
- Recoil_Accumulation: 后坐力最大累积值
- Recoil_Speed: 后坐力上升速度
- 累积系数: 后坐力累积对稳定性的影响权重
- 速度系数: 后坐力速度对稳定性的影响权重
# 4. 移动速度 Mobility (范围: 0-50)
定义: 衡量使用武器时对玩家移动速度的影响,越高越好。
计算公式:
Mobility = MAX(0, 50 + (movement_speed_modifier × 速度系数))基于YML配置的公式:
Mobility = MAX(0, 50 + ({Weapon.Item.Attributes.movement_speed} × 速度系数))参数说明:
- movement_speed_modifier: 武器对移动速度的修正值(通常为负值)
- 速度系数: 将速度修正转换为属性值的倍数(建议1000-2000)
标准化处理:
标准化Mobility = MIN(50, MAX(0, Mobility))# 5. 换弹速度 Reload_Speed (范围: 0-50)
定义: 衡量换弹时间的快慢,数值越高表示换弹越快。
计算公式:
Reload_Speed = MAX(0, 50 - Reload_Duration / 时间系数)基于YML配置的公式:
Reload_Speed = MAX(0, 50 - {Weapon.Reload.Reload_Duration} / 时间系数)参数说明:
- Reload_Duration: 换弹持续时间(以游戏刻度为单位)
- 时间系数: 将换弹时间转换为属性值的除数(建议范围1-3)
标准化处理:
标准化Reload_Speed = MIN(50, MAX(0, Reload_Speed))# 6. 有效射程 Effective_Range (范围: 0-100)
定义: 根据伤害衰减情况估算有效打击距离。
计算公式:
Effective_Range = 100 - (最大伤害衰减距离 / 最大射程 × 100)基于YML配置的公式:
Effective_Range = 100 - ({Weapon.Damage.Dropoff.最大距离} / 最大射程 × 100)参数说明:
- 最大伤害衰减距离: 伤害开始显著下降的距离(从Damage.Dropoff中提取)
- 最大射程: 武器的最大射击距离
简化计算:
Effective_Range = (有效射程距离 / 最大射程) × 100标准化处理:
标准化Effective_Range = MIN(100, MAX(0, Effective_Range))# 通用属性计算注意事项
- 数值范围控制: 所有属性值必须在指定范围内,超出范围时应进行截断处理
- 系数调整: 各公式中的系数需要根据实际游戏平衡进行调整
- 状态修正: 考虑瞄准、蹲伏、移动等状态对属性的影响
- 小数处理: 计算结果建议保留一位小数后四舍五入取整
# Python自动计算程序
警告
自动计算不适用于所有枪械!出现问题数据请手工计算!
Python自动计算程序
python
import os
import yaml
import json
from pathlib import Path
def find_yml_files(root_dir):
"""查找指定目录下所有yml文件(支持嵌套文件夹)"""
yml_files = []
for root, dirs, files in os.walk(root_dir):
for file in files:
if file.endswith('.yml') or file.endswith('.yaml'):
yml_files.append(os.path.join(root, file))
return yml_files
def extract_value_by_path(data, path):
"""根据路径提取值,支持嵌套结构"""
keys = path.split('.')
current = data
try:
for key in keys:
if isinstance(current, dict) and key in current:
current = current[key]
else:
return None
return current
except (KeyError, TypeError):
return None
def calculate_firepower(weapon_data):
"""计算火力输出能力 Firepower = (Base_Damage × Shots_Per_Second) × (1 - 平均伤害衰减比例)"""
base_damage = extract_value_by_path(weapon_data, 'Damage.Base_Damage')
shots_per_second = extract_value_by_path(weapon_data, 'Shoot.Fully_Automatic_Shots_Per_Second')
if base_damage is None or shots_per_second is None:
return 0
# 计算平均伤害衰减比例
dropoff = extract_value_by_path(weapon_data, 'Damage.Dropoff')
avg_dropoff = 0
if dropoff and isinstance(dropoff, list):
total_drop_rate = 0
valid_entries = 0
for item in dropoff:
if isinstance(item, str):
parts = item.strip().split()
if len(parts) == 2:
try:
distance = float(parts[0])
damage_reduction = float(parts[1])
if base_damage != 0:
drop_rate = abs(damage_reduction) / base_damage
total_drop_rate += drop_rate
valid_entries += 1
except ValueError:
continue
if valid_entries > 0:
avg_dropoff = total_drop_rate / valid_entries
firepower = (base_damage * shots_per_second) * (1 - avg_dropoff)
return max(0, min(100, firepower))
def calculate_accuracy(weapon_data):
"""计算精度 Accuracy = MAX(0, 100 - (Base_Spread × 15))"""
base_spread = extract_value_by_path(weapon_data, 'Shoot.Spread.Base_Spread')
if base_spread is None:
return 0
accuracy = 100 - (base_spread * 15)
return max(0, min(100, accuracy))
def calculate_stability(weapon_data):
"""计算稳定性 Stability = 100 - (Recoil_Accumulation × 10 + Recoil_Speed × 5)"""
max_accumulation = extract_value_by_path(weapon_data, 'Shoot.Recoil.Max_Accumulation')
recoil_speed = extract_value_by_path(weapon_data, 'Shoot.Recoil.Speed')
if max_accumulation is None or recoil_speed is None:
return 0
stability = 100 - (max_accumulation * 10 + recoil_speed * 5)
return max(0, min(100, stability))
def calculate_mobility(weapon_data):
"""计算机动性 Mobility = MAX(0, 50 + (movement_speed_modifier × 1000))"""
attributes = extract_value_by_path(weapon_data, 'Info.Weapon_Item.Attributes')
movement_speed_modifier = 0
if attributes and isinstance(attributes, list):
for attr in attributes:
if isinstance(attr, str) and 'movement_speed' in attr:
try:
parts = attr.split()
if len(parts) >= 2:
movement_speed_modifier = float(parts[1])
break
except ValueError:
pass
mobility = 50 + (movement_speed_modifier * 1000)
return max(0, min(50, mobility))
def calculate_effective_range(weapon_data):
"""计算有效射程:当伤害降到Base_Damage的50%时的距离"""
base_damage = extract_value_by_path(weapon_data, 'Damage.Base_Damage')
dropoff = extract_value_by_path(weapon_data, 'Damage.Dropoff')
if base_damage is None or base_damage <= 0:
return 50 # 默认值
target_damage = base_damage * 0.5 # 50%基础伤害
if not dropoff or not isinstance(dropoff, list):
return 50 # 默认值
# 解析伤害衰减数据
damage_points = []
for item in dropoff:
if isinstance(item, str):
parts = item.strip().split()
if len(parts) == 2:
try:
distance = float(parts[0])
damage_reduction = float(parts[1])
actual_damage = base_damage + damage_reduction # damage_reduction是负值
damage_points.append((distance, actual_damage))
except ValueError:
continue
# 按距离排序
damage_points.sort(key=lambda x: x[0])
# 如果没有衰减数据点,返回默认值
if len(damage_points) == 0:
return 50
# 如果第一个点就已经低于50%伤害,返回第一个点的距离
if damage_points[0][1] <= target_damage:
return max(0, min(100, damage_points[0][0]))
# 查找目标伤害所在的区间
for i in range(len(damage_points) - 1):
distance1, damage1 = damage_points[i]
distance2, damage2 = damage_points[i + 1]
# 如果目标伤害在这个区间内
if damage2 <= target_damage <= damage1:
# 线性插值计算精确距离
if damage1 != damage2:
ratio = (target_damage - damage2) / (damage1 - damage2)
effective_distance = distance2 + ratio * (distance1 - distance2)
return max(0, min(100, effective_distance))
else:
return max(0, min(100, distance1))
# 如果所有点都高于50%伤害,返回最远点的距离
return max(0, min(100, damage_points[-1][0]))
def process_weapon_file(file_path):
"""处理单个武器文件"""
try:
with open(file_path, 'r', encoding='utf-8') as f:
file_data = yaml.safe_load(f)
if not file_data or not isinstance(file_data, dict):
return None
# 获取武器根键名(如 "Uzi")
weapon_root_key = list(file_data.keys())[0] if len(file_data.keys()) > 0 else None
if not weapon_root_key:
return None
weapon_data = file_data[weapon_root_key]
weapon_name = extract_value_by_path(weapon_data, 'Info.Weapon_Item.Name') or weapon_root_key
# 计算六大属性
firepower = calculate_firepower(weapon_data)
accuracy = calculate_accuracy(weapon_data)
stability = calculate_stability(weapon_data)
mobility = calculate_mobility(weapon_data)
reload_speed = calculate_reload_speed(weapon_data)
effective_range = calculate_effective_range(weapon_data)
return {
'weapon_name': weapon_name,
'weapon_key': weapon_root_key,
'file_path': file_path,
'attributes': {
'firepower': round(firepower, 1),
'accuracy': round(accuracy, 1),
'stability': round(stability, 1),
'mobility': round(mobility, 1),
'reload_speed': round(reload_speed, 1),
'effective_range': round(effective_range, 1)
}
}
except Exception as e:
print(f"处理文件 {file_path} 时出错: {str(e)}")
return None
def calculate_reload_speed(weapon_data):
"""计算换弹效率 Reload_Speed = MAX(0, 50 - Reload_Duration / 2)"""
reload_duration = extract_value_by_path(weapon_data, 'Reload.Reload_Duration')
if reload_duration is None:
return 0
reload_speed = 50 - (reload_duration / 2)
return max(0, min(50, reload_speed))
def main():
"""主函数"""
# 创建wp目录(如果不存在)
wp_dir = './wp'
if not os.path.exists(wp_dir):
print(f"目录 {wp_dir} 不存在")
return
# 查找所有yml文件
yml_files = find_yml_files(wp_dir)
if not yml_files:
print("未找到任何yml文件")
return
print(f"找到 {len(yml_files)} 个yml文件")
# 处理所有武器文件
weapons_data = []
for file_path in yml_files:
print(f"处理文件: {os.path.basename(file_path)}")
weapon_info = process_weapon_file(file_path)
if weapon_info:
weapons_data.append(weapon_info)
print(f" 武器: {weapon_info['weapon_name']}")
print(f" 属性: {weapon_info['attributes']}")
# 输出为JSON
output_data = {
'total_weapons': len(weapons_data),
'weapons': weapons_data
}
# 保存到文件
output_file = 'weapons_attributes.json'
with open(output_file, 'w', encoding='utf-8') as f:
json.dump(output_data, f, ensure_ascii=False, indent=2)
print(f"\n处理完成,结果已保存到 {output_file}")
# 同时打印到控制台
print("\nJSON输出:")
print(json.dumps(output_data, ensure_ascii=False, indent=2))
if __name__ == '__main__':
main()