技能调试

master
humingxing 1 week ago
parent 10aca9fd25
commit e393880662
  1. 38
      assets/bundles/battleGameMonster/prefab/冰冻.prefab
  2. 239
      assets/bundles/battleHero/prefab/skill/冲锋.prefab
  3. 13
      assets/bundles/battleHero/prefab/skill/冲锋.prefab.meta
  4. 6
      assets/bundles/battleHero/prefab/skill/剑气.prefab
  5. 2
      assets/bundles/battleHero/prefab/skill/剑气.prefab.meta
  6. 239
      assets/bundles/battleHero/prefab/skill/土刺.prefab
  7. 13
      assets/bundles/battleHero/prefab/skill/土刺.prefab.meta
  8. 20
      assets/bundles/first/config/Level.json
  9. BIN
      assets/bundles/icons/weapon/土刺1.png
  10. 80
      assets/bundles/icons/weapon/土刺1.png.meta
  11. BIN
      assets/bundles/icons/weapon/土刺2.png
  12. 80
      assets/bundles/icons/weapon/土刺2.png.meta
  13. BIN
      assets/bundles/icons/weapon/土刺3.png
  14. 82
      assets/bundles/icons/weapon/土刺3.png.meta
  15. BIN
      assets/bundles/icons/weapon/土刺4.png
  16. 82
      assets/bundles/icons/weapon/土刺4.png.meta
  17. BIN
      assets/bundles/icons/weapon/土刺5.png
  18. 84
      assets/bundles/icons/weapon/土刺5.png.meta
  19. BIN
      assets/bundles/icons/weapon/地刺2.png
  20. 134
      assets/bundles/icons/weapon/地刺2.png.meta
  21. BIN
      assets/bundles/icons/weapon/地刺3.png
  22. 134
      assets/bundles/icons/weapon/地刺3.png.meta
  23. BIN
      assets/bundles/icons/weapon/地刺4.png
  24. 134
      assets/bundles/icons/weapon/地刺4.png.meta
  25. BIN
      assets/bundles/icons/weapon/地刺5.png
  26. 134
      assets/bundles/icons/weapon/地刺5.png.meta
  27. 13
      assets/res/battleGameWeapon/spine/like/技能特效/剑气x2/剑气.atlas
  28. 2
      assets/res/battleGameWeapon/spine/like/技能特效/剑气x2/剑气.json
  29. BIN
      assets/res/battleGameWeapon/spine/like/技能特效/剑气x2/剑气.png
  30. 20
      assets/res/battleGameWeapon/spine/like/技能特效/剑气x2/剑气.png.meta
  31. 255
      assets/scene/main.scene
  32. 4
      assets/script/battle/combat/PassiveSkillRuntime.ts
  33. 30
      assets/script/battle/config/baseAtk/SkillAbilityBuilder.ts
  34. 14
      assets/script/battle/config/weapon1/Weapon1BattleIds.ts
  35. 34
      assets/script/battle/presentation/AtkTypePresenters.ts
  36. 43
      assets/script/battle/presentation/BattleSpinePlayback.ts
  37. 538
      assets/script/battle/presentation/EarthChargePresenter.ts
  38. 9
      assets/script/battle/presentation/EarthChargePresenter.ts.meta
  39. 7
      assets/script/battle/presentation/NezhaChargePresenter.ts
  40. 2
      assets/script/battle/presentation/RingProjectilesPresenter.ts
  41. 142
      assets/script/battle/presentation/SkillVisualChannel.ts
  42. 3
      assets/script/battle/runtime/BattleRuntime.ts
  43. 74
      assets/script/battle/skill/Skill.ts
  44. 2
      assets/script/battle/skill/SkillController.ts
  45. 4
      assets/script/battle/view/CocosBattleCombatPresenter.ts
  46. 13
      assets/script/manager/BattleIllustratedGuideManager.ts
  47. 9
      docs/方案-Skill额外效果.md
  48. 5
      docs/方案-战斗技能逻辑层.md
  49. 5
      docs/方案-战斗表现数据驱动.md
  50. 46
      preview-template/index.ejs

@ -25,11 +25,11 @@
"_active": true,
"_components": [
{
"__id__": 10
"__id__": 12
}
],
"_prefab": {
"__id__": 12
"__id__": 14
},
"_lpos": {
"__type__": "cc.Vec3",
@ -79,15 +79,18 @@
},
{
"__id__": 7
},
{
"__id__": 9
}
],
"_prefab": {
"__id__": 9
"__id__": 11
},
"_lpos": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"y": 21.474,
"z": 0
},
"_lrot": {
@ -99,8 +102,8 @@
},
"_lscale": {
"__type__": "cc.Vec3",
"x": 1,
"y": 1,
"x": 1.2,
"y": 1.2,
"z": 1
},
"_mobility": 0,
@ -198,7 +201,7 @@
"__prefab": {
"__id__": 8
},
"_sortingLayer": 3,
"_sortingLayer": 4,
"_sortingOrder": 3,
"_id": ""
},
@ -206,6 +209,25 @@
"__type__": "cc.CompPrefabInfo",
"fileId": "31/vxsOuRNva4PPI7YuzDq"
},
{
"__type__": "cc.UIOpacity",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 2
},
"_enabled": true,
"__prefab": {
"__id__": 10
},
"_opacity": 180,
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "e4YjftPztGlZ5XMjFVpepe"
},
{
"__type__": "cc.PrefabInfo",
"root": {
@ -229,7 +251,7 @@
},
"_enabled": true,
"__prefab": {
"__id__": 11
"__id__": 13
},
"_contentSize": {
"__type__": "cc.Size",

@ -0,0 +1,239 @@
[
{
"__type__": "cc.Prefab",
"_name": "冲锋",
"_objFlags": 0,
"__editorExtras__": {},
"_native": "",
"data": {
"__id__": 1
},
"optimizationPolicy": 0,
"persistent": false
},
{
"__type__": "cc.Node",
"_name": "冲锋",
"_objFlags": 0,
"__editorExtras__": {},
"_parent": null,
"_children": [
{
"__id__": 2
}
],
"_active": true,
"_components": [
{
"__id__": 8
}
],
"_prefab": {
"__id__": 10
},
"_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": 33554432,
"_euler": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_id": ""
},
{
"__type__": "cc.Node",
"_name": "anim",
"_objFlags": 0,
"__editorExtras__": {},
"_parent": {
"__id__": 1
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 3
},
{
"__id__": 5
}
],
"_prefab": {
"__id__": 7
},
"_lpos": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_lrot": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 1,
"w": 6.123233995736766e-17
},
"_lscale": {
"__type__": "cc.Vec3",
"x": 1,
"y": 1,
"z": 1
},
"_mobility": 0,
"_layer": 33554432,
"_euler": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 180
},
"_id": ""
},
{
"__type__": "cc.UITransform",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 2
},
"_enabled": true,
"__prefab": {
"__id__": 4
},
"_contentSize": {
"__type__": "cc.Size",
"width": 73.52999877929688,
"height": 96.18000030517578
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5167958742126253,
"y": 0.46049075457472155
},
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "6dPq83nl1O5o9qTkimZ7R9"
},
{
"__type__": "sp.Skeleton",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 2
},
"_enabled": true,
"__prefab": {
"__id__": 6
},
"_customMaterial": null,
"_srcBlendFactor": 2,
"_dstBlendFactor": 4,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_skeletonData": {
"__uuid__": "542e1bba-b475-48e1-93b2-89480d605a79",
"__expectedType__": "sp.SkeletonData"
},
"defaultSkin": "default",
"defaultAnimation": "飞枪冲锋",
"_premultipliedAlpha": false,
"_timeScale": 1,
"_preCacheMode": 0,
"_cacheMode": 0,
"_sockets": [],
"_useTint": false,
"_debugMesh": false,
"_debugBones": false,
"_debugSlots": false,
"_enableBatch": false,
"loop": true,
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "63N5sjMbZDx7R+K9dcNiTs"
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__id__": 0
},
"fileId": "8fJAVQhwBGSKcm4lWgcbKD",
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": null
},
{
"__type__": "cc.UITransform",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 1
},
"_enabled": true,
"__prefab": {
"__id__": 9
},
"_contentSize": {
"__type__": "cc.Size",
"width": 200,
"height": 200
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "451RzMpQpFLalWlPKOafD2"
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__id__": 0
},
"fileId": "38JEit66ZI+Y7iGQ+17T7W",
"instance": null,
"targetOverrides": null
}
]

@ -0,0 +1,13 @@
{
"ver": "1.1.50",
"importer": "prefab",
"imported": true,
"uuid": "ddf958ce-0ad3-40fe-ab46-8a98be709de4",
"files": [
".json"
],
"subMetas": {},
"userData": {
"syncNodeName": "冲锋"
}
}

@ -1,7 +1,7 @@
[
{
"__type__": "cc.Prefab",
"_name": "玉帝刀光",
"_name": "剑气",
"_objFlags": 0,
"__editorExtras__": {},
"_native": "",
@ -13,7 +13,7 @@
},
{
"__type__": "cc.Node",
"_name": "玉帝刀光",
"_name": "剑气",
"_objFlags": 0,
"__editorExtras__": {},
"_parent": null,
@ -165,7 +165,7 @@
"__expectedType__": "sp.SkeletonData"
},
"defaultSkin": "default",
"defaultAnimation": "剑气红",
"defaultAnimation": "剑气金",
"_premultipliedAlpha": false,
"_timeScale": 1,
"_preCacheMode": 0,

@ -8,6 +8,6 @@
],
"subMetas": {},
"userData": {
"syncNodeName": "玉帝刀光"
"syncNodeName": "剑气"
}
}

@ -0,0 +1,239 @@
[
{
"__type__": "cc.Prefab",
"_name": "土刺",
"_objFlags": 0,
"__editorExtras__": {},
"_native": "",
"data": {
"__id__": 1
},
"optimizationPolicy": 0,
"persistent": false
},
{
"__type__": "cc.Node",
"_name": "土刺",
"_objFlags": 0,
"__editorExtras__": {},
"_parent": null,
"_children": [
{
"__id__": 2
}
],
"_active": true,
"_components": [
{
"__id__": 8
}
],
"_prefab": {
"__id__": 10
},
"_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": 33554432,
"_euler": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_id": ""
},
{
"__type__": "cc.Node",
"_name": "icon",
"_objFlags": 0,
"__editorExtras__": {},
"_parent": {
"__id__": 1
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 3
},
{
"__id__": 5
}
],
"_prefab": {
"__id__": 7
},
"_lpos": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_lrot": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 1,
"w": 6.123233995736766e-17
},
"_lscale": {
"__type__": "cc.Vec3",
"x": 1,
"y": 1,
"z": 1
},
"_mobility": 0,
"_layer": 33554432,
"_euler": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 180
},
"_id": ""
},
{
"__type__": "cc.UITransform",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 2
},
"_enabled": true,
"__prefab": {
"__id__": 4
},
"_contentSize": {
"__type__": "cc.Size",
"width": 139,
"height": 50
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "fdzTh+tYZEhI11kKqjFBe7"
},
{
"__type__": "cc.Sprite",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 2
},
"_enabled": true,
"__prefab": {
"__id__": 6
},
"_customMaterial": null,
"_srcBlendFactor": 2,
"_dstBlendFactor": 4,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_spriteFrame": {
"__uuid__": "84452a93-0349-435e-b732-8f7814e38a98@f9941",
"__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": "cfciGdRx1ORZesbsRtCqtj"
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__id__": 0
},
"fileId": "41giWeE6BPxKcxypzVJSnI",
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": null
},
{
"__type__": "cc.UITransform",
"_name": "",
"_objFlags": 0,
"__editorExtras__": {},
"node": {
"__id__": 1
},
"_enabled": true,
"__prefab": {
"__id__": 9
},
"_contentSize": {
"__type__": "cc.Size",
"width": 200,
"height": 200
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "451RzMpQpFLalWlPKOafD2"
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__id__": 0
},
"fileId": "38JEit66ZI+Y7iGQ+17T7W",
"instance": null,
"targetOverrides": null
}
]

@ -0,0 +1,13 @@
{
"ver": "1.1.50",
"importer": "prefab",
"imported": true,
"uuid": "33370061-8ff0-40ec-be91-e8560f564066",
"files": [
".json"
],
"subMetas": {},
"userData": {
"syncNodeName": "土刺"
}
}

