feat(web/server): add dodge and accuracy stats support

1. 调整FieldEditor中光环档位默认等级为4级
2. 更新SUPPORT_ULT技能列表,新增6415、6416、6518、6519
3. 新增闪避(dodge)和命中(accuracy)属性配置:
   - 在常量中定义属性注释
   - 在前端表单添加属性编辑控件
   - 在后端渲染逻辑中支持属性导出
4. 新增测试英雄"闪避哥"用于展示新属性
This commit is contained in:
panFD
2026-09-07 21:57:07 +08:00
parent d559fdbaa4
commit a1c8f46c50
5 changed files with 114 additions and 2 deletions

View File

@@ -1259,6 +1259,106 @@
"hp_bonus": [], "hp_bonus": [],
"def_bonus": [], "def_bonus": [],
"info": "大招全体反伤 普攻暴击 暴击反伤辅助" "info": "大招全体反伤 普攻暴击 暴击反伤辅助"
},
{
"uuid": 5014,
"name": "闪避哥",
"comment": "",
"path": "hk4",
"rarity": 4,
"roleKey": "Warrior",
"growKey": "Warrior",
"typeKey": "Melee",
"statBase": {
"hp": 0,
"ap": 0,
"def": 0
},
"dis": null,
"speed": null,
"dodge": null,
"accuracy": null,
"skills": [
{
"uuid": 6004,
"name": "普攻强化",
"cd": 1.05,
"cdExpr": "AtkSpeedSet[AtkSpeedLv.Normal].cd",
"overrides": {},
"desc": "",
"lv_entries": [
{
"lv": 2,
"s_lv": 2,
"overrides": {
"proc_skill": {
"s_uuid": 6518,
"chance": 20,
"overrides": {
"buff_value": 30
}
}
},
"desc": ""
}
]
},
{
"uuid": 6100,
"name": "寒冰斩",
"cd": 8,
"cdExpr": null,
"overrides": {
"ap": 200,
"timed_buff_id": 7030,
"buff_value": 50
},
"desc": "",
"lv_entries": [
{
"lv": 8,
"s_lv": 2,
"overrides": {
"ap": 250,
"timed_buff_id": 7030,
"buff_value": 50
},
"desc": ""
},
{
"lv": 16,
"s_lv": 3,
"overrides": {
"ap": 350,
"timed_buff_id": 7030,
"buff_value": 80
},
"desc": ""
}
]
}
],
"atking": {},
"atked": {},
"fstart": {},
"dead": {},
"field": [
{
"lv": 4,
"uuids": [
{
"uuid": 7023,
"value": 10,
"name": ""
}
],
"desc": ""
}
],
"ap_bonus": [],
"hp_bonus": [],
"def_bonus": [],
"info": ""
} }
] ]
} }

View File

