Compare commits
6 Commits
c2c1d5b520
...
a5ca43a62c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a5ca43a62c | ||
|
|
284d124486 | ||
|
|
8a506d9b83 | ||
|
|
6f988dabed | ||
|
|
4fc9acad7c | ||
|
|
a601b97f75 |
@@ -67,6 +67,7 @@ alwaysApply: true
|
||||
1. **技能底座纯净化**:SkillSet 中的技能只定义基础行为(伤害、弹道、命中),**禁止**在基础配置中写死 `timed_buff_id` / `buff_type` 等效果字段
|
||||
2. **效果由引用处注入**:英雄/怪物引用技能时,通过 `HSkillInfo.overrides` 按需附加 debuff/buff,实现"同一技能、不同效果"
|
||||
3. **数值覆盖优先**:`ap`(伤害百分比)、`hit_count`、`crt` 等数值差异,统一由 `overrides` 覆写,而非新建相似技能
|
||||
4. **Buff 统一百分比口径**:无论永久 buff(`buff_type`)还是计时 buff(`timed_buff_id`),修饰数值均按百分比/百分点结算;`ap`/`hp_max` 按基础值相对放大,概率类属性按百分点累加
|
||||
|
||||
## SkillSet 配置规范
|
||||
|
||||
|
||||
2013
assets/resources/game/skill/anm/atk/range2.anim
Normal file
2013
assets/resources/game/skill/anm/atk/range2.anim
Normal file
File diff suppressed because it is too large
Load Diff
13
assets/resources/game/skill/anm/atk/range2.anim.meta
Normal file
13
assets/resources/game/skill/anm/atk/range2.anim.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"ver": "2.0.3",
|
||||
"importer": "animation-clip",
|
||||
"imported": true,
|
||||
"uuid": "cb225ade-8b82-4bd0-913c-1f4b9cf8690a",
|
||||
"files": [
|
||||
".cconb"
|
||||
],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"name": "range2"
|
||||
}
|
||||
}
|
||||
4101
assets/resources/game/skill/anm/atk/range3.anim
Normal file
4101
assets/resources/game/skill/anm/atk/range3.anim
Normal file
File diff suppressed because it is too large
Load Diff
13
assets/resources/game/skill/anm/atk/range3.anim.meta
Normal file
13
assets/resources/game/skill/anm/atk/range3.anim.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"ver": "2.0.3",
|
||||
"importer": "animation-clip",
|
||||
"imported": true,
|
||||
"uuid": "9e3cd340-acbc-409e-9ceb-ca4678ecaea4",
|
||||
"files": [
|
||||
".cconb"
|
||||
],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"name": "range3"
|
||||
}
|
||||
}
|
||||
@@ -258,6 +258,9 @@
|
||||
"speed": 720,
|
||||
"time": 0,
|
||||
"distance": 0,
|
||||
"forceStartX": -1,
|
||||
"forceStartY": -1,
|
||||
"summon_count": 3,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
|
||||
928
assets/resources/game/skill/atk/range2.prefab
Normal file
928
assets/resources/game/skill/atk/range2.prefab
Normal file
@@ -0,0 +1,928 @@
|
||||
[
|
||||
{
|
||||
"__type__": "cc.Prefab",
|
||||
"_name": "range2",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"_native": "",
|
||||
"data": {
|
||||
"__id__": 1
|
||||
},
|
||||
"optimizationPolicy": 0,
|
||||
"persistent": false
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "range2",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"_parent": null,
|
||||
"_children": [
|
||||
{
|
||||
"__id__": 2
|
||||
}
|
||||
],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 30
|
||||
},
|
||||
{
|
||||
"__id__": 32
|
||||
},
|
||||
{
|
||||
"__id__": 34
|
||||
},
|
||||
{
|
||||
"__id__": 36
|
||||
},
|
||||
{
|
||||
"__id__": 38
|
||||
},
|
||||
{
|
||||
"__id__": 40
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 42
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
"__type__": "cc.Quat",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0,
|
||||
"w": 1
|
||||
},
|
||||
"_lscale": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"z": 1
|
||||
},
|
||||
"_mobility": 0,
|
||||
"_layer": 1073741824,
|
||||
"_euler": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "Node-001",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"_parent": {
|
||||
"__id__": 1
|
||||
},
|
||||
"_children": [
|
||||
{
|
||||
"__id__": 3
|
||||
},
|
||||
{
|
||||
"__id__": 21
|
||||
}
|
||||
],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 27
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 29
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": -111.631,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
"__type__": "cc.Quat",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0,
|
||||
"w": 1
|
||||
},
|
||||
"_lscale": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"z": 1
|
||||
},
|
||||
"_mobility": 0,
|
||||
"_layer": 1073741824,
|
||||
"_euler": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "Node",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"_parent": {
|
||||
"__id__": 2
|
||||
},
|
||||
"_children": [
|
||||
{
|
||||
"__id__": 4
|
||||
},
|
||||
{
|
||||
"__id__": 10
|
||||
}
|
||||
],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 16
|
||||
},
|
||||
{
|
||||
"__id__": 18
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 20
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
"__type__": "cc.Quat",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0,
|
||||
"w": 1
|
||||
},
|
||||
"_lscale": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"z": 1
|
||||
},
|
||||
"_mobility": 0,
|
||||
"_layer": 1073741824,
|
||||
"_euler": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "f",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"_parent": {
|
||||
"__id__": 3
|
||||
},
|
||||
"_children": [],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 5
|
||||
},
|
||||
{
|
||||
"__id__": 7
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 9
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 24.727,
|
||||
"y": 20.405,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
"__type__": "cc.Quat",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0.3826834323650898,
|
||||
"w": 0.9238795325112867
|
||||
},
|
||||
"_lscale": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"z": 1
|
||||
},
|
||||
"_mobility": 0,
|
||||
"_layer": 1073741824,
|
||||
"_euler": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 45
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.UITransform",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 4
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 6
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 104,
|
||||
"height": 92
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0.5,
|
||||
"y": 0
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "10vlMhQY5AqYpItsX+36u6"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Sprite",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 4
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 8
|
||||
},
|
||||
"_customMaterial": null,
|
||||
"_srcBlendFactor": 2,
|
||||
"_dstBlendFactor": 4,
|
||||
"_color": {
|
||||
"__type__": "cc.Color",
|
||||
"r": 255,
|
||||
"g": 255,
|
||||
"b": 255,
|
||||
"a": 255
|
||||
},
|
||||
"_spriteFrame": {
|
||||
"__uuid__": "abc35b6e-b052-4835-a3a3-cb85abd47f4d@bb1c9",
|
||||
"__expectedType__": "cc.SpriteFrame"
|
||||
},
|
||||
"_type": 0,
|
||||
"_fillType": 0,
|
||||
"_sizeMode": 1,
|
||||
"_fillCenter": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"_fillStart": 0,
|
||||
"_fillRange": 0,
|
||||
"_isTrimmedMode": true,
|
||||
"_useGrayscale": false,
|
||||
"_atlas": null,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "86HwoxWmhBnL8DBTzKTBFq"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.PrefabInfo",
|
||||
"root": {
|
||||
"__id__": 1
|
||||
},
|
||||
"asset": {
|
||||
"__id__": 0
|
||||
},
|
||||
"fileId": "4eVIHUruVEPKeL4meyjIez",
|
||||
"instance": null,
|
||||
"targetOverrides": null,
|
||||
"nestedPrefabInstanceRoots": null
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "f-001",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"_parent": {
|
||||
"__id__": 3
|
||||
},
|
||||
"_children": [],
|
||||
"_active": false,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 11
|
||||
},
|
||||
{
|
||||
"__id__": 13
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 15
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 24.727,
|
||||
"y": 20.405,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
"__type__": "cc.Quat",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0.3826834323650898,
|
||||
"w": 0.9238795325112867
|
||||
},
|
||||
"_lscale": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"z": 1
|
||||
},
|
||||
"_mobility": 0,
|
||||
"_layer": 1073741824,
|
||||
"_euler": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 45
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.UITransform",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 10
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 12
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 104,
|
||||
"height": 92
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0.5,
|
||||
"y": 0
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "7cUVEvKCxOR5PL3eKLw+/m"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Sprite",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 10
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 14
|
||||
},
|
||||
"_customMaterial": {
|
||||
"__uuid__": "8eee8ab1-fe48-4b22-b956-3f5c18fc4810",
|
||||
"__expectedType__": "cc.Material"
|
||||
},
|
||||
"_srcBlendFactor": 2,
|
||||
"_dstBlendFactor": 4,
|
||||
"_color": {
|
||||
"__type__": "cc.Color",
|
||||
"r": 255,
|
||||
"g": 255,
|
||||
"b": 255,
|
||||
"a": 255
|
||||
},
|
||||
"_spriteFrame": {
|
||||
"__uuid__": "abc35b6e-b052-4835-a3a3-cb85abd47f4d@bb1c9",
|
||||
"__expectedType__": "cc.SpriteFrame"
|
||||
},
|
||||
"_type": 0,
|
||||
"_fillType": 0,
|
||||
"_sizeMode": 1,
|
||||
"_fillCenter": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"_fillStart": 0,
|
||||
"_fillRange": 0,
|
||||
"_isTrimmedMode": true,
|
||||
"_useGrayscale": false,
|
||||
"_atlas": null,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "efxCF2oilFR4Mdk1TmeurF"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.PrefabInfo",
|
||||
"root": {
|
||||
"__id__": 1
|
||||
},
|
||||
"asset": {
|
||||
"__id__": 0
|
||||
},
|
||||
"fileId": "a1r6GcGwpNTrM8WvvrEqLU",
|
||||
"instance": null,
|
||||
"targetOverrides": null,
|
||||
"nestedPrefabInstanceRoots": null
|
||||
},
|
||||
{
|
||||
"__type__": "cc.UITransform",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 3
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 17
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 100,
|
||||
"height": 100
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0.5,
|
||||
"y": 0
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "70DHEflmNKcrXz52R+PxIm"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Sprite",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 3
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 19
|
||||
},
|
||||
"_customMaterial": null,
|
||||
"_srcBlendFactor": 2,
|
||||
"_dstBlendFactor": 4,
|
||||
"_color": {
|
||||
"__type__": "cc.Color",
|
||||
"r": 255,
|
||||
"g": 255,
|
||||
"b": 255,
|
||||
"a": 255
|
||||
},
|
||||
"_spriteFrame": null,
|
||||
"_type": 0,
|
||||
"_fillType": 0,
|
||||
"_sizeMode": 1,
|
||||
"_fillCenter": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"_fillStart": 0,
|
||||
"_fillRange": 0,
|
||||
"_isTrimmedMode": true,
|
||||
"_useGrayscale": false,
|
||||
"_atlas": null,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "717jT1RqhARpnrK9e9y6r8"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.PrefabInfo",
|
||||
"root": {
|
||||
"__id__": 1
|
||||
},
|
||||
"asset": {
|
||||
"__id__": 0
|
||||
},
|
||||
"fileId": "aevRQtaVFHroFdWuCtBPIE",
|
||||
"instance": null,
|
||||
"targetOverrides": null,
|
||||
"nestedPrefabInstanceRoots": null
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "zha_00052",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"_parent": {
|
||||
"__id__": 2
|
||||
},
|
||||
"_children": [],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 22
|
||||
},
|
||||
{
|
||||
"__id__": 24
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 26
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 132.79399999999998,
|
||||
"y": -95,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
"__type__": "cc.Quat",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0,
|
||||
"w": 1
|
||||
},
|
||||
"_lscale": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 1.7,
|
||||
"y": 1.5,
|
||||
"z": 1
|
||||
},
|
||||
"_mobility": 0,
|
||||
"_layer": 1073741824,
|
||||
"_euler": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.UITransform",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 21
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 23
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 200,
|
||||
"height": 180
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0.5,
|
||||
"y": 0
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "20/MgTXdpHnqgNPTUDwW0f"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Sprite",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 21
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 25
|
||||
},
|
||||
"_customMaterial": null,
|
||||
"_srcBlendFactor": 2,
|
||||
"_dstBlendFactor": 4,
|
||||
"_color": {
|
||||
"__type__": "cc.Color",
|
||||
"r": 255,
|
||||
"g": 255,
|
||||
"b": 255,
|
||||
"a": 0
|
||||
},
|
||||
"_spriteFrame": {
|
||||
"__uuid__": "2842dc10-d89e-4ff6-8a11-6d09bf48cf20@966d7",
|
||||
"__expectedType__": "cc.SpriteFrame"
|
||||
},
|
||||
"_type": 0,
|
||||
"_fillType": 0,
|
||||
"_sizeMode": 1,
|
||||
"_fillCenter": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"_fillStart": 0,
|
||||
"_fillRange": 0,
|
||||
"_isTrimmedMode": true,
|
||||
"_useGrayscale": false,
|
||||
"_atlas": null,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "f1ZaUa+eJBG6O5sGM6aJ3f"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.PrefabInfo",
|
||||
"root": {
|
||||
"__id__": 1
|
||||
},
|
||||
"asset": {
|
||||
"__id__": 0
|
||||
},
|
||||
"fileId": "b5OptiT15EzZkBo/RRwPJ7",
|
||||
"instance": null,
|
||||
"targetOverrides": null,
|
||||
"nestedPrefabInstanceRoots": null
|
||||
},
|
||||
{
|
||||
"__type__": "cc.UITransform",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 2
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 28
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 100,
|
||||
"height": 100
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0.5,
|
||||
"y": 0.5
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "f9OwrGiONLvrECWq4QjFuy"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.PrefabInfo",
|
||||
"root": {
|
||||
"__id__": 1
|
||||
},
|
||||
"asset": {
|
||||
"__id__": 0
|
||||
},
|
||||
"fileId": "ccwYlWWrFMBbLxMlGmAjxg",
|
||||
"instance": null,
|
||||
"targetOverrides": null,
|
||||
"nestedPrefabInstanceRoots": null
|
||||
},
|
||||
{
|
||||
"__type__": "cc.UITransform",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 1
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 31
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 150,
|
||||
"height": 120
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0.5,
|
||||
"y": 0.5
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "63NP9yq3hEUKD/OZZZ5t7x"
|
||||
},
|
||||
{
|
||||
"__type__": "57aabs7TE1J5obTAZczc+64",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 1
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 33
|
||||
},
|
||||
"atk_x": 20,
|
||||
"atk_y": 40,
|
||||
"runType": 2,
|
||||
"endType": 0,
|
||||
"speed": 720,
|
||||
"time": 0,
|
||||
"distance": 0,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "35nW0iQNBH2bqkWAr3MVkQ"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.RigidBody2D",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 1
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 35
|
||||
},
|
||||
"enabledContactListener": true,
|
||||
"bullet": false,
|
||||
"awakeOnLoad": true,
|
||||
"_group": 1,
|
||||
"_type": 1,
|
||||
"_allowSleep": false,
|
||||
"_gravityScale": 1,
|
||||
"_linearDamping": 0,
|
||||
"_angularDamping": 0,
|
||||
"_linearVelocity": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"_angularVelocity": 0,
|
||||
"_fixedRotation": false,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "57cr7S0YpK4oEZCavwXtIX"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.BoxCollider2D",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 1
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 37
|
||||
},
|
||||
"tag": 0,
|
||||
"_group": 1,
|
||||
"_density": 1,
|
||||
"_sensor": true,
|
||||
"_friction": 0.2,
|
||||
"_restitution": 0,
|
||||
"_offset": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"_size": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 150,
|
||||
"height": 120
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "ebw5mObxNGGKxnJXDgX5gl"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Animation",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 1
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 39
|
||||
},
|
||||
"playOnLoad": true,
|
||||
"_clips": [
|
||||
{
|
||||
"__uuid__": "cb225ade-8b82-4bd0-913c-1f4b9cf8690a",
|
||||
"__expectedType__": "cc.AnimationClip"
|
||||
}
|
||||
],
|
||||
"_defaultClip": {
|
||||
"__uuid__": "cb225ade-8b82-4bd0-913c-1f4b9cf8690a",
|
||||
"__expectedType__": "cc.AnimationClip"
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "20U0hP/NZErJJXRCEib1lq"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Sprite",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 1
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 41
|
||||
},
|
||||
"_customMaterial": null,
|
||||
"_srcBlendFactor": 2,
|
||||
"_dstBlendFactor": 4,
|
||||
"_color": {
|
||||
"__type__": "cc.Color",
|
||||
"r": 255,
|
||||
"g": 255,
|
||||
"b": 255,
|
||||
"a": 255
|
||||
},
|
||||
"_spriteFrame": null,
|
||||
"_type": 0,
|
||||
"_fillType": 0,
|
||||
"_sizeMode": 1,
|
||||
"_fillCenter": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"_fillStart": 0,
|
||||
"_fillRange": 0,
|
||||
"_isTrimmedMode": true,
|
||||
"_useGrayscale": false,
|
||||
"_atlas": null,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "bdU1jaclVIPaDk4N8vuMfY"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.PrefabInfo",
|
||||
"root": {
|
||||
"__id__": 1
|
||||
},
|
||||
"asset": {
|
||||
"__id__": 0
|
||||
},
|
||||
"fileId": "c46/YsCPVOJYA4mWEpNYRx",
|
||||
"instance": null,
|
||||
"targetOverrides": null
|
||||
}
|
||||
]
|
||||
13
assets/resources/game/skill/atk/range2.prefab.meta
Normal file
13
assets/resources/game/skill/atk/range2.prefab.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"ver": "1.1.50",
|
||||
"importer": "prefab",
|
||||
"imported": true,
|
||||
"uuid": "995d12bf-b91c-414d-b815-a0a1cc62ee5e",
|
||||
"files": [
|
||||
".json"
|
||||
],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"syncNodeName": "range2"
|
||||
}
|
||||
}
|
||||
2294
assets/resources/game/skill/atk/range3.prefab
Normal file
2294
assets/resources/game/skill/atk/range3.prefab
Normal file
File diff suppressed because it is too large
Load Diff
13
assets/resources/game/skill/atk/range3.prefab.meta
Normal file
13
assets/resources/game/skill/atk/range3.prefab.meta
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"ver": "1.1.50",
|
||||
"importer": "prefab",
|
||||
"imported": true,
|
||||
"uuid": "904a5d1f-6888-4b8c-a2ad-8a6db80db202",
|
||||
"files": [
|
||||
".json"
|
||||
],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"syncNodeName": "range3"
|
||||
}
|
||||
}
|
||||
@@ -88,8 +88,8 @@ export const BuffList: Record<number, BuffConfig> = {
|
||||
7001: {
|
||||
id: 7001, name: "攻击强化", icon: "Stat_Attack_03",
|
||||
category: BuffCategory.Buff, duration: 10, max_stack: 0,
|
||||
modifiers: [{ attr: Attrs.ap, op: ModOp.Flat, value: 5 }],
|
||||
info: "攻击力 +5,持续 10 秒",
|
||||
modifiers: [{ attr: Attrs.ap, op: ModOp.PercentAdd, value: 5 }],
|
||||
info: "攻击力提升 5%,持续 10 秒",
|
||||
},
|
||||
// 易伤(灼热火球附加;受到伤害时附加固定值,可被易伤抗性百分比减免)
|
||||
// 注:modifiers.attr 用 hp 仅为占位以通过 aggregateTimedMods 结构校验,实际易伤值由 HeroAtkSystem 按 VULNERABLE_BUFF_ID 直接汇总
|
||||
@@ -124,8 +124,8 @@ export const BuffList: Record<number, BuffConfig> = {
|
||||
7006: {
|
||||
id: 7006, name: "减攻", icon: "Stat_Attack_01",
|
||||
category: BuffCategory.Debuff, duration: 5, max_stack: 1,
|
||||
modifiers: [{ attr: Attrs.ap, op: ModOp.Flat, value: -10 }],
|
||||
info: "攻击力降低 10 点,持续 5 秒",
|
||||
modifiers: [{ attr: Attrs.ap, op: ModOp.PercentAdd, value: -10 }],
|
||||
info: "攻击力降低 10%,持续 5 秒",
|
||||
},
|
||||
// 出血(每层使目标被暴击率 +1%,微量伤害 DoT;暴击率加成由 HeroAtkSystem 按 BLEED_BUFF_ID 层数结算)
|
||||
7007: {
|
||||
@@ -134,12 +134,12 @@ export const BuffList: Record<number, BuffConfig> = {
|
||||
tick: { interval: 0.5, damage_or_heal: -1, scale_by_ap_pct: 0 },
|
||||
info: "微量出血,每层使自身被暴击率提升 1%,可叠加,持续 5 秒",
|
||||
},
|
||||
// 占卜师战前攻击强化(基础档:+30/5s;高阶通过 buff_value/buff_duration 覆写成长)
|
||||
// 占卜师战前攻击强化(基础档:+30%/5s;高阶通过 buff_value/buff_duration 覆写成长)
|
||||
7111: {
|
||||
id: 7111, name: "战前强攻", icon: "Stat_Attack_03",
|
||||
category: BuffCategory.Buff, duration: 5, max_stack: 0,
|
||||
modifiers: [{ attr: Attrs.ap, op: ModOp.Flat, value: 30 }],
|
||||
info: "攻击力 +30,持续 5 秒",
|
||||
modifiers: [{ attr: Attrs.ap, op: ModOp.PercentAdd, value: 30 }],
|
||||
info: "攻击力提升 30%,持续 5 秒",
|
||||
},
|
||||
|
||||
// ==================== 玩家计时性强化(药水/技能用,默认 5s) ====================
|
||||
@@ -161,77 +161,77 @@ export const BuffList: Record<number, BuffConfig> = {
|
||||
7012: {
|
||||
id: 7012, name: "暴击爆发", icon: "Stat_CriticalChance_02",
|
||||
category: BuffCategory.Buff, duration: 5, max_stack: 1,
|
||||
modifiers: [{ attr: Attrs.critical, op: ModOp.Flat, value: 30 }],
|
||||
modifiers: [{ attr: Attrs.critical, op: ModOp.PercentAdd, value: 30 }],
|
||||
info: "暴击率提升 30%,持续 5 秒",
|
||||
},
|
||||
// 击退距离强化(限时)
|
||||
7013: {
|
||||
id: 7013, name: "击退爆发", icon: "Stat_Stun_01",
|
||||
category: BuffCategory.Buff, duration: 5, max_stack: 1,
|
||||
modifiers: [{ attr: Attrs.knockback_chance, op: ModOp.Flat, value: 30 }],
|
||||
info: "击退距离提升 30,持续 5 秒",
|
||||
modifiers: [{ attr: Attrs.knockback_chance, op: ModOp.PercentAdd, value: 30 }],
|
||||
info: "击退距离提升 30%,持续 5 秒",
|
||||
},
|
||||
// 穿透强化(限时)
|
||||
7014: {
|
||||
id: 7014, name: "穿透爆发", icon: "Stat_Tripleshot",
|
||||
category: BuffCategory.Buff, duration: 5, max_stack: 1,
|
||||
modifiers: [{ attr: Attrs.puncture_chance, op: ModOp.Flat, value: 30 }],
|
||||
modifiers: [{ attr: Attrs.puncture_chance, op: ModOp.PercentAdd, value: 30 }],
|
||||
info: "穿透概率提升 30%,持续 5 秒",
|
||||
},
|
||||
// 攻速强化(限时,走 getEffectiveSkillCd 计时修饰)
|
||||
7015: {
|
||||
id: 7015, name: "攻速爆发", icon: "Stat_AttackSpeed_02",
|
||||
category: BuffCategory.Buff, duration: 5, max_stack: 1,
|
||||
modifiers: [{ attr: Attrs.speed, op: ModOp.Flat, value: 40 }],
|
||||
modifiers: [{ attr: Attrs.speed, op: ModOp.PercentAdd, value: 40 }],
|
||||
info: "攻击速度提升 40%,持续 5 秒",
|
||||
},
|
||||
// 风怒强化(限时,按概率百分点)
|
||||
7016: {
|
||||
id: 7016, name: "风怒爆发", icon: "Stat_CriticalComboChance",
|
||||
category: BuffCategory.Buff, duration: 5, max_stack: 1,
|
||||
modifiers: [{ attr: Attrs.wfuny, op: ModOp.Flat, value: 20 }],
|
||||
modifiers: [{ attr: Attrs.wfuny, op: ModOp.PercentAdd, value: 20 }],
|
||||
info: "风怒概率提升 20%,持续 5 秒",
|
||||
},
|
||||
// 击晕概率强化(限时)
|
||||
7017: {
|
||||
id: 7017, name: "击晕爆发", icon: "Stat_Stun_01",
|
||||
category: BuffCategory.Buff, duration: 5, max_stack: 1,
|
||||
modifiers: [{ attr: Attrs.stun_chance, op: ModOp.Flat, value: 30 }],
|
||||
modifiers: [{ attr: Attrs.stun_chance, op: ModOp.PercentAdd, value: 30 }],
|
||||
info: "击晕概率提升 30%,持续 5 秒",
|
||||
},
|
||||
// 击晕抗性强化(限时)
|
||||
7018: {
|
||||
id: 7018, name: "击晕抗性", icon: "Stat_Armor_01",
|
||||
category: BuffCategory.Buff, duration: 5, max_stack: 1,
|
||||
modifiers: [{ attr: Attrs.stun_res, op: ModOp.Flat, value: 50 }],
|
||||
modifiers: [{ attr: Attrs.stun_res, op: ModOp.PercentAdd, value: 50 }],
|
||||
info: "击晕抗性提升 50%,持续 5 秒",
|
||||
},
|
||||
// 冰冻抗性强化(限时)
|
||||
7019: {
|
||||
id: 7019, name: "冰冻抗性", icon: "Stat_Freeze",
|
||||
category: BuffCategory.Buff, duration: 5, max_stack: 1,
|
||||
modifiers: [{ attr: Attrs.freeze_res, op: ModOp.Flat, value: 50 }],
|
||||
modifiers: [{ attr: Attrs.freeze_res, op: ModOp.PercentAdd, value: 50 }],
|
||||
info: "冰冻抗性提升 50%,持续 5 秒",
|
||||
},
|
||||
// 暴伤强化(限时)
|
||||
7020: {
|
||||
id: 7020, name: "暴伤爆发", icon: "Stat_Critical_01",
|
||||
category: BuffCategory.Buff, duration: 5, max_stack: 1,
|
||||
modifiers: [{ attr: Attrs.critical_damage, op: ModOp.Flat, value: 30 }],
|
||||
modifiers: [{ attr: Attrs.critical_damage, op: ModOp.PercentAdd, value: 30 }],
|
||||
info: "暴击伤害提升 30%,持续 5 秒",
|
||||
},
|
||||
// 冰冻概率强化(限时)
|
||||
7021: {
|
||||
id: 7021, name: "冰冻概率爆发", icon: "Stat_Freeze",
|
||||
category: BuffCategory.Buff, duration: 5, max_stack: 1,
|
||||
modifiers: [{ attr: Attrs.freeze_chance, op: ModOp.Flat, value: 5 }],
|
||||
modifiers: [{ attr: Attrs.freeze_chance, op: ModOp.PercentAdd, value: 5 }],
|
||||
info: "冰冻概率提升 5%,持续 5 秒",
|
||||
},
|
||||
// 穿透伤害强化(限时)
|
||||
7022: {
|
||||
id: 7022, name: "穿透伤害爆发", icon: "Stat_Tripleshot",
|
||||
category: BuffCategory.Buff, duration: 5, max_stack: 1,
|
||||
modifiers: [{ attr: Attrs.puncture_dmg_bonus, op: ModOp.Flat, value: 30 }],
|
||||
modifiers: [{ attr: Attrs.puncture_dmg_bonus, op: ModOp.PercentAdd, value: 30 }],
|
||||
info: "穿透后伤害提升 30%,持续 5 秒",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -42,6 +42,8 @@ export enum FightSet {
|
||||
FROST_TIME = 3,//冰冻时间
|
||||
STUN_TIME = 2,//击晕时间
|
||||
SKILL_CAST_DELAY = 0.15,
|
||||
/** 多发/召唤技能每次实例化之间的间隔(秒),首个立即执行 */
|
||||
SUMMON_INTERVAL = 0.12,
|
||||
CSKILL_START_X = -340,
|
||||
CSKILL_START_Y = 30,
|
||||
/** 护盾数值上限(数值减免型:1 点护盾吸收 1 点伤害) */
|
||||
|
||||
@@ -57,16 +57,16 @@ export const SkillDescSet: Record<number, SkillDescConfig> = {
|
||||
verb: "", unit: "", permField: "ap",
|
||||
templPerm: "{target}回复攻击力{value}%生命",
|
||||
},
|
||||
// 6401 攻击强化:永久 ap=攻击点;计时 buff_value=攻击点
|
||||
// 6401 攻击强化:永久 ap=攻击%;计时 buff_value=攻击%
|
||||
6401: {
|
||||
verb: "攻击力", unit: "", permField: "ap", timedField: "buff_value",
|
||||
templPerm: "{target}{verb}永久+{value}",
|
||||
templTimed: "{target}{verb}+{value}, 持续{dur}秒",
|
||||
verb: "攻击力", unit: "%", permField: "ap", timedField: "buff_value",
|
||||
templPerm: "{target}{verb}永久+{value}{unit}",
|
||||
templTimed: "{target}{verb}+{value}{unit}, 持续{dur}秒",
|
||||
},
|
||||
// 6402 生命强化:ap = 最大生命点
|
||||
// 6402 生命强化:ap = 最大生命%
|
||||
6402: {
|
||||
verb: "最大生命", unit: "", permField: "ap",
|
||||
templPerm: "{target}{verb}永久+{value}",
|
||||
verb: "最大生命", unit: "%", permField: "ap",
|
||||
templPerm: "{target}{verb}永久+{value}{unit}",
|
||||
},
|
||||
// 6403 暴击强化:永久 ap=暴击%;计时 buff_value=暴击%
|
||||
6403: {
|
||||
|
||||
@@ -26,7 +26,6 @@ export enum SkillKind {
|
||||
Heal = 1,
|
||||
Shield = 2,
|
||||
Support = 3,
|
||||
Gold = 4
|
||||
}
|
||||
|
||||
|
||||
@@ -131,7 +130,6 @@ export interface SkillConfig {
|
||||
act: string, // 角色执行的动画
|
||||
DTType: DTType, // 伤害类型(单体/范围)
|
||||
ap: number, // 伤害/治疗技能为攻击百分比,护盾技能为免疫次数
|
||||
gold?: number, // 获取金币技能的金币值
|
||||
hit_count: number, // 可命中次数
|
||||
hitcd: number, // 持续伤害的伤害间隔(秒)
|
||||
speed: number, // 移动速度
|
||||
@@ -165,7 +163,6 @@ export interface SkillConfig {
|
||||
export interface SkillOverrides {
|
||||
TGroup?: TGroup;
|
||||
ap?: number;
|
||||
gold?: number;
|
||||
hit_count?: number;
|
||||
hitcd?: number;
|
||||
crt?: number;
|
||||
@@ -278,40 +275,74 @@ export const SkillSet: Record<number, SkillConfig> = {
|
||||
DTType: DTType.single, ap: 100, hit_count: 2, hitcd: 0.3, speed: 720, with: 90, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote,
|
||||
RType: RType.bezier, EType: EType.collision, info: "造成攻击力100%的伤害",
|
||||
},
|
||||
|
||||
// 暗影术 — 纯伤害底座
|
||||
6015: {
|
||||
uuid: 6015, name: "暗影术", sp_name: "fb-2", icon: "Stat_DarkDamage", TGroup: TGroup.Enemy, readyAnm: "", endAnm: "", act: "atk",
|
||||
DTType: DTType.single, ap: 100, hit_count: 2, hitcd: 0.3, speed: 720, with: 90, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote,
|
||||
RType: RType.bezier, EType: EType.collision, info: "造成攻击力100%的伤害",
|
||||
},
|
||||
// 光波 — 纯伤害底座
|
||||
6016: {
|
||||
uuid: 6016, name: "光波", sp_name: "fb-3", icon: "Stat_HolyDamage", TGroup: TGroup.Enemy, readyAnm: "", endAnm: "", act: "atk",
|
||||
DTType: DTType.single, ap: 100, hit_count: 2, hitcd: 0.3, speed: 720, with: 90, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote,
|
||||
RType: RType.bezier, EType: EType.collision, info: "造成攻击力100%的伤害",
|
||||
},
|
||||
// 能量波 — 纯伤害底座
|
||||
6017: {
|
||||
uuid: 6017, name: "能量波", sp_name: "fb-4", icon: "Stat_SplashDamage", TGroup: TGroup.Enemy, readyAnm: "", endAnm: "", act: "atk",
|
||||
DTType: DTType.single, ap: 100, hit_count: 2, hitcd: 0.3, speed: 720, with: 90, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote,
|
||||
RType: RType.bezier, EType: EType.collision, info: "造成攻击力100%的伤害",
|
||||
},
|
||||
// 毒气弹 — 纯伤害底座
|
||||
6018: {
|
||||
uuid: 6018, name: "毒气弹", sp_name: "fb-5", icon: "Stat_NatureDamage", TGroup: TGroup.Enemy, readyAnm: "", endAnm: "", act: "atk",
|
||||
DTType: DTType.single, ap: 100, hit_count: 2, hitcd: 0.3, speed: 720, with: 90, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote,
|
||||
RType: RType.bezier, EType: EType.collision, info: "造成攻击力100%的伤害",
|
||||
},
|
||||
|
||||
//大招
|
||||
6102: {
|
||||
uuid: 6102, name: "飓风", sp_name: "fb-2", icon: "Stat_Mana", TGroup: TGroup.Enemy, readyAnm: "", endAnm: "", act: "atk",
|
||||
uuid: 6102, name: "飓风", sp_name: "bm-1", icon: "Stat_Mana", TGroup: TGroup.Enemy, readyAnm: "", endAnm: "", act: "max1",
|
||||
DTType: DTType.single, ap: 100, hit_count: 2, hitcd: 0.3, speed: 720, with: 90, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote,
|
||||
RType: RType.linear, EType: EType.collision, info: "造成攻击力100%的伤害, 高阶技能",
|
||||
},
|
||||
6103: {
|
||||
uuid: 6103, name: "光闪", sp_name: "atk3", icon: "Stat_Attack_01", TGroup: TGroup.Enemy, readyAnm: "", endAnm: "", act: "atk",
|
||||
uuid: 6103, name: "光闪", sp_name: "atk3", icon: "Stat_Attack_01", TGroup: TGroup.Enemy, readyAnm: "", endAnm: "", act: "max0",
|
||||
DTType: DTType.single, ap: 150, hit_count: 5, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.Melee, is_accel: true,
|
||||
RType: RType.bezier, EType: EType.collision, info: "对周围的敌人造成攻击力150%的伤害",//英雄配置技能的时候,可以叠加出血debuff
|
||||
},
|
||||
6104: {
|
||||
uuid: 6104, name: "气斩", sp_name: "atk2", icon: "Stat_Attack_01", TGroup: TGroup.Enemy, readyAnm: "", endAnm: "", act: "atk",
|
||||
uuid: 6104, name: "气斩", sp_name: "atk2", icon: "Stat_Attack_01", TGroup: TGroup.Enemy, readyAnm: "", endAnm: "", act: "max0",
|
||||
DTType: DTType.single, ap: 150, hit_count: 5, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.Melee, is_accel: true,
|
||||
RType: RType.bezier, EType: EType.collision, info: "对周围的敌人造成攻击力150%的伤害",//英雄配置技能的时候,可以叠加击退
|
||||
},
|
||||
6105: {
|
||||
uuid: 6105, name: "火焰斩", sp_name: "atk5", icon: "Stat_Attack_01", TGroup: TGroup.Enemy, readyAnm: "", endAnm: "", act: "atk",
|
||||
uuid: 6105, name: "火焰斩", sp_name: "atk5", icon: "Stat_Attack_01", TGroup: TGroup.Enemy, readyAnm: "", endAnm: "", act: "max0",
|
||||
DTType: DTType.single, ap: 150, hit_count: 5, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.Melee, is_accel: true,
|
||||
RType: RType.bezier, EType: EType.collision, info: "对周围的敌人造成攻击力150%的伤害",//英雄配置技能的时候,可以叠加暴击debuff
|
||||
},
|
||||
6106: {
|
||||
uuid: 6106, name: "闪电斩", sp_name: "atk5", icon: "Stat_Attack_01", TGroup: TGroup.Enemy, readyAnm: "", endAnm: "", act: "atk",
|
||||
uuid: 6106, name: "闪电斩", sp_name: "atk5", icon: "Stat_Attack_01", TGroup: TGroup.Enemy, readyAnm: "", endAnm: "", act: "max0",
|
||||
DTType: DTType.single, ap: 150, hit_count: 5, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.Melee, is_accel: true,
|
||||
RType: RType.bezier, EType: EType.collision, info: "对周围的敌人造成攻击力150%的伤害",//英雄配置技能的时候,可以疲惫触发6013闪电术
|
||||
},
|
||||
6107: {
|
||||
uuid: 6201, name: "万剑朝宗", sp_name: "range3", icon: "Stat_Tripleshot", TGroup: TGroup.Enemy, readyAnm: "blues", endAnm: "", act: "max1",
|
||||
DTType: DTType.aoe_grid, stun: 0, ap: 150, hit_count: 6, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote,
|
||||
RType: RType.fixed, EType: EType.animationEnd, info: "召唤6把冰剑攻击敌人",//可以附加冰冻增强
|
||||
},
|
||||
6108: {
|
||||
uuid: 6201, name: "开山斧", sp_name: "range2", icon: "Stat_Tripleshot", TGroup: TGroup.Enemy, readyAnm: "blues", endAnm: "", act: "max0",
|
||||
DTType: DTType.aoe_grid, stun: 0, ap: 300, hit_count: 6, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote,
|
||||
RType: RType.fixed, EType: EType.animationEnd, info: "召唤巨斧劈向前方敌人",//可以附加击晕增强
|
||||
},
|
||||
6201: {
|
||||
uuid: 6201, name: "陨石术", sp_name: "fb-3", icon: "Stat_Tripleshot", TGroup: TGroup.Enemy, readyAnm: "blues", endAnm: "", act: "max",
|
||||
uuid: 6201, name: "陨石术", sp_name: "fb-3", icon: "Stat_Tripleshot", TGroup: TGroup.Enemy, readyAnm: "blues", endAnm: "", act: "max1",
|
||||
DTType: DTType.aoe_grid, stun: 0, ap: 150, hit_count: 6, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.remote,
|
||||
RType: RType.fixed, EType: EType.animationEnd, info: "召唤陨石范围攻击敌人, 有概率击晕",
|
||||
},
|
||||
|
||||
//============================= ====== 辅助技能 技能卡牌 1 回合技能 ====== ==========================
|
||||
//============================= ====== 辅助技能 回合技能 ====== ==========================
|
||||
6301: {
|
||||
uuid: 6301, name: "护盾", sp_name: "buff_wind", icon: "Stat_Defense", TGroup: TGroup.Self, readyAnm: "up_blue", endAnm: "", act: "atk",
|
||||
DTType: DTType.single, kind: SkillKind.Shield, ap: 3, hit_count: 1, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.support,
|
||||
@@ -322,22 +353,16 @@ export const SkillSet: Record<number, SkillConfig> = {
|
||||
DTType: DTType.single, kind: SkillKind.Heal, ap: 300, hit_count: 1, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.support,
|
||||
RType: RType.fixed, EType: EType.animationEnd, info: "治疗伙伴/自己",
|
||||
},
|
||||
//==========================buff 技能 也是 技能卡牌 5 回合技能
|
||||
6303: {
|
||||
uuid: 6303, name: "获取金币", sp_name: "buff_wind", icon: "Stat_GoldGainIncrease_01", TGroup: TGroup.Self, readyAnm: "up_blue", endAnm: "gold", act: "atk",
|
||||
DTType: DTType.single, kind: SkillKind.Gold, ap: 0, gold: 1, hit_count: 1, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.support,
|
||||
RType: RType.fixed, EType: EType.animationEnd, info: "增加一定数量的金币",
|
||||
},
|
||||
//==========================buff 技能=====================
|
||||
6401: {
|
||||
uuid: 6401, name: "攻击强化", sp_name: "buff_wind", icon: "Stat_Attack_03", TGroup: TGroup.Team, readyAnm: "up_ap", endAnm: "", act: "atk",
|
||||
DTType: DTType.single, kind: SkillKind.Support, ap: 5, hit_count: 1, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.support,
|
||||
RType: RType.fixed, EType: EType.animationEnd, buff_type: Attrs.ap, info: "全体友方攻击力提升5点, 持续1次",
|
||||
RType: RType.fixed, EType: EType.animationEnd, buff_type: Attrs.ap, info: "全体友方攻击力提升5%, 持续1次",
|
||||
},
|
||||
6402: {
|
||||
uuid: 6402, name: "生命强化", sp_name: "buff_wind", icon: "Stat_Hp_02", TGroup: TGroup.Team, readyAnm: "up_hp", endAnm: "", act: "atk",
|
||||
DTType: DTType.single, kind: SkillKind.Support, ap: 20, hit_count: 1, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.support,
|
||||
RType: RType.fixed, EType: EType.animationEnd, buff_type: Attrs.hp_max, info: "全体友方最大生命值提升20点, 持续1次",
|
||||
RType: RType.fixed, EType: EType.animationEnd, buff_type: Attrs.hp_max, info: "全体友方最大生命值提升20%, 持续1次",
|
||||
},
|
||||
6403: {
|
||||
uuid: 6403, name: "暴击强化", sp_name: "buff_wind", icon: "Stat_CriticalChance_02", TGroup: TGroup.Team, readyAnm: "up_ap", endAnm: "", act: "atk",
|
||||
@@ -382,7 +407,7 @@ export const SkillSet: Record<number, SkillConfig> = {
|
||||
6411: {
|
||||
uuid: 6411, name: "穿透伤害强化", sp_name: "buff_wind", icon: "Stat_Tripleshot", TGroup: TGroup.Team, readyAnm: "up_ap", endAnm: "", act: "atk",
|
||||
DTType: DTType.single, kind: SkillKind.Support, ap: 10, hit_count: 1, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.support,
|
||||
RType: RType.fixed, EType: EType.animationEnd, buff_type: Attrs.puncture_dmg_bonus, info: "全体友方穿透后伤害提升10%(百分点), 永久生效",
|
||||
RType: RType.fixed, EType: EType.animationEnd, buff_type: Attrs.puncture_dmg_bonus, info: "全体友方穿透后伤害提升10%, 永久生效",
|
||||
},
|
||||
6501: {
|
||||
uuid: 6501, name: "复活", sp_name: "buff_wind", icon: "Stat_HolyDamage", TGroup: TGroup.Self, readyAnm: "up_ap", endAnm: "", act: "atk",
|
||||
@@ -391,7 +416,7 @@ export const SkillSet: Record<number, SkillConfig> = {
|
||||
},
|
||||
|
||||
// ==================== 计时性强化技能(药水底座,统一 5s,走 timed_buff_id) ====================
|
||||
// 注:ap 字段在此类技能中无意义,修饰数值由 BuffList 配置;hit_count=99 确保覆盖全队。
|
||||
// 注:ap 字段在此类技能中无意义,修饰数值由 BuffList 配置(PercentAdd 百分比口径);hit_count=99 确保覆盖全队。
|
||||
6502: {
|
||||
uuid: 6502, name: "计时回血", sp_name: "buff_wind", icon: "Stat_PotionBoost", TGroup: TGroup.Team, readyAnm: "up_green", endAnm: "", act: "atk",
|
||||
DTType: DTType.single, kind: SkillKind.Support, ap: 0, hit_count: 3, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.support,
|
||||
@@ -410,7 +435,7 @@ export const SkillSet: Record<number, SkillConfig> = {
|
||||
6505: {
|
||||
uuid: 6505, name: "击退爆发", sp_name: "buff_wind", icon: "Stat_Stun_01", TGroup: TGroup.Team, readyAnm: "up_blue", endAnm: "", act: "atk",
|
||||
DTType: DTType.single, kind: SkillKind.Support, ap: 0, hit_count: 3, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.support,
|
||||
RType: RType.fixed, EType: EType.animationEnd, buff_type: Attrs.knockback_chance, timed_buff_id: 7013, info: "全体友方击退距离提升30, 持续5秒",
|
||||
RType: RType.fixed, EType: EType.animationEnd, buff_type: Attrs.knockback_chance, timed_buff_id: 7013, info: "全体友方击退距离提升30%, 持续5秒",
|
||||
},
|
||||
6506: {
|
||||
uuid: 6506, name: "穿透爆发", sp_name: "buff_wind", icon: "Stat_Tripleshot", TGroup: TGroup.Team, readyAnm: "up_ap", endAnm: "", act: "atk",
|
||||
|
||||
@@ -1114,7 +1114,7 @@ function calcBuffPermanentEquivalent(buff: BuffConfig, apEff: number, cd: number
|
||||
}
|
||||
|
||||
/** 计算 Support 类技能单次触发的效果价值 */
|
||||
function calcSupportEffectValue(config: SkillConfig, apEff: number, cd: number, seconds: number): number {
|
||||
function calcSupportEffectValue(config: SkillConfig, hpEff: number, apEff: number, cd: number, seconds: number): number {
|
||||
const weights = HERO_POWER_WEIGHTS;
|
||||
const value = config.ap || 0;
|
||||
|
||||
@@ -1131,10 +1131,12 @@ function calcSupportEffectValue(config: SkillConfig, apEff: number, cd: number,
|
||||
|
||||
switch (config.buff_type) {
|
||||
case Attrs.ap:
|
||||
return (value / cd) * weights.W_DPS_PER_SEC * seconds;
|
||||
// 永久 buff 已改为百分比口径:value 是百分比,需先换算为基础 ap 的绝对增量
|
||||
return ((value / 100) * apEff / cd) * weights.W_DPS_PER_SEC * seconds;
|
||||
case Attrs.hp_max:
|
||||
case Attrs.hp:
|
||||
return value * weights.W_HP;
|
||||
// 永久 buff 已改为百分比口径:value 是百分比,需先换算为基础 hp 的绝对增量
|
||||
return (value / 100) * hpEff * weights.W_HP;
|
||||
case Attrs.critical:
|
||||
return (value / 100) * (apEff / cd) * 0.5 * weights.W_DPS_PER_SEC * seconds;
|
||||
case Attrs.critical_damage:
|
||||
@@ -1154,7 +1156,7 @@ function calcSupportEffectValue(config: SkillConfig, apEff: number, cd: number,
|
||||
|
||||
/** 计算单条技能配置单次触发的效果价值 */
|
||||
function calcSkillEffectValue(skill: SkillConfig, overrides: SkillOverrides | undefined, hero: heroInfo, targetLv: number, seconds: number): number {
|
||||
const { ap: apEff } = getEffectiveStats(hero, targetLv);
|
||||
const { hp: hpEff, ap: apEff } = getEffectiveStats(hero, targetLv);
|
||||
const cd = getAttackCd(hero);
|
||||
const config = overrides ? mergeSkillParams(skill, overrides) : skill;
|
||||
const weights = HERO_POWER_WEIGHTS;
|
||||
@@ -1168,7 +1170,7 @@ function calcSkillEffectValue(skill: SkillConfig, overrides: SkillOverrides | un
|
||||
// 护盾为数值减免型:1 点护盾 ≈ 1 点预期伤害减免
|
||||
return (config.ap || 0) * weights.W_shield;
|
||||
case SkillKind.Support:
|
||||
return calcSupportEffectValue(config, apEff, cd, seconds);
|
||||
return calcSupportEffectValue(config, hpEff, apEff, cd, seconds);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
knockback_chance: number = 0; // 击退强化(原击退概率,现转换为击退距离增量)
|
||||
knockback_distance: number = 0; // 击退距离强化
|
||||
knockback_res: number = 0; // 击退抗性(削减击退距离增量)
|
||||
crit_damage: number = 0; // 额外暴击伤害
|
||||
critical_damage: number = 0; // 额外暴击伤害(与 Attrs.critical_damage 同名,供 add_special_attr 动态累加)
|
||||
puncture_chance: number = 0; // 穿透概率
|
||||
puncture_dmg_bonus: number = 0; // 穿透后伤害增量(百分点,乘算加成)
|
||||
wfuny: number = 0; // 风怒
|
||||
@@ -334,8 +334,8 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
|
||||
/** 英雄实时暴击伤害 = 基础额外暴伤 + 驻场暴伤。 */
|
||||
public getRuntimeCritDamageBonus(): number {
|
||||
if (this.fac !== FacSet.HERO) return this.crit_damage;
|
||||
return this.crit_damage + HeroAttrsComp.getFieldPercentValue(FieldSkillType.HeroCritDamage);
|
||||
if (this.fac !== FacSet.HERO) return this.critical_damage;
|
||||
return this.critical_damage + HeroAttrsComp.getFieldPercentValue(FieldSkillType.HeroCritDamage);
|
||||
}
|
||||
|
||||
/** 攻速加成通过缩短普通攻击技能 CD 生效,正值越高,攻击越快。 */
|
||||
@@ -606,7 +606,7 @@ export class HeroAttrsComp extends ecs.Comp {
|
||||
this.knockback_chance = 0;
|
||||
this.knockback_distance = 0;
|
||||
this.knockback_res = 0;
|
||||
this.crit_damage = 0;
|
||||
this.critical_damage = 0;
|
||||
this.revived_count = 0;
|
||||
this.invincible_time = 0;
|
||||
this.puncture_chance = 0;
|
||||
|
||||
@@ -4,6 +4,7 @@ import { HeroAttrsComp } from "./HeroAttrsComp";
|
||||
import { HeroViewComp } from "./HeroViewComp";
|
||||
import { DTType, RType, SkillConfig, SkillKind, SkillSet, TGroup, SkillOverrides, mergeSkillParams } from "../common/config/SkillSet";
|
||||
import { Skill } from "../skill/Skill";
|
||||
import { SkillView } from "../skill/SkillView";
|
||||
import { smc } from "../common/SingletonModuleComp";
|
||||
import { HeroDisVal, HeroInfo, HType } from "../common/config/heroSet";
|
||||
import { Attrs } from "../common/config/HeroAttrs";
|
||||
@@ -90,9 +91,11 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
targetEids = this.collectFriendlyTargetEids(FacSet.HERO, undefined, true); // 获取所有英雄阵营的目标
|
||||
}
|
||||
|
||||
// 多发次数由 overrides.num 提供(技能卡差异化多发),限制在 [0, 2]
|
||||
const cNum = Math.min(2, Math.max(0, Math.floor(overrides?.num ?? 0)));
|
||||
const castTimes = 1 + cNum;
|
||||
// 召唤数量由技能 prefab 的 SkillView.summon_count 决定;召唤类技能(>1)默认不再参与风怒多发
|
||||
const summonCount = this.resolveSummonCount(config);
|
||||
// 多发次数由 overrides.num 提供(技能卡差异化多发),限制在 [0, 2];召唤类技能屏蔽风怒多发
|
||||
const cNum = summonCount > 1 ? 0 : Math.min(2, Math.max(0, Math.floor(overrides?.num ?? 0)));
|
||||
const castTimes = Math.max(summonCount, 1 + cNum);
|
||||
|
||||
// 构造一个模拟的 HeroAttrsComp 用于数值计算,只包含基础卡牌伤害计算所需的属性
|
||||
const mockAttrs = new HeroAttrsComp();
|
||||
@@ -145,14 +148,23 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
|
||||
mLogger.log(this.debugMode, "SCastSystem", "forceCastCardSkill: casting skill", s_uuid, "castTimes", castTimes, "targetPos", targetPos, "isFriendly", isFriendly, "buff_value", config.buff_value, "timed_buff_id", config.timed_buff_id);
|
||||
for (let i = 0; i < castTimes; i++) {
|
||||
if (isFriendly) {
|
||||
const friendlyTargets = this.resolveFriendlyTargets(targetEids, FacSet.HERO);
|
||||
mLogger.log(this.debugMode, "SCastSystem", "friendlyTargets count =", friendlyTargets.length);
|
||||
if (friendlyTargets.length === 0) continue;
|
||||
this.applyFriendlySkillEffects(s_uuid, cardLv, config, null as any, mockAttrs, friendlyTargets, spawnPos);
|
||||
// 多发/召唤按间隔错峰执行:i=0 立即,其余延迟 i*SUMMON_INTERVAL(卡牌无施法主体,用 setTimeout 并在回调内做效期校验)
|
||||
const exec = () => {
|
||||
if (!smc.mission.play || smc.mission.pause) return;
|
||||
if (isFriendly) {
|
||||
const friendlyTargets = this.resolveFriendlyTargets(targetEids, FacSet.HERO);
|
||||
mLogger.log(this.debugMode, "SCastSystem", "friendlyTargets count =", friendlyTargets.length);
|
||||
if (friendlyTargets.length === 0) return;
|
||||
this.applyFriendlySkillEffects(s_uuid, cardLv, config, null as any, mockAttrs, friendlyTargets, spawnPos);
|
||||
} else {
|
||||
const enemyTargetPos = this.resolveRepeatCastTargetPos(targetPos, i);
|
||||
this.createSkillEntityForCard(s_uuid, cardLv, mockAttrs, spawnPos, enemyTargetPos, i, overrides);
|
||||
}
|
||||
};
|
||||
if (i === 0) {
|
||||
exec();
|
||||
} else {
|
||||
const enemyTargetPos = this.resolveRepeatCastTargetPos(targetPos, i);
|
||||
this.createSkillEntityForCard(s_uuid, cardLv, mockAttrs, spawnPos, enemyTargetPos, i, overrides);
|
||||
setTimeout(exec, i * FightSet.SUMMON_INTERVAL * 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -184,6 +196,29 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
/** 查询缓存:避免每帧重复创建 matcher */
|
||||
private heroMatcher: ecs.IMatcher | null = null;
|
||||
|
||||
/** 技能 prefab 召唤数量缓存:sp_name -> summon_count */
|
||||
private summonCountCache: Map<string, number> = new Map();
|
||||
|
||||
/**
|
||||
* 解析技能 prefab 上 SkillView.summon_count 配置的单次施法召唤数量。
|
||||
* 仅使用已缓存的 prefab(oops.res.get 同步命中),未加载时回退 1(单体),不引入异步等待。
|
||||
*/
|
||||
private resolveSummonCount(config: SkillConfig): number {
|
||||
const cached = this.summonCountCache.get(config.sp_name);
|
||||
if (cached !== undefined) return cached;
|
||||
const path = `game/skill/atk/${config.sp_name}`;
|
||||
let count = 1;
|
||||
const prefab = oops.res.get(path, Prefab) as Prefab | null;
|
||||
if (prefab) {
|
||||
const view = prefab.data?.getComponent(SkillView);
|
||||
if (view) {
|
||||
count = Math.max(1, Math.floor(view.summon_count));
|
||||
}
|
||||
this.summonCountCache.set(config.sp_name, count);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/** 获取英雄查询条件(包含属性与视图组件) */
|
||||
private getHeroMatcher(): ecs.IMatcher {
|
||||
if (!this.heroMatcher) {
|
||||
@@ -273,9 +308,11 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
}
|
||||
}
|
||||
|
||||
// 多发次数由 overrides.num 提供(技能卡差异化多发),限制在 [0, 2]
|
||||
const cNum = Math.min(2, Math.max(0, Math.floor(overrides?.num ?? 0)));
|
||||
const castTimes = 1 + cNum;
|
||||
// 召唤数量由技能 prefab 的 SkillView.summon_count 决定;召唤类技能(>1)默认不再参与风怒多发
|
||||
const summonCount = this.resolveSummonCount(config);
|
||||
// 多发次数由 overrides.num 提供(技能卡差异化多发),限制在 [0, 2];召唤类技能屏蔽风怒多发
|
||||
const cNum = summonCount > 1 ? 0 : Math.min(2, Math.max(0, Math.floor(overrides?.num ?? 0)));
|
||||
const castTimes = Math.max(summonCount, 1 + cNum);
|
||||
let val = ""
|
||||
if (castTimes > 1) {
|
||||
val = "*" + castTimes.toString
|
||||
@@ -283,14 +320,19 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
heroView.skill_name(val, s_uuid, triggerType)
|
||||
for (let i = 0; i < castTimes; i++) {
|
||||
if (!heroView.node || !heroView.node.isValid) return;
|
||||
if (isFriendly) {
|
||||
const friendlyTargets = this.resolveFriendlyTargets(targetEids, heroAttrs.fac);
|
||||
if (friendlyTargets.length === 0) continue;
|
||||
this.applyFriendlySkillEffects(s_uuid, skillLv, config, heroView, heroAttrs, friendlyTargets, null);
|
||||
} else {
|
||||
// 多发/召唤按间隔错峰执行:i=0 立即,其余延迟 i*SUMMON_INTERVAL
|
||||
heroView.scheduleOnce(() => {
|
||||
if (!smc.mission.play || smc.mission.pause) return;
|
||||
if (!heroView.node || !heroView.node.isValid || heroAttrs.is_dead) return;
|
||||
if (isFriendly) {
|
||||
const friendlyTargets = this.resolveFriendlyTargets(targetEids, heroAttrs.fac);
|
||||
if (friendlyTargets.length === 0) return;
|
||||
this.applyFriendlySkillEffects(s_uuid, skillLv, config, heroView, heroAttrs, friendlyTargets, null);
|
||||
return;
|
||||
}
|
||||
const enemyTargetPos = this.resolveRepeatCastTargetPos(targetPos, i);
|
||||
this.applyEnemySkillEffects(s_uuid, skillLv, config, heroView, heroAttrs, enemyTargetPos, i, overrides);
|
||||
}
|
||||
}, i * FightSet.SUMMON_INTERVAL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,12 +385,16 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
const skillLv = castPlan.skillLv;
|
||||
const overrides = castPlan.overrides;
|
||||
let config = SkillSet[s_uuid];
|
||||
// 多发次数由 overrides.num 提供(技能卡差异化多发),限制在 [0, 2]
|
||||
const cNum = Math.min(2, Math.max(0, Math.floor(overrides?.num ?? 0)));
|
||||
if (!config) return;
|
||||
|
||||
config = mergeSkillParams(config, overrides);
|
||||
|
||||
// 召唤数量由技能 prefab 的 SkillView.summon_count 决定;召唤类技能(>1)默认不再触发风怒
|
||||
const summonCount = this.resolveSummonCount(config);
|
||||
const isSummonSkill = summonCount > 1;
|
||||
// 多发次数由 overrides.num 提供(技能卡差异化多发),限制在 [0, 2];召唤类技能屏蔽风怒多发
|
||||
const cNum = isSummonSkill ? 0 : Math.min(2, Math.max(0, Math.floor(overrides?.num ?? 0)));
|
||||
|
||||
//播放前摇技能动画
|
||||
heroView.playReady(config.readyAnm);
|
||||
//播放角色攻击动画
|
||||
@@ -356,8 +402,9 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
|
||||
// 因为 castSkill 只由 update 循环调用,处理的必然是 heroAttrs.skills 中的普通技能
|
||||
// 特殊触发技能(call/dead/atking等)走的是 forceCastTriggerSkill,不会调用 castSkill
|
||||
// 召唤类技能(summon_count>1)不再计入普攻链,避免触发 atking(风怒类)附加技能
|
||||
const skillIds = heroAttrs.getSkillIds();
|
||||
if (skillIds.includes(s_uuid)) {
|
||||
if (!isSummonSkill && skillIds.includes(s_uuid)) {
|
||||
heroAttrs.atk_count++;
|
||||
this.checkAndTriggerAtkingSkills(heroAttrs, heroView);
|
||||
}
|
||||
@@ -370,18 +417,21 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
heroView.scheduleOnce(() => {
|
||||
if (!smc.mission.play || smc.mission.pause || !smc.mission.in_fight) return;
|
||||
if (!heroView.node || !heroView.node.isValid || heroAttrs.is_dead) return;
|
||||
const castTimes = 1 + cNum;
|
||||
const castTimes = Math.max(summonCount, 1 + cNum);
|
||||
for (let i = 0; i < castTimes; i++) {
|
||||
if (!smc.mission.play || smc.mission.pause || !smc.mission.in_fight) return;
|
||||
if (!heroView.node || !heroView.node.isValid || heroAttrs.is_dead) return;
|
||||
if (castPlan.isFriendly) {
|
||||
const friendlyTargets = this.resolveFriendlyTargets(castPlan.targetEids, heroAttrs.fac);
|
||||
if (friendlyTargets.length === 0) return;
|
||||
this.applyFriendlySkillEffects(s_uuid, skillLv, config, heroView, heroAttrs, friendlyTargets, null);
|
||||
continue;
|
||||
}
|
||||
const enemyTargetPos = this.resolveRepeatCastTargetPos(castPlan.targetPos, i);
|
||||
this.applyEnemySkillEffects(s_uuid, skillLv, config, heroView, heroAttrs, enemyTargetPos, i, overrides);
|
||||
// 多发/召唤按间隔错峰执行:i=0 立即,其余延迟 i*SUMMON_INTERVAL
|
||||
heroView.scheduleOnce(() => {
|
||||
if (!smc.mission.play || smc.mission.pause || !smc.mission.in_fight) return;
|
||||
if (!heroView.node || !heroView.node.isValid || heroAttrs.is_dead) return;
|
||||
if (castPlan.isFriendly) {
|
||||
const friendlyTargets = this.resolveFriendlyTargets(castPlan.targetEids, heroAttrs.fac);
|
||||
if (friendlyTargets.length === 0) return;
|
||||
this.applyFriendlySkillEffects(s_uuid, skillLv, config, heroView, heroAttrs, friendlyTargets, null);
|
||||
return;
|
||||
}
|
||||
const enemyTargetPos = this.resolveRepeatCastTargetPos(castPlan.targetPos, i);
|
||||
this.applyEnemySkillEffects(s_uuid, skillLv, config, heroView, heroAttrs, enemyTargetPos, i, overrides);
|
||||
}, i * FightSet.SUMMON_INTERVAL);
|
||||
}
|
||||
}, delay);
|
||||
heroAttrs.triggerSkillCD(s_uuid);
|
||||
@@ -392,11 +442,14 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
SkillTriggerHelper.trigger(SkillTriggerType.Atking, heroAttrs, heroView);
|
||||
}
|
||||
|
||||
/** 多发/召唤的纵向扇形偏移档位(像素),索引按 中/上/下/上上/下下... 循环 */
|
||||
private static readonly REPEAT_Y_OFFSETS: number[] = [0, 15, -15, 30, -30, 45, -45, 60, -60];
|
||||
|
||||
private resolveRepeatCastTargetPos(targetPos: Vec3 | null, castIndex: number): Vec3 | null {
|
||||
if (!targetPos) return null;
|
||||
if (castIndex === 1) return new Vec3(targetPos.x, targetPos.y + 15, targetPos.z);
|
||||
if (castIndex === 2) return new Vec3(targetPos.x, targetPos.y - 15, targetPos.z);
|
||||
return targetPos;
|
||||
const offset = SCastSystem.REPEAT_Y_OFFSETS[castIndex % SCastSystem.REPEAT_Y_OFFSETS.length];
|
||||
if (offset === 0) return targetPos;
|
||||
return new Vec3(targetPos.x, targetPos.y + offset, targetPos.z);
|
||||
}
|
||||
|
||||
/** 构建技能尝试顺序:优先主动技能,其次普攻 */
|
||||
@@ -431,9 +484,9 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
}
|
||||
|
||||
private resolveRepeatCastStartPos(startPos: Readonly<Vec3>, castIndex: number): Vec3 {
|
||||
if (castIndex === 1) return new Vec3(startPos.x, startPos.y + 15, startPos.z);
|
||||
if (castIndex === 2) return new Vec3(startPos.x, startPos.y - 15, startPos.z);
|
||||
return startPos.clone();
|
||||
const offset = SCastSystem.REPEAT_Y_OFFSETS[castIndex % SCastSystem.REPEAT_Y_OFFSETS.length];
|
||||
if (offset === 0) return startPos.clone();
|
||||
return new Vec3(startPos.x, startPos.y + offset, startPos.z);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -478,11 +531,6 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
} else if (kind === SkillKind.Shield && sAp !== 0) {
|
||||
const addShield = Math.max(0, Math.floor(sAp));
|
||||
model.add_shield(addShield);
|
||||
} else if (kind === SkillKind.Gold) {
|
||||
const addGold = config.gold ?? config.ap;
|
||||
if (addGold > 0) {
|
||||
MissionEconomy.addCoin(addGold);
|
||||
}
|
||||
}
|
||||
|
||||
if (config.buff_type !== undefined) {
|
||||
@@ -503,18 +551,24 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
|
||||
return;
|
||||
}
|
||||
|
||||
// 永久 buff 的数值直接取 config.ap(已由 SkillConfig/SkillOverrides 提供最终值)
|
||||
// 永久 buff 统一按百分比结算:攻击/生命按基础值相对放大,其余按百分点累加
|
||||
const totalBuffValue = config.ap;
|
||||
|
||||
switch (config.buff_type) {
|
||||
case Attrs.ap:
|
||||
model.add_ap(totalBuffValue);
|
||||
case Attrs.ap: {
|
||||
// 攻击力按基础 ap 的百分比提升
|
||||
const addAp = Math.floor(model.ap * totalBuffValue / 100);
|
||||
model.add_ap(addAp);
|
||||
break;
|
||||
case Attrs.hp_max:
|
||||
model.add_hp_max(totalBuffValue);
|
||||
}
|
||||
case Attrs.hp_max: {
|
||||
// 最大生命按基础 hp_max 的百分比提升
|
||||
const addHp = Math.floor(model.hp_max * totalBuffValue / 100);
|
||||
model.add_hp_max(addHp);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// 除了 hp_max 和 ap,其他固定属性走统一的 add_special_attr 方法
|
||||
// 暴击/击晕/穿透/攻速等概率类属性按百分点直接累加
|
||||
model.add_special_attr(config.buff_type, totalBuffValue);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -159,8 +159,17 @@ export class Skill extends ecs.Entity {
|
||||
SView.group = caster.box_group
|
||||
|
||||
this.add(SView);
|
||||
startPos.x = startPos.x + SView.atk_x * face
|
||||
startPos.y = startPos.y + SView.atk_y
|
||||
// 强制出生点:-1=不强制使用 atk_x/atk_y 偏移,>=0=强制世界坐标
|
||||
if (SView.forceStartX >= 0) {
|
||||
startPos.x = SView.forceStartX;
|
||||
} else {
|
||||
startPos.x = startPos.x + SView.atk_x * face;
|
||||
}
|
||||
if (SView.forceStartY >= 0) {
|
||||
startPos.y = SView.forceStartY;
|
||||
} else {
|
||||
startPos.y = startPos.y + SView.atk_y;
|
||||
}
|
||||
|
||||
node.setPosition(startPos);
|
||||
|
||||
@@ -179,7 +188,8 @@ export class Skill extends ecs.Entity {
|
||||
sMoveCom.endType = SView.endType;
|
||||
sMoveCom.speed = SView.speed > 0 ? SView.speed : config.speed;
|
||||
sMoveCom.bezierStartHeight = config.bezier_start_y ?? sMoveCom.bezierStartHeight;
|
||||
sMoveCom.bezierMidHeight = config.bezier_mid_y ?? sMoveCom.bezierMidHeight;
|
||||
// 抛射物高度增量:叠加视图层 height_offset,抬高贝塞尔弹道顶点
|
||||
sMoveCom.bezierMidHeight = (config.bezier_mid_y ?? sMoveCom.bezierMidHeight) + Math.max(0, SView.height_offset);
|
||||
sMoveCom.bezierArc = config.bezier_arc ?? sMoveCom.bezierArc;
|
||||
// 从SkillView获取移动参数,位置初始化由SMoveSystem统一处理
|
||||
sMoveCom.atk_x = SView.atk_x;
|
||||
|
||||
@@ -42,6 +42,22 @@ export class SkillView extends CCComp {
|
||||
@property({ type: CCFloat, slide: true, range: [0, 2000, 10], tooltip: "直线飞行距离(仅 linear 生效)" })
|
||||
distance: number = 0;
|
||||
|
||||
/** 强制出生点世界坐标X(-1=不强制,使用 atk_x 偏移;>=0 时强制使用该值,如 0=屏幕中心) */
|
||||
@property({ type: CCFloat, tooltip: "强制出生点X:-1=不强制,>=0=强制世界坐标X" })
|
||||
forceStartX: number = -1;
|
||||
|
||||
/** 强制出生点世界坐标Y(-1=不强制,使用 atk_y 偏移;>=0 时强制使用该值) */
|
||||
@property({ type: CCFloat, tooltip: "强制出生点Y:-1=不强制,>=0=强制世界坐标Y" })
|
||||
forceStartY: number = -1;
|
||||
|
||||
/** 召唤数量:SCastSystem 单次施法实例化的技能实体个数(<=1 为单体;>1 时按召唤物语义,不再参与风怒等额外触发) */
|
||||
@property({ type: CCInteger, slide: true, range: [1, 8, 1], tooltip: "单次施法召唤的技能实体个数" })
|
||||
summon_count: number = 1;
|
||||
|
||||
/** 抛射物高度增量(像素),贝塞尔弹道时叠加到 bezierMidHeight,控制抛物线顶点抬高 */
|
||||
@property({ type: CCFloat, slide: true, range: [0, 500, 5], tooltip: "抛射物高度增量(叠加到贝塞尔弹道中点高度)" })
|
||||
height_offset: number = 0;
|
||||
|
||||
private debugMode: boolean = false;
|
||||
|
||||
anim: Animation = null;
|
||||
|
||||
Reference in New Issue
Block a user