@ -4,7 +4,7 @@
"name": "金系地图",
"desc": "",
"map": "mapLayer1",
"startnumber": 20,
"startnumber": 100,
"diffcult": 1,
"expdrop": "1101,10|1201,10|1301,10|1401,10|2101,5",
"reward": "",
@ -12,7 +12,7 @@
"monster": "1,101,10,1.6|2,101,11,1.6|3,101,12,1.6|4,101,13,1.6|5,101,15,1.6|6,101,16,1.6|7,101,18,1.6|8,101,19,1.6|9,101,21,1.6|10,101,24,1.6|11,101,26,1.6|12,101,29,1.6|13,101,30,1.6|14,101,35,1.6|15,101,38,1.6|16,101,42,1.6|17,101,45,1.6|18,101,50,1.6|19,101,50,1.6|20,101,50,1.6|21,101,50,1.6|22,101,50,1.6|23,101,50,1.6|24,101,50,1.6|25,101,50,1.6",
"boss": "3|105,6|106,9|107,12|105,15|106,18|107,21|106,24|107",
"bosspro": 1200,
"unlockland1": "0,3,5",
"unlockland1": "0,2,5",
"unlockland2": "0,4,5",
"unlockland3": "0,5,5|1,5,1|2,5,1|3,5,1|4,5,1|5,5,1",
"unlockland4": "0,6,5|1,6,1|2,6,1|3,6,1|4,6,1|5,6,1",
@ -41,7 +41,7 @@
"name": "木系地图",
"desc": "",
"map": "mapLayer2",
"startnumber": 20,
"startnumber": 100,
"diffcult": 1,
"expdrop": "1101,10|1201,10|1301,10|1401,10|3101,5",
"reward": "",
@ -49,7 +49,7 @@
"monster": "1,201,10,1.6|2,201,11,1.6|3,201,12,1.6|4,201,13,1.6|5,201,15,1.6|6,201,16,1.6|7,201,18,1.6|8,201,19,1.6|9,201,21,1.6|10,201,24,1.6|11,201,26,1.6|12,201,29,1.6|13,201,30,1.6|14,201,35,1.6|15,201,38,1.6|16,201,42,1.6|17,201,45,1.6|18,201,50,1.6|19,201,50,1.6|20,201,50,1.6|21,201,50,1.6|22,201,50,1.6|23,201,50,1.6|24,201,50,1.6|25,201,50,1.6",
"boss": "3|205,6|206,9|207,12|205,15|206,18|207,21|206,24|207",
"bosspro": 1200,
"unlockland1": "0,3,5",
"unlockland1": "0,2,5",
"unlockland2": "0,4,5",
"unlockland3": "0,5,5|1,5,1|2,5,1|3,5,1|4,5,1|5,5,1",
"unlockland4": "0,6,5|1,6,1|2,6,1|3,6,1|4,6,1|5,6,1",
@ -78,7 +78,7 @@
"name": "水系地图",
"desc": "",
"map": "mapLayer3",
"startnumber": 20,
"startnumber": 100,
"diffcult": 1,
"expdrop": "1101,10|1201,10|1301,10|1401,10|4101,5",
"reward": "",
@ -86,7 +86,7 @@
"monster": "1,301,10,1.6|2,301,11,1.6|3,301,12,1.6|4,301,13,1.6|5,301,15,1.6|6,301,16,1.6|7,301,18,1.6|8,301,19,1.6|9,301,21,1.6|10,301,24,1.6|11,301,26,1.6|12,301,29,1.6|13,301,30,1.6|14,301,35,1.6|15,301,38,1.6|16,301,42,1.6|17,301,45,1.6|18,301,50,1.6|19,301,50,1.6|20,301,50,1.6|21,301,50,1.6|22,301,50,1.6|23,301,50,1.6|24,301,50,1.6|25,301,50,1.6",
"boss": "3|305,6|306,9|307,12|305,15|306,18|307,21|306,24|307",
"bosspro": 1200,
"unlockland1": "0,3,5",
"unlockland1": "0,2,5",
"unlockland2": "0,4,5",
"unlockland3": "0,5,5|1,5,1|2,5,1|3,5,1|4,5,1|5,5,1",
"unlockland4": "0,6,5|1,6,1|2,6,1|3,6,1|4,6,1|5,6,1",
@ -115,7 +115,7 @@
"name": "火系地图",
"desc": "",
"map": "mapLayer4",
"startnumber": 20,
"startnumber": 100,
"diffcult": 1,
"expdrop": "1101,10|1201,10|1301,10|1401,10|5101,5",
"reward": "",
@ -123,7 +123,7 @@
"monster": "1,401,10,1.6|2,401,11,1.6|3,401,12,1.6|4,401,13,1.6|5,401,15,1.6|6,401,16,1.6|7,401,18,1.6|8,401,19,1.6|9,401,21,1.6|10,401,24,1.6|11,401,26,1.6|12,401,29,1.6|13,401,30,1.6|14,401,35,1.6|15,401,38,1.6|16,401,42,1.6|17,401,45,1.6|18,401,50,1.6|19,401,50,1.6|20,401,50,1.6|21,401,50,1.6|22,401,50,1.6|23,401,50,1.6|24,401,50,1.6|25,401,50,1.6",
"boss": "3|405,6|406,9|407,12|405,15|406,18|407,21|406,24|407",
"bosspro": 1200,
"unlockland1": "0,3,5",
"unlockland1": "0,2,5",
"unlockland2": "0,4,5",
"unlockland3": "0,5,5|1,5,1|2,5,1|3,5,1|4,5,1|5,5,1",
"unlockland4": "0,6,5|1,6,1|2,6,1|3,6,1|4,6,1|5,6,1",
@ -152,7 +152,7 @@
"name": "土系地图",
"desc": "",
"map": "mapLayer5",
"startnumber": 20,
"startnumber": 100,
"diffcult": 1,
"expdrop": "1101,10|1201,10|1301,10|1401,10|6101,5",
"reward": "",
@ -160,7 +160,7 @@
"monster": "1,101,10,1.6|2,101,11,1.6|3,101,12,1.6|4,101,13,1.6|5,101,15,1.6|6,101,16,1.6|7,101,18,1.6|8,101,19,1.6|9,101,21,1.6|10,101,24,1.6|11,101,26,1.6|12,101,29,1.6|13,101,30,1.6|14,101,35,1.6|15,101,38,1.6|16,101,42,1.6|17,101,45,1.6|18,101,50,1.6|19,101,50,1.6|20,101,50,1.6|21,101,50,1.6|22,101,50,1.6|23,101,50,1.6|24,101,50,1.6|25,101,50,1.6",
"boss": "3|105,6|106,9|107,12|105,15|106,18|107,21|106,24|107",
"bosspro": 1200,
"unlockland1": "0,3,5",
"unlockland1": "0,2,5",
"unlockland2": "0,4,5",
"unlockland3": "0,5,5|1,5,1|2,5,1|3,5,1|4,5,1|5,5,1",
"unlockland4": "0,6,5|1,6,1|2,6,1|3,6,1|4,6,1|5,6,1",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 49 KiB