@@ -131,6 +131,8 @@ function renderSingleHero(h) {
) )
if (h.dis != null) push(` dis: ${h.dis},`) if (h.dis != null) push(` dis: ${h.dis},`)
if (h.speed != null) push(` speed: ${h.speed},`) if (h.speed != null) push(` speed: ${h.speed},`)
if (h.dodge != null) push(` dodge: ${h.dodge},`)
if (h.accuracy != null) push(` accuracy: ${h.accuracy},`)
// skills // skills
push(` skills: {`) push(` skills: {`)
@@ -336,6 +338,8 @@ function renderHeroCsv(heroes) {
rows.push(['ap', ...sorted.map((h) => csvStatLine(h, 'ap'))]) rows.push(['ap', ...sorted.map((h) => csvStatLine(h, 'ap'))])
rows.push(['hp', ...sorted.map((h) => csvStatLine(h, 'hp'))]) rows.push(['hp', ...sorted.map((h) => csvStatLine(h, 'hp'))])
rows.push(['def', ...sorted.map((h) => csvStatLine(h, 'def'))]) rows.push(['def', ...sorted.map((h) => csvStatLine(h, 'def'))])
rows.push(['dodge', ...sorted.map((h) => (h.dodge != null ? h.dodge : ''))])
rows.push(['accuracy', ...sorted.map((h) => (h.accuracy != null ? h.accuracy : ''))])
rows.push(['skill[0]_lv1', ...sorted.map((h) => csvSkillLv1(h.skills?.[0], false))]) rows.push(['skill[0]_lv1', ...sorted.map((h) => csvSkillLv1(h.skills?.[0], false))])
rows.push(['skill[0]_lv2', ...sorted.map((h) => csvSkillLvUp(h.skills?.[0], 2))]) rows.push(['skill[0]_lv2', ...sorted.map((h) => csvSkillLvUp(h.skills?.[0], 2))])
rows.push(['skill[1]_lv1', ...sorted.map((h) => csvSkillLv1(h.skills?.[1], true))]) rows.push(['skill[1]_lv1', ...sorted.map((h) => csvSkillLv1(h.skills?.[1], true))])

View File

@@ -110,6 +110,12 @@
<el-form-item label="攻击距离 dis(可选)"> <el-form-item label="攻击距离 dis(可选)">
<el-input-number v-model="current.dis" :min="0" :controls="false" style="width: 100%" placeholder="默认按形态" /> <el-input-number v-model="current.dis" :min="0" :controls="false" style="width: 100%" placeholder="默认按形态" />
</el-form-item> </el-form-item>
<el-form-item label="闪避 dodge(可选)">
<el-input-number v-model="current.dodge" :min="0" :max="100" :controls="false" style="width: 100%" placeholder="默认 15" />
</el-form-item>
<el-form-item label="命中 accuracy(可选)">
<el-input-number v-model="current.accuracy" :min="0" :max="100" :controls="false" style="width: 100%" placeholder="默认 10" />
</el-form-item>
<el-form-item label="hp 偏移"> <el-form-item label="hp 偏移">
<el-input-number v-model="current.statBase.hp" :controls="false" style="width: 100%" /> <el-input-number v-model="current.statBase.hp" :controls="false" style="width: 100%" />
</el-form-item> </el-form-item>

View File

@@ -27,7 +27,7 @@
</div> </div>
</el-form-item> </el-form-item>
</div> </div>
<el-button size="small" type="primary" @click="model.push({ lv: 6, uuids: [], desc: '' })">+ 添加光环档位</el-button> <el-button size="small" type="primary" @click="model.push({ lv: 4, uuids: [], desc: '' })">+ 添加光环档位</el-button>
</div> </div>
</template> </template>

View File

@@ -52,7 +52,7 @@ export const ROLE_ULT_SKILL = {
} }
// 辅助类技能(任意职业可用作大招) // 辅助类技能(任意职业可用作大招)
export const SUPPORT_ULT = [6301, 6302, 6407, 6412, 6413, 6414, 6501, 6514, 6515, 6516, 6517] export const SUPPORT_ULT = [6301, 6302, 6407, 6412, 6413, 6414, 6415, 6416, 6501, 6514, 6515, 6516, 6517, 6518, 6519]
export function defaultHero() { export function defaultHero() {
return { return {
@@ -67,6 +67,8 @@ export function defaultHero() {
statBase: { hp: 0, ap: 0, def: 0 }, statBase: { hp: 0, ap: 0, def: 0 },
dis: null, dis: null,
speed: null, speed: null,
dodge: null, // 闪避率(null = 全局默认 15,填值覆盖)
accuracy: null, // 命中率(null = 全局默认 10,填值覆盖)
skills: [], // [{uuid,name,cd,cdExpr,overrides,desc,lv_entries:[{lv,s_lv,overrides,desc}]}] skills: [], // [{uuid,name,cd,cdExpr,overrides,desc,lv_entries:[{lv,s_lv,overrides,desc}]}]
atking: {}, // {uuid:[{lv,s_lv,name,t_num,overrides,desc}]} atking: {}, // {uuid:[{lv,s_lv,name,t_num,overrides,desc}]}
atked: {}, atked: {},