@ -2,7 +2,7 @@
"ver": "1.0.27",
"importer": "image",
"imported": true,
"uuid": "436f23e3-a300-49a5-8404-94bfc4a1cf99",
"uuid": "e9d895bc-ccdf-481f-b5cc-c67c551469b5",
"files": [
".json",
".png"
@ -10,14 +10,14 @@
"subMetas": {
"6c48a": {
"importer": "texture",
"uuid": "436f23e3-a300-49a5-8404-94bfc4a1cf99@6c48a",
"uuid": "e9d895bc-ccdf-481f-b5cc-c67c551469b5@6c48a",
"displayName": "土刺1",
"id": "6c48a",
"name": "texture",
"userData": {
"wrapModeS": "clamp-to-edge",
"wrapModeT": "clamp-to-edge",
"imageUuidOrDatabaseUri": "436f23e3-a300-49a5-8404-94bfc4a1cf99",
"imageUuidOrDatabaseUri": "e9d895bc-ccdf-481f-b5cc-c67c551469b5",
"isUuid": true,
"visible": false,
"minfilter": "linear",
@ -34,7 +34,7 @@
},
"f9941": {
"importer": "sprite-frame",
"uuid": "436f23e3-a300-49a5-8404-94bfc4a1cf99@f9941",
"uuid": "e9d895bc-ccdf-481f-b5cc-c67c551469b5@f9941",
"displayName": "土刺1",
"id": "f9941",
"name": "spriteFrame",
@ -43,12 +43,12 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 137,
"height": 36,
"rawWidth": 137,
"rawHeight": 36,
"trimX": 24,
"trimY": 30,
"width": 152,
"height": 140,
"rawWidth": 200,
"rawHeight": 200,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
@ -60,17 +60,17 @@
"meshType": 0,
"vertices": {
"rawPosition": [
-68.5,
-18,
-76,
-70,
0,
68.5,
-18,
76,
-70,
0,
-68.5,
18,
-76,
70,
0,
68.5,
18,
76,
70,
0
],
"indexes": [
@ -82,38 +82,38 @@
3
],
"uv": [
0,
36,
137,
36,
0,
0,
137,
0
24,
170,
176,
170,
24,
30,
176,
30
],
"nuv": [
0,
0,
1,
0,
0,
1,
1,
1
0.12,
0.15,
0.88,
0.15,
0.12,
0.85,
0.88,
0.85
],
"minPos": [
-68.5,
-18,
-76,
-70,
0
],
"maxPos": [
68.5,
18,
76,
70,
0
]
},
"isUuid": true,
"imageUuidOrDatabaseUri": "436f23e3-a300-49a5-8404-94bfc4a1cf99@6c48a",
"imageUuidOrDatabaseUri": "e9d895bc-ccdf-481f-b5cc-c67c551469b5@6c48a",
"atlasUuid": "",
"trimType": "auto"
},
@ -129,6 +129,6 @@
"type": "sprite-frame",
"fixAlphaTransparencyArtifacts": false,
"hasAlpha": true,
"redirect": "436f23e3-a300-49a5-8404-94bfc4a1cf99@6c48a"
"redirect": "e9d895bc-ccdf-481f-b5cc-c67c551469b5@6c48a"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 49 KiB

@ -2,7 +2,7 @@
"ver": "1.0.27",
"importer": "image",
"imported": true,
"uuid": "00e5484b-1cf2-46ae-9c2a-c2e44e101abc",
"uuid": "8a89f72b-42ea-494d-9a21-4dc500334374",
"files": [
".json",
".png"
@ -10,14 +10,14 @@
"subMetas": {
"6c48a": {
"importer": "texture",
"uuid": "00e5484b-1cf2-46ae-9c2a-c2e44e101abc@6c48a",
"uuid": "8a89f72b-42ea-494d-9a21-4dc500334374@6c48a",
"displayName": "土刺2",
"id": "6c48a",
"name": "texture",
"userData": {
"wrapModeS": "clamp-to-edge",
"wrapModeT": "clamp-to-edge",
"imageUuidOrDatabaseUri": "00e5484b-1cf2-46ae-9c2a-c2e44e101abc",
"imageUuidOrDatabaseUri": "8a89f72b-42ea-494d-9a21-4dc500334374",
"isUuid": true,
"visible": false,
"minfilter": "linear",
@ -34,7 +34,7 @@
},
"f9941": {
"importer": "sprite-frame",
"uuid": "00e5484b-1cf2-46ae-9c2a-c2e44e101abc@f9941",
"uuid": "8a89f72b-42ea-494d-9a21-4dc500334374@f9941",
"displayName": "土刺2",
"id": "f9941",
"name": "spriteFrame",
@ -43,12 +43,12 @@
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 137,
"height": 36,
"rawWidth": 137,
"rawHeight": 36,
"trimX": 24,
"trimY": 30,
"width": 152,
"height": 140,
"rawWidth": 200,
"rawHeight": 200,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
@ -60,17 +60,17 @@
"meshType": 0,
"vertices": {
"rawPosition": [
-68.5,
-18,
-76,
-70,
0,
68.5,
-18,
76,
-70,
0,
-68.5,
18,
-76,
70,
0,
68.5,
18,
76,
70,
0
],
"indexes": [
@ -82,38 +82,38 @@
3
],
"uv": [
0,
36,
137,
36,
0,
0,
137,
0
24,
170,
176,
170,
24,
30,
176,
30
],
"nuv": [
0,
0,
1,
0,
0,
1,
1,
1
0.12,
0.15,
0.88,
0.15,
0.12,
0.85,
0.88,
0.85
],
"minPos": [
-68.5,
-18,
-76,
-70,
0
],
"maxPos": [
68.5,
18,
76,
70,
0
]
},
"isUuid": true,
"imageUuidOrDatabaseUri": "00e5484b-1cf2-46ae-9c2a-c2e44e101abc@6c48a",
"imageUuidOrDatabaseUri": "8a89f72b-42ea-494d-9a21-4dc500334374@6c48a",
"atlasUuid": "",
"trimType": "auto"
},
@ -129,6 +129,6 @@
"type": "sprite-frame",
"fixAlphaTransparencyArtifacts": false,
"hasAlpha": true,
"redirect": "00e5484b-1cf2-46ae-9c2a-c2e44e101abc@6c48a"
"redirect": "8a89f72b-42ea-494d-9a21-4dc500334374@6c48a"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 46 KiB

@ -2,7 +2,7 @@
"ver": "1.0.27",
"importer": "image",
"imported": true,
"uuid": "985f55ec-dc5c-49bf-8396-20fa5200b9ee",
"uuid": "5d412788-43dc-4908-9ae0-8dcba40f865c",
"files": [
".json",
".png"
@ -10,14 +10,14 @@
"subMetas": {
"6c48a": {
"importer": "texture",
"uuid": "985f55ec-dc5c-49bf-8396-20fa5200b9ee@6c48a",
"uuid": "5d412788-43dc-4908-9ae0-8dcba40f865c@6c48a",
"displayName": "土刺3",
"id": "6c48a",
"name": "texture",
"userData": {
"wrapModeS": "clamp-to-edge",
"wrapModeT": "clamp-to-edge",
"imageUuidOrDatabaseUri": "985f55ec-dc5c-49bf-8396-20fa5200b9ee",
"imageUuidOrDatabaseUri": "5d412788-43dc-4908-9ae0-8dcba40f865c",
"isUuid": true,
"visible": false,
"minfilter": "linear",
@ -34,7 +34,7 @@
},
"f9941": {
"importer": "sprite-frame",
"uuid": "985f55ec-dc5c-49bf-8396-20fa5200b9ee@f9941",
"uuid": "5d412788-43dc-4908-9ae0-8dcba40f865c@f9941",
"displayName": "土刺3",
"id": "f9941",
"name": "spriteFrame",
@ -42,13 +42,13 @@
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 137,
"height": 36,
"rawWidth": 137,
"rawHeight": 36,
"offsetY": 0.5,
"trimX": 26,
"trimY": 20,
"width": 148,
"height": 159,
"rawWidth": 200,
"rawHeight": 200,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
@ -60,17 +60,17 @@
"meshType": 0,
"vertices": {
"rawPosition": [
-68.5,
-18,
-74,
-79.5,
0,
68.5,
-18,
74,
-79.5,
0,
-68.5,
18,
-74,
79.5,
0,
68.5,
18,
74,
79.5,
0
],
"indexes": [
@ -82,38 +82,38 @@
3
],
"uv": [
0,
36,
137,
36,
0,
0,
137,
0
26,
180,
174,
180,
26,
21,
174,
21
],
"nuv": [
0,
0,
1,
0,
0,
1,
1,
1
0.13,
0.105,
0.87,
0.105,
0.13,
0.9,
0.87,
0.9
],
"minPos": [
-68.5,
-18,
-74,
-79.5,
0
],
"maxPos": [
68.5,
18,
74,
79.5,
0
]
},
"isUuid": true,
"imageUuidOrDatabaseUri": "985f55ec-dc5c-49bf-8396-20fa5200b9ee@6c48a",
"imageUuidOrDatabaseUri": "5d412788-43dc-4908-9ae0-8dcba40f865c@6c48a",
"atlasUuid": "",
"trimType": "auto"
},
@ -129,6 +129,6 @@
"type": "sprite-frame",
"fixAlphaTransparencyArtifacts": false,
"hasAlpha": true,
"redirect": "985f55ec-dc5c-49bf-8396-20fa5200b9ee@6c48a"
"redirect": "5d412788-43dc-4908-9ae0-8dcba40f865c@6c48a"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 57 KiB

@ -2,7 +2,7 @@
"ver": "1.0.27",
"importer": "image",
"imported": true,
"uuid": "e1cbc8df-09ad-407f-9f02-b5a5731d2467",
"uuid": "eb06c713-ba2b-43b6-b730-9cf887f91acf",
"files": [
".json",
".png"
@ -10,14 +10,14 @@
"subMetas": {
"6c48a": {
"importer": "texture",
"uuid": "e1cbc8df-09ad-407f-9f02-b5a5731d2467@6c48a",
"uuid": "eb06c713-ba2b-43b6-b730-9cf887f91acf@6c48a",
"displayName": "土刺4",
"id": "6c48a",
"name": "texture",
"userData": {
"wrapModeS": "clamp-to-edge",
"wrapModeT": "clamp-to-edge",
"imageUuidOrDatabaseUri": "e1cbc8df-09ad-407f-9f02-b5a5731d2467",
"imageUuidOrDatabaseUri": "eb06c713-ba2b-43b6-b730-9cf887f91acf",
"isUuid": true,
"visible": false,
"minfilter": "linear",
@ -34,21 +34,21 @@
},
"f9941": {
"importer": "sprite-frame",
"uuid": "e1cbc8df-09ad-407f-9f02-b5a5731d2467@f9941",
"uuid": "eb06c713-ba2b-43b6-b730-9cf887f91acf@f9941",
"displayName": "土刺4",
"id": "f9941",
"name": "spriteFrame",
"userData": {
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetX": -0.5,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 137,
"height": 36,
"rawWidth": 137,
"rawHeight": 36,
"trimX": 16,
"trimY": 25,
"width": 167,
"height": 150,
"rawWidth": 200,
"rawHeight": 200,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
@ -60,17 +60,17 @@
"meshType": 0,
"vertices": {
"rawPosition": [
-68.5,
-18,
-83.5,
-75,
0,
68.5,
-18,
83.5,
-75,
0,
-68.5,
18,
-83.5,
75,
0,
68.5,
18,
83.5,
75,
0
],
"indexes": [
@ -82,38 +82,38 @@
3
],
"uv": [
0,
36,
137,
36,
0,
0,
137,
0
16,
175,
183,
175,
16,
25,
183,
25
],
"nuv": [
0,
0,
1,
0,
0,
1,
1,
1
0.08,
0.125,
0.915,
0.125,
0.08,
0.875,
0.915,
0.875
],
"minPos": [
-68.5,
-18,
-83.5,
-75,
0
],
"maxPos": [
68.5,
18,
83.5,
75,
0
]
},
"isUuid": true,
"imageUuidOrDatabaseUri": "e1cbc8df-09ad-407f-9f02-b5a5731d2467@6c48a",
"imageUuidOrDatabaseUri": "eb06c713-ba2b-43b6-b730-9cf887f91acf@6c48a",
"atlasUuid": "",
"trimType": "auto"
},
@ -129,6 +129,6 @@
"type": "sprite-frame",
"fixAlphaTransparencyArtifacts": false,
"hasAlpha": true,
"redirect": "e1cbc8df-09ad-407f-9f02-b5a5731d2467@6c48a"
"redirect": "eb06c713-ba2b-43b6-b730-9cf887f91acf@6c48a"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 53 KiB

@ -2,7 +2,7 @@
"ver": "1.0.27",
"importer": "image",
"imported": true,
"uuid": "564b4190-c118-4f9c-8363-5bd2d9908387",
"uuid": "57095dc9-bab4-4732-8a52-98135b49c8a0",
"files": [
".json",
".png"
@ -10,14 +10,14 @@
"subMetas": {
"6c48a": {
"importer": "texture",
"uuid": "564b4190-c118-4f9c-8363-5bd2d9908387@6c48a",
"uuid": "57095dc9-bab4-4732-8a52-98135b49c8a0@6c48a",
"displayName": "土刺5",
"id": "6c48a",
"name": "texture",
"userData": {
"wrapModeS": "clamp-to-edge",
"wrapModeT": "clamp-to-edge",
"imageUuidOrDatabaseUri": "564b4190-c118-4f9c-8363-5bd2d9908387",
"imageUuidOrDatabaseUri": "57095dc9-bab4-4732-8a52-98135b49c8a0",
"isUuid": true,
"visible": false,
"minfilter": "linear",
@ -34,21 +34,21 @@
},
"f9941": {
"importer": "sprite-frame",
"uuid": "564b4190-c118-4f9c-8363-5bd2d9908387@f9941",
"uuid": "57095dc9-bab4-4732-8a52-98135b49c8a0@f9941",
"displayName": "土刺5",
"id": "f9941",
"name": "spriteFrame",
"userData": {
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 137,
"height": 36,
"rawWidth": 137,
"rawHeight": 36,
"offsetX": -0.5,
"offsetY": 0.5,
"trimX": 17,
"trimY": 20,
"width": 165,
"height": 159,
"rawWidth": 200,
"rawHeight": 200,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
@ -60,17 +60,17 @@
"meshType": 0,
"vertices": {
"rawPosition": [
-68.5,
-18,
-82.5,
-79.5,
0,
68.5,
-18,
82.5,
-79.5,
0,
-68.5,
18,
-82.5,
79.5,
0,
68.5,
18,
82.5,
79.5,
0
],
"indexes": [
@ -82,38 +82,38 @@
3
],
"uv": [
0,
36,
137,
36,
0,
0,
137,
0
17,
180,
182,
180,
17,
21,
182,
21
],
"nuv": [
0,
0,
1,
0,
0,
1,
1,
1
0.085,
0.105,
0.91,
0.105,
0.085,
0.9,
0.91,
0.9
],
"minPos": [
-68.5,
-18,
-82.5,
-79.5,
0
],
"maxPos": [
68.5,
18,
82.5,
79.5,
0
]
},
"isUuid": true,
"imageUuidOrDatabaseUri": "564b4190-c118-4f9c-8363-5bd2d9908387@6c48a",
"imageUuidOrDatabaseUri": "57095dc9-bab4-4732-8a52-98135b49c8a0@6c48a",
"atlasUuid": "",
"trimType": "auto"
},
@ -129,6 +129,6 @@
"type": "sprite-frame",
"fixAlphaTransparencyArtifacts": false,
"hasAlpha": true,
"redirect": "564b4190-c118-4f9c-8363-5bd2d9908387@6c48a"
"redirect": "57095dc9-bab4-4732-8a52-98135b49c8a0@6c48a"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

@ -1,134 +0,0 @@
{
"ver": "1.0.27",
"importer": "image",
"imported": true,
"uuid": "e9d895bc-ccdf-481f-b5cc-c67c551469b5",
"files": [
".json",
".png"
],
"subMetas": {
"6c48a": {
"importer": "texture",
"uuid": "e9d895bc-ccdf-481f-b5cc-c67c551469b5@6c48a",
"displayName": "地刺2",
"id": "6c48a",
"name": "texture",
"userData": {
"wrapModeS": "clamp-to-edge",
"wrapModeT": "clamp-to-edge",
"imageUuidOrDatabaseUri": "e9d895bc-ccdf-481f-b5cc-c67c551469b5",
"isUuid": true,
"visible": false,
"minfilter": "linear",
"magfilter": "linear",
"mipfilter": "none",
"anisotropy": 0
},
"ver": "1.0.22",
"imported": true,
"files": [
".json"
],
"subMetas": {}
},
"f9941": {
"importer": "sprite-frame",
"uuid": "e9d895bc-ccdf-481f-b5cc-c67c551469b5@f9941",
"displayName": "地刺2",
"id": "f9941",
"name": "spriteFrame",
"userData": {
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0,
"trimX": 24,
"trimY": 30,
"width": 152,
"height": 140,
"rawWidth": 200,
"rawHeight": 200,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"packable": true,
"pixelsToUnit": 100,
"pivotX": 0.5,
"pivotY": 0.5,
"meshType": 0,
"vertices": {
"rawPosition": [
-76,
-70,
0,
76,
-70,
0,
-76,
70,
0,
76,
70,
0
],
"indexes": [
0,
1,
2,
2,
1,
3
],
"uv": [
24,
170,
176,
170,
24,
30,
176,
30
],
"nuv": [
0.12,
0.15,
0.88,
0.15,
0.12,
0.85,
0.88,
0.85
],
"minPos": [
-76,
-70,
0
],
"maxPos": [
76,
70,
0
]
},
"isUuid": true,
"imageUuidOrDatabaseUri": "e9d895bc-ccdf-481f-b5cc-c67c551469b5@6c48a",
"atlasUuid": "",
"trimType": "auto"
},
"ver": "1.0.12",
"imported": true,
"files": [
".json"
],
"subMetas": {}
}
},
"userData": {
"type": "sprite-frame",
"fixAlphaTransparencyArtifacts": false,
"hasAlpha": true,
"redirect": "e9d895bc-ccdf-481f-b5cc-c67c551469b5@6c48a"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

@ -1,134 +0,0 @@
{
"ver": "1.0.27",
"importer": "image",
"imported": true,
"uuid": "5d412788-43dc-4908-9ae0-8dcba40f865c",
"files": [
".json",
".png"
],
"subMetas": {
"6c48a": {
"importer": "texture",
"uuid": "5d412788-43dc-4908-9ae0-8dcba40f865c@6c48a",
"displayName": "地刺3",
"id": "6c48a",
"name": "texture",
"userData": {
"wrapModeS": "clamp-to-edge",
"wrapModeT": "clamp-to-edge",
"imageUuidOrDatabaseUri": "5d412788-43dc-4908-9ae0-8dcba40f865c",
"isUuid": true,
"visible": false,
"minfilter": "linear",
"magfilter": "linear",
"mipfilter": "none",
"anisotropy": 0
},
"ver": "1.0.22",
"imported": true,
"files": [
".json"
],
"subMetas": {}
},
"f9941": {
"importer": "sprite-frame",
"uuid": "5d412788-43dc-4908-9ae0-8dcba40f865c@f9941",
"displayName": "地刺3",
"id": "f9941",
"name": "spriteFrame",
"userData": {
"trimThreshold": 1,
"rotated": false,
"offsetX": 0,
"offsetY": 0.5,
"trimX": 26,
"trimY": 20,
"width": 148,
"height": 159,
"rawWidth": 200,
"rawHeight": 200,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"packable": true,
"pixelsToUnit": 100,
"pivotX": 0.5,
"pivotY": 0.5,
"meshType": 0,
"vertices": {
"rawPosition": [
-74,
-79.5,
0,
74,
-79.5,
0,
-74,
79.5,
0,
74,
79.5,
0
],
"indexes": [
0,
1,
2,
2,
1,
3
],
"uv": [
26,
180,
174,
180,
26,
21,
174,
21
],
"nuv": [
0.13,
0.105,
0.87,
0.105,
0.13,
0.9,
0.87,
0.9
],
"minPos": [
-74,
-79.5,
0
],
"maxPos": [
74,
79.5,
0
]
},
"isUuid": true,
"imageUuidOrDatabaseUri": "5d412788-43dc-4908-9ae0-8dcba40f865c@6c48a",
"atlasUuid": "",
"trimType": "auto"
},
"ver": "1.0.12",
"imported": true,
"files": [
".json"
],
"subMetas": {}
}
},
"userData": {
"type": "sprite-frame",
"fixAlphaTransparencyArtifacts": false,
"hasAlpha": true,
"redirect": "5d412788-43dc-4908-9ae0-8dcba40f865c@6c48a"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

@ -1,134 +0,0 @@
{
"ver": "1.0.27",
"importer": "image",
"imported": true,
"uuid": "eb06c713-ba2b-43b6-b730-9cf887f91acf",
"files": [
".json",
".png"
],
"subMetas": {
"6c48a": {
"importer": "texture",
"uuid": "eb06c713-ba2b-43b6-b730-9cf887f91acf@6c48a",
"displayName": "地刺4",
"id": "6c48a",
"name": "texture",
"userData": {
"wrapModeS": "clamp-to-edge",
"wrapModeT": "clamp-to-edge",
"imageUuidOrDatabaseUri": "eb06c713-ba2b-43b6-b730-9cf887f91acf",
"isUuid": true,
"visible": false,
"minfilter": "linear",
"magfilter": "linear",
"mipfilter": "none",
"anisotropy": 0
},
"ver": "1.0.22",
"imported": true,
"files": [
".json"
],
"subMetas": {}
},
"f9941": {
"importer": "sprite-frame",
"uuid": "eb06c713-ba2b-43b6-b730-9cf887f91acf@f9941",
"displayName": "地刺4",
"id": "f9941",
"name": "spriteFrame",
"userData": {
"trimThreshold": 1,
"rotated": false,
"offsetX": -0.5,
"offsetY": 0,
"trimX": 16,
"trimY": 25,
"width": 167,
"height": 150,
"rawWidth": 200,
"rawHeight": 200,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"packable": true,
"pixelsToUnit": 100,
"pivotX": 0.5,
"pivotY": 0.5,
"meshType": 0,
"vertices": {
"rawPosition": [
-83.5,
-75,
0,
83.5,
-75,
0,
-83.5,
75,
0,
83.5,
75,
0
],
"indexes": [
0,
1,
2,
2,
1,
3
],
"uv": [
16,
175,
183,
175,
16,
25,
183,
25
],
"nuv": [
0.08,
0.125,
0.915,
0.125,
0.08,
0.875,
0.915,
0.875
],
"minPos": [
-83.5,
-75,
0
],
"maxPos": [
83.5,
75,
0
]
},
"isUuid": true,
"imageUuidOrDatabaseUri": "eb06c713-ba2b-43b6-b730-9cf887f91acf@6c48a",
"atlasUuid": "",
"trimType": "auto"
},
"ver": "1.0.12",
"imported": true,
"files": [
".json"
],
"subMetas": {}
}
},
"userData": {
"type": "sprite-frame",
"fixAlphaTransparencyArtifacts": false,
"hasAlpha": true,
"redirect": "eb06c713-ba2b-43b6-b730-9cf887f91acf@6c48a"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

@ -1,134 +0,0 @@
{
"ver": "1.0.27",
"importer": "image",
"imported": true,
"uuid": "57095dc9-bab4-4732-8a52-98135b49c8a0",
"files": [
".json",
".png"
],
"subMetas": {
"6c48a": {
"importer": "texture",
"uuid": "57095dc9-bab4-4732-8a52-98135b49c8a0@6c48a",
"displayName": "地刺5",
"id": "6c48a",
"name": "texture",
"userData": {
"wrapModeS": "clamp-to-edge",
"wrapModeT": "clamp-to-edge",
"imageUuidOrDatabaseUri": "57095dc9-bab4-4732-8a52-98135b49c8a0",
"isUuid": true,
"visible": false,
"minfilter": "linear",
"magfilter": "linear",
"mipfilter": "none",
"anisotropy": 0
},
"ver": "1.0.22",
"imported": true,
"files": [
".json"
],
"subMetas": {}
},
"f9941": {
"importer": "sprite-frame",
"uuid": "57095dc9-bab4-4732-8a52-98135b49c8a0@f9941",
"displayName": "地刺5",
"id": "f9941",
"name": "spriteFrame",
"userData": {
"trimThreshold": 1,
"rotated": false,
"offsetX": -0.5,
"offsetY": 0.5,
"trimX": 17,
"trimY": 20,
"width": 165,
"height": 159,
"rawWidth": 200,
"rawHeight": 200,
"borderTop": 0,
"borderBottom": 0,
"borderLeft": 0,
"borderRight": 0,
"packable": true,
"pixelsToUnit": 100,
"pivotX": 0.5,
"pivotY": 0.5,
"meshType": 0,
"vertices": {
"rawPosition": [
-82.5,
-79.5,
0,
82.5,
-79.5,
0,
-82.5,
79.5,
0,
82.5,
79.5,
0
],
"indexes": [
0,
1,
2,
2,
1,
3
],
"uv": [
17,
180,
182,
180,
17,
21,
182,
21
],
"nuv": [
0.085,
0.105,
0.91,
0.105,
0.085,
0.9,
0.91,
0.9
],
"minPos": [
-82.5,
-79.5,
0
],
"maxPos": [
82.5,
79.5,
0
]
},
"isUuid": true,
"imageUuidOrDatabaseUri": "57095dc9-bab4-4732-8a52-98135b49c8a0@6c48a",
"atlasUuid": "",
"trimType": "auto"
},
"ver": "1.0.12",
"imported": true,
"files": [
".json"
],
"subMetas": {}
}
},
"userData": {
"type": "sprite-frame",
"fixAlphaTransparencyArtifacts": false,
"hasAlpha": true,
"redirect": "57095dc9-bab4-4732-8a52-98135b49c8a0@6c48a"
}
}

@ -1,19 +1,26 @@
剑气.png
size: 750,352
size: 1126,352
format: RGBA8888
filter: Linear,Linear
repeat: none
images/剑气1
rotate: false
xy: 376, 0
xy: 0, 0
size: 374, 352
orig: 502, 416
offset: 80, 31
index: -1
images/剑气3
rotate: false
xy: 0, 0
xy: 376, 0
size: 374, 352
orig: 502, 416
offset: 80, 31
index: -1
images/剑气33
rotate: false
xy: 752, 0
size: 374, 352
orig: 502, 416
offset: 80, 31

@ -1 +1 @@
{"skeleton":{"hash":"yW1x4hib05QPd5jdplJVnWreS0o","spine":"3.8.75","x":-86.82,"y":-61.02,"width":173.43,"height":148.72},"bones":[{"name":"root"},{"name":"images/剑气1","parent":"root","length":167.47,"rotation":-179.53,"x":-7.89,"y":9.3,"scaleX":-0.3245,"scaleY":0.3245},{"name":"images/剑气2","parent":"root","length":167.47,"rotation":-179.53,"x":-7.89,"y":9.3,"scaleX":-0.3245,"scaleY":0.3245},{"name":"images/剑气3","parent":"root","length":167.47,"rotation":-179.53,"x":-7.89,"y":16,"scaleX":-0.3245,"scaleY":-0.3245}],"slots":[{"name":"images/剑气1","bone":"images/剑气1","attachment":"images/剑气2"},{"name":"images/剑气2","bone":"images/剑气2","attachment":"images/剑气2"},{"name":"images/剑气3","bone":"images/剑气3","attachment":"images/剑气2"}],"skins":[{"name":"default","attachments":{"images/剑气1":{"images/剑气2":{"path":"images/剑气1","x":23.93,"y":-7.12,"scaleY":-1,"rotation":-175.77,"width":502,"height":416},"images/剑气3":{"x":24.05,"y":-20.96,"rotation":177.07,"width":502,"height":416}},"images/剑气2":{"images/剑气2":{"path":"images/剑气1","x":23.93,"y":-7.12,"scaleY":-1,"rotation":-175.77,"width":502,"height":416},"images/剑气3":{"x":24.05,"y":-20.96,"rotation":177.07,"width":502,"height":416}},"images/剑气3":{"images/剑气2":{"path":"images/剑气1","x":23.93,"y":-7.12,"scaleY":-1,"rotation":-175.77,"width":502,"height":416},"images/剑气3":{"x":24.05,"y":-20.96,"rotation":177.07,"width":502,"height":416}}}}],"animations":{"剑气红":{"slots":{"images/剑气2":{"color":[{"color":"ffffff00"},{"time":0.2,"color":"ffffffff"},{"time":0.3667,"color":"ffffff00"}],"attachment":[{"name":"images/剑气3"},{"time":0.4,"name":"images/剑气2"}]},"images/剑气3":{"color":[{"color":"ffffffd4"},{"time":0.0333,"color":"ffffffff"},{"time":0.2,"color":"ffffff00","curve":"stepped"},{"time":0.2333,"color":"ffffff00"},{"time":0.4,"color":"ffffffd4"}],"attachment":[{"name":"images/剑气3"}]},"images/剑气1":{"attachment":[{"name":"images/剑气3"}]}},"bones":{"images/剑气1":{"scale":[{},{"time":0.0667,"x":1.084},{"time":0.2},{"time":0.2667,"x":1.084},{"time":0.4}]},"images/剑气2":{"translate":[{},{"time":0.3667,"x":12.51},{"time":0.4}],"scale":[{},{"time":0.3667,"x":1.251},{"time":0.4}]},"images/剑气3":{"translate":[{"x":5.68},{"time":0.2,"x":12.51},{"time":0.2333},{"time":0.4,"x":5.68}],"scale":[{"x":1.114},{"time":0.2,"x":1.251},{"time":0.2333},{"time":0.4,"x":1.114}]}}},"剑气蓝":{"slots":{"images/剑气2":{"color":[{"color":"ffffff00"},{"time":0.2,"color":"ffffffff"},{"time":0.3667,"color":"ffffff00"}]},"images/剑气3":{"color":[{"color":"ffffffd4"},{"time":0.0333,"color":"ffffffff"},{"time":0.2,"color":"ffffff00","curve":"stepped"},{"time":0.2333,"color":"ffffff00"},{"time":0.4,"color":"ffffffd4"}]}},"bones":{"images/剑气1":{"scale":[{},{"time":0.0667,"x":1.084},{"time":0.2},{"time":0.2667,"x":1.084},{"time":0.4}]},"images/剑气2":{"translate":[{},{"time":0.3667,"x":12.51},{"time":0.4}],"scale":[{},{"time":0.3667,"x":1.251},{"time":0.4}]},"images/剑气3":{"translate":[{"x":5.68},{"time":0.2,"x":12.51},{"time":0.2333},{"time":0.4,"x":5.68}],"scale":[{"x":1.114},{"time":0.2,"x":1.251},{"time":0.2333},{"time":0.4,"x":1.114}]}}}}}
{"skeleton":{"hash":"DORgd4np+LknxrEWjCEEpz3Tpw8","spine":"3.8.75","x":-86.82,"y":-61.02,"width":173.43,"height":148.72},"bones":[{"name":"root"},{"name":"images/剑气1","parent":"root","length":167.47,"rotation":-179.53,"x":-7.89,"y":9.3,"scaleX":-0.3245,"scaleY":0.3245},{"name":"images/剑气2","parent":"root","length":167.47,"rotation":-179.53,"x":-7.89,"y":9.3,"scaleX":-0.3245,"scaleY":0.3245},{"name":"images/剑气3","parent":"root","length":167.47,"rotation":-179.53,"x":-7.89,"y":16,"scaleX":-0.3245,"scaleY":-0.3245}],"slots":[{"name":"images/剑气1","bone":"images/剑气1","attachment":"images/剑气2"},{"name":"images/剑气2","bone":"images/剑气2","attachment":"images/剑气2"},{"name":"images/剑气3","bone":"images/剑气3","attachment":"images/剑气2"}],"skins":[{"name":"default","attachments":{"images/剑气1":{"images/剑气2":{"path":"images/剑气1","x":23.93,"y":-7.12,"scaleY":-1,"rotation":-175.77,"width":502,"height":416},"images/剑气3":{"x":24.05,"y":-20.96,"rotation":177.07,"width":502,"height":416},"images/剑气33":{"x":23.93,"y":-7.12,"scaleY":-1,"rotation":-175.77,"width":502,"height":416}},"images/剑气2":{"images/剑气2":{"path":"images/剑气1","x":23.93,"y":-7.12,"scaleY":-1,"rotation":-175.77,"width":502,"height":416},"images/剑气3":{"x":24.05,"y":-20.96,"rotation":177.07,"width":502,"height":416},"images/剑气33":{"x":23.93,"y":-7.12,"scaleY":-1,"rotation":-175.77,"width":502,"height":416}},"images/剑气3":{"images/剑气2":{"path":"images/剑气1","x":23.93,"y":-7.12,"scaleY":-1,"rotation":-175.77,"width":502,"height":416},"images/剑气3":{"x":24.05,"y":-20.96,"rotation":177.07,"width":502,"height":416},"images/剑气33":{"x":24.05,"y":-20.96,"rotation":177.07,"width":502,"height":416}}}}],"animations":{"剑气红":{"slots":{"images/剑气1":{"attachment":[{"name":"images/剑气3"}]},"images/剑气2":{"color":[{"color":"ffffff00"},{"time":0.2,"color":"ffffffff"},{"time":0.3667,"color":"ffffff00"}],"attachment":[{"name":"images/剑气3"},{"time":0.4,"name":"images/剑气2"}]},"images/剑气3":{"color":[{"color":"ffffffd4"},{"time":0.0333,"color":"ffffffff"},{"time":0.2,"color":"ffffff00","curve":"stepped"},{"time":0.2333,"color":"ffffff00"},{"time":0.4,"color":"ffffffd4"}],"attachment":[{"name":"images/剑气3"}]}},"bones":{"images/剑气1":{"scale":[{},{"time":0.0667,"x":1.084},{"time":0.2},{"time":0.2667,"x":1.084},{"time":0.4}]},"images/剑气2":{"translate":[{},{"time":0.3667,"x":12.51},{"time":0.4}],"scale":[{},{"time":0.3667,"x":1.251},{"time":0.4}]},"images/剑气3":{"translate":[{"x":5.68},{"time":0.2,"x":12.51},{"time":0.2333},{"time":0.4,"x":5.68}],"scale":[{"x":1.114},{"time":0.2,"x":1.251},{"time":0.2333},{"time":0.4,"x":1.114}]}}},"剑气蓝":{"slots":{"images/剑气2":{"color":[{"color":"ffffff00"},{"time":0.2,"color":"ffffffff"},{"time":0.3667,"color":"ffffff00"}]},"images/剑气3":{"color":[{"color":"ffffffd4"},{"time":0.0333,"color":"ffffffff"},{"time":0.2,"color":"ffffff00","curve":"stepped"},{"time":0.2333,"color":"ffffff00"},{"time":0.4,"color":"ffffffd4"}]}},"bones":{"images/剑气1":{"scale":[{},{"time":0.0667,"x":1.084},{"time":0.2},{"time":0.2667,"x":1.084},{"time":0.4}]},"images/剑气2":{"translate":[{},{"time":0.3667,"x":12.51},{"time":0.4}],"scale":[{},{"time":0.3667,"x":1.251},{"time":0.4}]},"images/剑气3":{"translate":[{"x":5.68},{"time":0.2,"x":12.51},{"time":0.2333},{"time":0.4,"x":5.68}],"scale":[{"x":1.114},{"time":0.2,"x":1.251},{"time":0.2333},{"time":0.4,"x":1.114}]}}},"剑气金":{"slots":{"images/剑气1":{"attachment":[{"name":"images/剑气33"}]},"images/剑气2":{"color":[{"color":"ffffff00"},{"time":0.2,"color":"ffffffff"},{"time":0.3667,"color":"ffffff00"}],"attachment":[{"name":"images/剑气33"},{"time":0.4,"name":"images/剑气2"}]},"images/剑气3":{"color":[{"color":"ffffffd4"},{"time":0.0333,"color":"ffffffff"},{"time":0.2,"color":"ffffff00","curve":"stepped"},{"time":0.2333,"color":"ffffff00"},{"time":0.4,"color":"ffffffd4"}],"attachment":[{"name":"images/剑气33"}]}},"bones":{"images/剑气1":{"scale":[{},{"time":0.0667,"x":1.084},{"time":0.2},{"time":0.2667,"x":1.084},{"time":0.4}]},"images/剑气2":{"translate":[{},{"time":0.3667,"x":12.51},{"time":0.4}],"scale":[{},{"time":0.3667,"x":1.251},{"time":0.4}]},"images/剑气3":{"translate":[{"x":5.68},{"time":0.2,"x":12.51},{"time":0.2333},{"time":0.4,"x":5.68}],"scale":[{"x":1.114},{"time":0.2,"x":1.251},{"time":0.2333},{"time":0.4,"x":1.114}]}}}}}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 KiB

After

Width:  |  Height:  |  Size: 202 KiB

@ -45,9 +45,9 @@
"offsetY": 0,
"trimX": 0,
"trimY": 0,
"width": 750,
"width": 1126,
"height": 352,
"rawWidth": 750,
"rawWidth": 1126,
"rawHeight": 352,
"borderTop": 0,
"borderBottom": 0,
@ -60,16 +60,16 @@
"meshType": 0,
"vertices": {
"rawPosition": [
-375,
-563,
-176,
0,
375,
563,
-176,
0,
-375,
-563,
176,
0,
375,
563,
176,
0
],
@ -84,11 +84,11 @@
"uv": [
0,
352,
750,
1126,
352,
0,
0,
750,
1126,
0
],
"nuv": [
@ -102,12 +102,12 @@
1
],
"minPos": [
-375,
-563,
-176,
0
],
"maxPos": [
375,
563,
176,
0
]

@ -23,7 +23,7 @@
"_active": true,
"_components": [],
"_prefab": {
"__id__": 108
"__id__": 91
},
"_lpos": {
"__type__": "cc.Vec3",
@ -54,7 +54,7 @@
},
"autoReleaseAssets": false,
"_globals": {
"__id__": 109
"__id__": 92
},
"_id": "89cd0565-e1e7-4d4c-b1f5-8a3061282934"
},
@ -82,9 +82,6 @@
{
"__id__": 51
},
{
"__id__": 88
},
{
"__id__": 31
}
@ -92,13 +89,13 @@
"_active": true,
"_components": [
{
"__id__": 105
"__id__": 88
},
{
"__id__": 106
"__id__": 89
},
{
"__id__": 107
"__id__": 90
}
],
"_prefab": null,
@ -1338,8 +1335,8 @@
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": -0.32067581511085863,
"w": -0.9471890104953735
"z": -0.7077950954816707,
"w": -0.7064177962171798
}
},
{
@ -1416,7 +1413,7 @@
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 37.407600467686855
"z": 25.779600467668224
}
},
{
@ -2697,223 +2694,6 @@
"_alphaThreshold": 0.1,
"_id": "40VoHUWzhLOr5NOd/GJV7i"
},
{
"__type__": "cc.Node",
"_objFlags": 0,
"_parent": {
"__id__": 2
},
"_prefab": {
"__id__": 89
},
"__editorExtras__": {}
},
{
"__type__": "cc.PrefabInfo",
"root": {
"__id__": 88
},
"asset": {
"__uuid__": "65a39722-cfca-4817-b338-2f015258ee87",
"__expectedType__": "cc.Prefab"
},
"fileId": "c46/YsCPVOJYA4mWEpNYRx",
"instance": {
"__id__": 90
},
"targetOverrides": null,
"nestedPrefabInstanceRoots": null
},
{
"__type__": "cc.PrefabInstance",
"fileId": "87l92MXgdED6kjLdYd1gXj",
"prefabRootNode": null,
"mountedChildren": [],
"mountedComponents": [],
"propertyOverrides": [
{
"__id__": 91
},
{
"__id__": 93
},
{
"__id__": 95
},
{
"__id__": 97
},
{
"__id__": 98
},
{
"__id__": 99
},
{
"__id__": 100
},
{
"__id__": 101
},
{
"__id__": 103
}
],
"removedComponents": []
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 92
},
"propertyPath": [
"_contentSize"
],
"value": {
"__type__": "cc.Size",
"width": 501.25,
"height": 90.39999999999998
}
},
{
"__type__": "cc.TargetInfo",
"localID": [
"1dFXz44m1LkZmzk8OolWau"
]
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 94
},
"propertyPath": [
"_lpos"
],
"value": {
"__type__": "cc.Vec3",
"x": -0.3199999999999932,
"y": 52.893,
"z": 0
}
},
{
"__type__": "cc.TargetInfo",
"localID": [
"07SxUtb4RCfpsP8K4UEY6V"
]
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 96
},
"propertyPath": [
"_name"
],
"value": "checkLayer"
},
{
"__type__": "cc.TargetInfo",
"localID": [
"c46/YsCPVOJYA4mWEpNYRx"
]
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 96
},
"propertyPath": [
"_lpos"
],
"value": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 96
},
"propertyPath": [
"_lrot"
],
"value": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 96
},
"propertyPath": [
"_euler"
],
"value": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
}
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 96
},
"propertyPath": [
"_active"
],
"value": false
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 102
},
"propertyPath": [
"_contentSize"
],
"value": {
"__type__": "cc.Size",
"width": 750,
"height": 1600
}
},
{
"__type__": "cc.TargetInfo",
"localID": [
"acm6EQkrpE+rjKivMEZQya"
]
},
{
"__type__": "CCPropertyOverrideInfo",
"targetInfo": {
"__id__": 104
},
"propertyPath": [
"_contentSize"
],
"value": {
"__type__": "cc.Size",
"width": 1549.9999999999977,
"height": 2999.999999691111
}
},
{
"__type__": "cc.TargetInfo",
"localID": [
"9cfTGC1jpOpLYKVk63FO2s"
]
},
{
"__type__": "cc.UITransform",
"_name": "",
@ -2990,9 +2770,6 @@
"instance": null,
"targetOverrides": [],
"nestedPrefabInstanceRoots": [
{
"__id__": 88
},
{
"__id__": 31
}
@ -3001,28 +2778,28 @@
{
"__type__": "cc.SceneGlobals",
"ambient": {
"__id__": 110
"__id__": 93
},
"shadows": {
"__id__": 111
"__id__": 94
},
"_skybox": {
"__id__": 112
"__id__": 95
},
"fog": {
"__id__": 113
"__id__": 96
},
"octree": {
"__id__": 114
"__id__": 97
},
"skin": {
"__id__": 115
"__id__": 98
},
"lightProbeInfo": {
"__id__": 116
"__id__": 99
},
"postSettings": {
"__id__": 117
"__id__": 100
},
"bakedWithStationaryMainLight": false,
"bakedWithHighpLightmap": false

@ -137,9 +137,9 @@ const LINE_DRAGON_HALF_WID = 15;
/** 剑气飞行速度(配表无速度段;与直线火龙常见 400 同量级) */
const SWORD_WAVE_SPEED = 400;
/** 轩辕剑刀光动画 */
const SWORD_WAVE_ANIM_BLUE = '剑气蓝';
const SWORD_WAVE_ANIM_BLUE = '剑气金';
/** 吴钩双剑刀光动画 */
const SWORD_WAVE_ANIM_RED = '剑气红';
const SWORD_WAVE_ANIM_RED = '剑气金';
/** 玉帝刀光碰撞盒宽 100,命中半长 */
const SWORD_WAVE_HALF_LEN = 50;
/** 玉帝刀光碰撞盒高 200,命中半宽 */

@ -6,6 +6,7 @@ import {
entityHeroAbilityId,
entityMonsterAbilityId,
entityWeaponAbilityId,
isEarthChargeSkillId,
isFlySwordSkillId,
normalAbilityId,
} from '../weapon1/Weapon1BattleIds';
@ -203,7 +204,26 @@ export class SkillAbilityBuilder {
priority,
};
}
// 1 冲锋:开战不锁敌。skill 9 仅半屏迷雾 / atk_buff 9 封格:不锁英雄
// 土冲锋:射程内锁附近怪;飞出后独立,不占普攻
if (kind !== 'monster' && extraHead === 1 && isEarthChargeSkillId(row.id)) {
const rangePx = this._rangePx(row);
return {
id: abilityId,
triggers: [this._activeTick(interval, kind, startOnCooldown)],
costs,
conditions: [{ type: 'HasTargetInRange' }],
targeting: this._withAttackRangeFallback(rangePx, {
team: 'enemy',
selector: 'Nearest',
shape: 'Single',
maxCount: 1,
params: { stageStrategy: row.target_stage || 1, stageRangePx: rangePx },
}),
timeline: this._deferredPipeline(presentation, []),
priority,
};
}
// 1 哪吒冲锋:开战不锁敌。skill 9 仅半屏迷雾 / atk_buff 9 封格:不锁英雄
// atk_type=15 + skill 9:仍锁射程内主目标并扩圆
if ((kind !== 'monster' && extraHead === 1)
|| (kind === 'monster' && ((extraHead === 9 && atkHead === 0) || buffHead === 9))) {
@ -594,20 +614,20 @@ export class SkillAbilityBuilder {
params,
};
}
// 19 全屏直线冰锥:atk_para=数量,伤害万分比;按威胁锁最多 N 个全屏敌
// 19 直线冰锥:atk_para=数量,伤害万分比;射程内按威胁锁最多 N 个(Skill.range≤0 用塔射程)
if (atkHead === 19) {
const maxCount = Math.max(0, Math.floor(atkParts[0] || 0));
const wan = Number(atkParts[1]);
if (!(maxCount > 0) || !Number.isFinite(wan)) {
console.log('[SkillAbilityBuilder] atk_type=19 参数须为「数量,伤害万分比」', row.id, row.atk_para);
}
return {
return this._withAttackRangeFallback(rangePx, {
team,
selector: 'AllEnemies',
selector: 'Nearest',
shape: 'Single',
maxCount,
params: { ...baseParams, pickCount: maxCount },
};
});
}
// 8 / 11 召唤:可无目标
if (atkHead === 8 || atkHead === 11) {

@ -78,6 +78,9 @@ export function isMonsterAbilityId(abilityId: string): boolean {
/** 飞剑武器主动 Skill.id(atk_type=10 走飞剑预制体,非连砸) */
export const FLY_SWORD_SKILL_IDS: readonly number[] = [210101, 220101, 230101, 240101, 250101];
/** 土宝石冲锋 Skill.id(skill type=1,独立飞枪,非哪吒冲锋) */
export const EARTH_CHARGE_SKILL_IDS: readonly number[] = [620201, 630201, 640201, 650201];
/**
* 是否为飞剑武器主动。
* @param skillId Skill.id
@ -89,6 +92,17 @@ export function isFlySwordSkillId(skillId: number): boolean {
return false;
}
/**
* 是否为土属性冲锋宝石主动。
* @param skillId Skill.id
*/
export function isEarthChargeSkillId(skillId: number): boolean {
for (let i = 0; i < EARTH_CHARGE_SKILL_IDS.length; i++) {
if (EARTH_CHARGE_SKILL_IDS[i] === skillId) return true;
}
return false;
}
/** 塔实体 Hero 标签 */
export function weapon1Tag(heroId: number): string {
return `weapon1_${heroId}`;

@ -289,7 +289,7 @@ export class FallbackAtkPresenter implements ISkillPresenter {
}
/**
* atk_type=19 全屏直线冰锥:瞬发,对锁定的最多 N 个敌各发一枚「冰锥」,落地结算。
* atk_type=19 直线冰锥:射程内锁最多 N 个,播配表动画,对齐「挥砍」关键帧再出弹。
*/
export class IceConeAtkPresenter implements ISkillPresenter {
present(ctx: SkillPresentationContext, host: Skill): void {
@ -311,23 +311,18 @@ export class IceConeAtkPresenter implements ISkillPresenter {
const seq = host.beginPresentationCast(ctx);
if (!(seq > 0)) return;
host.disarmAnimComplete();
const scale = wan / 10000;
const buff1 = String(ctx.params.buff1 ?? '');
const buff2 = String(ctx.params.buff2 ?? '');
const targets = ctx.targets;
let launched = 0;
for (let i = 0; i < targets.length && launched < count; i++) {
const tid = targets[i];
if (!(tid > 0)) continue;
if (host.visualChannel.launchIceCone(ctx.caster, ctx.abilityId, tid, scale, buff1, buff2)) {
launched += 1;
}
}
if (launched <= 0) {
console.log('[IceConeAtkPresenter] 无有效发射', ctx.params.skillId);
}
ctx.releasePresentationLock();
host.finishPresentationCast(seq, false);
const animation = String(ctx.params.animation ?? '');
host.prepareIceConeLaunch(seq, count, wan / 10000, String(ctx.params.buff1 ?? ''), String(ctx.params.buff2 ?? ''), ctx.targets);
const animTs = host.visualChannel.playCastAnim({
caster: ctx.caster,
animation,
followWeapon,
skillKind,
primaryTarget: ctx.targets[0] ?? null,
holdCasting: true,
onAnimComplete: host.onIceConeAnimCompleteBound,
});
host.scheduleIceConeLaunch(seq, host.visualChannel.resolveStaffProjectileDelay(animTs, animation));
}
}
@ -384,9 +379,10 @@ export class VolleyArrowAtkPresenter implements ISkillPresenter {
host.finishPresentationCast(seq, false);
return;
}
const animation = String(ctx.params.animation ?? '');
const animTs = host.visualChannel.playCastAnim({
caster: ctx.caster,
animation: String(ctx.params.animation ?? ''),
animation,
followWeapon,
skillKind,
primaryTarget: ctx.targets[0] ?? null,

@ -88,6 +88,49 @@ export class BattleSpinePlayback {
}
}
/**
* 读 skeletonJson:骨骼 rotate/translate/scale 轨道上 time>0 的最早关键帧。
* 用于法杖「挥砍」等出手特效骨(非槽位卸附件)。
* @param skeleton 骨架
* @param animName 动画名
* @param boneSubstr 骨骼名须包含的子串(如「挥砍」);空串匹配全部
* @returns 秒;无则 null
*/
static findFirstBoneKeyframeTime(skeleton: sp.Skeleton, animName: string, boneSubstr: string): number | null {
if (!skeleton?.isValid || !animName) return null;
const sd = skeleton.skeletonData as sp.SkeletonData & { skeletonJson?: unknown; _skeletonJson?: unknown };
if (!sd?.isValid) return null;
try {
ensureSpineSkeletonDataRuntime(sd);
type BoneTrack = { rotate?: Array<{ time?: number }>; translate?: Array<{ time?: number }>; scale?: Array<{ time?: number }> };
const raw = (sd.skeletonJson ?? sd._skeletonJson) as { animations?: Record<string, { bones?: Record<string, BoneTrack> }> } | null;
const bones = raw?.animations?.[animName]?.bones;
if (!bones) return null;
const needle = String(boneSubstr ?? '');
let best: number | null = null;
const names = Object.keys(bones);
for (let i = 0; i < names.length; i++) {
const bn = names[i];
if (needle && bn.indexOf(needle) < 0) continue;
const track = bones[bn];
if (!track) continue;
const lanes = [track.rotate, track.translate, track.scale];
for (let L = 0; L < lanes.length; L++) {
const keys = lanes[L];
if (!keys || keys.length === 0) continue;
for (let k = 0; k < keys.length; k++) {
const t = Number(keys[k]?.time);
if (!(t > 0)) continue;
if (best == null || t < best) best = t;
}
}
}
return best;
} catch {
return null;
}
}
/**
* 战斗逻辑时钟下的播完延迟(秒)。
* anim.timeScale 已含战斗倍速时,delay = duration / userTimeScale。

@ -0,0 +1,538 @@
import { Node, Vec3, sp } from 'cc';
import type { BattleSession, Cell, EntityId } from 'db://assets/mx/module/battle';
import { BattleTeamId } from 'db://assets/mx/module/battle';
import {
HealthComp,
MovementComp,
TeamComp,
TransformComp,
isBajiaoBlowRetreating,
isYanSoulClaimed,
} from 'db://assets/mx/module/battle/ecs/Components';
import { GBundle, GPath } from '../../game/ConfigRes';
import { BattleMapSpec } from '../map/BattleMapSpec';
import type { MapManager } from '../map/legacy/MapManager';
import type { Skill } from '../skill/Skill';
import type { SkillPresentationContext } from '../skill/SkillPresentationTypes';
import { SkillPresentationEnv } from '../skill/SkillPresentationEnv';
import {
computeAimAngleDeg,
setNodeWorldPos,
shortestAngleDeltaDeg,
} from '../skill/SkillTransformDriver';
import { ensureSpineSkeletonDataRuntime } from 'db://assets/mx/module/lang/spineRuntimePatch';
import { BattleSpinePlayback } from './BattleSpinePlayback';
import { buildShadowDealContext } from './SkillShadowContext';
import type { ISkillPresenter } from './SkillPresenter';
/** battleHero/prefab/skill/冲锋 */
const CHARGE_PREFAB = '冲锋';
/** 朝向转速(度/秒) */
const TURN_DEG = 540;
/** 沿路径前瞻(像素) */
const LOOKAHEAD = 28;
/** 沿途命中半径(像素,对齐预制体半边) */
const HIT_RADIUS = 100;
/** 冲锋直伤类型 */
const DMG_TYPE = 'earth_charge';
/** Skill.skill type=1 土冲锋参数 */
interface EarthChargeParams {
/** 冲锋速度(像素/秒) */
speed: number;
/** 持续秒 */
duration: number;
/** 伤害系数 */
scale: number;
}
/** 一次土冲锋运行态 */
interface EarthChargeRun {
/** 施法者 */
caster: EntityId;
/** 影子伤害上下文 */
ctx: SkillPresentationContext;
/** 冲锋根 */
node: Node;
/** 路径世界坐标 */
waypoints: Vec3[];
/** 像素/秒 */
speed: number;
/** 持续秒 */
duration: number;
/** 伤害系数 */
scale: number;
/** 已过秒 */
elapsed: number;
/** 节点朝向角 */
angle: number;
/** 已命中 */
hitIds: EntityId[];
/** 上一帧世界 X */
lastX: number;
/** 上一帧世界 Y */
lastY: number;
}
let _host: EarthChargeHost | null = null;
/** 土冲锋运行时 */
export function getEarthChargeHost(): EarthChargeHost {
if (!_host) _host = new EarthChargeHost();
return _host;
}
/**
* 土属性冲锋:自枪格吸附进路格生成「冲锋」预制体,沿哪吒同款进路反冲,沿途伤+击退;飞出后独立。
*/
export class EarthChargeHost {
private readonly _runs: EarthChargeRun[] = [];
private readonly _tmp = new Vec3();
private readonly _aim = new Vec3();
private readonly _from = new Vec3();
private _hitRun: EarthChargeRun | null = null;
/**
* 解析 `1,速度,时长,伤害万分比`。
* @param raw Skill.skill
*/
static parse(raw: string): EarthChargeParams | null {
const parts = String(raw ?? '').split(',').map((s) => Number(String(s).trim()));
if (parts[0] !== 1) return null;
const speed = parts[1];
const duration = parts[2];
const wan = parts[3];
if (!(speed > 0) || !(duration > 0) || !(wan > 0)) {
console.log('[EarthCharge] skill 参数无效');
return null;
}
return { speed, duration, scale: wan / 10000 };
}
/**
* 开战:自施法者格吸附进路生成冲锋体并立刻放锁。
* @param ctx 表现上下文
* @param host Skill 宿主
*/
start(ctx: SkillPresentationContext, host: Skill): void {
this._abortCaster(ctx.caster);
const raw = String(ctx.params.extraSkill ?? ctx.params.skillRaw ?? '');
const params = EarthChargeHost.parse(raw);
if (!params) {
host.drainLogicPresentation(ctx);
return;
}
const session = SkillPresentationEnv.getBattleSession();
const map = SkillPresentationEnv.getMap();
if (!session || !map) {
console.log('[EarthCharge] 无 session/map');
host.drainLogicPresentation(ctx);
return;
}
const target = ctx.targets[0] ?? 0;
if (!(target > 0) || !session.world.isAlive(target)) {
console.log('[EarthCharge] 无附近怪物', target);
host.drainLogicPresentation(ctx);
return;
}
const fromCell = this._casterCell(session, map, ctx.caster);
if (!fromCell) {
console.log('[EarthCharge] 无施法者格', ctx.caster);
host.drainLogicPresentation(ctx);
return;
}
const snap = this._snapApproachCell(session, ctx.caster, fromCell);
if (!snap) {
console.log('[EarthCharge] 进路上无吸附格', fromCell);
host.drainLogicPresentation(ctx);
return;
}
const waypoints = this._buildRetreatWorlds(session, ctx.caster, snap, params);
if (waypoints.length < 1) {
console.log('[EarthCharge] 反向路径为空');
host.drainLogicPresentation(ctx);
return;
}
const parent = SkillPresentationEnv.flyLayer ?? map.ensureHeroParent();
if (!parent?.isValid) {
console.log('[EarthCharge] 无父节点');
host.drainLogicPresentation(ctx);
return;
}
let node: Node | null = null;
try {
node = gg.res.getNode(GPath.HeroSkillPrefab(), CHARGE_PREFAB, GBundle.BattleHero);
} catch (err) {
console.log('[EarthCharge] getNode 失败', String(err));
host.drainLogicPresentation(ctx);
return;
}
if (!node?.isValid) {
console.log('[EarthCharge] 预制体未加载', CHARGE_PREFAB);
host.drainLogicPresentation(ctx);
return;
}
const seq = host.beginPresentationCast(ctx);
if (!(seq > 0)) {
gg.res.putNode(node);
return;
}
host.disarmAnimComplete();
parent.active = true;
node.active = true;
node.layer = parent.layer;
node.parent = parent;
node.setSiblingIndex(parent.children.length - 1);
node.setScale(1, 1, 1);
const start = waypoints[0];
setNodeWorldPos(node, start);
const angle = this._chargeAimDeg(start.x, start.y, waypoints, 0) ?? 0;
node.angle = angle;
this._playPrefabAnim(node);
const shadow = buildShadowDealContext(
ctx,
String(ctx.params.buff1 ?? ''),
String(ctx.params.buff2 ?? ''),
);
this._runs.push({
caster: ctx.caster,
ctx: shadow,
node,
waypoints,
speed: params.speed,
duration: params.duration,
scale: params.scale,
elapsed: 0,
angle,
hitIds: [],
lastX: start.x,
lastY: start.y,
});
ctx.releasePresentationLock();
host.finishPresentationCast(seq, false);
}
/**
* 推进冲锋。
* @param dt 逻辑秒
*/
tick(dt: number): void {
if (!(dt > 0)) return;
for (let i = this._runs.length - 1; i >= 0; i--) {
if (!this._step(this._runs[i], dt)) {
this._finish(this._runs[i]);
this._runs.splice(i, 1);
}
}
}
/** 结束全部冲锋 */
abortAll(): void {
for (let i = this._runs.length - 1; i >= 0; i--) {
this._finish(this._runs[i]);
}
this._runs.length = 0;
}
/**
* 结束该施法者未完成的冲锋。
* @param caster 施法者
*/
private _abortCaster(caster: EntityId): void {
for (let i = this._runs.length - 1; i >= 0; i--) {
if (this._runs[i].caster !== caster) continue;
this._finish(this._runs[i]);
this._runs.splice(i, 1);
}
}
/**
* 单帧位移与命中。false=结束。
* @param run 运行态
* @param dt 逻辑秒
*/
private _step(run: EarthChargeRun, dt: number): boolean {
if (!run.ctx.isAlive || !run.node.isValid) return false;
run.elapsed += dt;
const cap = run.speed * Math.min(run.duration, run.elapsed);
this._pointAlong(run.waypoints, cap, this._tmp);
setNodeWorldPos(run.node, this._tmp);
run.lastX = this._tmp.x;
run.lastY = this._tmp.y;
this._turn(run, dt, this._chargeAimDeg(run.lastX, run.lastY, run.waypoints, cap));
this._hitNear(run);
const pathLen = this._pathLen(run.waypoints);
if (run.elapsed >= run.duration || cap >= pathLen - 0.5) return false;
return true;
}
/**
* 冲锋体附近敌对怪各伤一次(含 atk_buff 击退)。
* @param run 运行态
*/
private _hitNear(run: EarthChargeRun): void {
const session = SkillPresentationEnv.getBattleSession();
if (!session || !session.world.isAlive(run.caster)) return;
this._hitRun = run;
session.world.view(HealthComp).forEach(this._hitOne);
this._hitRun = null;
}
/**
* 单体命中。
* @param id 实体
* @param hp 生命
*/
private readonly _hitOne = (id: EntityId, hp: HealthComp): void => {
const run = this._hitRun;
const session = SkillPresentationEnv.getBattleSession();
if (!run || !session) return;
if (id === run.caster) return;
if (this._alreadyHit(run, id)) return;
if (!session.world.isAlive(id) || !(hp.hp > 0)) return;
const move = session.world.getComponent(id, MovementComp);
if (move?.spawnProtected || isYanSoulClaimed(move) || isBajiaoBlowRetreating(move)) return;
const casterTeam = session.world.getComponent(run.caster, TeamComp);
if (!BattleTeamId.isHostile(casterTeam, session.world.getComponent(id, TeamComp))) return;
const wp = SkillPresentationEnv.getTargetWorldPos(id);
if (!wp) return;
const dx = wp.x - run.lastX;
const dy = wp.y - run.lastY;
if (dx * dx + dy * dy > HIT_RADIUS * HIT_RADIUS) return;
run.hitIds.push(id);
run.ctx.dealDamage(id, { scale: run.scale, damageType: DMG_TYPE });
};
/**
* 是否已命中。
* @param run 运行态
* @param id 实体
*/
private _alreadyHit(run: EarthChargeRun, id: EntityId): boolean {
const ids = run.hitIds;
for (let i = 0; i < ids.length; i++) {
if (ids[i] === id) return true;
}
return false;
}
/**
* 回收冲锋体。
* @param run 运行态
*/
private _finish(run: EarthChargeRun): void {
if (!run.node?.isValid) return;
const list = run.node.getComponentsInChildren(sp.Skeleton);
for (let i = 0; i < list.length; i++) {
BattleSpinePlayback.clearPendingComplete(list[i]);
}
run.node.angle = 0;
run.node.setScale(1, 1, 1);
gg.res.putNode(run.node);
}
/**
* 施法者落点格(Transform / 地图格,禁 session.grid.worldToCell——世界坐标原点与逻辑格不一致)。
* @param session 会话
* @param map 地图
* @param caster 施法者
*/
private _casterCell(session: BattleSession, map: MapManager, caster: EntityId): Cell | null {
const tf = session.world.getComponent(caster, TransformComp);
if (tf && session.grid.inBounds({ row: tf.row, col: tf.col })) {
return { row: tf.row, col: tf.col };
}
const center = SkillPresentationEnv.getCasterGridCenter(caster);
if (!center) return null;
const mg = map.getMapGridByWorldPos(center);
if (!mg) return null;
return { row: mg.Row, col: mg.Col };
}
/**
* 攻我方进路上离枪格最近的格;同距优先枪格正下方(更大 row)。
* @param session 会话
* @param caster 施法者
* @param from 施法者格
*/
private _snapApproachCell(session: BattleSession, caster: EntityId, from: Cell): { Row: number; Col: number } | null {
const enemyPort = this._enemyPort(session, caster);
const spawn = session.topology.getSpawnCell(enemyPort);
if (!spawn) {
console.log('[EarthCharge] 敌方出怪口缺失', enemyPort);
return null;
}
const forward = session.pathfinder.getApproachPath(spawn, enemyPort);
if (forward.length < 1) return null;
// 枪格正下方若在进路上,优先落该格
const belowRow = from.row + 1;
for (let i = 0; i < forward.length; i++) {
if (forward[i].row === belowRow && forward[i].col === from.col) {
return { Row: forward[i].row, Col: forward[i].col };
}
}
let best = 0;
let bestD = Number.POSITIVE_INFINITY;
let bestRow = Number.NEGATIVE_INFINITY;
for (let i = 0; i < forward.length; i++) {
const d = Math.abs(forward[i].row - from.row) + Math.abs(forward[i].col - from.col);
if (d < bestD || (d === bestD && forward[i].row > bestRow)) {
bestD = d;
bestRow = forward[i].row;
best = i;
}
}
return { Row: forward[best].row, Col: forward[best].col };
}
/**
* 攻向施法者阵营的出怪口。
* @param session 会话
* @param caster 施法者
*/
private _enemyPort(session: BattleSession, caster: EntityId): number {
const team = session.world.getComponent(caster, TeamComp);
const owner = team?.ownerId ?? team?.team ?? 0;
return owner === 0 ? 1 : 2;
}
/**
* 从吸附格沿进路退向敌方出怪口。
* @param session 会话
* @param caster 施法者
* @param snap 吸附格
* @param params 配表
*/
private _buildRetreatWorlds(session: BattleSession, caster: EntityId, snap: { Row: number; Col: number }, params: EarthChargeParams): Vec3[] {
const enemyPort = this._enemyPort(session, caster);
const spawn = session.topology.getSpawnCell(enemyPort);
if (!spawn) {
console.log('[EarthCharge] 敌方出怪口缺失', enemyPort);
return [];
}
const cellSize = Math.max(1, BattleMapSpec.CELL_SIZE);
const maxSteps = Math.ceil(params.speed * params.duration / cellSize) + 8;
const from: Cell = { row: snap.Row, col: snap.Col };
const cells = session.pathfinder.buildRetreatPath(from, maxSteps, spawn, enemyPort);
const out: Vec3[] = [];
for (let i = 0; i < cells.length; i++) {
const w = SkillPresentationEnv.getGridWorldCenterByRowCol(cells[i].row, cells[i].col);
if (w) out.push(w.clone());
}
return out;
}
/**
* 沿折线取点。
* @param points 路点
* @param dist 路程
* @param out 输出
*/
private _pointAlong(points: readonly Vec3[], dist: number, out: Vec3): void {
if (points.length === 0) {
out.set(0, 0, 0);
return;
}
if (points.length === 1 || dist <= 0) {
out.set(points[0].x, points[0].y, points[0].z);
return;
}
let left = dist;
for (let i = 0; i < points.length - 1; i++) {
const a = points[i];
const b = points[i + 1];
const dx = b.x - a.x;
const dy = b.y - a.y;
const seg = Math.sqrt(dx * dx + dy * dy);
if (seg <= 1e-4) continue;
if (left <= seg) {
const t = left / seg;
out.set(a.x + dx * t, a.y + dy * t, a.z);
return;
}
left -= seg;
}
const last = points[points.length - 1];
out.set(last.x, last.y, last.z);
}
/**
* 折线总长。
* @param points 路点
*/
private _pathLen(points: readonly Vec3[]): number {
let len = 0;
for (let i = 0; i < points.length - 1; i++) {
const dx = points[i + 1].x - points[i].x;
const dy = points[i + 1].y - points[i].y;
len += Math.sqrt(dx * dx + dy * dy);
}
return len;
}
/**
* 播预制体默认循环动画。
* @param root 冲锋根
*/
private _playPrefabAnim(root: Node): void {
const sk = root.getComponent(sp.Skeleton) ?? root.getComponentInChildren(sp.Skeleton);
if (!sk?.isValid) {
console.warn('[EarthCharge] 缺 Spine');
return;
}
if (sk.skeletonData) ensureSpineSkeletonDataRuntime(sk.skeletonData);
const typed = sk as sp.Skeleton & { defaultAnimation?: string };
const name = String(typed.defaultAnimation || sk.animation || '').trim();
if (!name) {
console.warn('[EarthCharge] 无默认动画');
return;
}
BattleSpinePlayback.play(sk, name, { loop: true, optional: true });
}
/**
* 节点对准冲锋前方。
* @param run 运行态
* @param dt 逻辑秒
* @param desired 目标角
*/
private _turn(run: EarthChargeRun, dt: number, desired: number | null): void {
if (desired == null || !run.node.isValid) return;
const delta = shortestAngleDeltaDeg(run.angle, desired);
const maxStep = TURN_DEG * dt;
const step = delta > maxStep ? maxStep : (delta < -maxStep ? -maxStep : delta);
run.angle += step;
run.node.angle = run.angle;
}
/**
* 沿路径前瞻朝向(度,0=右)。
* @param fromX 当前 X
* @param fromY 当前 Y
* @param waypoints 路点
* @param traveled 已走路程
*/
private _chargeAimDeg(fromX: number, fromY: number, waypoints: readonly Vec3[], traveled: number): number | null {
this._from.set(fromX, fromY, 0);
this._pointAlong(waypoints, traveled + LOOKAHEAD, this._aim);
return computeAimAngleDeg(this._from, this._aim);
}
}
/** Skill.skill type=1 土冲锋入口 */
export class EarthChargePresenter implements ISkillPresenter {
/**
* 播放土冲锋。
* @param ctx 表现上下文
* @param host Skill 宿主
*/
present(ctx: SkillPresentationContext, host: Skill): void {
if (!ctx.isAlive) {
ctx.finish();
return;
}
getEarthChargeHost().start(ctx, host);
}
}

@ -0,0 +1,9 @@
{
"ver": "4.0.24",
"importer": "typescript",
"imported": true,
"uuid": "226cc175-37c2-4371-bfcc-765f604f1c9c",
"files": [],
"subMetas": {},
"userData": {}
}

@ -24,6 +24,8 @@ import {
import { ensureSpineSkeletonDataRuntime } from 'db://assets/mx/module/lang/spineRuntimePatch';
import { applyWeaponSpineSkin } from '../view/GlyphSpineSkin';
import { BattleSpinePlayback } from './BattleSpinePlayback';
import { getEarthChargeHost } from './EarthChargePresenter';
import { isEarthChargeSkillId } from '../config/weapon1/Weapon1BattleIds';
import type { ISkillPresenter } from './SkillPresenter';
/** battleHero/prefab/skill/哪吒冲锋 */
@ -773,6 +775,11 @@ export class NezhaChargePresenter implements ISkillPresenter {
ctx.finish();
return;
}
const skillId = Math.floor(Number(ctx.params.skillId) || 0);
if (isEarthChargeSkillId(skillId)) {
getEarthChargeHost().start(ctx, host);
return;
}
getNezhaChargeHost().start(ctx, host);
}
}

@ -20,7 +20,7 @@ import type { ISkillPresenter } from './SkillPresenter';
/** 龙影预制体(battleHero/prefab/skill/棍,子节点 Spine 剑气) */
const RING_PREFAB = '棍';
/** 龙影 Spine 兜底动画(预制体未勾 playOnLoad,需显式播放) */
const RING_ANIM = '剑气红';
const RING_ANIM = '剑气金';
/** 出生外扩兜底(像素):施法者攻击范围取不到时用 */
const RING_SPAWN_OFFSET_FALLBACK = 200;
/** 首中保底可视飞行时长(秒):贴脸命中不凭空消失 */

@ -20,10 +20,14 @@ export const PRES_HIT_AT_BASE = 0.33;
/** 武器弓「攻击」拉满时刻(秒 @ timeScale=1):bone5 拉到最满,早于卸箭 0.4667 / 整段 1.0 */
const BOW_RELEASE_AT_BASE = 0.4333;
/**
* 「水弹攻击1」出手帧(秒 @ timeScale=1)。
* 对齐聚集光能接近最亮(color≈0.5);整段约 1.5s,勿等播完再发射。
* 法杖发射物出手兜底帧(秒 @ timeScale=1)。
* 对齐骨骼「挥砍」首关键帧(聚能后砸出);优先读 runtime skeletonJson。
*/
const WATER_BALL_RELEASE_AT = 0.5;
const STAFF_PROJECTILE_RELEASE_AT = 0.6333;
/** 法杖发射物出手下限(动画时间轴秒);配表动作至少蓄力这么久再出弹 */
const STAFF_PROJECTILE_MIN_AT = 0.3;
/** 法杖出手特效骨(水弹/冰锥/暴风雪共用「挥砍」) */
const STAFF_RELEASE_BONE = '挥砍';
/**
* weaponType4 / 弓类武器+专属技能:「攻击」「攻击2」「攻击3」槽位「箭矢*」附件清空帧。
* 整段动画 1.5s,卸箭=拉完放箭时刻(非动画结束)。
@ -551,7 +555,9 @@ export class SkillVisualChannel {
this._weapon.setArrowVisible(false);
} else if (this._isBowWeapon()) {
this._weapon.showBowAtk();
} else if (this._weaponFlies.length === 0) {
} else {
// 五行数字 / 法杖:出手必显。勿因在飞水弹/冰锥占着 _weaponFlies 而跳过,
// 否则武器藏着仍按出手帧发射,表现为「无施法动作却出弹」。
this._weapon.setVisible(true);
}
this._weaponCasting = true;
@ -665,19 +671,35 @@ export class SkillVisualChannel {
}
/**
* 五行数字:攻击结束后保持武器可见;弓/枪保持当前朝向。
* 1 秒无下一击再回待机角、藏武器并播数字「待机」。
* 五行数字:攻击结束后保持武器可见。
* 弓/枪:定格攻击末帧并保持当前朝向,1 秒无下一击再插值回待机角后藏武器。
* 刀/木等:可立刻复位;超时藏武器并播数字「待机」。
*/
private _enterAttackOnlyRestHold(): void {
this._cancelRestHold();
if (this._isBowWeapon()) this._weapon.hideBowAtk(false);
this._weapon.setArrowVisible(false);
// 刀/木可立刻复位;弓/枪连击窗内保持瞄准角
if (!this._shouldTweenRestAim() && !this._isStaffWeapon()) {
this._weapon.resetAim();
}
this.syncWeaponPivot(this._caster, true);
this._weapon.setVisible(true);
// 弓/枪:连击窗内保持攻击姿与瞄准角(对齐组合弓/枪 _enterWeaponRestHold)
if (this._shouldTweenRestAim()) {
const skin = this._weapon.skinAnim;
if (skin?.isValid) {
BattleSpinePlayback.clearPendingComplete(skin);
skin.timeScale = 0;
}
this._restHoldActive = true;
this._restHoldAspd = 1;
const seq = ++this._restHoldSeq;
schedulePresentation(WEAPON_REST_HOLD_SEC, () => {
if (seq !== this._restHoldSeq) return;
if (this._weaponCasting) return;
this._restHoldActive = false;
if (skin?.isValid) skin.timeScale = 1;
this._restAttackOnlyWeaponAim();
});
return;
}
if (!this._isStaffWeapon()) this._weapon.resetAim();
this._weapon.playIdle();
this._restHoldActive = true;
const seq = ++this._restHoldSeq;
@ -685,12 +707,27 @@ export class SkillVisualChannel {
if (seq !== this._restHoldSeq) return;
if (this._weaponCasting) return;
this._restHoldActive = false;
if (this._shouldTweenRestAim()) this._weapon.resetAim();
this._weapon.setVisible(false);
this._playGlyphIdle();
});
}
/**
* 五行弓/枪:连击窗结束,从当前瞄准角插值回待机角后再藏武器。
*/
private _restAttackOnlyWeaponAim(): void {
const duration = WEAPON_AIM_SEC / Math.max(0.01, this._restHoldAspd > 0 ? this._restHoldAspd : 1);
this._tweenWeaponAim(WEAPON_REST_ANGLE, duration, this._onAttackOnlyAimRestCompleteBound);
}
/** 五行弓/枪拧回待机角后:藏武器并播数字待机 */
private readonly _onAttackOnlyAimRestCompleteBound = (): void => {
if (this._weaponCasting) return;
this._weapon.resetAim();
this._weapon.setVisible(false);
this._playGlyphIdle();
};
/** 是否有字形释放 Spine */
private _hasGlyphCastAnim(): boolean {
return !!(this._skin?.anim?.isValid || this._resolveGlyphAnim()?.isValid);
@ -999,6 +1036,44 @@ export class SkillVisualChannel {
return ELEMENT_BOW_ARROW_CLEAR_AT;
}
/**
* 是否法杖发射类配表动画(水弹 / 冰锥),不依赖 weaponType 是否已挂上。
* @param animation Skill.animation
*/
private _isStaffProjectileAnim(animation: string): boolean {
const name = String(animation ?? '').trim();
return name.indexOf('水弹') >= 0 || name.indexOf('冰锥') >= 0;
}
/**
* 法杖发射物出手时刻(动画时间轴秒):读「挥砍」首关键帧,且不低于 STAFF_PROJECTILE_MIN_AT。
* @param animation Skill.animation
*/
private _resolveStaffReleaseAt(animation: string): number {
const name = String(animation ?? '').trim();
const anim = this._weapon.skinAnim;
let releaseAt = STAFF_PROJECTILE_RELEASE_AT;
if (name && anim?.isValid) {
const t = BattleSpinePlayback.findFirstBoneKeyframeTime(anim, name, STAFF_RELEASE_BONE);
if (t != null && t > 0) releaseAt = t;
else console.warn('[SkillVisualChannel] 法杖无挥砍关键帧,用默认', name, STAFF_PROJECTILE_RELEASE_AT);
} else if (name) {
console.warn('[SkillVisualChannel] 法杖无骨架可读,用默认出手帧', name, STAFF_PROJECTILE_RELEASE_AT);
}
return Math.max(STAFF_PROJECTILE_MIN_AT, releaseAt);
}
/**
* 法杖水弹/冰锥首次出手延迟(逻辑秒):动画关键帧 / 攻速倍速。
* @param animScale playCastAnim 返回的倍速
* @param animation Skill.animation;空则读当前施法参数
*/
resolveStaffProjectileDelay(animScale: number, animation?: string): number {
const scale = Math.max(0.01, animScale);
const name = String(animation ?? this._castAnimParams?.animation ?? '').trim();
return this._resolveStaffReleaseAt(name) / scale;
}
/**
* 弓箭出手基准秒:组合弓对齐 BOW_RELEASE_AT_BASE;五行弓对齐 Spine 卸箭帧(拉完)。
*/
@ -1156,12 +1231,15 @@ export class SkillVisualChannel {
}
/**
* atk_type 12/13/17 首次出手延迟(逻辑秒):弓对齐拉满帧,法杖对齐水弹关键帧,其它对齐 PRES_HIT。
* atk_type 12/13/17 首次出手延迟(逻辑秒):弓对齐拉满帧,法杖/水弹冰锥对齐「挥砍」关键帧,其它对齐 PRES_HIT。
* @param animScale playCastAnim 返回的攻速倍速
*/
resolveBowShapeLaunchDelay(animScale: number): number {
const scale = Math.max(0.01, animScale);
if (this._isStaffWeapon()) return WATER_BALL_RELEASE_AT / scale;
const animName = String(this._castAnimParams?.animation ?? '').trim();
if (this._isStaffWeapon() || this._isStaffProjectileAnim(animName)) {
return this.resolveStaffProjectileDelay(animScale, animName);
}
if (this._isBowWeapon()) {
if (this._attackOnlyWeapon) {
return this._resolveBowReleaseAtBase() / scale;
@ -1201,6 +1279,7 @@ export class SkillVisualChannel {
return false;
}
this._weaponCasting = true;
this._weapon.setVisible(true);
const fromNode = this._weapon.skinAnim?.node ?? this._weapon.aim ?? this._weapon.root;
const fromWorld = fromNode?.isValid
? fromNode.worldPosition
@ -1300,7 +1379,8 @@ export class SkillVisualChannel {
}
launchVolleyShot(caster: EntityId, abilityId: string, target: EntityId, scale: number, buff1: string, buff2: string, shotIndex: number, aimWorld: Readonly<Vec3>): boolean {
if (this._isStaffWeapon()) {
const castAnim = String(this._castAnimParams?.animation ?? '').trim();
if (this._isStaffWeapon() || this._isStaffProjectileAnim(castAnim)) {
return this._launchWaterBall(caster, abilityId, target, scale, buff1, buff2, aimWorld);
}
if (this._usesElementBow()) {
@ -1418,7 +1498,6 @@ export class SkillVisualChannel {
if (flyUt) clone.setPosition(flyUt.convertToNodeSpaceAR(fromWorld));
else clone.setWorldPosition(fromWorld);
clone.setSiblingIndex(flyLayer.children.length - 1);
this._applyArrowSkin(clone, this._weapon.skinName);
this._playArrowFly(clone);
this._bowArrows.push(clone);
return clone;
@ -1517,6 +1596,8 @@ export class SkillVisualChannel {
*/
private _launchWaterBall(caster: EntityId, abilityId: string, target: EntityId, scale: number, buff1: string, buff2: string, aimWorld: Readonly<Vec3>): boolean {
this._weaponCasting = true;
// 出手瞬间再确保法杖可见(避免在飞弹道占 _weaponFlies 时藏武器)
this._weapon.setVisible(true);
const fromNode = this._weapon.skinAnim?.node ?? this._weapon.aim ?? this._weapon.root;
const fromWorld = fromNode?.isValid
? fromNode.worldPosition
@ -1724,7 +1805,6 @@ export class SkillVisualChannel {
node.setSiblingIndex(flyLayer.children.length - 1);
const sk = node.getChildByName('anim')?.getComponent(sp.Skeleton)
?? node.getComponentInChildren(sp.Skeleton);
this._applyArrowSkin(node, this._weapon.skinName);
if (!sk?.isValid) {
console.log('[SkillVisualChannel] 玉帝飞剑缺 Spine');
} else {
@ -1804,34 +1884,6 @@ export class SkillVisualChannel {
return true;
}
/**
* 箭克隆套武器皮肤。
* @param node 箭根
* @param skinName Weapon.skin
*/
private _applyArrowSkin(node: Node, skinName: string): void {
const name = String(skinName ?? '').trim();
if (!name) {
console.log('[SkillVisualChannel] 弓箭皮肤为空', this._weapon.weaponId);
return;
}
const anim = node.getComponent(sp.Skeleton) ?? node.getComponentInChildren(sp.Skeleton);
if (!anim?.isValid) {
console.log('[SkillVisualChannel] 弓箭克隆缺 Spine');
return;
}
if (anim.skeletonData) ensureSpineSkeletonDataRuntime(anim.skeletonData);
if (!glyphSpineHasSkin(anim, name)) {
console.log('[SkillVisualChannel] 弓箭无此皮肤', name, this._weapon.weaponId);
return;
}
try {
anim.setSkin(name);
anim.setSlotsToSetupPose();
} catch {
console.log('[SkillVisualChannel] 弓箭 setSkin 失败', name, this._weapon.weaponId);
}
}
/**
* 播箭飞行动画。

@ -35,6 +35,7 @@ import { BattleBuffCarryStore } from '../../manager/battleBuff/BattleBuffCarrySt
import { resolveCarriedBaseHpBonus, rollCarriedKillPeachBonus } from '../../manager/battleBuff/BattleBuffPassiveSkillUtil';
import { getMonsterSkillHost } from '../combat/MonsterSkillHost';
import { getNezhaChargeHost } from '../presentation/NezhaChargePresenter';
import { getEarthChargeHost } from '../presentation/EarthChargePresenter';
import { getArrowRainHost } from '../presentation/ArrowRainPresenter';
import { getExtraRingHost } from '../presentation/RingProjectilesPresenter';
import { getExtraStrikeHost } from '../presentation/ExtraStrikePresenter';
@ -900,6 +901,7 @@ export class BattleRuntime implements IBattleRuntimeHandle {
return;
case 13:
getNezhaChargeHost().tick(scaledDt);
getEarthChargeHost().tick(scaledDt);
return;
case 14:
getArrowRainHost().tick(scaledDt);
@ -1166,6 +1168,7 @@ export class BattleRuntime implements IBattleRuntimeHandle {
getBattleBuffBaseThunderHost().unbind();
getBattleBuffBossInterruptHost().unbind();
getNezhaChargeHost().abortAll();
getEarthChargeHost().abortAll();
getArrowRainHost().abortAll();
getExtraRingHost().abortAll();
getExtraStrikeHost().abortAll();

@ -412,6 +412,44 @@ export class Skill extends Component {
this.schedulePresentation(this._onBowShapeTick, delayLogicalSec);
}
/**
* 登记 atk_type=19 冰锥发射参数(须在延迟出手前)。
* @param seq 播控序号
* @param count 最多发射数
* @param scale 伤害倍率
* @param buff1 atk_buff1
* @param buff2 atk_buff2
* @param targets 锁定目标
*/
prepareIceConeLaunch(seq: number, count: number, scale: number, buff1: string, buff2: string, targets: readonly EntityId[]): void {
if (seq !== this._presSeq || this._presFinished) return;
this._iceConeAwaitSeq = seq;
this._iceConeCount = count;
this._iceConeScale = scale;
this._iceConeBuff1 = buff1;
this._iceConeBuff2 = buff2;
this._iceConeTargets.length = 0;
for (let i = 0; i < targets.length; i++) this._iceConeTargets.push(targets[i]);
}
/**
* atk_type=19:对齐武器关键帧后发射冰锥。
* @param seq 播控序号
* @param delayLogicalSec 出手延迟
*/
scheduleIceConeLaunch(seq: number, delayLogicalSec: number): void {
if (this._iceConeAwaitSeq !== seq || this._presFinished || seq !== this._presSeq) return;
this.schedulePresentation(this._onIceConeLaunchDue, delayLogicalSec);
}
/** 冰锥配表动画结束:收招并结束播控 */
readonly onIceConeAnimCompleteBound = (): void => {
this.visualChannel.endHoldCast();
if (this._iceConeAwaitSeq > 0 && this.isPresentationCast(this._iceConeAwaitSeq)) {
this.finishPresentationCast(this._iceConeAwaitSeq, false);
}
};
/** 结算当前 Router 播控 */
finishPresentationCast(seq: number, drainHits: boolean): void {
if (this._presFinished || seq !== this._presSeq) return;
@ -419,6 +457,9 @@ export class Skill extends Component {
const ctx = this._presCtx;
this._presCtx = null;
this._presSmashPool.length = 0;
this._iceConeAwaitSeq = 0;
this._iceConeCount = 0;
this._iceConeTargets.length = 0;
if (ctx?.isAlive) {
if (drainHits) {
while (ctx.isAlive && ctx.hit()) {
@ -495,6 +536,18 @@ export class Skill extends Component {
private _volleyHasAim = false;
/** 动画已结束、等待弹道出手完再 finish */
private _presAnimWait = false;
/** 冰锥播控序号 */
private _iceConeAwaitSeq = 0;
/** 冰锥最多发射数 */
private _iceConeCount = 0;
/** 冰锥伤害倍率 */
private _iceConeScale = 0;
/** 冰锥 atk_buff1 */
private _iceConeBuff1 = '';
/** 冰锥 atk_buff2 */
private _iceConeBuff2 = '';
/** 冰锥锁定目标 */
private readonly _iceConeTargets: EntityId[] = [];
private _onPresCastHitTick = (): void => {
if (this._presFinished || this._presCastAwaitSeq !== this._presSeq) return;
@ -717,6 +770,24 @@ export class Skill extends Component {
this.finishPresentationCast(this._presSeq, false);
}
/** 冰锥关键帧出手 */
private readonly _onIceConeLaunchDue = (): void => {
if (this._presFinished || this._iceConeAwaitSeq !== this._presSeq) return;
const ctx = this._presCtx;
if (!ctx?.isAlive) return;
let launched = 0;
for (let i = 0; i < this._iceConeTargets.length && launched < this._iceConeCount; i++) {
const tid = this._iceConeTargets[i];
if (!(tid > 0)) continue;
if (this.visualChannel.launchIceCone(ctx.caster, ctx.abilityId, tid, this._iceConeScale, this._iceConeBuff1, this._iceConeBuff2)) {
launched += 1;
}
}
if (launched <= 0) {
console.log('[Skill] atk_type=19 无有效发射', ctx.params.skillId);
}
};
/** 打断 Router 播控 */
protected abortPresentationCast(): void {
++this._presSeq;
@ -733,6 +804,9 @@ export class Skill extends Component {
this._presAnimWaitForShow = false;
this._showEffectGate = false;
this._showEffectApplied = true;
this._iceConeAwaitSeq = 0;
this._iceConeCount = 0;
this._iceConeTargets.length = 0;
this._cancelBowLandJobs();
const ctx = this._presCtx;
this._presCtx = null;

@ -25,6 +25,7 @@ import { isHeroActorWeapon1 } from '../heros/HeroActorRes';
import { isElementCombatHeroId } from '../config/BattleHeroTable';
import { ensureSpecialSkillPresenters } from '../presentation/SpecialSkillPresenters';
import { getNezhaChargeHost } from '../presentation/NezhaChargePresenter';
import { getEarthChargeHost } from '../presentation/EarthChargePresenter';
import { getPagodaSmashHost } from '../presentation/PagodaSmashPresenter';
import { getStaffSmashHost } from '../presentation/StaffSmashPresenter';
const { ccclass } = _decorator;
@ -81,6 +82,7 @@ export class SkillController extends Component {
this._skills.clear();
this._entityGridIndex.clear();
getNezhaChargeHost().abortAll();
getEarthChargeHost().abortAll();
getPagodaSmashHost().abortAll();
getStaffSmashHost().abortAll();
HeroActorHost.instance.destroyAll();

@ -81,10 +81,10 @@ const ICE_CONE_PREFAB = '冰锥';
const ICE_CONE_SRC_W = 322;
/** 剑阵根节点参考边长(预制体 UITransform 200,直径=边长) */
const SWORD_ARRAY_REF_SIDE = 200;
const HOMING_DRAGON_PREFAB = '追踪火龙';
const HOMING_DRAGON_PREFAB = '土刺';
const LINE_DRAGON_PREFAB = '直线火龙';
/** 轩辕剑剑气预制体 */
const SWORD_WAVE_PREFAB = '玉帝刀光';
const SWORD_WAVE_PREFAB = '剑气';
/** 剑气飞出可视区的额外路程(相对屏幕对角线) */
const SWORD_WAVE_SCREEN_PAD = 0.2;
/** 闪电链电弧 */

@ -1,9 +1,6 @@
import { GEvent } from '../../mx/module/event/GEvent';
/** 战斗内图鉴引导:第 5 波提示点击图鉴(waveIndex 0-based = 4) */
const ILLUSTRATED_HINT_WAVE_INDEX = 4;
/** 战斗图鉴引导:存档标记 + 事件通知 */
/** 战斗图鉴引导:存档标记 + 事件通知(本项目已无图鉴,引导永不展示) */
export class BattleIllustratedGuideManager {
/** 是否已点击过战斗图鉴(砚台) */
static hasClicked(): boolean {
@ -23,10 +20,10 @@ export class BattleIllustratedGuideManager {
/**
* 是否应在指定波次显示图鉴引导。
* @param waveIndex 当前波次索引(0-based,与 WaveStart 一致)
* 本项目已无图鉴,永不显示。
* @param _waveIndex 当前波次索引(0-based,与 WaveStart 一致)
*/
static shouldShowHintAtWave(waveIndex: number): boolean {
if (this.hasClicked()) return false;
return Math.floor(Number(waveIndex) || 0) === ILLUSTRATED_HINT_WAVE_INDEX;
static shouldShowHintAtWave(_waveIndex: number): boolean {
return false;
}
}

@ -9,7 +9,7 @@
| 类型 | 含义 | 参数 |
|------|------|------|
| 1 | 哪吒反向冲锋(只配哪吒) | 冲锋速度(px/s),持续时间(s),伤害系数(万分比) |
| 1 | 反向冲锋 | 冲锋速度(px/s),持续时间(s),伤害系数(万分比) |
| 2 | 万箭齐发(只配弓) | 发射间隔(s),每格箭数,伤害系数(万分比) |
| 3 | 额外给友军加速 | 加速系数(万分比),加速时间(s) |
| 4 | 额外给友军加血 | 加血比例(万分比,相对最大生命) |
@ -22,6 +22,8 @@
## 2. type 1 流程
### 哪吒
1. 释放英雄主动后:哪吒 HeroActor 保持可见,播「待机单字」,隐藏预制体「阴影」第二节点(吒影)与武器。开战不锁敌(`team=self`),CD 到即可放。
2. 在「吒」格世界坐标加载 `battleHero/prefab/skill/哪吒冲锋`。冲锋 `disarmAnimComplete`,旧武器动画 complete 不得收掉跳出。
3. 从吒位先蹲再弹,跳到**攻本阵营进路**上离吒最近的格(格距;不先找任意可走格再二次吸附)。
@ -30,6 +32,10 @@
6. 沿途对敌对存活怪各伤一次,系数取配表第 4 段。
7. 时长到或路径走完:回池、英雄回「待机」、恢复阴影第二节点。
### 土宝石冲锋(Skill.id 620201/630201/640201/650201)
参数同哪吒(`1,速度,时长,伤害万分比`)。**不占输出**:开战立刻 `releasePresentationLock`。射程内锁附近怪;自**枪格**吸附进路(同距优先正下方格),在格心生成 `battleHero/prefab/skill/冲锋`(无跳出/无英雄显隐),再 `buildRetreatPath` 反冲。沿途各伤一次并走行上 `atk_buff`(击退 `2,10000,50`)。时长到或路径走完回池。施法者格须用 `TransformComp` / `map.getMapGridByWorldPos`,禁止 `session.grid.worldToCell`(世界坐标原点与逻辑格不一致)。
## 2b. type 2 流程
1. 场上无敌方行军怪(非塔)则不放,CD 保持就绪;有怪才开战。不锁具体目标,伤害仍由落点结算。
@ -114,6 +120,7 @@
- 哪吒主动(10146~10148)放出后场上只留「哪」,冲锋体从吒位跳到路上再沿敌方来路反冲
- 冲锋枪保持预制体默认动画,节点朝向跟着冲锋方向转
- 土冲锋:自枪格吸附进路(优先正下方)生成「冲锋」预制体后独立反冲,不占普攻
- 沿途怪吃到 `10000` 万分比伤害;结束后英雄与双字恢复
- 弓主动(如 10186~10188、10216~10218)场上无敌方行军怪则不放;有怪后**敌方来路**通行格陆续落下与普攻相同的箭;己方出怪路径不射;空格仍空落消失
- 玉帝主动(10196~10198)放出后己方行军怪加速 3 秒并播 `怪_加速`(表内暂无 showeffect,仍立刻施加);阎王主动(10206~10208)`0.1,生死簿` 预兆起播后 0.33s:对敌直伤身上播 `怪_流血`,己方行军怪回 20% 最大生命并播 `怪物加血`;攻向自己的敌怪不受益

@ -134,9 +134,9 @@ Hero(合成等级 level)
`atk_para` 同 18(段数,间隔秒,半径,伤害万分比)。开战时以主目标逻辑坐标锁圆心与半径;**无 deferred 段**。**占施法锁至全部段结束**(期间不可普攻);武器循环播 `Skill.animation`(如「暴风雪技能」),同时在主目标落点实例化 `battleHero/prefab/skill/暴风雪`(缩放=`半径/200`;预制体默认循环),由 `GroundCircleHost` 按段 `pulseHostileCircle` **重新索敌**圈伤。行上 `atk_buff1/2` 随每段影子伤害施加。
### atk_type 19 全屏直线冰锥
### atk_type 19 直线冰锥
`atk_para`=`数量,伤害万分比`。全屏按威胁锁最多 N 个敌;瞬发不占普攻,对每个目标发直线「冰锥」预制体,落地结算伤害与 `atk_buff`。
`atk_para`=`数量,伤害万分比`。**射程内**按威胁锁最多 N 个敌(`Skill.range`≤0 则塔 `Hero.atk_range`,与点击范围圈一致);对每个目标发直线「冰锥」预制体,落地结算伤害与 `atk_buff`。配表写「根据范围内怪物数量」,禁止全屏 `AllEnemies`。
### atk_buff 13 冰冻
@ -194,6 +194,7 @@ Hero(合成等级 level)
| 2026-09-30 | atk_type=16:扇形多段(段数,间隔秒,角度,伤害万分比);atk_buff1/2 命中效果保持不变(100001~100005) |
| 2026-10-04 | atk_type=18:丢出独立圈伤(瞬发不占普攻);atk_type=20:占锁且每段播 animation;result 14 爆炸;atk_buff 14 点燃 |
| 2026-10-08 | atk_type=19 全屏直线冰锥;atk_buff 13 冰冻;result 13 分裂冰锥;飞棍 320301~350301 atk_para 补间隔段 |
| 2026-10-09 | atk_type=19 改射程内索敌(与范围指示器一致),不再 AllEnemies 全屏 |
| 2026-10-08 | 飞剑主动 210101~250101:飞剑.prefab 直线落地伤;剑阵 result1 仍为目标点区域持续跳伤 |
| 2026-10-08 | atk_type=18/20:每段伤害按锁定圆 `pulseHostileCircle` 重新索敌,非施法瞬间名单、非怪上持续 buff |
| 2026-10-08 | atk_type=18:丢出 `飞棍.prefab`(按半径缩放),落地后持续圈伤 |

@ -115,6 +115,7 @@ M| 1 / 3 / 6 / 7 / 15 | 通道播动画 → drain hit(15:逻辑已锁主目
| 2026-09-02 | 去掉地图层 Graphics 组合品质框(ComposedUnitFrame*) |
| 2026-09-02 | Skill.showeffect 预兆特效 |
| 2026-09-03 | Skill.skill type 1 哪吒反向冲锋 |
| 2026-10-09 | 土宝石冲锋(620201~650201):自枪格吸附进路生成「冲锋」预制体,同哪吒进路反冲,飞出独立 |
| 2026-09-04 | 玲珑宝塔 20509:目标处播宝塔砸地技能2 |
| 2026-09-04 | 跟随武器释放:字形与武器都播完才 finish(玉帝普攻 0.5s 不再掐断字形攻击 1s) |
| 2026-09-04 | atk_type=4 非弓:隐藏原武器且不播原武器攻击,飞「玉帝飞剑」(皮肤=当前武器,动画=玉帝普攻,朝向切线) |
@ -143,6 +144,7 @@ M| 1 / 3 / 6 / 7 / 15 | 通道播动画 → drain hit(15:逻辑已锁主目
| 2026-09-30 | 修复弓字形塔散射不发射:Gong 宿主 12/17 委托自身「英雄弓-攻击/投掷物」扇出(BowScatterAtkPresenter),result 10 覆盖普攻形态同步分流 |
| 2026-09-30 | 补注册 atk_type=11 召唤(10051~10055)→ SummonAtkPresenter;表内 1~17 表现已全覆盖,仅 9(将武器形 30406)按兜底结算待策划定义攻效 |
| 2026-10-08 | atk_type=19 冰锥 → IceConeAtkPresenter(水弹直线落地);18/20 已有独立 Presenter |
| 2026-10-09 | atk_type=19 索敌改塔射程,不再全屏 |
| 2026-10-09 | atk_type=19 / 分裂冰锥发射物改「冰锥」;debuff_13 用「冰冻」覆盖播怪物冻结/解冻 |
| 2026-10-09 | atk_type=14:holdCasting+loopWeapon 至多段结束(棍神通「原地旋转大风车」) |
| 2026-10-09 | atk_type=14:每段 `pulseHostileCircle` 重扫施法者射程圆结算 |
@ -150,4 +152,7 @@ M| 1 / 3 / 6 / 7 / 15 | 通道播动画 → drain hit(15:逻辑已锁主目
| 2026-10-08 | atk_type=18 ThrownCircle:改丢 `飞棍.prefab`(半径缩放=半径/175),落地后圈伤 |
| 2026-10-08 | atk_type=20 GroundCircle:主目标圆心放置 `暴风雪.prefab`;占锁循环「暴风雪技能」至圈伤结束 |
| 2026-10-08 | 法杖水弹普攻出手改对齐「水弹攻击1」聚集光能关键帧(0.5s),不再等整段播完 |
| 2026-10-09 | 法杖出手必显武器:勿因在飞水弹/冰锥占 `_weaponFlies` 跳过 `setVisible`,避免无施法动作却出弹 |
| 2026-10-09 | 法杖水弹出手改读 Spine 骨骼「挥砍」首关键帧(约 0.6333s,聚能后砸出);资源更新后随 skeletonJson 自适应 |
| 2026-10-09 | 水属性发射物统一:水弹(atk13)+冰锥(atk19) 均播配表动画,按「挥砍」关键帧出手(下限 0.3s);冰锥不再瞬发 |
| 2026-09-30 | 棍 200005 环形刀光:GunRingAtkPresenter,攻效播完从字位置按 atk_para(起始角,角度间隔,伤害系数)逆时针发射龙影(prefab/skill/棍),体盒弹道首中即消耗;atk_type 改 17(锁单体、伤害全在弹道) |

@ -0,0 +1,46 @@
<html>
<head>
<link rel="icon" href="./favicon.ico" />
<meta charset="utf-8" />
<title><%=title%></title>
<meta
name="viewport"
content="width=device-width,user-scalable=no,initial-scale=1,minimum-scale=1,maximum-scale=1,minimal-ui=true"
/>
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="mobile-web-app-capable" content="yes">
<meta name="full-screen" content="yes" />
<meta name="screen-orientation" content="portrait" />
<meta name="x5-fullscreen" content="true" />
<meta name="360-fullscreen" content="true" />
<meta name="renderer" content="webkit" />
<meta name="force-rendering" content="webkit" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<link rel="stylesheet" type="text/css" href="./index.css" />
</head>
<body style="overflow: hidden;">
<%- include(cocosToolBar, {config: config}) %>
<div id="content" class="content" style="overflow: hidden;">
<div class="contentWrap">
<div id="GameDiv" class="wrapper">
<div id="Cocos3dGameContainer">
<canvas id="GameCanvas" tabindex="-1" style="background-color: '';"></canvas>
</div>
<div id="splash">
<div class="progress-bar stripes"><span></span></div>
</div>
<div id="bulletin">
<div id="sceneIsEmpty" class="inner"><%=tip_sceneIsEmpty%></div>
</div>
<div class="error" id="error">
<div class="title">Error <i>(Please open the console to see detailed errors)</i></div>
<div class="error-main"></div>
<div class="error-stack"></div>
</div>
</div>
</div>
</div>
<%- include(cocosTemplate, {}) %>
</body>
</html>
Loading…
Cancel
Save