diff --git a/assets/bundles/battleGame/prefab/BattleGame.prefab b/assets/bundles/battleGame/prefab/BattleGame.prefab index cf0450d..6364c8f 100644 --- a/assets/bundles/battleGame/prefab/BattleGame.prefab +++ b/assets/bundles/battleGame/prefab/BattleGame.prefab @@ -9972,7 +9972,7 @@ }, "clickEvents": [], "_interactable": true, - "_transition": 3, + "_transition": 0, "_normalColor": { "__type__": "cc.Color", "r": 255, diff --git a/assets/bundles/battleGame/prefab/营地血条.prefab b/assets/bundles/battleGame/prefab/营地血条.prefab index 5a100ee..74f49d5 100644 --- a/assets/bundles/battleGame/prefab/营地血条.prefab +++ b/assets/bundles/battleGame/prefab/营地血条.prefab @@ -20,19 +20,22 @@ "_children": [ { "__id__": 2 + }, + { + "__id__": 14 } ], "_active": true, "_components": [ { - "__id__": 14 + "__id__": 20 }, { - "__id__": 16 + "__id__": 22 } ], "_prefab": { - "__id__": 18 + "__id__": 24 }, "_lpos": { "__type__": "cc.Vec3", @@ -332,6 +335,142 @@ "targetOverrides": null, "nestedPrefabInstanceRoots": null }, + { + "__type__": "cc.Node", + "_name": "保护派派", + "_objFlags": 0, + "__editorExtras__": {}, + "_parent": { + "__id__": 1 + }, + "_children": [], + "_active": true, + "_components": [ + { + "__id__": 15 + }, + { + "__id__": 17 + } + ], + "_prefab": { + "__id__": 19 + }, + "_lpos": { + "__type__": "cc.Vec3", + "x": 0, + "y": -43.859, + "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.UITransform", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 14 + }, + "_enabled": true, + "__prefab": { + "__id__": 16 + }, + "_contentSize": { + "__type__": "cc.Size", + "width": 45.7599983215332, + "height": 52.790000915527344 + }, + "_anchorPoint": { + "__type__": "cc.Vec2", + "x": 0.4755244979683985, + "y": 0.3559386359093728 + }, + "_id": "" + }, + { + "__type__": "cc.CompPrefabInfo", + "fileId": "f5/i6nMStGQb2+BCobRDcY" + }, + { + "__type__": "sp.Skeleton", + "_name": "", + "_objFlags": 0, + "__editorExtras__": {}, + "node": { + "__id__": 14 + }, + "_enabled": true, + "__prefab": { + "__id__": 18 + }, + "_customMaterial": null, + "_srcBlendFactor": 2, + "_dstBlendFactor": 4, + "_color": { + "__type__": "cc.Color", + "r": 255, + "g": 255, + "b": 255, + "a": 255 + }, + "_skeletonData": { + "__uuid__": "7349a7a2-5944-4811-993a-0febfe291be3", + "__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": "cfLPcS9oxASqTT67HsdQl9" + }, + { + "__type__": "cc.PrefabInfo", + "root": { + "__id__": 1 + }, + "asset": { + "__id__": 0 + }, + "fileId": "8egfQqvRhCGLfXhalDzSH8", + "instance": null, + "targetOverrides": null, + "nestedPrefabInstanceRoots": null + }, { "__type__": "cc.UITransform", "_name": "", @@ -342,7 +481,7 @@ }, "_enabled": true, "__prefab": { - "__id__": 15 + "__id__": 21 }, "_contentSize": { "__type__": "cc.Size", @@ -370,7 +509,7 @@ }, "_enabled": true, "__prefab": { - "__id__": 17 + "__id__": 23 }, "_customMaterial": null, "_srcBlendFactor": 2, @@ -414,6 +553,7 @@ "__id__": 0 }, "fileId": "e1uX9LxBJNRqVgq//ID0oy", + "instance": null, "targetOverrides": null } ] \ No newline at end of file diff --git a/assets/bundles/first/config/Battlebuff.json b/assets/bundles/first/config/Battlebuff.json index 8b7bd51..6e2e0bb 100644 --- a/assets/bundles/first/config/Battlebuff.json +++ b/assets/bundles/first/config/Battlebuff.json @@ -17,7 +17,7 @@ "desc": "一定几率召唤出倍率卡,拖到数字上升1级或2级", "icon": "倍率卡", "quality": 4, - "type": 1, + "type": 2, "functiontype": 2, "functionpar": "1000,80,20", "weight": 1, @@ -79,7 +79,7 @@ "quality": 3, "type": 2, "functiontype": 7, - "functionpar": 50003000, + "functionpar": "5000,3000", "weight": 1, "price": 120 }, @@ -185,7 +185,7 @@ "desc": "一定几率召唤出属性卡,拖到数字上随机变换一个属性", "icon": "属性卡", "quality": 3, - "type": 1, + "type": 2, "functiontype": 16, "functionpar": 1000, "weight": 1, diff --git a/assets/bundles/first/config/Const.json b/assets/bundles/first/config/Const.json index aded47d..545a357 100644 --- a/assets/bundles/first/config/Const.json +++ b/assets/bundles/first/config/Const.json @@ -220,5 +220,11 @@ "desc": "星期7地图id", "para": 0, "para1": "6,1,2" + }, + { + "id": 38, + "desc": "战斗中看视频加金币次数和对应数量,次数就是数组长度", + "para": 0, + "para1": "30,100,200" } ] \ No newline at end of file diff --git a/assets/bundles/icons/img/仙桃.png b/assets/bundles/icons/img/仙桃.png deleted file mode 100644 index 3f1460e..0000000 Binary files a/assets/bundles/icons/img/仙桃.png and /dev/null differ diff --git a/assets/bundles/icons/img/金币.png b/assets/bundles/icons/img/金币.png new file mode 100644 index 0000000..e7e773b Binary files /dev/null and b/assets/bundles/icons/img/金币.png differ diff --git a/assets/bundles/icons/img/仙桃.png.meta b/assets/bundles/icons/img/金币.png.meta similarity index 75% rename from assets/bundles/icons/img/仙桃.png.meta rename to assets/bundles/icons/img/金币.png.meta index e06a45a..7ea4b14 100644 --- a/assets/bundles/icons/img/仙桃.png.meta +++ b/assets/bundles/icons/img/金币.png.meta @@ -11,7 +11,7 @@ "6c48a": { "importer": "texture", "uuid": "838b701a-0e28-49f7-8d4d-175b36c48b6d@6c48a", - "displayName": "仙桃", + "displayName": "金币", "id": "6c48a", "name": "texture", "userData": { @@ -35,20 +35,20 @@ "f9941": { "importer": "sprite-frame", "uuid": "838b701a-0e28-49f7-8d4d-175b36c48b6d@f9941", - "displayName": "仙桃", + "displayName": "金币", "id": "f9941", "name": "spriteFrame", "userData": { "trimThreshold": 1, "rotated": false, "offsetX": 0, - "offsetY": -4, - "trimX": 8, - "trimY": 24, - "width": 184, - "height": 160, - "rawWidth": 200, - "rawHeight": 200, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 49, + "height": 47, + "rawWidth": 49, + "rawHeight": 47, "borderTop": 0, "borderBottom": 0, "borderLeft": 0, @@ -60,17 +60,17 @@ "meshType": 0, "vertices": { "rawPosition": [ - -92, - -80, + -24.5, + -23.5, 0, - 92, - -80, + 24.5, + -23.5, 0, - -92, - 80, + -24.5, + 23.5, 0, - 92, - 80, + 24.5, + 23.5, 0 ], "indexes": [ @@ -82,33 +82,33 @@ 3 ], "uv": [ - 8, - 176, - 192, - 176, - 8, - 16, - 192, - 16 + 0, + 47, + 49, + 47, + 0, + 0, + 49, + 0 ], "nuv": [ - 0.04, - 0.08, - 0.96, - 0.08, - 0.04, - 0.88, - 0.96, - 0.88 + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 ], "minPos": [ - -92, - -80, + -24.5, + -23.5, 0 ], "maxPos": [ - 92, - 80, + 24.5, + 23.5, 0 ] }, diff --git a/assets/mx/components/list/List.ts b/assets/mx/components/list/List.ts index 926078c..86e3bbc 100644 --- a/assets/mx/components/list/List.ts +++ b/assets/mx/components/list/List.ts @@ -397,8 +397,7 @@ export default class List extends Component { /** ScrollView.view(Mask 裁剪区)尺寸,用于虚拟列表可视范围计算 */ private _getViewUt(): UITransform { - const viewNode = this._scrollView?.view as Node | null; - return viewNode?.getComponent(UITransform) ?? this._thisNodeUt; + return this._scrollView?.view ?? this._thisNodeUt; } //---------------------------------------------------------------------------- diff --git a/assets/mx/module/merge/core/MergeSession.ts b/assets/mx/module/merge/core/MergeSession.ts index a942479..fdacd4d 100644 --- a/assets/mx/module/merge/core/MergeSession.ts +++ b/assets/mx/module/merge/core/MergeSession.ts @@ -84,7 +84,7 @@ export class MergeSession { this._coordOf = options.coordOf; this.bag = new BagBoard(options.bagSlotCount ?? 5); this.map = new MapTileBoard(); - this._upgrade = new UpgradeSystem(this._config); + this._upgrade = new UpgradeSystem(); } get compositions(): readonly ComposedUnit[] { diff --git a/assets/res/spine/保护派派.atlas b/assets/res/spine/保护派派.atlas new file mode 100644 index 0000000..9d9a29e --- /dev/null +++ b/assets/res/spine/保护派派.atlas @@ -0,0 +1,55 @@ + +保护派派.png +size: 194,67 +format: RGBA8888 +filter: Linear,Linear +repeat: none +π + rotate: true + xy: 139, 21 + size: 46, 40 + orig: 46, 40 + offset: 0, 0 + index: -1 +抖动1 + rotate: true + xy: 0, 0 + size: 67, 68 + orig: 68, 68 + offset: 0, 0 + index: -1 +抖动2 + rotate: false + xy: 70, 2 + size: 67, 65 + orig: 68, 65 + offset: 0, 0 + index: -1 +眼1 + rotate: true + xy: 139, 2 + size: 17, 21 + orig: 20, 23 + offset: 1, 1 + index: -1 +眼2 + rotate: true + xy: 162, 2 + size: 17, 21 + orig: 20, 23 + offset: 1, 1 + index: -1 +眼泪 + rotate: false + xy: 181, 47 + size: 13, 20 + orig: 13, 20 + offset: 0, 0 + index: -1 +眼睛2 + rotate: false + xy: 181, 37 + size: 6, 8 + orig: 8, 10 + offset: 1, 1 + index: -1 diff --git a/assets/res/spine/保护派派.atlas.meta b/assets/res/spine/保护派派.atlas.meta new file mode 100644 index 0000000..a236efb --- /dev/null +++ b/assets/res/spine/保护派派.atlas.meta @@ -0,0 +1,12 @@ +{ + "ver": "1.0.0", + "importer": "*", + "imported": true, + "uuid": "9dbebd97-b7db-41b2-9c9f-c632b77aedd2", + "files": [ + ".atlas", + ".json" + ], + "subMetas": {}, + "userData": {} +} diff --git a/assets/res/spine/保护派派.json b/assets/res/spine/保护派派.json new file mode 100644 index 0000000..3cd272c --- /dev/null +++ b/assets/res/spine/保护派派.json @@ -0,0 +1 @@ +{"skeleton":{"hash":"GSmpy5X6+pk9GoC8yL539dThMXw","spine":"3.8.75","x":-21.76,"y":-18.79,"width":45.76,"height":52.79},"bones":[{"name":"root"},{"name":"π","parent":"root","length":20.11,"rotation":90.34,"x":1.25,"y":-12.56},{"name":"π2","parent":"π","length":6.05,"rotation":-168.92,"x":13.74,"y":-6.41},{"name":"π3","parent":"π2","length":4.58,"rotation":27.02,"x":6.23,"y":0.02},{"name":"π4","parent":"π3","length":6.29,"rotation":46.89,"x":4.93,"y":0.16},{"name":"眼1","parent":"π","length":8.29,"rotation":-89.29,"x":27.62,"y":-6.78},{"name":"眼睛2","parent":"眼1","x":0.22,"y":8.05},{"name":"眼2","parent":"眼1","x":9.03,"y":29.95},{"name":"眼3","parent":"π","length":8.29,"rotation":-89.29,"x":27.72,"y":9.57},{"name":"眼睛3","parent":"眼3","x":0.22,"y":8.05},{"name":"眼4","parent":"眼3","x":9.03,"y":29.95},{"name":"眼泪","parent":"π","length":9.6,"rotation":179.66,"x":27.53,"y":10.74}],"slots":[{"name":"π","bone":"π","attachment":"π"},{"name":"眼2","bone":"眼1","attachment":"眼2"},{"name":"眼3","bone":"眼3","attachment":"眼2"},{"name":"眼睛2","bone":"眼睛2","attachment":"眼睛2"},{"name":"眼睛3","bone":"眼睛3","attachment":"眼睛2"},{"name":"眼22","bone":"眼2","attachment":"眼22"},{"name":"眼1","bone":"眼1","attachment":"眼1"},{"name":"眼23","bone":"眼4","attachment":"眼22"},{"name":"眼4","bone":"眼3","attachment":"眼1"},{"name":"抖动1","bone":"root"},{"name":"眼泪","bone":"眼泪"}],"skins":[{"name":"default","attachments":{"π":{"π":{"type":"mesh","uvs":[0.12367,0.03948,0.04295,0.08061,0.01537,0.15698,0.00515,0.25921,0.01434,0.40021,0.05624,0.48951,0.13389,0.52711,0.12776,0.63168,0.08689,0.73743,0.06134,0.81733,0.09915,0.94893,0.20541,0.98418,0.37502,0.99476,0.47106,0.97243,0.52317,0.87373,0.59571,0.94541,0.72037,0.97948,0.87567,0.95716,0.96763,0.88196,1,0.73978,0.9993,0.56001,0.9615,0.48128,0.8726,0.46718,0.95537,0.39903,0.98193,0.27331,0.96456,0.11351,0.89713,0.01481,0.68256,0.02068,0.46187,0.03126,0.27489,0.03713,0.50682,0.66811,0.49558,0.49068,0.4915,0.33441,0.46391,0.34028,0.46595,0.47541,0.46493,0.61758,0.47311,0.77856],"triangles":[24,22,27,24,27,25,32,28,27,33,28,32,29,28,33,0,4,3,32,27,22,34,33,32,31,34,32,0,2,1,2,0,3,6,5,4,22,31,32,29,4,0,6,29,33,6,33,34,29,6,4,35,6,34,35,34,31,7,6,35,30,31,22,35,31,30,36,35,30,15,14,30,36,30,14,30,19,15,36,10,8,9,8,10,36,7,35,13,36,14,7,36,8,36,11,10,36,12,11,13,12,36,25,27,26,23,22,24,19,22,20,20,22,21,22,19,30,15,19,16,18,17,19,17,16,19],"vertices":[1,1,32.09,17.37,1,1,1,30.46,21.09,1,1,1,27.42,22.38,1,1,1,23.33,22.87,1,1,1,17.69,22.48,1,1,1,14.1,20.58,1,1,1,12.58,17.01,1,1,1,8.4,17.32,1,1,1,4.18,19.22,1,1,1,0.99,20.42,1,1,1,-4.29,18.71,1,1,1,-5.72,13.83,1,1,1,-6.19,6.03,1,1,1,-5.33,1.61,1,3,1,-1.39,-0.81,0.90434,3,2.9,-10.93,0.08931,4,-9.49,-6.1,0.00635,3,1,-4.28,-4.13,0.47323,3,7.22,-10.1,0.42058,4,-5.93,-8.69,0.1062,3,1,-5.68,-9.86,0.17673,3,11.85,-6.46,0.3376,4,-0.1,-9.58,0.48567,3,1,-4.83,-17.01,0.01808,3,15.6,-0.31,0.02881,4,6.95,-8.1,0.95311,2,1,-1.84,-21.26,5.0E-5,4,10.92,-4.76,0.99995,2,2,12.87,14.16,0.03585,4,11.94,1.03,0.96415,2,2,5.81,15.55,0.28862,4,11.32,8.19,0.71138,3,2,2.38,14.47,0.40511,3,3.14,14.62,6.6E-4,4,9.33,11.19,0.59423,4,1,14.77,-16.98,0.00818,2,1.02,10.58,0.6894,3,0.16,11.77,0.00558,4,5.21,11.42,0.29684,3,1,17.48,-20.81,0.03645,2,-0.9,14.85,0.86294,4,8.78,14.45,0.10061,3,1,22.5,-22.06,0.0795,2,-5.59,17.04,0.87601,4,9.59,19.56,0.04449,3,1,28.9,-21.3,0.15437,2,-12.01,17.52,0.83554,4,8.27,25.86,0.01009,3,1,32.86,-18.22,0.20884,2,-16.49,15.26,0.78944,4,4.86,29.54,0.00171,2,1,32.69,-8.35,0.50028,2,-18.22,5.54,0.49972,2,1,32.32,1.81,0.92372,2,-19.81,-4.49,0.07628,2,1,32.14,10.41,0.99993,2,-21.28,-12.97,7.0E-5,3,1,6.84,-0.11,0.99436,2,5.57,-7.51,0.00186,3,-4.01,-6.41,0.00377,1,1,13.94,0.37,1,1,1,20.19,0.52,1,1,1,19.96,1.79,1,1,1,14.56,1.73,1,1,1,8.87,1.81,1,1,1,2.43,1.47,1],"hull":30}},"抖动1":{"抖动1":{"x":0.94,"y":9.07,"rotation":1.05,"width":68,"height":68},"抖动2":{"x":-0.1,"y":8.42,"width":68,"height":65}},"眼泪":{"眼泪":{"x":7.33,"y":0.1,"rotation":90,"width":13,"height":20}},"眼睛2":{"眼睛2":{"x":0.06,"y":-0.16,"rotation":-1.05,"width":8,"height":10}},"眼睛3":{"眼睛2":{"x":0.06,"y":-0.16,"rotation":-1.05,"width":8,"height":10}},"眼1":{"眼1":{"x":-0.73,"y":7.42,"rotation":-1.05,"width":20,"height":23}},"眼2":{"眼2":{"x":-0.73,"y":7.42,"rotation":-1.05,"width":20,"height":23}},"眼3":{"眼2":{"x":-0.73,"y":7.42,"rotation":-1.05,"width":20,"height":23}},"眼4":{"眼1":{"x":-0.73,"y":7.42,"rotation":-1.05,"width":20,"height":23}},"眼22":{"眼22":{"type":"clipping","end":"眼1","vertexCount":4,"vertices":[-22.4,13.56,-21.36,-12.23,-0.43,-11.24,-0.9,13.24]}},"眼23":{"眼22":{"type":"clipping","end":"眼4","vertexCount":4,"vertices":[-22.4,13.56,-21.36,-12.23,-0.43,-11.24,-0.9,13.24]}}}}],"animations":{"害怕":{"slots":{"眼泪":{"attachment":[{"name":"眼泪"}]},"抖动1":{"attachment":[{"time":0.1,"name":"抖动2"},{"time":0.2,"name":"抖动1"},{"time":0.3,"name":"抖动2"},{"time":0.4,"name":"抖动1"},{"time":0.5,"name":null},{"time":0.8667,"name":"抖动1"},{"time":0.9667,"name":"抖动2"},{"time":1.0667,"name":"抖动1"},{"time":1.1667,"name":"抖动2"},{"time":1.2667,"name":"抖动1"},{"time":1.3667,"name":"抖动2"},{"time":1.4667,"name":"抖动1"},{"time":1.5667,"name":null}]}},"bones":{"眼4":{"rotate":[{"angle":19.62}],"translate":[{"x":-4.82,"y":-6.95},{"time":0.1,"x":-4.84,"y":-7.84},{"time":0.2,"x":-4.82,"y":-6.95},{"time":0.3,"x":-4.84,"y":-7.84},{"time":0.4333,"x":-4.82,"y":-6.95},{"time":0.5667,"x":-4.84,"y":-7.84},{"time":0.6667,"x":-4.82,"y":-6.95},{"time":0.7667,"x":-4.84,"y":-7.84},{"time":0.8667,"x":-4.82,"y":-6.95},{"time":0.9667,"x":-4.84,"y":-7.84},{"time":1.1,"x":-4.82,"y":-6.95},{"time":1.2333,"x":-4.84,"y":-7.84},{"time":1.3333,"x":-4.82,"y":-6.95},{"time":1.4333,"x":-4.84,"y":-7.84},{"time":1.5333,"x":-4.82,"y":-6.95},{"time":1.6333,"x":-4.84,"y":-7.84},{"time":1.7667,"x":-4.82,"y":-6.95},{"time":1.9,"x":-4.84,"y":-7.84},{"time":2,"x":-4.82,"y":-6.95}]},"眼2":{"rotate":[{"angle":-19.03}],"translate":[{"x":6.41,"y":-12.74},{"time":0.1,"x":6.4,"y":-13.63},{"time":0.2,"x":6.41,"y":-12.74},{"time":0.3,"x":6.4,"y":-13.63},{"time":0.4333,"x":6.41,"y":-12.74},{"time":0.5667,"x":6.4,"y":-13.63},{"time":0.6667,"x":6.41,"y":-12.74},{"time":0.7667,"x":6.4,"y":-13.63},{"time":0.8667,"x":6.41,"y":-12.74},{"time":0.9667,"x":6.4,"y":-13.63},{"time":1.1,"x":6.41,"y":-12.74},{"time":1.2333,"x":6.4,"y":-13.63},{"time":1.3333,"x":6.41,"y":-12.74},{"time":1.4333,"x":6.4,"y":-13.63},{"time":1.5333,"x":6.41,"y":-12.74},{"time":1.6333,"x":6.4,"y":-13.63},{"time":1.7667,"x":6.41,"y":-12.74},{"time":1.9,"x":6.4,"y":-13.63},{"time":2,"x":6.41,"y":-12.74}]},"π2":{"rotate":[{},{"time":0.1,"angle":-1.6},{"time":0.1667},{"time":0.2667,"angle":-1.6},{"time":0.3333},{"time":0.4333,"angle":-1.6},{"time":0.5},{"time":0.6,"angle":-1.6},{"time":0.6667},{"time":0.7667,"angle":-1.6},{"time":0.8333},{"time":0.9333,"angle":-1.6},{"time":1},{"time":1.1,"angle":-1.6},{"time":1.1667},{"time":1.2667,"angle":-1.6},{"time":1.3333},{"time":1.4333,"angle":-1.6},{"time":1.5},{"time":1.6,"angle":-1.6},{"time":1.6667},{"time":1.7667,"angle":-1.6},{"time":1.8333},{"time":1.9333,"angle":-1.6},{"time":2}],"translate":[{},{"time":0.1,"x":-0.69,"y":1.19},{"time":0.1667},{"time":0.2667,"x":-0.69,"y":1.19},{"time":0.3333},{"time":0.4333,"x":-0.69,"y":1.19},{"time":0.5},{"time":0.6,"x":-0.69,"y":1.19},{"time":0.6667},{"time":0.7667,"x":-0.69,"y":1.19},{"time":0.8333},{"time":0.9333,"x":-0.69,"y":1.19},{"time":1},{"time":1.1,"x":-0.69,"y":1.19},{"time":1.1667},{"time":1.2667,"x":-0.69,"y":1.19},{"time":1.3333},{"time":1.4333,"x":-0.69,"y":1.19},{"time":1.5},{"time":1.6,"x":-0.69,"y":1.19},{"time":1.6667},{"time":1.7667,"x":-0.69,"y":1.19},{"time":1.8333},{"time":1.9333,"x":-0.69,"y":1.19},{"time":2}]},"π3":{"rotate":[{},{"time":0.1,"angle":-1.6},{"time":0.1667},{"time":0.2667,"angle":-1.6},{"time":0.3333},{"time":0.4333,"angle":-1.6},{"time":0.5},{"time":0.6,"angle":-1.6},{"time":0.6667},{"time":0.7667,"angle":-1.6},{"time":0.8333},{"time":0.9333,"angle":-1.6},{"time":1},{"time":1.1,"angle":-1.6},{"time":1.1667},{"time":1.2667,"angle":-1.6},{"time":1.3333},{"time":1.4333,"angle":-1.6},{"time":1.5},{"time":1.6,"angle":-1.6},{"time":1.6667},{"time":1.7667,"angle":-1.6},{"time":1.8333},{"time":1.9333,"angle":-1.6},{"time":2}]},"π4":{"rotate":[{},{"time":0.1,"angle":-1.6},{"time":0.1667},{"time":0.2667,"angle":-1.6},{"time":0.3333},{"time":0.4333,"angle":-1.6},{"time":0.5},{"time":0.6,"angle":-1.6},{"time":0.6667},{"time":0.7667,"angle":-1.6},{"time":0.8333},{"time":0.9333,"angle":-1.6},{"time":1},{"time":1.1,"angle":-1.6},{"time":1.1667},{"time":1.2667,"angle":-1.6},{"time":1.3333},{"time":1.4333,"angle":-1.6},{"time":1.5},{"time":1.6,"angle":-1.6},{"time":1.6667},{"time":1.7667,"angle":-1.6},{"time":1.8333},{"time":1.9333,"angle":-1.6},{"time":2}]},"眼睛3":{"translate":[{"x":-0.51,"y":-0.78}]},"眼泪":{"translate":[{"x":0.2,"y":-0.2}],"scale":[{"x":0.639,"y":0.639},{"time":0.3333,"x":0.734,"y":0.734},{"time":0.6667,"x":0.639,"y":0.639},{"time":1,"x":0.734,"y":0.734},{"time":1.3333,"x":0.639,"y":0.639},{"time":1.6667,"x":0.734,"y":0.734},{"time":2,"x":0.639,"y":0.639}]}}},"待机":{"bones":{"π2":{"rotate":[{},{"time":0.2333,"angle":3.03},{"time":0.5},{"time":0.7333,"angle":3.03},{"time":1},{"time":1.2333,"angle":3.03},{"time":1.5},{"time":1.7333,"angle":3.03},{"time":2},{"time":2.2333,"angle":3.03},{"time":2.5},{"time":2.7333,"angle":3.03},{"time":3},{"time":3.2333,"angle":3.03},{"time":3.5},{"time":3.7333,"angle":3.03},{"time":4}]},"π3":{"rotate":[{},{"time":0.2333,"angle":9.2},{"time":0.5},{"time":0.7333,"angle":9.2},{"time":1},{"time":1.2333,"angle":9.2},{"time":1.5},{"time":1.7333,"angle":9.2},{"time":2},{"time":2.2333,"angle":9.2},{"time":2.5},{"time":2.7333,"angle":9.2},{"time":3},{"time":3.2333,"angle":9.2},{"time":3.5},{"time":3.7333,"angle":9.2},{"time":4}]},"π4":{"rotate":[{},{"time":0.2333,"angle":15.91},{"time":0.5},{"time":0.7333,"angle":15.91},{"time":1},{"time":1.2333,"angle":15.91},{"time":1.5},{"time":1.7333,"angle":15.91},{"time":2},{"time":2.2333,"angle":15.91},{"time":2.5},{"time":2.7333,"angle":15.91},{"time":3},{"time":3.2333,"angle":15.91},{"time":3.5},{"time":3.7333,"angle":15.91},{"time":4}]},"眼睛3":{"translate":[{"time":0.3333},{"time":0.5,"x":-3.96,"y":1.57,"curve":"stepped"},{"time":1.3333,"x":-3.96,"y":1.57},{"time":1.5667,"x":-2.22,"y":-3.2,"curve":"stepped"},{"time":2.8333,"x":-2.22,"y":-3.2},{"time":3.1}]},"眼睛2":{"translate":[{"time":0.3333},{"time":0.5,"x":-3.96,"y":1.57,"curve":"stepped"},{"time":1.3333,"x":-3.96,"y":1.57},{"time":1.5667,"x":-2.22,"y":-3.2,"curve":"stepped"},{"time":2.8333,"x":-2.22,"y":-3.2},{"time":3.1}]},"眼4":{"translate":[{"time":2},{"time":2.1667,"x":0.38,"y":-11.13,"curve":"stepped"},{"time":2.8333,"x":0.38,"y":-11.13},{"time":3.1}]},"眼2":{"translate":[{"time":2},{"time":2.1667,"x":0.38,"y":-11.13,"curve":"stepped"},{"time":2.8333,"x":0.38,"y":-11.13},{"time":3.1}]},"π":{"rotate":[{"time":1.5},{"time":1.8333,"angle":-5.3,"curve":"stepped"},{"time":2.8,"angle":-5.3},{"time":3.1667}],"scale":[{},{"time":0.5,"x":0.977,"y":1.03},{"time":1},{"time":1.5,"x":0.977,"y":1.03},{"time":2},{"time":2.5,"x":0.977,"y":1.03},{"time":3},{"time":3.5,"x":0.977,"y":1.03},{"time":4}]}}}}} \ No newline at end of file diff --git a/assets/res/spine/保护派派.json.meta b/assets/res/spine/保护派派.json.meta new file mode 100644 index 0000000..f358b3a --- /dev/null +++ b/assets/res/spine/保护派派.json.meta @@ -0,0 +1,13 @@ +{ + "ver": "1.2.7", + "importer": "spine-data", + "imported": true, + "uuid": "7349a7a2-5944-4811-993a-0febfe291be3", + "files": [ + ".json" + ], + "subMetas": {}, + "userData": { + "atlasUuid": "9dbebd97-b7db-41b2-9c9f-c632b77aedd2" + } +} diff --git a/assets/res/spine/保护派派.png b/assets/res/spine/保护派派.png new file mode 100644 index 0000000..5ae6a4f Binary files /dev/null and b/assets/res/spine/保护派派.png differ diff --git a/assets/res/spine/保护派派.png.meta b/assets/res/spine/保护派派.png.meta new file mode 100644 index 0000000..aee1c00 --- /dev/null +++ b/assets/res/spine/保护派派.png.meta @@ -0,0 +1,134 @@ +{ + "ver": "1.0.27", + "importer": "image", + "imported": true, + "uuid": "74485d02-37cf-43f9-b793-460ffa49be2f", + "files": [ + ".json", + ".png" + ], + "subMetas": { + "6c48a": { + "importer": "texture", + "uuid": "74485d02-37cf-43f9-b793-460ffa49be2f@6c48a", + "displayName": "保护派派", + "id": "6c48a", + "name": "texture", + "userData": { + "wrapModeS": "clamp-to-edge", + "wrapModeT": "clamp-to-edge", + "imageUuidOrDatabaseUri": "74485d02-37cf-43f9-b793-460ffa49be2f", + "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": "74485d02-37cf-43f9-b793-460ffa49be2f@f9941", + "displayName": "保护派派", + "id": "f9941", + "name": "spriteFrame", + "userData": { + "trimThreshold": 1, + "rotated": false, + "offsetX": 0, + "offsetY": 0, + "trimX": 0, + "trimY": 0, + "width": 194, + "height": 67, + "rawWidth": 194, + "rawHeight": 67, + "borderTop": 0, + "borderBottom": 0, + "borderLeft": 0, + "borderRight": 0, + "packable": true, + "pixelsToUnit": 100, + "pivotX": 0.5, + "pivotY": 0.5, + "meshType": 0, + "vertices": { + "rawPosition": [ + -97, + -33.5, + 0, + 97, + -33.5, + 0, + -97, + 33.5, + 0, + 97, + 33.5, + 0 + ], + "indexes": [ + 0, + 1, + 2, + 2, + 1, + 3 + ], + "uv": [ + 0, + 67, + 194, + 67, + 0, + 0, + 194, + 0 + ], + "nuv": [ + 0, + 0, + 1, + 0, + 0, + 1, + 1, + 1 + ], + "minPos": [ + -97, + -33.5, + 0 + ], + "maxPos": [ + 97, + 33.5, + 0 + ] + }, + "isUuid": true, + "imageUuidOrDatabaseUri": "74485d02-37cf-43f9-b793-460ffa49be2f@6c48a", + "atlasUuid": "", + "trimType": "auto" + }, + "ver": "1.0.12", + "imported": true, + "files": [ + ".json" + ], + "subMetas": {} + } + }, + "userData": { + "type": "sprite-frame", + "fixAlphaTransparencyArtifacts": false, + "hasAlpha": true, + "redirect": "74485d02-37cf-43f9-b793-460ffa49be2f@6c48a" + } +} diff --git a/assets/res/spine/likeRole/数字.meta b/assets/res/spine/数字.meta similarity index 100% rename from assets/res/spine/likeRole/数字.meta rename to assets/res/spine/数字.meta diff --git a/assets/res/spine/likeRole/数字/数字1.atlas b/assets/res/spine/数字/数字1.atlas similarity index 100% rename from assets/res/spine/likeRole/数字/数字1.atlas rename to assets/res/spine/数字/数字1.atlas diff --git a/assets/res/spine/likeRole/数字/数字1.atlas.meta b/assets/res/spine/数字/数字1.atlas.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字1.atlas.meta rename to assets/res/spine/数字/数字1.atlas.meta diff --git a/assets/res/spine/likeRole/数字/数字1.json b/assets/res/spine/数字/数字1.json similarity index 100% rename from assets/res/spine/likeRole/数字/数字1.json rename to assets/res/spine/数字/数字1.json diff --git a/assets/res/spine/likeRole/数字/数字1.json.meta b/assets/res/spine/数字/数字1.json.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字1.json.meta rename to assets/res/spine/数字/数字1.json.meta diff --git a/assets/res/spine/likeRole/数字/数字1.png b/assets/res/spine/数字/数字1.png similarity index 100% rename from assets/res/spine/likeRole/数字/数字1.png rename to assets/res/spine/数字/数字1.png diff --git a/assets/res/spine/likeRole/数字/数字1.png.meta b/assets/res/spine/数字/数字1.png.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字1.png.meta rename to assets/res/spine/数字/数字1.png.meta diff --git a/assets/res/spine/likeRole/数字/数字1024.atlas b/assets/res/spine/数字/数字1024.atlas similarity index 100% rename from assets/res/spine/likeRole/数字/数字1024.atlas rename to assets/res/spine/数字/数字1024.atlas diff --git a/assets/res/spine/likeRole/数字/数字1024.atlas.meta b/assets/res/spine/数字/数字1024.atlas.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字1024.atlas.meta rename to assets/res/spine/数字/数字1024.atlas.meta diff --git a/assets/res/spine/likeRole/数字/数字1024.json b/assets/res/spine/数字/数字1024.json similarity index 100% rename from assets/res/spine/likeRole/数字/数字1024.json rename to assets/res/spine/数字/数字1024.json diff --git a/assets/res/spine/likeRole/数字/数字1024.json.meta b/assets/res/spine/数字/数字1024.json.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字1024.json.meta rename to assets/res/spine/数字/数字1024.json.meta diff --git a/assets/res/spine/likeRole/数字/数字1024.png b/assets/res/spine/数字/数字1024.png similarity index 100% rename from assets/res/spine/likeRole/数字/数字1024.png rename to assets/res/spine/数字/数字1024.png diff --git a/assets/res/spine/likeRole/数字/数字1024.png.meta b/assets/res/spine/数字/数字1024.png.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字1024.png.meta rename to assets/res/spine/数字/数字1024.png.meta diff --git a/assets/res/spine/likeRole/数字/数字128.atlas b/assets/res/spine/数字/数字128.atlas similarity index 100% rename from assets/res/spine/likeRole/数字/数字128.atlas rename to assets/res/spine/数字/数字128.atlas diff --git a/assets/res/spine/likeRole/数字/数字128.atlas.meta b/assets/res/spine/数字/数字128.atlas.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字128.atlas.meta rename to assets/res/spine/数字/数字128.atlas.meta diff --git a/assets/res/spine/likeRole/数字/数字128.json b/assets/res/spine/数字/数字128.json similarity index 100% rename from assets/res/spine/likeRole/数字/数字128.json rename to assets/res/spine/数字/数字128.json diff --git a/assets/res/spine/likeRole/数字/数字128.json.meta b/assets/res/spine/数字/数字128.json.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字128.json.meta rename to assets/res/spine/数字/数字128.json.meta diff --git a/assets/res/spine/likeRole/数字/数字128.png b/assets/res/spine/数字/数字128.png similarity index 100% rename from assets/res/spine/likeRole/数字/数字128.png rename to assets/res/spine/数字/数字128.png diff --git a/assets/res/spine/likeRole/数字/数字128.png.meta b/assets/res/spine/数字/数字128.png.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字128.png.meta rename to assets/res/spine/数字/数字128.png.meta diff --git a/assets/res/spine/likeRole/数字/数字16.atlas b/assets/res/spine/数字/数字16.atlas similarity index 100% rename from assets/res/spine/likeRole/数字/数字16.atlas rename to assets/res/spine/数字/数字16.atlas diff --git a/assets/res/spine/likeRole/数字/数字16.atlas.meta b/assets/res/spine/数字/数字16.atlas.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字16.atlas.meta rename to assets/res/spine/数字/数字16.atlas.meta diff --git a/assets/res/spine/likeRole/数字/数字16.json b/assets/res/spine/数字/数字16.json similarity index 100% rename from assets/res/spine/likeRole/数字/数字16.json rename to assets/res/spine/数字/数字16.json diff --git a/assets/res/spine/likeRole/数字/数字16.json.meta b/assets/res/spine/数字/数字16.json.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字16.json.meta rename to assets/res/spine/数字/数字16.json.meta diff --git a/assets/res/spine/likeRole/数字/数字16.png b/assets/res/spine/数字/数字16.png similarity index 100% rename from assets/res/spine/likeRole/数字/数字16.png rename to assets/res/spine/数字/数字16.png diff --git a/assets/res/spine/likeRole/数字/数字16.png.meta b/assets/res/spine/数字/数字16.png.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字16.png.meta rename to assets/res/spine/数字/数字16.png.meta diff --git a/assets/res/spine/likeRole/数字/数字2.atlas b/assets/res/spine/数字/数字2.atlas similarity index 100% rename from assets/res/spine/likeRole/数字/数字2.atlas rename to assets/res/spine/数字/数字2.atlas diff --git a/assets/res/spine/likeRole/数字/数字2.atlas.meta b/assets/res/spine/数字/数字2.atlas.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字2.atlas.meta rename to assets/res/spine/数字/数字2.atlas.meta diff --git a/assets/res/spine/likeRole/数字/数字2.json b/assets/res/spine/数字/数字2.json similarity index 100% rename from assets/res/spine/likeRole/数字/数字2.json rename to assets/res/spine/数字/数字2.json diff --git a/assets/res/spine/likeRole/数字/数字2.json.meta b/assets/res/spine/数字/数字2.json.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字2.json.meta rename to assets/res/spine/数字/数字2.json.meta diff --git a/assets/res/spine/likeRole/数字/数字2.png b/assets/res/spine/数字/数字2.png similarity index 100% rename from assets/res/spine/likeRole/数字/数字2.png rename to assets/res/spine/数字/数字2.png diff --git a/assets/res/spine/likeRole/数字/数字2.png.meta b/assets/res/spine/数字/数字2.png.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字2.png.meta rename to assets/res/spine/数字/数字2.png.meta diff --git a/assets/res/spine/likeRole/数字/数字2048.atlas b/assets/res/spine/数字/数字2048.atlas similarity index 100% rename from assets/res/spine/likeRole/数字/数字2048.atlas rename to assets/res/spine/数字/数字2048.atlas diff --git a/assets/res/spine/likeRole/数字/数字2048.atlas.meta b/assets/res/spine/数字/数字2048.atlas.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字2048.atlas.meta rename to assets/res/spine/数字/数字2048.atlas.meta diff --git a/assets/res/spine/likeRole/数字/数字2048.json b/assets/res/spine/数字/数字2048.json similarity index 100% rename from assets/res/spine/likeRole/数字/数字2048.json rename to assets/res/spine/数字/数字2048.json diff --git a/assets/res/spine/likeRole/数字/数字2048.json.meta b/assets/res/spine/数字/数字2048.json.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字2048.json.meta rename to assets/res/spine/数字/数字2048.json.meta diff --git a/assets/res/spine/likeRole/数字/数字2048.png b/assets/res/spine/数字/数字2048.png similarity index 100% rename from assets/res/spine/likeRole/数字/数字2048.png rename to assets/res/spine/数字/数字2048.png diff --git a/assets/res/spine/likeRole/数字/数字2048.png.meta b/assets/res/spine/数字/数字2048.png.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字2048.png.meta rename to assets/res/spine/数字/数字2048.png.meta diff --git a/assets/res/spine/likeRole/数字/数字256.atlas b/assets/res/spine/数字/数字256.atlas similarity index 100% rename from assets/res/spine/likeRole/数字/数字256.atlas rename to assets/res/spine/数字/数字256.atlas diff --git a/assets/res/spine/likeRole/数字/数字256.atlas.meta b/assets/res/spine/数字/数字256.atlas.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字256.atlas.meta rename to assets/res/spine/数字/数字256.atlas.meta diff --git a/assets/res/spine/likeRole/数字/数字256.json b/assets/res/spine/数字/数字256.json similarity index 100% rename from assets/res/spine/likeRole/数字/数字256.json rename to assets/res/spine/数字/数字256.json diff --git a/assets/res/spine/likeRole/数字/数字256.json.meta b/assets/res/spine/数字/数字256.json.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字256.json.meta rename to assets/res/spine/数字/数字256.json.meta diff --git a/assets/res/spine/likeRole/数字/数字256.png b/assets/res/spine/数字/数字256.png similarity index 100% rename from assets/res/spine/likeRole/数字/数字256.png rename to assets/res/spine/数字/数字256.png diff --git a/assets/res/spine/likeRole/数字/数字256.png.meta b/assets/res/spine/数字/数字256.png.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字256.png.meta rename to assets/res/spine/数字/数字256.png.meta diff --git a/assets/res/spine/likeRole/数字/数字32.atlas b/assets/res/spine/数字/数字32.atlas similarity index 100% rename from assets/res/spine/likeRole/数字/数字32.atlas rename to assets/res/spine/数字/数字32.atlas diff --git a/assets/res/spine/likeRole/数字/数字32.atlas.meta b/assets/res/spine/数字/数字32.atlas.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字32.atlas.meta rename to assets/res/spine/数字/数字32.atlas.meta diff --git a/assets/res/spine/likeRole/数字/数字32.json b/assets/res/spine/数字/数字32.json similarity index 100% rename from assets/res/spine/likeRole/数字/数字32.json rename to assets/res/spine/数字/数字32.json diff --git a/assets/res/spine/likeRole/数字/数字32.json.meta b/assets/res/spine/数字/数字32.json.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字32.json.meta rename to assets/res/spine/数字/数字32.json.meta diff --git a/assets/res/spine/likeRole/数字/数字32.png b/assets/res/spine/数字/数字32.png similarity index 100% rename from assets/res/spine/likeRole/数字/数字32.png rename to assets/res/spine/数字/数字32.png diff --git a/assets/res/spine/likeRole/数字/数字32.png.meta b/assets/res/spine/数字/数字32.png.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字32.png.meta rename to assets/res/spine/数字/数字32.png.meta diff --git a/assets/res/spine/likeRole/数字/数字4.atlas b/assets/res/spine/数字/数字4.atlas similarity index 100% rename from assets/res/spine/likeRole/数字/数字4.atlas rename to assets/res/spine/数字/数字4.atlas diff --git a/assets/res/spine/likeRole/数字/数字4.atlas.meta b/assets/res/spine/数字/数字4.atlas.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字4.atlas.meta rename to assets/res/spine/数字/数字4.atlas.meta diff --git a/assets/res/spine/likeRole/数字/数字4.json b/assets/res/spine/数字/数字4.json similarity index 100% rename from assets/res/spine/likeRole/数字/数字4.json rename to assets/res/spine/数字/数字4.json diff --git a/assets/res/spine/likeRole/数字/数字4.json.meta b/assets/res/spine/数字/数字4.json.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字4.json.meta rename to assets/res/spine/数字/数字4.json.meta diff --git a/assets/res/spine/likeRole/数字/数字4.png b/assets/res/spine/数字/数字4.png similarity index 100% rename from assets/res/spine/likeRole/数字/数字4.png rename to assets/res/spine/数字/数字4.png diff --git a/assets/res/spine/likeRole/数字/数字4.png.meta b/assets/res/spine/数字/数字4.png.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字4.png.meta rename to assets/res/spine/数字/数字4.png.meta diff --git a/assets/res/spine/likeRole/数字/数字4096.atlas b/assets/res/spine/数字/数字4096.atlas similarity index 100% rename from assets/res/spine/likeRole/数字/数字4096.atlas rename to assets/res/spine/数字/数字4096.atlas diff --git a/assets/res/spine/likeRole/数字/数字4096.atlas.meta b/assets/res/spine/数字/数字4096.atlas.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字4096.atlas.meta rename to assets/res/spine/数字/数字4096.atlas.meta diff --git a/assets/res/spine/likeRole/数字/数字4096.json b/assets/res/spine/数字/数字4096.json similarity index 100% rename from assets/res/spine/likeRole/数字/数字4096.json rename to assets/res/spine/数字/数字4096.json diff --git a/assets/res/spine/likeRole/数字/数字4096.json.meta b/assets/res/spine/数字/数字4096.json.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字4096.json.meta rename to assets/res/spine/数字/数字4096.json.meta diff --git a/assets/res/spine/likeRole/数字/数字4096.png b/assets/res/spine/数字/数字4096.png similarity index 100% rename from assets/res/spine/likeRole/数字/数字4096.png rename to assets/res/spine/数字/数字4096.png diff --git a/assets/res/spine/likeRole/数字/数字4096.png.meta b/assets/res/spine/数字/数字4096.png.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字4096.png.meta rename to assets/res/spine/数字/数字4096.png.meta diff --git a/assets/res/spine/likeRole/数字/数字512.atlas b/assets/res/spine/数字/数字512.atlas similarity index 100% rename from assets/res/spine/likeRole/数字/数字512.atlas rename to assets/res/spine/数字/数字512.atlas diff --git a/assets/res/spine/likeRole/数字/数字512.atlas.meta b/assets/res/spine/数字/数字512.atlas.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字512.atlas.meta rename to assets/res/spine/数字/数字512.atlas.meta diff --git a/assets/res/spine/likeRole/数字/数字512.json b/assets/res/spine/数字/数字512.json similarity index 100% rename from assets/res/spine/likeRole/数字/数字512.json rename to assets/res/spine/数字/数字512.json diff --git a/assets/res/spine/likeRole/数字/数字512.json.meta b/assets/res/spine/数字/数字512.json.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字512.json.meta rename to assets/res/spine/数字/数字512.json.meta diff --git a/assets/res/spine/likeRole/数字/数字512.png b/assets/res/spine/数字/数字512.png similarity index 100% rename from assets/res/spine/likeRole/数字/数字512.png rename to assets/res/spine/数字/数字512.png diff --git a/assets/res/spine/likeRole/数字/数字512.png.meta b/assets/res/spine/数字/数字512.png.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字512.png.meta rename to assets/res/spine/数字/数字512.png.meta diff --git a/assets/res/spine/likeRole/数字/数字64.atlas b/assets/res/spine/数字/数字64.atlas similarity index 100% rename from assets/res/spine/likeRole/数字/数字64.atlas rename to assets/res/spine/数字/数字64.atlas diff --git a/assets/res/spine/likeRole/数字/数字64.atlas.meta b/assets/res/spine/数字/数字64.atlas.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字64.atlas.meta rename to assets/res/spine/数字/数字64.atlas.meta diff --git a/assets/res/spine/likeRole/数字/数字64.json b/assets/res/spine/数字/数字64.json similarity index 100% rename from assets/res/spine/likeRole/数字/数字64.json rename to assets/res/spine/数字/数字64.json diff --git a/assets/res/spine/likeRole/数字/数字64.json.meta b/assets/res/spine/数字/数字64.json.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字64.json.meta rename to assets/res/spine/数字/数字64.json.meta diff --git a/assets/res/spine/likeRole/数字/数字64.png b/assets/res/spine/数字/数字64.png similarity index 100% rename from assets/res/spine/likeRole/数字/数字64.png rename to assets/res/spine/数字/数字64.png diff --git a/assets/res/spine/likeRole/数字/数字64.png.meta b/assets/res/spine/数字/数字64.png.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字64.png.meta rename to assets/res/spine/数字/数字64.png.meta diff --git a/assets/res/spine/likeRole/数字/数字8.atlas b/assets/res/spine/数字/数字8.atlas similarity index 100% rename from assets/res/spine/likeRole/数字/数字8.atlas rename to assets/res/spine/数字/数字8.atlas diff --git a/assets/res/spine/likeRole/数字/数字8.atlas.meta b/assets/res/spine/数字/数字8.atlas.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字8.atlas.meta rename to assets/res/spine/数字/数字8.atlas.meta diff --git a/assets/res/spine/likeRole/数字/数字8.json b/assets/res/spine/数字/数字8.json similarity index 100% rename from assets/res/spine/likeRole/数字/数字8.json rename to assets/res/spine/数字/数字8.json diff --git a/assets/res/spine/likeRole/数字/数字8.json.meta b/assets/res/spine/数字/数字8.json.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字8.json.meta rename to assets/res/spine/数字/数字8.json.meta diff --git a/assets/res/spine/likeRole/数字/数字8.png b/assets/res/spine/数字/数字8.png similarity index 100% rename from assets/res/spine/likeRole/数字/数字8.png rename to assets/res/spine/数字/数字8.png diff --git a/assets/res/spine/likeRole/数字/数字8.png.meta b/assets/res/spine/数字/数字8.png.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字8.png.meta rename to assets/res/spine/数字/数字8.png.meta diff --git a/assets/res/spine/likeRole/数字/数字8192.atlas b/assets/res/spine/数字/数字8192.atlas similarity index 100% rename from assets/res/spine/likeRole/数字/数字8192.atlas rename to assets/res/spine/数字/数字8192.atlas diff --git a/assets/res/spine/likeRole/数字/数字8192.atlas.meta b/assets/res/spine/数字/数字8192.atlas.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字8192.atlas.meta rename to assets/res/spine/数字/数字8192.atlas.meta diff --git a/assets/res/spine/likeRole/数字/数字8192.json b/assets/res/spine/数字/数字8192.json similarity index 100% rename from assets/res/spine/likeRole/数字/数字8192.json rename to assets/res/spine/数字/数字8192.json diff --git a/assets/res/spine/likeRole/数字/数字8192.json.meta b/assets/res/spine/数字/数字8192.json.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字8192.json.meta rename to assets/res/spine/数字/数字8192.json.meta diff --git a/assets/res/spine/likeRole/数字/数字8192.png b/assets/res/spine/数字/数字8192.png similarity index 100% rename from assets/res/spine/likeRole/数字/数字8192.png rename to assets/res/spine/数字/数字8192.png diff --git a/assets/res/spine/likeRole/数字/数字8192.png.meta b/assets/res/spine/数字/数字8192.png.meta similarity index 100% rename from assets/res/spine/likeRole/数字/数字8192.png.meta rename to assets/res/spine/数字/数字8192.png.meta diff --git a/assets/script/battle/ai/runtime/AiActiveSkillHost.ts b/assets/script/battle/ai/runtime/AiActiveSkillHost.ts index 438ed0c..5d5e52f 100644 --- a/assets/script/battle/ai/runtime/AiActiveSkillHost.ts +++ b/assets/script/battle/ai/runtime/AiActiveSkillHost.ts @@ -30,6 +30,7 @@ import type { MapManager } from '../../map/legacy/MapManager'; import { buildEnemyMarchPathGridIndices, isEnemyMonsterWalkGrid, + resolveOwnSpawnPort, } from '../../map/MapPathQueries'; import { findEntityIdByGridIndex } from '../../runtime/DeployEntityQuery'; import { composeKey } from '../../runtime/ComposeUnitKey'; @@ -695,7 +696,7 @@ export class AiActiveSkillHost { const aiPlayerId = AiHeadlessBagHost.AI_PLAYER_ID; const ok = BattleGameExtraBossSkill.trySummon(battle, aiPlayerId); if (!ok) return this._failCast('召唤Boss失败(无配置/spawner)'); - const spawnPort = aiPlayerId === 0 ? 2 : 1; + const spawnPort = resolveOwnSpawnPort(aiPlayerId); aiOp(`AI 万神幡 AI#${aiPlayerId} 出怪口 port=${spawnPort} slot#${slotIndex}`); this._emitCastFx(slotIndex, parsed, BattleGameSkillDragKind.ExtraBoss, { kind: 'spawn', spawnPort }); return true; diff --git a/assets/script/battle/bag/AutoMergePlanner.ts b/assets/script/battle/bag/AutoMergePlanner.ts index a385bbf..90885cd 100644 --- a/assets/script/battle/bag/AutoMergePlanner.ts +++ b/assets/script/battle/bag/AutoMergePlanner.ts @@ -21,6 +21,8 @@ interface BoardSnapshot { bagSlots: Array; mapCells: Array<{ gridIndex: number; cell: MapCellSnapshot }>; mapTiles: Array<{ gridIndex: number; tile: MapTileRecord }>; + /** 与 MergeSession.restoreBoardState 对齐;自动合成试算不依赖组合态 */ + compositions: []; } /** 盘面单位快照:用于区分「真合成」与「落子/交换」 */ @@ -55,6 +57,7 @@ function exportBoardSnapshot(session: BattleBagSession): BoardSnapshot { bagSlots, mapCells, mapTiles, + compositions: [], }; } diff --git a/assets/script/battle/bag/BagPrepConfig.ts b/assets/script/battle/bag/BagPrepConfig.ts index 5b4b672..0c2c88f 100644 --- a/assets/script/battle/bag/BagPrepConfig.ts +++ b/assets/script/battle/bag/BagPrepConfig.ts @@ -69,6 +69,23 @@ export function getShieldPushCells(): number { return cells; } +/** + * 战斗看视频加金币奖励序列(Const id=38 para1)。 + * 次数=数组长度,第 N 次奖励=元素 N-1;非法项丢弃,全空则广告不可用。 + */ +export function getBattleCoinAdRewards(): number[] { + const raw = gg.data.table.getConstArray(ConstNumType.BattleCoinAdRewards); + const out: number[] = []; + for (let i = 0; i < raw.length; i++) { + const n = Math.floor(Number(raw[i]) || 0); + if (n > 0) out.push(n); + } + if (out.length <= 0) { + console.log('[BagPrepConfig] Const 局内金币广告奖励无效', ConstNumType.BattleCoinAdRewards); + } + return out; +} + /** 免费格子已下线 */ export function getFreeGridAdMax(_levelId: number): number { return 0; diff --git a/assets/script/battle/bond/InBattleBondHost.ts b/assets/script/battle/bond/InBattleBondHost.ts index 14ada14..e1d0248 100644 --- a/assets/script/battle/bond/InBattleBondHost.ts +++ b/assets/script/battle/bond/InBattleBondHost.ts @@ -1,20 +1,18 @@ -import { createMembershipSet, membershipAdd } from '../../../mx/tools/MembershipSet'; import type { EntityId } from 'db://assets/mx/module/ecs'; import type { IBattleRuntimeHandle } from '../types/ProjectBattleTypes'; import type { Player } from '../../game/Player'; import type { TextGrid } from '../view/TextGrid'; -import { parseSkillGroup } from './BondConfigParser'; -import { isPartnerWeaponActiveOnMap } from './BondEvaluator'; -import { applyBondAttrsToEntity, removeBondModifiers } from './BondEffectApplier'; +import { removeBondModifiers } from './BondEffectApplier'; import { entriesAffectingWeapon } from '../skill/GlobalSkillEffects'; import { getTowerLoadoutService } from '../combat/TowerLoadoutService'; -/** 局内羁绊宿主:按伙伴激活态动态物化 group 属性 */ +/** + * 局内羁绊宿主(旧词条 Skill.group / group2 已从配表删除)。 + * 保留调用点:仅清掉历史 bond modifier,不再物化属性。 + */ export class InBattleBondHost { private _runtime: IBattleRuntimeHandle | null = null; private _mapGrids: ReadonlyMap | undefined; - /** group2 伙伴上次是否在 map 攻击激活 */ - private _group2PartnerActive = new Map(); bindRuntime(runtime: IBattleRuntimeHandle): void { this._runtime = runtime; @@ -31,139 +29,44 @@ export class InBattleBondHost { unbind(): void { this._runtime = null; this._mapGrids = undefined; - this._group2PartnerActive.clear(); } - /** - * group2 羁绊:伙伴 Weapon1 在场且攻击激活时,词条效果翻倍(×2)。 - * 配表 group2 为伙伴 Hero.id。 - */ - getGroup2StackMultiplier(entry: ITableSkill): number { - const partnerId = Number((entry as ITableSkill & { group2?: number }).group2); - if (!Number.isFinite(partnerId) || partnerId <= 0) return 1; - if (!this._runtime) return 1; - return isPartnerWeaponActiveOnMap(this._runtime, partnerId, this._mapGrids) ? 2 : 1; + /** 旧 group2 翻倍已废弃;恒为 1 */ + getGroup2StackMultiplier(_entry: ITableSkill): number { + return 1; } - /** 组合激活态变化 / 词条物化后刷新 */ + /** 清已部署单位上的羁绊 modifier(词条表已删,不做物化) */ refreshPlayer(player: Player): void { const runtime = this._runtime; if (!runtime) return; const session = runtime.session; - const loadoutSvc = getTowerLoadoutService(); - const byWeapon = new Map(); - for (const entityId of player.deployedUnits) { if (!session.world.isAlive(entityId)) continue; - const weapon1Id = loadoutSvc.getLoadout(entityId)?.weapon1Id; - if (!weapon1Id) continue; - if (!byWeapon.has(weapon1Id)) byWeapon.set(weapon1Id, []); - byWeapon.get(weapon1Id)!.push(entityId); - } - - for (const [weapon1Id, entities] of byWeapon) { - const entries = entriesAffectingWeapon(player.selectedSkills, weapon1Id); - for (const entityId of entities) { - this._refreshEntity(entityId, entries); - } + removeBondModifiers(session, entityId); } - this._rematerializeGroup2WeaponsIfPartnerChanged(player); } refreshEntity(entityId: EntityId, player: Player): void { const loadout = getTowerLoadoutService().getLoadout(entityId); if (!loadout) return; - const entries = entriesAffectingWeapon(player.selectedSkills, loadout.weapon1Id); - this._refreshEntity(entityId, entries); - } - - private _refreshEntity( - entityId: EntityId, - entries: readonly ITableSkill[], - ): void { - const runtime = this._runtime; - if (!runtime) return; - const session = runtime.session; - if (!session.world.isAlive(entityId)) return; - - removeBondModifiers(session, entityId); - - const countById = new Map(); - for (const entry of entries) { - countById.set(entry.id, (countById.get(entry.id) ?? 0) + 1); - } - - const seen = createMembershipSet(); - for (const entry of entries) { - if (seen.has(entry.id)) continue; - membershipAdd(seen, entry.id); - - const groupRaw = String(entry.group ?? '').trim(); - if (!groupRaw) continue; - const parsed = parseSkillGroup(groupRaw); - if (!parsed || parsed.targetType !== 1) continue; - if (!isPartnerWeaponActiveOnMap(runtime, parsed.partnerWeapon1Id, this._mapGrids)) { - continue; - } - const stack = countById.get(entry.id) ?? 1; - applyBondAttrsToEntity( - session, - entityId, - parsed.attrs, - `bond_entry_${entry.id}`, - stack, - ); - } - } - - /** 伙伴上下场后重算带 group2 词条的武器 */ - private _rematerializeGroup2WeaponsIfPartnerChanged(player: Player): void { + // 保持调用形态;entriesAffectingWeapon 已恒空 + entriesAffectingWeapon(player.selectedSkills, loadout.weapon1Id); const runtime = this._runtime; - if (!runtime) return; - const session = runtime.session; - - const partnerIds = createMembershipSet(); - for (const entry of player.selectedSkills) { - const partnerId = Number((entry as ITableSkill & { group2?: number }).group2); - if (Number.isFinite(partnerId) && partnerId > 0) membershipAdd(partnerIds, partnerId); - } - if (partnerIds.size === 0) return; - - let changed = false; - for (const partnerId of partnerIds.keys()) { - const active = isPartnerWeaponActiveOnMap(runtime, partnerId, this._mapGrids); - if (this._group2PartnerActive.get(partnerId) === active) continue; - this._group2PartnerActive.set(partnerId, active); - changed = true; - } - if (!changed) return; - - const weapons = createMembershipSet(); - for (const entry of player.selectedSkills) { - const partnerId = Number((entry as ITableSkill & { group2?: number }).group2); - if (partnerId > 0 && partnerIds.has(partnerId)) { - membershipAdd(weapons, Number((entry as ITableSkill & { weapon?: number }).weapon) || 0); - } - } - if (weapons.size === 0) return; - - const loadoutSvc = getTowerLoadoutService(); - for (const entityId of player.deployedUnits) { - if (!session.world.isAlive(entityId)) continue; - const loadout = loadoutSvc.getLoadout(entityId); - if (!loadout || !weapons.has(loadout.weapon1Id)) continue; - this.refreshEntity(entityId, player); - } + if (!runtime?.session.world.isAlive(entityId)) return; + removeBondModifiers(runtime.session, entityId); } } let _host: InBattleBondHost | null = null; +/** 局内羁绊宿主单例 */ export function getInBattleBondHost(): InBattleBondHost { if (!_host) _host = new InBattleBondHost(); return _host; } +/** 测试重置 */ export function resetInBattleBondHostForTests(): void { _host = null; } diff --git a/assets/script/battle/combat/MonsterSkillHost.ts b/assets/script/battle/combat/MonsterSkillHost.ts index f6660f4..9badac5 100644 --- a/assets/script/battle/combat/MonsterSkillHost.ts +++ b/assets/script/battle/combat/MonsterSkillHost.ts @@ -1110,7 +1110,7 @@ export class MonsterSkillHost { console.log('[MonsterSkillHost] 千里眼缺少 Skeleton', label); return; } - const name = String(sk.defaultAnimation ?? '').trim(); + const name = String((sk as sp.Skeleton & { defaultAnimation?: string }).defaultAnimation ?? '').trim(); if (!name) { console.log('[MonsterSkillHost] 千里眼无默认动画', label); return; @@ -1426,7 +1426,7 @@ export class MonsterSkillHost { gg.res.putNode(node); return false; } - const animName = String(sk.defaultAnimation ?? '').trim(); + const animName = String((sk as sp.Skeleton & { defaultAnimation?: string }).defaultAnimation ?? '').trim(); if (!animName) { console.log('[MonsterSkillHost] 损毁文字无默认动画', DESTROY_PREFAB); gg.res.putNode(node); @@ -1607,7 +1607,7 @@ export class MonsterSkillHost { gg.res.putNode(node); return false; } - const animName = String(sk.defaultAnimation ?? '').trim(); + const animName = String((sk as sp.Skeleton & { defaultAnimation?: string }).defaultAnimation ?? '').trim(); if (!animName) { console.log('[MonsterSkillHost] 降雨无默认动画', RAIN_PREFAB); gg.res.putNode(node); diff --git a/assets/script/battle/combat/TowerQueryService.ts b/assets/script/battle/combat/TowerQueryService.ts index 7ca0756..dd9a3cf 100644 --- a/assets/script/battle/combat/TowerQueryService.ts +++ b/assets/script/battle/combat/TowerQueryService.ts @@ -30,10 +30,10 @@ import type { const TILE_TYPE_NAMES: Record = { 1: 'Element1', 2: 'Element2', - 3: 'Element3OrGrid', + /** type=3 与遗留 Grid 同值;新产品按五行 3 读 */ + [Weapon2TileType.Grid]: 'Element3OrGrid', 4: 'Element4Fire', 5: 'Element5', - [Weapon2TileType.Grid]: 'Grid', }; /** 文字 / 塔数据查询(战斗层唯一读入口) */ diff --git a/assets/script/battle/config/ChapterLevelBuilder.ts b/assets/script/battle/config/ChapterLevelBuilder.ts index a1f11de..e8fb9ba 100644 --- a/assets/script/battle/config/ChapterLevelBuilder.ts +++ b/assets/script/battle/config/ChapterLevelBuilder.ts @@ -242,12 +242,10 @@ export class ChapterLevelBuilder { return this.resolveMonsterPrefabFromRow(row); } - /** Monster 行 → battleGameMonster 预制体文件名 */ + /** Monster 行 → battleGameMonster 预制体文件名(icon → name) */ static resolveMonsterPrefabFromRow(row: ITableMonster): string | null { - const ext = row as ITableMonster & { model?: string }; const icon = typeof row.icon === 'string' ? row.icon.trim() : ''; - const model = typeof ext.model === 'string' ? ext.model.trim() : ''; - const raw = icon || model || row.name; + const raw = icon || row.name; return this.resolveMonsterPrefabName(raw); } diff --git a/assets/script/battle/config/TableBattleConfigProvider.ts b/assets/script/battle/config/TableBattleConfigProvider.ts index dfe7723..3aff90a 100644 --- a/assets/script/battle/config/TableBattleConfigProvider.ts +++ b/assets/script/battle/config/TableBattleConfigProvider.ts @@ -276,7 +276,7 @@ export class TableBattleConfigProvider implements IConfigProvider { if (parsed && !cfg) { console.log('[TableBattleConfigProvider] 出怪缺 monsterConfig,回退 Monster.hp', unitDefId); } - return finitePositiveHp((row as ITableMonster & { HP?: number }).HP ?? row.hp, 1); + return finitePositiveHp(row.hp, 1); } private ensureFallbackEnemy(): void { diff --git a/assets/script/battle/debug/BagRefreshDebugLog.ts b/assets/script/battle/debug/BagRefreshDebugLog.ts index 92ef94b..ebdb063 100644 --- a/assets/script/battle/debug/BagRefreshDebugLog.ts +++ b/assets/script/battle/debug/BagRefreshDebugLog.ts @@ -30,10 +30,10 @@ export function logBagRefreshSection(title: string): void { const TILE_TYPE_LABEL: Record = { 1: '五行1', 2: '五行2', - 3: '五行3/格', + /** type=3 与遗留 Grid 同值 */ + [Weapon2TileType.Grid]: '五行3/格', 4: '五行4(火)', 5: '五行5', - [Weapon2TileType.Grid]: '格子', }; export function formatWeapon2Brief( diff --git a/assets/script/battle/debug/GlobalSkillDebugLog.ts b/assets/script/battle/debug/GlobalSkillDebugLog.ts index 18e7929..6f8302a 100644 --- a/assets/script/battle/debug/GlobalSkillDebugLog.ts +++ b/assets/script/battle/debug/GlobalSkillDebugLog.ts @@ -169,7 +169,7 @@ export function logGlobalSkillPickCompare( ): void { if (!_enabled) return; _log('──────── 选技能前后对比 ────────'); - _log('本次选择:', picked.map((s) => `${s.id}:${s.name} base_attr=${s.base_attr || '-'}`).join(' | ')); + _log('本次选择:', picked.map((s) => `${s.id}:${s.name}`).join(' | ')); _log('已选列表 前:', before.skillBrief.join(', ') || '(空)'); _log('已选列表 后:', after.skillBrief.join(', ') || '(空)'); _log(`base_attr万分比 前: ${JSON.stringify(before.attrWan)}`); diff --git a/assets/script/battle/mechanism/MechanismResCollector.ts b/assets/script/battle/mechanism/MechanismResCollector.ts index 4b3d9c5..d8f6071 100644 --- a/assets/script/battle/mechanism/MechanismResCollector.ts +++ b/assets/script/battle/mechanism/MechanismResCollector.ts @@ -2,6 +2,7 @@ import { Prefab } from 'cc'; import { createMembershipSet, membershipAdd } from '../../../mx/tools/MembershipSet'; import { ChapterNewPlayTypeEnum } from '../../game/ChapterPlayTypes'; import { TableNames } from '../../game/ConfigTableData'; +import { ChapterLevelBuilder } from '../config/ChapterLevelBuilder'; import { WITCH_MECHANISM_MONSTER_ID } from './MechanismConstants'; import type { ResPakage } from 'db://assets/mx/module/res/ResourcesManager'; @@ -55,8 +56,9 @@ export function collectMechanismBattleRes(playIds: number[]): MechanismResEntry[ switch (rawId as ChapterNewPlayTypeEnum) { case ChapterNewPlayTypeEnum.Witch: { const row = gg.data.project.getMonsterDataByID(WITCH_MECHANISM_MONSTER_ID); - if (row?.model) { - add(MECH_BUNDLE.BattleGameMonster, 'prefab/monster/', row.model); + const prefab = row ? ChapterLevelBuilder.resolveMonsterPrefabFromRow(row) : null; + if (prefab) { + add(MECH_BUNDLE.BattleGameMonster, 'prefab/monster/', prefab); } add(MECH_BUNDLE.BattleGameMonster, 'prefab/', '怪物加血'); break; diff --git a/assets/script/battle/mechanism/MechanismServices.ts b/assets/script/battle/mechanism/MechanismServices.ts index 34654e2..b653546 100644 --- a/assets/script/battle/mechanism/MechanismServices.ts +++ b/assets/script/battle/mechanism/MechanismServices.ts @@ -718,7 +718,7 @@ export function calcParatroopMonsterHp(ctx: MechanismContext, monsterId: number) const monsterConfig = readMonsterConfigFromLevel(ctx.session.levelDef.extra); if (!monsterConfig) { console.error('[MechanismServices] monsterConfig missing,飞禽血量无法按波次系数计算'); - return Math.max(1, gg.data.project.getMonsterDataByID(monsterId)?.HP ?? 1); + return Math.max(1, gg.data.project.getMonsterDataByID(monsterId)?.hp ?? 1); } const difficultyRow = getUpcomingWaveDifficultyRow(ctx); return calcChapterMonsterHp(monsterId, 1, difficultyRow, monsterConfig); diff --git a/assets/script/battle/presentation/ExtraStrikePresenter.ts b/assets/script/battle/presentation/ExtraStrikePresenter.ts index 8b002dd..f46d6d5 100644 --- a/assets/script/battle/presentation/ExtraStrikePresenter.ts +++ b/assets/script/battle/presentation/ExtraStrikePresenter.ts @@ -108,9 +108,6 @@ export class ExtraStrikeHost { p.ctx.dealDamage(id, { scale: p.scale, damageType: DMG_TYPE, - // 命中效果类型+对应参数(空串走影子上下文默认=技能 atk_buff1/2) - skillAtkBuff1: p.hitEffect, - skillAtkBuff2: '', }); } } diff --git a/assets/script/battle/presentation/RingProjectilesPresenter.ts b/assets/script/battle/presentation/RingProjectilesPresenter.ts index 766ea79..cabb17c 100644 --- a/assets/script/battle/presentation/RingProjectilesPresenter.ts +++ b/assets/script/battle/presentation/RingProjectilesPresenter.ts @@ -293,7 +293,8 @@ export class ExtraRingHost { const skel = clone.getComponentInChildren(sp.Skeleton); if (skel?.isValid) { skel.timeScale = 1; - skel.setAnimation(0, String(skel.defaultAnimation || RING_ANIM), true); + const typed = skel as sp.Skeleton & { defaultAnimation?: string }; + skel.setAnimation(0, String(typed.defaultAnimation || RING_ANIM), true); } return clone; } diff --git a/assets/script/battle/runtime/BattleRuntime.ts b/assets/script/battle/runtime/BattleRuntime.ts index 0ebad82..fdd4953 100644 --- a/assets/script/battle/runtime/BattleRuntime.ts +++ b/assets/script/battle/runtime/BattleRuntime.ts @@ -92,6 +92,7 @@ import { parseChapterAdvertiseLimit, getChapterFreeBox, getChapterFreeTips, + getBattleCoinAdRewards, } from '../bag/BagPrepConfig'; import { parseLegacyMonsterId, parseMonsterUnitDefId } from '../config/MonsterHpCalculator'; import { MonsterDataManager, MonsterType } from '../../manager/MonsterDataManager'; @@ -333,6 +334,10 @@ export class BattleRuntime implements IBattleRuntimeHandle { menShenAdOfferVisible = false; /** 门神盾牌:本局已观看广告并放置陷阱 */ menShenAdConsumed = false; + /** 局内看视频加金币:已用次数 */ + coinAdUsed = 0; + /** 局内看视频加金币:每次奖励数量(Const38 para1) */ + coinAdRewards: number[] = []; /** 备战:本局剩余免费摆放提示次数(Chapter.free_tips) */ prepFreeTipsRemaining = 0; /** 备战:本局免费摆放提示上限(Chapter.free_tips,UI 展示用) */ @@ -1220,12 +1225,40 @@ export class BattleRuntime implements IBattleRuntimeHandle { this.bajiaoFanAdMax = limits[6] ?? 0; this.menShenAdOfferVisible = false; this.menShenAdConsumed = false; + this.coinAdRewards = getBattleCoinAdRewards(); + this.coinAdUsed = 0; this.curFailReviveLeftNum = limits[5] ?? limits[3] ?? 1; this.curAdAddHpLeftNum = 0; this.MonsterDeadNum = 0; this.TotalMonsterNum = this._countLevelMonsters(this.session.levelDef); } + /** 局内看视频加金币是否仍可观看 */ + canUseCoinAd(): boolean { + return this.coinAdUsed < this.coinAdRewards.length; + } + + /** 下一次看视频加金币数量;不可用时返回 0 */ + nextCoinAdAmount(): number { + if (!this.canUseCoinAd()) return 0; + return this.coinAdRewards[this.coinAdUsed] ?? 0; + } + + /** + * 观看金币广告成功:入账并消耗一次。 + * @returns 实际入账数量;不可用时 0 + */ + consumeCoinAd(): number { + const amount = this.nextCoinAdAmount(); + if (!(amount > 0)) { + console.log('[BattleRuntime] 金币广告不可用', this.coinAdUsed, this.coinAdRewards.length); + return 0; + } + this._addLocalGold(amount); + this.coinAdUsed++; + return amount; + } + getPrepFreeGridRemaining(): number { return Math.max(0, this.prepFreeGridRemaining); } diff --git a/assets/script/battle/skill/SkillPresentationEnv.ts b/assets/script/battle/skill/SkillPresentationEnv.ts index 0665b5a..d52fec2 100644 --- a/assets/script/battle/skill/SkillPresentationEnv.ts +++ b/assets/script/battle/skill/SkillPresentationEnv.ts @@ -93,7 +93,7 @@ export class SkillPresentationEnv { */ private static _readMapTextGrid(node: Node | null | undefined): IMapTextGrid | null { if (!node?.isValid) return null; - return node.getComponentInChildren('TextGrid') as IMapTextGrid | null; + return node.getComponentInChildren('TextGrid') as unknown as IMapTextGrid | null; } static unbind(): void { @@ -403,73 +403,49 @@ export class SkillPresentationEnv { return parseWheelSkillParts(parts); } - /** 施法者是否已选指定词条(按 tower weapon1 过滤) */ + /** 施法者已选技能是否含指定 id(旧词条 weapon 过滤已删) */ static casterHasSkillEntry(caster: EntityId, entryId: number): boolean { const session = this._battle?.session; if (!session?.world.isAlive(caster)) return false; - - const weapon1Id = resolveTowerHeroId(session.world, caster) - || this.getDeployed(caster)?.weapon1Id; - if (!weapon1Id) return false; - for (const player of this._resolvePlayersForCaster(session, caster)) { for (const entry of player.selectedSkills) { - if (Number(entry.weapon) !== weapon1Id) continue; if (Number(entry.id) === entryId) return true; } } return false; } - /** 塔上已生效的 skill_special 原始串(如 `2,2`);与 Player.selectedSkills 合并 */ + /** 塔上 AtkHookComp.specials(旧 Skill.skill_special 词条已删) */ static getSkillSpecials(caster: EntityId): readonly string[] { - return this._collectSkillSpecials(caster, null); + return this._collectSkillSpecials(caster, false); } - /** 大招词条 skill_special(up_type 2 / 4);如哪吒 1055 变大、1056 回旋 */ + /** 大招向 specials:head=3/4/5/8 */ static getUltSkillSpecials(caster: EntityId): readonly string[] { - return this._collectSkillSpecials( - caster, - (entry) => entry.up_type === 2 || entry.up_type === 4, - ); + return this._collectSkillSpecials(caster, true); } - private static _collectSkillSpecials( - caster: EntityId, - filter: ((entry: ITableSkill) => boolean) | null, - ): readonly string[] { + /** + * @param caster 施法者 + * @param ultOnly 是否只收大招 head + */ + private static _collectSkillSpecials(caster: EntityId, ultOnly: boolean): readonly string[] { const session = this._battle?.session; if (!session?.world.isAlive(caster)) return []; - let weapon1Id = resolveTowerHeroId(session.world, caster); - if (!weapon1Id) { - weapon1Id = this.getDeployed(caster)?.weapon1Id; - } - const out = createMembershipSet(); - for (const player of this._resolvePlayersForCaster(session, caster)) { - for (const entry of player.selectedSkills) { - if (weapon1Id && entry.weapon !== weapon1Id) continue; - if (filter && !filter(entry)) continue; - const raw = String(entry.skill_special ?? '').trim(); - if (raw) membershipAdd(out, raw); - } - } - const hook = session.world.getComponent(caster, AtkHookComp); if (hook?.specials?.length) { for (const raw of hook.specials) { const s = String(raw ?? '').trim(); if (!s) continue; - if (filter) { + if (ultOnly) { const head = Number(s.split(',')[0]); - // 大招 skill_special:3 散射 / 4 变大 / 5 回旋 / 8 轮半径脉冲(1 由 ultCanCrit 处理) if (head !== 3 && head !== 4 && head !== 5 && head !== 8) continue; } membershipAdd(out, s); } } - return membershipToArray(out); } diff --git a/assets/script/battle/skill/WangMuConfig.ts b/assets/script/battle/skill/WangMuConfig.ts index cd97028..fe07ba6 100644 --- a/assets/script/battle/skill/WangMuConfig.ts +++ b/assets/script/battle/skill/WangMuConfig.ts @@ -1,5 +1,4 @@ import { Vec3 } from 'cc'; -import { createMembershipSet, membershipAdd, membershipFromArray, membershipDedupeArray, type MembershipSet, type ReadonlyMembershipSet } from '../../../mx/tools/MembershipSet'; import type { BattleSession } from 'db://assets/mx/module/battle'; import { BattleTeamId } from 'db://assets/mx/module/battle/ecs/BattleTeamId'; import { AttrId, AttributeComp, TeamComp } from 'db://assets/mx/module/battle/ecs/Components'; @@ -25,10 +24,10 @@ export interface WangMuUltParams { durationSec: number; } +/** 旧词条 type12 加攻扩展(配表已删,collect 恒空) */ interface Extra12 { attrCode: number; wan: number; - group3: ReadonlyMembershipSet; } export function readWangMuUltParams( @@ -94,10 +93,9 @@ function applyTimedBuffs( let critWan = params.critWan; let critDamWan = params.critDamWan; for (const e of extras) { - const wan = e.group3.has(targetWeapon1Id) ? e.wan * 2 : e.wan; - if (e.attrCode === 1) atkWan += wan; - else if (e.attrCode === 3) critWan += wan; - else if (e.attrCode === 4) critDamWan += wan; + if (e.attrCode === 1) atkWan += e.wan; + else if (e.attrCode === 3) critWan += e.wan; + else if (e.attrCode === 4) critDamWan += e.wan; } const remain = params.durationSec; const attrs = session.attributes; @@ -184,23 +182,9 @@ function applyFieldAtkSteal(session: BattleSession, caster: EntityId, ownerId: n logWangMuFieldAtkSteal(caster, wan, allyLines, sum, extra, before, after); } -function collectType12(caster: EntityId): Extra12[] { - const out: Extra12[] = []; - for (const player of SkillPresentationEnv.getPlayersForCaster(caster)) { - for (const entry of player.selectedSkills) { - if (entry.weapon !== WANG_MU_WEAPON1_ID) continue; - const raw = String(entry.skill_special ?? '').trim(); - if (!raw) continue; - const p = raw.split(',').map(Number); - if (p[0] !== 12 || p.length < 3) continue; - out.push({ - attrCode: p[1] ?? 0, - wan: p[2] ?? 0, - group3: parseIdSet(entry.group3), - }); - } - } - return out; +/** 旧词条 Skill.skill_special type12 / group3 已删;无表字段可驱动 */ +function collectType12(_caster: EntityId): Extra12[] { + return []; } function casterHasSpecialHead(caster: EntityId, head: number): boolean { @@ -219,15 +203,6 @@ function readType14Wan(caster: EntityId): number { return wan; } -function parseIdSet(raw: string): MembershipSet { - const out = createMembershipSet(); - for (const part of String(raw ?? '').split(',')) { - const n = Number(part); - if (Number.isFinite(n) && n > 0) membershipAdd(out, n); - } - return out; -} - function forEachAlly(session: BattleSession, caster: EntityId, fn: (id: EntityId) => void): void { const team = session.world.getComponent(caster, TeamComp); if (!team) return; diff --git a/assets/script/battle/view/AreaUnlockGuidePresenter.ts b/assets/script/battle/view/AreaUnlockGuidePresenter.ts index 62627cc..0acbeb8 100644 --- a/assets/script/battle/view/AreaUnlockGuidePresenter.ts +++ b/assets/script/battle/view/AreaUnlockGuidePresenter.ts @@ -1,4 +1,4 @@ -import { Color, Graphics, Node, Sorting2D, UITransform, Vec3, isValid, sp } from 'cc'; +import { Color, Graphics, Node, UITransform, Vec3, isValid, sp } from 'cc'; import { isElementGlyphType } from 'db://assets/mx/module/merge'; import { GBundle } from '../../game/ConfigRes'; import { AI_VIEW_LOCAL_CAMP } from '../ai/runtime/AiCampArea'; @@ -18,18 +18,14 @@ const FRAME_ANIM = 'animation'; const LINE_LAYER = 'ui_areaUnlockGuideLine'; /** 黑白交替每段长度(对齐效果图) */ const DASH_LEN = 12; -/** 斑马段半宽(实心矩形,避免细 stroke 在深色底上看不见) */ +/** 斑马段半宽 */ const DASH_HALF_W = 2.5; -/** 描边相对半宽加宽,保证黑/白段在任意底上都可见 */ +/** 描边相对半宽加宽 */ const DASH_OUTLINE_EXTRA = 1.5; /** 背包端取字块顶边中点的向上偏移 */ const BAG_TOP_PAD = 2; /** 气泡端取底边中点的向下偏移 */ const TIP_BOTTOM_PAD = 2; -/** 虚线框须压在字形之上(textGrid skin Sorting2D order=3,canUpEff=4) */ -const FRAME_SORT_LAYER = 3; -/** 虚线框 Sorting2D order */ -const FRAME_SORT_ORDER = 6; /** 交替色:黑 */ const DASH_BLACK = new Color(15, 15, 15, 255); /** 交替色:白 */ @@ -54,14 +50,17 @@ export interface AreaUnlockGuideRefresh { campAreaId?: number; /** 取背包槽字块 */ slotGridAt: (slotIndex: number) => TextGrid | null; + /** 取背包槽位节点(虚线框挂这里,禁止挂 TextGrid,避免合成叠字) */ + slotNodeAt: (slotIndex: number) => Node | null; /** 槽位是否可拖(开启且非待开启) */ canDragSlot: (slotIndex: number) => boolean; - /** 为 true 时只清不显(拖动中 / 入场中) */ + /** 为 true 时只清不显(拖动中 / 入场中 / 落子飞行中) */ skip?: boolean; } /** * 背包可解锁当前地图区域时:随机标一个背包字 + 连到格子锁气泡。 + * 虚线框挂在槽位节点上,不进入 TextGrid 子树,避免合成/回收把框和字皮搅在一起。 */ export class AreaUnlockGuidePresenter { /** 连线层父节点 */ @@ -103,8 +102,10 @@ export class AreaUnlockGuidePresenter { /** 立刻隐藏虚线框与连线 */ clear(): void { + const prevHost = this._frame?.parent; this._slotIndex = null; this._releaseFrame(); + if (prevHost?.isValid) this._purgeOrphanFrames(prevHost); if (this._graphics?.isValid) this._graphics.clear(); if (this._lineLayer?.isValid) this._lineLayer.active = false; } @@ -145,11 +146,12 @@ export class AreaUnlockGuidePresenter { slot = candidates[Math.floor(Math.random() * candidates.length)]; } const grid = opts.slotGridAt(slot); - if (!grid?.node?.isValid) { + const slotNode = opts.slotNodeAt(slot); + if (!grid?.node?.isValid || !slotNode?.isValid) { this.clear(); return; } - if (!this._attachFrame(grid.node)) { + if (!this._attachFrame(slotNode, grid.node)) { this.clear(); return; } @@ -192,10 +194,13 @@ export class AreaUnlockGuidePresenter { } /** - * 把虚线框挂到背包字块上并循环播放。 - * @param host 字块节点 + * 虚线框挂到背包槽位(不是 TextGrid),与字块同中心,不参与合成节点树。 + * @param slotNode 背包槽 + * @param glyphNode 字块(仅用于对齐位置) */ - private _attachFrame(host: Node): boolean { + private _attachFrame(slotNode: Node, glyphNode: Node): boolean { + this._purgeOrphanFrames(slotNode); + this._purgeOrphanFrames(glyphNode); if (!this._frame?.isValid) { if (typeof gg === 'undefined' || !gg.res?.getNode) { console.warn('[AreaUnlockGuide] gg.res 未就绪,无法加载引导虚线框'); @@ -210,40 +215,49 @@ export class AreaUnlockGuidePresenter { } const frame = this._frame; if (!frame.isValid) return false; - frame.layer = host.layer; - if (frame.parent !== host) { - frame.parent = host; - frame.setPosition(0, 0, 0); - frame.setScale(1, 1, 1); + frame.layer = slotNode.layer; + if (frame.parent !== slotNode) { + frame.parent = slotNode; } - frame.setSiblingIndex(host.children.length - 1); - this._applyFrameSorting(frame); + // 与槽内字块同局部坐标,避免挂 TextGrid 导致合成叠字 + frame.setPosition(glyphNode.position.x, glyphNode.position.y, glyphNode.position.z); + frame.setScale(1, 1, 1); + frame.setSiblingIndex(slotNode.children.length - 1); + this._disableNodeHit(frame); frame.active = true; const sk = frame.getComponent(sp.Skeleton) ?? frame.getComponentInChildren(sp.Skeleton); if (sk?.isValid) { - sk.node.layer = host.layer; + sk.node.layer = slotNode.layer; BattleSpinePlayback.play(sk, FRAME_ANIM, { loop: true, optional: true }); } return true; } /** - * 虚线框加 Sorting2D,避免被 textGrid 字形盖住。 - * @param frame 引导虚线框 + * 关闭节点树命中,防止 Spine/UITransform 截获拖拽。 + * @param root 虚线框或连线层 */ - private _applyFrameSorting(frame: Node): void { - let rootSort = frame.getComponent(Sorting2D); - if (!rootSort) rootSort = frame.addComponent(Sorting2D); - rootSort.sortingLayer = FRAME_SORT_LAYER; - rootSort.sortingOrder = FRAME_SORT_ORDER; - const skels = frame.getComponentsInChildren(sp.Skeleton); - for (let i = 0; i < skels.length; i++) { - const n = skels[i]?.node; - if (!n?.isValid) continue; - let sort = n.getComponent(Sorting2D); - if (!sort) sort = n.addComponent(Sorting2D); - sort.sortingLayer = FRAME_SORT_LAYER; - sort.sortingOrder = FRAME_SORT_ORDER; + private _disableNodeHit(root: Node): void { + const uts = root.getComponentsInChildren(UITransform); + for (let i = 0; i < uts.length; i++) { + const ut = uts[i]; + if (!ut) continue; + (ut as UITransform & { hitTest: () => boolean }).hitTest = () => false; + } + } + + /** + * 清掉残留虚线框(含误挂在 TextGrid 上的旧实现残留)。 + * @param host 槽位或字块 + */ + private _purgeOrphanFrames(host: Node): void { + const children = host.children; + for (let i = children.length - 1; i >= 0; i--) { + const child = children[i]; + if (!child?.isValid || child.name !== FRAME_NAME) continue; + if (child === this._frame) continue; + if (child['resKey']) gg.res.putNode(child); + else child.destroy(); } } @@ -277,9 +291,11 @@ export class AreaUnlockGuidePresenter { else ut.setContentSize(2000, 2000); ut.setAnchorPoint(0.5, 0.5); layer.addComponent(Graphics); + this._disableNodeHit(layer); } this._lineLayer = layer; this._graphics = layer.getComponent(Graphics); + this._disableNodeHit(layer); layer.active = false; } @@ -312,7 +328,7 @@ export class AreaUnlockGuidePresenter { } /** - * 黑白段交替实心绳:每段先画反色描边再画本色,深色/浅色底上都清晰。 + * 黑白段交替实心绳:每段先画反色描边再画本色。 * @param g Graphics * @param x1 起点 x * @param y1 起点 y @@ -340,7 +356,7 @@ export class AreaUnlockGuidePresenter { } /** - * 沿路径画一段实心矩形(比 stroke 短段更稳、更粗)。 + * 沿路径画一段实心矩形。 * @param g Graphics * @param x1 路径起点 x * @param y1 路径起点 y diff --git a/assets/script/battle/view/BoardPlaceFlightExecutor.ts b/assets/script/battle/view/BoardPlaceFlightExecutor.ts index 8a054c8..865db75 100644 --- a/assets/script/battle/view/BoardPlaceFlightExecutor.ts +++ b/assets/script/battle/view/BoardPlaceFlightExecutor.ts @@ -106,14 +106,14 @@ export class BoardPlaceFlightExecutor { let pending = swapLeg ? 2 : 1; let settled = false; const failState = { failed: false }; - let safetyTimer = 0; + let safetyTimer: ReturnType | null = null; const onAnimDone = (): void => { if (settled) return; pending--; if (pending > 0) return; settled = true; - clearTimeout(safetyTimer); + if (safetyTimer != null) clearTimeout(safetyTimer); BoardPlaceFlightExecutor._completeFlight(req, failState); }; diff --git a/assets/script/battle/view/CampHpBarPresenter.ts b/assets/script/battle/view/CampHpBarPresenter.ts index 4f3bf24..6193718 100644 --- a/assets/script/battle/view/CampHpBarPresenter.ts +++ b/assets/script/battle/view/CampHpBarPresenter.ts @@ -1,14 +1,23 @@ -import { instantiate, Layout, Node, Sorting2D, tween, Tween, UIOpacity, UITransform, Vec3 } from 'cc'; -import { GBundle } from '../../game/ConfigRes'; +import { instantiate, Layout, Node, Sorting2D, sp, tween, Tween, UIOpacity, UITransform, Vec3 } from 'cc'; +import type { EntityId } from 'db://assets/mx/module/ecs'; import { BATTLE_EVENT_ALL, BattleEventType, BattlePhase, + BattleTeamId, + MovementComp, + TeamComp, + isBajiaoBlowRetreating, + isYanSoulClaimed, type BattleEvent, } from 'db://assets/mx/module/battle'; -import type { ProjectBattleHandle } from '../runtime/BattleRuntime'; +import { GBundle } from '../../game/ConfigRes'; +import { MonsterType } from '../../manager/MonsterDataManager'; +import { isMechanismUnit } from '../mechanism/MechanismServices'; import type { MapManager } from '../map/legacy/MapManager'; import { resolveSpawnGoalWallName } from '../map/MapPathQueries'; +import { BattleSpinePlayback } from '../presentation/BattleSpinePlayback'; +import type { ProjectBattleHandle } from '../runtime/BattleRuntime'; /** 血条轨道总宽(与预制体「血量」节点一致) */ const BAR_TRACK_W = 60; @@ -20,6 +29,8 @@ const PREFAB_NAME = '营地血条'; const TRACK_NAME = '血量'; /** 血格模板节点名 */ const PIP_NAME = '长血格'; +/** π 动效节点名 */ +const PAI_NAME = '保护派派'; /** 出怪口节点名前缀(spawnPoint_N) */ const SPAWN_PREFIX = 'spawnPoint_'; /** 血条贴营地外观的外扩(像素);负值表示向营地内收,避开贴图透明边 */ @@ -30,10 +41,18 @@ const BAR_SORT_LAYER = 3; const BAR_SORT_ORDER = 20; /** 扣血格渐隐秒 */ const PIP_FADE_SEC = 0.2; +/** π 默认待机 */ +const PAI_ANIM_IDLE = '待机'; +/** π 怪物靠近时 */ +const PAI_ANIM_SCARE = '害怕'; +/** 进攻怪剩余路径格数 ≤ 此值视为靠近(与危机提示一致) */ +const SCARE_PATH_CELLS = 3; +/** 靠近检测降频(帧) */ +const SCARE_SCAN_PERIOD = 8; /** 单营血条绑定 */ interface CampBar { - /** 玩家槽 ID */ + /** 玩家槽 ID(被进攻的防守方) */ playerId: number; /** 血条根节点 */ root: Node; @@ -45,9 +64,13 @@ interface CampBar { pips: Node[]; /** 开场最大血量(用于格宽) */ maxHp: number; + /** 保护派派 Spine */ + skeleton: sp.Skeleton | null; + /** 是否正在播害怕 */ + scared: boolean; } -/** 己方/敌方营地血条:格数=当前血,扣血渐隐回收 */ +/** 己方/敌方营地血条:格数=当前血,扣血渐隐回收;π 默认待机、怪靠近播害怕 */ export class CampHpBarPresenter { /** 当前战斗 */ private _battle: ProjectBattleHandle | null = null; @@ -57,9 +80,11 @@ export class CampHpBarPresenter { private readonly _bars: CampBar[] = []; /** 渐隐完成待回收队列(FIFO,与 tween 启动顺序一致) */ private readonly _fadeQueue: Node[] = []; + /** 靠近扫描帧计数 */ + private _scareScanAcc = 0; /** - * 按本图挂血条:血条贴在该口怪物的终点下方。 + * 按本图挂血条:贴在该口怪物终点上方(预制体血条在上、π 在下,双方同一套)。 * @param battle 战斗句柄 * @param map 地图 */ @@ -81,6 +106,17 @@ export class CampHpBarPresenter { } } + /** 帧刷新:怪物靠近时切害怕,否则待机 */ + tick(): void { + const battle = this._battle; + if (!battle || battle.session.ended || this._bars.length <= 0) return; + this._scareScanAcc++; + if (this._scareScanAcc % SCARE_SCAN_PERIOD !== 1) return; + for (let i = 0; i < this._bars.length; i++) { + this._refreshScare(battle, this._bars[i]); + } + } + /** 回收节点、停 tween、解事件 */ unbind(): void { const battle = this._battle; @@ -89,6 +125,7 @@ export class CampHpBarPresenter { } this._battle = null; this._mapNode = null; + this._scareScanAcc = 0; this._clearFades(); for (let i = 0; i < this._bars.length; i++) { this._recycleBar(this._bars[i]); @@ -169,6 +206,7 @@ export class CampHpBarPresenter { root.parent = mapNode; this._syncLayer(root, anchor.layer); this._placeAtCamp(root, anchor); + const skeleton = this._resolvePaiSkeleton(root); const bar: CampBar = { playerId, root, @@ -176,8 +214,11 @@ export class CampHpBarPresenter { template, pips: [], maxHp, + skeleton, + scared: false, }; this._bars.push(bar); + this._playPai(bar, false); this._fillPips(bar, slot.wallHp); } @@ -219,7 +260,7 @@ export class CampHpBarPresenter { } /** - * 双方血条都贴在攻击点下方。 + * 双方都贴攻击点上方:血条在上、π 在下,落在中间墙两侧格子上。 * @param root 血条根 * @param anchor 位置节点(wallTargetN) */ @@ -235,12 +276,100 @@ export class CampHpBarPresenter { console.log('[CampHpBar] 血条无 UITransform'); } const barHalfH = barUt ? barUt.height * 0.5 : 0; - const edgeLocalY = -spawnUt.height * spawnUt.anchorY; - const localY = edgeLocalY - (barHalfH + BAR_EDGE_GAP); + const edgeLocalY = spawnUt.height * (1 - spawnUt.anchorY); + const localY = edgeLocalY + (barHalfH + BAR_EDGE_GAP); const world = spawnUt.convertToWorldSpaceAR(new Vec3(0, localY, 0)); root.setWorldPosition(world); } + /** + * @param root 血条根 + */ + private _resolvePaiSkeleton(root: Node): sp.Skeleton | null { + const pai = root.getChildByName(PAI_NAME); + if (!pai?.isValid) { + console.warn('[CampHpBar] 预制体缺「保护派派」'); + return null; + } + const skel = pai.getComponent(sp.Skeleton); + if (!skel) { + console.warn('[CampHpBar] 保护派派无 Skeleton'); + return null; + } + return skel; + } + + /** + * @param battle 战斗 + * @param bar 血条 + */ + private _refreshScare(battle: ProjectBattleHandle, bar: CampBar): void { + if (!bar.skeleton?.isValid) return; + const near = this._hasNearAttacker(battle, bar.playerId); + if (near === bar.scared) return; + this._playPai(bar, near); + } + + /** + * 进攻该防守方的怪是否已进入靠近距离。 + * @param battle 战斗 + * @param defenderPlayerId 防守方 + */ + private _hasNearAttacker(battle: ProjectBattleHandle, defenderPlayerId: number): boolean { + const session = battle.session; + let found = false; + session.world.forEachAlive((entityId) => { + if (found) return; + if (!this._isScareCandidate(battle, defenderPlayerId, entityId)) return; + const move = session.world.getComponent(entityId, MovementComp); + if (!move) return; + if (move.reachedGoal) { + found = true; + return; + } + const remainCells = move.path.length - move.pathIndex; + if (remainCells <= SCARE_PATH_CELLS) found = true; + }); + return found; + } + + /** + * @param battle 战斗 + * @param defenderPlayerId 防守方 + * @param entityId 实体 + */ + private _isScareCandidate(battle: ProjectBattleHandle, defenderPlayerId: number, entityId: EntityId): boolean { + const session = battle.session; + const world = session.world; + if (!world.isAlive(entityId)) return false; + if (isMechanismUnit(session, entityId)) return false; + const team = world.getComponent(entityId, TeamComp); + if (!team || !BattleTeamId.isEnemyTeam(team.team)) return false; + if (Math.max(0, Math.floor(Number(team.ownerId) || 0)) !== defenderPlayerId) return false; + const row = battle.resolveMonsterRow(entityId); + if (!row) return false; + const type = Math.floor(Number(row.type)); + if (type !== MonsterType.SmallMonster && type !== MonsterType.Boss && type !== MonsterType.SummonMonster) { + return false; + } + const move = world.getComponent(entityId, MovementComp); + if (!move || move.spawnProtected || move.presentLocked || move.imprisoned) return false; + if (isYanSoulClaimed(move) || isBajiaoBlowRetreating(move)) return false; + return true; + } + + /** + * @param bar 血条 + * @param scare 是否害怕 + */ + private _playPai(bar: CampBar, scare: boolean): void { + const skel = bar.skeleton; + if (!skel?.isValid) return; + bar.scared = scare; + const name = scare ? PAI_ANIM_SCARE : PAI_ANIM_IDLE; + BattleSpinePlayback.play(skel, name, { loop: true, optional: true }); + } + /** * 槽位当前最大血;被动/AI 加血后必须重读,不能用挂条时的快照。 * @param bar 血条 @@ -405,6 +534,10 @@ export class CampHpBarPresenter { */ private _recycleBar(bar: CampBar): void { this._destroyPips(bar); + const skel = bar.skeleton; + if (skel?.isValid) BattleSpinePlayback.clearPendingComplete(skel); + bar.skeleton = null; + bar.scared = false; if (bar.root?.isValid) { Tween.stopAllByTarget(bar.root); gg.res.putNode(bar.root); diff --git a/assets/script/battle/view/CocosBagBoardView.ts b/assets/script/battle/view/CocosBagBoardView.ts index 444eb33..b703232 100644 --- a/assets/script/battle/view/CocosBagBoardView.ts +++ b/assets/script/battle/view/CocosBagBoardView.ts @@ -943,10 +943,10 @@ export class CocosBagBoardView { const grid = this._resolveBagTextGridForUpgrade(bagSlot, slotNode); const record = this._bagSession.getBagSlots()[bagSlot]; if (grid?.isValid && record) { + this._grids.setBagGrid(bagSlot, grid); grid.applyMapLevel(record.level ?? 1); - grid.enableDrag(this._canEnableBagGridDrag(grid)); - this._bindDrag(grid); } + this._sanitizeBagSlotAfterMerge(bagSlot); this._playBagUpgradeEffect(bagSlot); this._refreshCanUpgradeHints(); } @@ -3203,6 +3203,8 @@ export class CocosBagBoardView { let mapDrag: { fromGridIndex: number; weapon2Id: number; tileSource?: TileSource } | undefined; let type3Backup: { gridIndex: number; tile: MapTileRecord } | null = null; + // 任意拖动先清解锁引导,避免框/连线参与合成节点树造成叠字 + this._unlockGuide.clear(); if (source.kind === 'bag') { const slot = this._bagSession!.getBagSlots()[source.slotIndex]; if (!slot || Number(slot.weapon2Id) !== grid.weapon2Id) { @@ -3210,9 +3212,6 @@ export class CocosBagBoardView { this._rebuildFromSession(); return; } - if (this._unlockGuide.slotIndex === source.slotIndex) { - this._unlockGuide.clear(); - } } else if (source.kind === 'map') { const mapIndex = this._resolveMapGridIndexForTextGrid(grid); if (mapIndex == null) { @@ -3728,7 +3727,10 @@ export class CocosBagBoardView { swapCommit: swapToSource && displacedGrid ? { grid: displacedGrid, target: { kind: 'bag', slotIndex: fromSlot } } : undefined, - hooks: this._createPlaceHooks({ onSuccessRebuild: 'flush' }), + hooks: this._createPlaceHooks({ + onSuccessRebuild: 'flush', + onComplete: () => this._refreshDragEnabled(), + }), }); } @@ -4412,6 +4414,7 @@ export class CocosBagBoardView { break; } if (this._applyBagUpgradeInPlace(event.slotIndex, event.level)) { + this._sanitizeBagSlotAfterMerge(event.slotIndex); if (!this._suppressDefaultUpgradeFx) { this._playBagUpgradeEffect(event.slotIndex); } @@ -5213,16 +5216,51 @@ if (weapon2Id === GRID_WEAPON2_ID) return true; this._unlockGuide.clear(); return; } + // 落子飞行 / drop 同步中禁止刷新,否则框会踩进合成中的 TextGrid 树 + const skip = this._activeDrag != null + || this._bagEntrancePlaying + || !this._canDrag() + || this._mapDropAnimInflight > 0 + || this._dropSyncPhase !== 'idle'; this._unlockGuide.refresh({ bagSession: this._bagSession, map: this._map, campAreaId: AI_VIEW_LOCAL_CAMP, slotGridAt: (slotIndex) => this._slotGrids.get(slotIndex) ?? null, + slotNodeAt: (slotIndex) => this._bagSlotNodeAt(slotIndex), canDragSlot: (slotIndex) => this._land.stateOf(slotIndex) === TextListCellState.Open, - skip: this._activeDrag != null || this._bagEntrancePlaying || !this._canDrag(), + skip, }); } + /** + * 背包合成后:槽内只留一块真身,清 select,避免叠字/红框残留。 + * @param slotIndex 合成目标槽 + */ + private _sanitizeBagSlotAfterMerge(slotIndex: number): void { + const slotNode = this._bagSlotNodeAt(slotIndex); + if (!slotNode?.isValid) return; + const keep = this._slotGrids.get(slotIndex); + for (const child of [...slotNode.children]) { + if (!child?.isValid) continue; + if (child.name === '引导虚线框') { + if (child['resKey']) gg.res.putNode(child); + else child.destroy(); + continue; + } + const tg = child.getComponent(TextGrid); + if (!tg?.isValid) continue; + if (tg === keep) continue; + this._forceRecycleTextGrid(tg); + } + if (keep?.isValid) { + keep.isSelectStatus = false; + keep.isRedSelectStatus = false; + keep.enableDrag(this._canEnableBagGridDrag(keep)); + this._bindDrag(keep); + } + } + private _playBagUpgradeEffect(slotIndex: number): void { BattleAudio.playUpgrade(); this._playLevelUpTextForBag(slotIndex); @@ -6740,7 +6778,10 @@ if (weapon2Id === GRID_WEAPON2_ID) return true; const tg = this._slotGrids.get(slotIndex); if (!selected) { - if (tg?.node?.isValid) tg.isSelectStatus = false; + if (tg?.node?.isValid) { + tg.isSelectStatus = false; + tg.isRedSelectStatus = false; + } if (slotSelect && isValid(slotSelect)) slotSelect.active = false; return; } diff --git a/assets/script/battle/view/GridUpgradeSpineEffect.ts b/assets/script/battle/view/GridUpgradeSpineEffect.ts index d1bebb2..e5f0b60 100644 --- a/assets/script/battle/view/GridUpgradeSpineEffect.ts +++ b/assets/script/battle/view/GridUpgradeSpineEffect.ts @@ -132,11 +132,11 @@ function playNamedSpine( BattleSpinePlayback.resetTracks(spine); let settled = false; - let hideTimer = 0; + let hideTimer: ReturnType | null = null; const finish = (): void => { if (settled) return; settled = true; - clearTimeout(hideTimer); + if (hideTimer != null) clearTimeout(hideTimer); if (spineNode?.isValid) spineNode.active = false; onComplete?.(); }; diff --git a/assets/script/com/itemPic.ts b/assets/script/com/itemPic.ts index 5dea984..6e32aa2 100644 --- a/assets/script/com/itemPic.ts +++ b/assets/script/com/itemPic.ts @@ -75,7 +75,7 @@ export class itemPic extends Component { let spineQuality4 = icon?.getChildByName('橙色'); let spineQuality5 = icon?.getChildByName('红色'); if (this.lbName) this.lbName.string = gg.lang.get(itemData.name);//itemData.name; - if (this.lbDesc) this.lbDesc.string = gg.lang.get(itemData.desc1);//itemData.desc1; + if (this.lbDesc) this.lbDesc.string = gg.lang.get(itemData.desc); if (spineQuality3) spineQuality3.active = itemData.quality == 3 if (spineQuality4) spineQuality4.active = itemData.quality == 4 if (spineQuality5) spineQuality5.active = false diff --git a/assets/script/game/ConfigProjectData.ts b/assets/script/game/ConfigProjectData.ts index d716efc..6d3c71c 100644 --- a/assets/script/game/ConfigProjectData.ts +++ b/assets/script/game/ConfigProjectData.ts @@ -4,7 +4,6 @@ import { LevelFieldResolver } from "../manager/LevelFieldResolver"; import { SkillMultiplyType, TableNames } from "./ConfigTableData"; import { heroNormalSkillId, isBasicHero } from '../battle/config/BattleHeroTable'; import { resolveAtkLevelCoef } from '../battle/combat/TowerStatResolver'; -import { parseEntryBaseAttr } from '../battle/skill/SkillEntryParse'; import type { IBattleRuntimeHandle } from '../battle/types/ProjectBattleTypes'; import MTools from "../../mx/tools/MTools"; import { DailyWinStats } from '../manager/DailyWinStats'; @@ -808,16 +807,11 @@ export class ConfigProjectData extends Singleton { const t2 = skill.multiply_type2; const v2 = skill.multiply_num2; if (t2 === type) sum += v2 ?? 0; - for (const { type: attrType, value } of parseEntryBaseAttr(skill.base_attr)) { - if (ConfigProjectData._baseAttrToMultiplyType[attrType] === type) { - sum += value / 10000; - } - } } return sum; } - /**根据一组技能获取所有乘区类型(兼容旧 multiply_type + 新 base_attr) */ + /** 根据一组技能获取所有乘区类型(旧 base_attr 词条已删,仅兼容遗留 multiply_type 扩展字段) */ getAllMultiplyType(skillArr: ITableSkill[]) { const typeArr: number[] = []; for (let i = 0; i < skillArr.length; i++) { @@ -829,12 +823,6 @@ export class ConfigProjectData extends Singleton { const t2 = skill.multiply_type2; if (t1 > 0 && typeArr.indexOf(t1) === -1) typeArr.push(t1); if (t2 > 0 && typeArr.indexOf(t2) === -1) typeArr.push(t2); - for (const { type: attrType } of parseEntryBaseAttr(skill.base_attr)) { - const multType = ConfigProjectData._baseAttrToMultiplyType[attrType]; - if (multType > 0 && typeArr.indexOf(multType) === -1) { - typeArr.push(multType); - } - } } return typeArr; } @@ -891,8 +879,8 @@ export class ConfigProjectData extends Singleton { const w1 = this.getWeapon1Data(weapon1Id); if (!w1 || composeLevel <= 0) return 0; - const weaponSkills = skills.filter(s => s.weapon === weapon1Id); - const dpsMult = this.calculateDPSWeight(weaponSkills, weapon1Id); + // 旧词条 Skill.weapon 已删:DPS 乘区用传入 skills(局外带入/调试),无则按 1 + const dpsMult = this.calculateDPSWeight(skills as ITableSkill[], weapon1Id); const levelLimit = w1.level_limit > 0 ? w1.level_limit : composeLevel; const effectiveLevel = Math.max(1, Math.min(composeLevel, levelLimit)); diff --git a/assets/script/game/ConfigRes.ts b/assets/script/game/ConfigRes.ts index 498cfd5..12af2fa 100644 --- a/assets/script/game/ConfigRes.ts +++ b/assets/script/game/ConfigRes.ts @@ -160,8 +160,8 @@ export class GPath { } /** 每日商店飘字标题(icons/shopSkillTitle/{name}) */ static ShopSkillTitle(name: string | number) { return "shopSkillTitle/" + name; } - /**通用仙桃图标(icons/img/仙桃) */ - static CommPeach() { return "img/仙桃"; } + /**通用金币图标(icons/img/金币) */ + static CommPeach() { return "img/金币"; } /** 五行属性图标(icons/img/金|木|水|火|土) */ static ElementAttr(name: string) { return "img/" + name; } /**障碍物 */ diff --git a/assets/script/game/GameData.ts b/assets/script/game/GameData.ts index 856ebc3..d94adc2 100644 --- a/assets/script/game/GameData.ts +++ b/assets/script/game/GameData.ts @@ -1104,7 +1104,8 @@ export class GameData extends Singleton { const itemData = this.table.getItemData(goodID); if (!itemData || itemData.quality !== quality1) continue; qualityArray1.push(goodID); - weightArray1.push(itemData.weight); + // Item 表无 weight:同品质碎片池等权 + weightArray1.push(1); } fragmentArrayAll.push( ...MTools.getRandomByWeightArray(num1, qualityArray1, weightArray1), diff --git a/assets/script/game/GameDataEnums.ts b/assets/script/game/GameDataEnums.ts index d987926..31a0b75 100644 --- a/assets/script/game/GameDataEnums.ts +++ b/assets/script/game/GameDataEnums.ts @@ -550,6 +550,8 @@ export enum ConstNumType { WeekMapSat = 36, /** 周日匹配地图池 para1:Level.id 逗号分隔 */ WeekMapSun = 37, + /** 战斗中看视频加金币:para1 为每次奖励数量,次数=数组长度 */ + BattleCoinAdRewards = 38, } export enum TaskType { diff --git a/assets/script/ui/BattleGame/BattlePeachCoinFlyPresenter.ts b/assets/script/ui/BattleGame/BattlePeachCoinFlyPresenter.ts index bb08c29..9dec7eb 100644 --- a/assets/script/ui/BattleGame/BattlePeachCoinFlyPresenter.ts +++ b/assets/script/ui/BattleGame/BattlePeachCoinFlyPresenter.ts @@ -15,8 +15,8 @@ const PLUS_OFFSET_X = 40 / FLY_VISUAL_SCALE; const PLUS_CHILD = 'dropPlusOne'; /** - * 战斗内仙桃飘字:使用 battleGame/prefab/coinFly。 - * 起点 skill1/skill2,终点 ui_money。 + * 战斗内金币飘字:使用 battleGame/prefab/coinFly。 + * 起点击杀/回收点,终点底部 btnCoin/金币。 */ export class BattlePeachCoinFlyPresenter { private _moneyNode: Node | null = null; @@ -26,7 +26,7 @@ export class BattlePeachCoinFlyPresenter { /** 掉落 +1 飘字 */ private readonly _plusQueue: Node[] = []; - /** 绑定目标 ui_money 与飞行层(ui_fly) */ + /** 绑定飞向目标(btnCoin/金币)与飞行层(ui_fly) */ bind(moneyNode: Node | null | undefined, flyLayer: Node | null | undefined): void { this._moneyNode = moneyNode?.isValid ? moneyNode : null; this._flyLayer = flyLayer?.isValid ? flyLayer : null; diff --git a/assets/script/ui/BattleGame/CoinFly.ts b/assets/script/ui/BattleGame/CoinFly.ts index c167e1e..795a145 100644 --- a/assets/script/ui/BattleGame/CoinFly.ts +++ b/assets/script/ui/BattleGame/CoinFly.ts @@ -1,5 +1,5 @@ -import { _decorator, Component, tween, Tween, Vec3 } from 'cc'; +import { _decorator, Component, Node, tween, Tween, Vec3 } from 'cc'; const { ccclass } = _decorator; /** 蹦跳峰值相对起点世界 Y 偏移(与乾坤袋回收飘桃一致) */ diff --git a/assets/script/ui/BattleGame/UIBattleGame.ts b/assets/script/ui/BattleGame/UIBattleGame.ts index 57f1f3e..f69a22d 100644 --- a/assets/script/ui/BattleGame/UIBattleGame.ts +++ b/assets/script/ui/BattleGame/UIBattleGame.ts @@ -4,7 +4,7 @@ // time: Tue Aug 18 2026 // desc: 战斗界面 — 地图、出怪、背包刷新(召唤) //********************* -import { _decorator, find, Label, Node, Sprite, Tween, tween, v3, Vec3, sp } from 'cc'; +import { _decorator, find, game, Label, Node, Sprite, Tween, tween, v3, Vec3, sp } from 'cc'; import { Auto_BattleGame } from './Auto_BattleGame'; import { CocosBattleMapHost } from '../../battle/map/CocosBattleMapHost'; import { applyMapTopologyToSession } from '../../battle/map/importTopologyFromMapManager'; @@ -21,6 +21,7 @@ import { getDiscountedBagNormalRefreshCost } from '../../battle/bag/BagPrepConfi import { resolveCarriedSummonCostReduceWan } from '../../manager/battleBuff/BattleBuffPassiveSkillUtil'; import type { ProjectBattleHandle } from '../../battle/runtime/BattleRuntime'; import { BattleAudio } from '../../battle/audio/BattleAudio'; +import { BattleUiPauseGate } from '../../battle/BattleUiPauseGate'; import { SkillController } from '../../battle/skill/SkillController'; import { SkillPresentationEnv } from '../../battle/skill/SkillPresentationEnv'; import { MonsterType } from '../../manager/MonsterDataManager'; @@ -83,6 +84,8 @@ const REFRESH_BOUNCE_AMP = 0.1; const REFRESH_BOUNCE_SEC = 0.22; /** 开局未放置数字则强制开怪的等待秒数 */ const FIRST_PLACE_COMBAT_TIMEOUT_SEC = 10; +/** 看视频加金币期间暂停 token */ +const COIN_AD_PAUSE_TOKEN = 'ad:battleCoin'; /** 砚台 Spine:资源里名字取反,出字过程播「待机」 */ const INKSTONE_SPINE_SPAWN = '待机'; @@ -186,6 +189,12 @@ export class UIBattleGame extends Auto_BattleGame { private _peachUiGold = -1; /** 召唤消耗缓存 */ private _peachUiCost = -1; + /** 金币广告已用次数缓存 */ + private _peachUiCoinAdUsed = -1; + /** btnCoin/视频标 */ + private _coinAdVideoIcon: Node | null = null; + /** 看视频加金币进行中 */ + private _coinAdPending = false; /** 波次 UI 缓存 */ private _waveUiIdx = -999; /** AI 技能条降频 */ @@ -304,7 +313,12 @@ export class UIBattleGame extends Auto_BattleGame { this._otherSkillView = new BattleGameOtherSkillView(this.ui_otherskill1List, this.ui_otherskill2List); this._otherSkillView.setOwnedDesc(this._otherOwnedDesc); this._otherSkillView.refresh(); + if (this.ui_money?.isValid) this.ui_money.active = false; + this._coinAdVideoIcon = this.btnCoin?.getChildByName('视频标') ?? null; this._waveUiIdx = -999; + this._peachUiGold = -1; + this._peachUiCost = -1; + this._peachUiCoinAdUsed = -1; this._refreshPeachUi(); this._refreshWaveUi(); this._syncIllustratedHint(false); @@ -340,6 +354,7 @@ export class UIBattleGame extends Auto_BattleGame { } this._bagView?.tickPeachTreePresentations(); getBattleGameMonsterCrisisHintPresenter().tick(); + this._campHpBar.tick(); } this._bindNetTrap?.tick(dt); this._fireTrap?.tick(dt); @@ -736,12 +751,13 @@ export class UIBattleGame extends Auto_BattleGame { getBattleBuffBaseThunderHost().bind(battle, this._baseThunderFx); } - /** 绑定 ui_money 飞桃(击杀 / 回收共用) */ + /** 绑定底部金币飞币(击杀 / 回收共用) */ private _ensurePeachCoinFly(): void { if (!this._peachCoinFly) { this._peachCoinFly = new BattlePeachCoinFlyPresenter(); } - this._peachCoinFly.bind(this.ui_money, this.ui_fly ?? this.ui_mapParentNode); + const moneyTarget = this.btnCoin?.getChildByName('金币') ?? this.btnCoin; + this._peachCoinFly.bind(moneyTarget, this.ui_fly ?? this.ui_mapParentNode); } /** 绑定乾坤袋回收演出 */ @@ -958,7 +974,7 @@ export class UIBattleGame extends Auto_BattleGame { sc.refreshEntitySkillBindings(map, this._bagView?.getMapGrids()); } - /** 刷新顶部桃子数、召唤消耗与按钮填充状态 */ + /** 刷新底部金币数、召唤消耗、金币广告与按钮填充状态 */ private _refreshPeachUi(): void { const battle = this._battle; if (!battle) return; @@ -967,12 +983,15 @@ export class UIBattleGame extends Auto_BattleGame { const cost = battle.bagSession ? battle.bagSession.normalRefreshCost : getDiscountedBagNormalRefreshCost(0, resolveCarriedSummonCostReduceWan().reduceWan); - if (gold === this._peachUiGold && cost === this._peachUiCost) return; + const coinAdUsed = battle.coinAdUsed; + if (gold === this._peachUiGold && cost === this._peachUiCost && coinAdUsed === this._peachUiCoinAdUsed) return; this._peachUiGold = gold; this._peachUiCost = cost; - if (this.lb_money?.isValid) { - this.lb_money.string = `${gold}`; + this._peachUiCoinAdUsed = coinAdUsed; + if (this.lb_coin?.isValid) { + this.lb_coin.string = `${gold}`; } + this._syncCoinAdUi(battle); if (this.lb_RefreshNeed?.isValid) { this.lb_RefreshNeed.string = `${cost}`; } @@ -1000,6 +1019,35 @@ export class UIBattleGame extends Auto_BattleGame { this._syncRefreshBounce(enough); } + /** + * 同步 btnCoin 广告区:次数未满显示下一次 +数量与 used+1/max;用尽则隐藏。 + * @param battle 当前对局 + */ + private _syncCoinAdUi(battle: ProjectBattleHandle): void { + const canAd = battle.canUseCoinAd(); + const amount = battle.nextCoinAdAmount(); + const max = battle.coinAdRewards.length; + this._setNodeActive(this._coinAdVideoIcon, canAd); + this._setNodeActive(this.lb_coinAdLimit?.node ?? null, canAd); + this._setNodeActive(this.lb_coinAdNum?.node ?? null, canAd); + if (!canAd) return; + if (this.lb_coinAdNum?.isValid) { + this.lb_coinAdNum.string = `+${amount}`; + } + if (this.lb_coinAdLimit?.isValid) { + this.lb_coinAdLimit.string = `${battle.coinAdUsed + 1}/${max}`; + } + } + + /** + * 安全设置节点显隐。 + * @param node 目标节点 + * @param active 是否显示 + */ + private _setNodeActive(node: Node | null, active: boolean): void { + if (node?.isValid && node.active !== active) node.active = active; + } + /** btnRefresh/bg2:水平从右到左;fillRange = min(-0.1, -(1 - 桃子/消耗)),凑够为 0 */ private _setupRefreshFillSprite(): void { const sprite = this._refreshFill; @@ -1214,6 +1262,12 @@ export class UIBattleGame extends Auto_BattleGame { this._illustratedHintShownThisBattle = false; this._peachUiGold = -1; this._peachUiCost = -1; + this._peachUiCoinAdUsed = -1; + this._coinAdVideoIcon = null; + if (this._coinAdPending) { + this._coinAdPending = false; + BattleUiPauseGate.release(COIN_AD_PAUSE_TOKEN); + } this._waveUiIdx = -999; this._aiSkillUiFrame = 0; this._lbWaveTip = null; @@ -1247,8 +1301,45 @@ export class UIBattleGame extends Auto_BattleGame { } + /** 底部金币:看视频加币 */ + click_btnCoin(): void { + this._tryWatchCoinAd(); + } + + /** 旧入口:转调看视频加币 */ click_btnGetMoneyAd(): void { + this._tryWatchCoinAd(); + } + /** 观看激励视频,按 Const38 下一次数量加金币 */ + private _tryWatchCoinAd(): void { + const battle = this._battle; + if (!battle || this._coinAdPending) return; + if (!battle.canUseCoinAd()) return; + + this._coinAdPending = true; + BattleUiPauseGate.acquire(COIN_AD_PAUSE_TOKEN); + gg.sdk.showVideoAd((res) => { + if (!this._coinAdPending) return; + this._coinAdPending = false; + BattleUiPauseGate.release(COIN_AD_PAUSE_TOKEN); + if (game.isPaused()) game.resume(); + if (!res) { + gg.ui.showToast('观看视频失败'); + return; + } + const b = this._battle; + if (!b?.canUseCoinAd()) return; + b.IsWatchAd = true; + const amount = b.consumeCoinAd(); + if (!(amount > 0)) { + console.log('[UIBattleGame] 金币广告入账失败'); + return; + } + const curWaveNum = gg.game.CurentBattle.CurentWaveNum; + gg.sdk.reportDY('inLevel', `${gg.game.getReportDYBattleCountLabel(curWaveNum)}-AD-广告获得金币`); + this._refreshPeachUi(); + }); } click_btnIllustrated(): void { @@ -1291,7 +1382,7 @@ export class UIBattleGame extends Auto_BattleGame { if (result === 'no_slot') { gg.ui.showToast('暂无空格'); } else if (result === 'not_enough') { - gg.ui.showToast('桃子不足'); + gg.ui.showToast('金币不足'); } else { gg.ui.showToast('刷新失败'); console.log('[UIBattleGame] tryFillEmptyOpenSlots failed', result); diff --git a/assets/script/ui/BattleWeaponDesc/UIBattleWeaponDesc.ts b/assets/script/ui/BattleWeaponDesc/UIBattleWeaponDesc.ts index 8b4c94f..c760e09 100644 --- a/assets/script/ui/BattleWeaponDesc/UIBattleWeaponDesc.ts +++ b/assets/script/ui/BattleWeaponDesc/UIBattleWeaponDesc.ts @@ -316,8 +316,10 @@ export class UIBattleWeaponDesc extends Auto_BattleWeaponDesc { const bg2 = item.getChildByName('bg2'); if (!bg?.isValid || !bg2?.isValid) return; - bg.getOrAddComponent(SpriteLoad).setSprite(GPath.popRes('battleGameResult', `texture/q${entry.quality}`), GBundle.PopBattle); - bg2.getOrAddComponent(SpriteLoad).setSprite(GPath.popRes('battleGameResult', `texture/q${entry.quality}开`), GBundle.PopBattle); + // Skill 表无 quality(旧词条品级已删);遗留列表用默认框 + const q = 1; + bg.getOrAddComponent(SpriteLoad).setSprite(GPath.popRes('battleGameResult', `texture/q${q}`), GBundle.PopBattle); + bg2.getOrAddComponent(SpriteLoad).setSprite(GPath.popRes('battleGameResult', `texture/q${q}开`), GBundle.PopBattle); const name = gg.lang.get(entry.name ?? ''); const desc = gg.lang.get(entry.desc ?? ''); diff --git a/assets/script/ui/GetReward/RewardGrid.ts b/assets/script/ui/GetReward/RewardGrid.ts index a53ba53..ad019fe 100644 --- a/assets/script/ui/GetReward/RewardGrid.ts +++ b/assets/script/ui/GetReward/RewardGrid.ts @@ -68,9 +68,10 @@ export class RewardGrid extends Component { let isHaveWeapon = gg.data.project.isWeaponUnlocked(this.Data.id); if (isHaveWeapon) { - //有武器转为碎片数量 - this.suipianNode.active = true - this.num.string = 'x' + MTools.formatChineseUnit({ num: this.Data.num * itemData.transition }); + // 有武器转为碎片:按 Weapon.synthesisnumber(Item 无 transition) + this.suipianNode.active = true; + const scrapMul = Math.max(1, gg.data.project.getWeaponFlagNumByLevel(this.Data.id)); + this.num.string = 'x' + MTools.formatChineseUnit({ num: this.Data.num * scrapMul }); } else { //没有武器正常数量 this.suipianNode.active = false diff --git a/assets/script/ui/GetReward/UIGetReward.ts b/assets/script/ui/GetReward/UIGetReward.ts index 61fcd0f..fe5ba7b 100644 --- a/assets/script/ui/GetReward/UIGetReward.ts +++ b/assets/script/ui/GetReward/UIGetReward.ts @@ -168,13 +168,13 @@ export class UIGetReward extends Auto_GetReward { let isHaveWeapon = gg.data.project.isWeaponUnlocked(data.id); if (isHaveWeapon) { - //有武器转为碎片数量 - //武器属性 + // 有武器转为碎片:按 Weapon.synthesisnumber(Item 无 transition) let weaponData = gg.data.project.getWeaponData(data.id); const scrapId = gg.data.project.getWeaponScrapId(weaponData.id); let itemData = gg.data.table.getItemData(scrapId); if (!itemData) continue; - gg.data.addItemNum(scrapId, data.num * itemData.transition); + const scrapMul = Math.max(1, gg.data.project.getWeaponFlagNumByLevel(data.id)); + gg.data.addItemNum(scrapId, data.num * scrapMul); } else { //没有武器添加武器数据 gg.data.project.unlockWeapon(data.id); diff --git a/assets/script/ui/PopDailyShopLottery/UIPopDailyShopLottery.ts b/assets/script/ui/PopDailyShopLottery/UIPopDailyShopLottery.ts index 9def968..101a834 100644 --- a/assets/script/ui/PopDailyShopLottery/UIPopDailyShopLottery.ts +++ b/assets/script/ui/PopDailyShopLottery/UIPopDailyShopLottery.ts @@ -522,7 +522,7 @@ export class UIPopDailyShopLottery extends Auto_PopDailyShopLottery { if (!node?.isValid) { resolve(); return; } tween(node) .to(dur, { scale: v3(scale, scale, 1) }) - .call(resolve) + .call(() => { resolve(); }) .start(); }); } diff --git a/assets/script/ui/PopGM/UIPopGM.ts b/assets/script/ui/PopGM/UIPopGM.ts index 62ca68b..45aaeca 100644 --- a/assets/script/ui/PopGM/UIPopGM.ts +++ b/assets/script/ui/PopGM/UIPopGM.ts @@ -4,7 +4,7 @@ // time: Mon Apr 20 2026 // desc: //********************* -import { _decorator, Component, Node, find, Color, instantiate, Label, EditBox, RichText } from 'cc'; +import { _decorator, Component, Node, Color, instantiate, Label, EditBox } from 'cc'; import { Auto_PopGM } from './Auto_PopGM'; import { TableNames } from '../../game/ConfigTableData'; import { WeaponComposeConfigProvider } from '../../battle/bag/WeaponComposeConfigProvider'; @@ -112,38 +112,9 @@ export class UIPopGM extends Auto_PopGM { n.on(Node.EventType.TOUCH_END, this.onClickWp.bind(this, n, w1), this); } - //已选武器 - let selectedList = allList.filter(item => this.curentwpArr.includes(Number(item.id))); - //所有技能(词条表 Skill,按 weapon 字段关联 Weapon1) - let allSkillList = gg.data.table.getTableList(TableNames.Skill); - //已选武器的所有技能 - let selectedSkillList = allSkillList.filter(item => - selectedList.some(w => Number(w.id) === Number(item.weapon)), - ); + // 旧词条 Skill.weapon / quality 已删:GM「已选武器技能」列表清空 this.ui_waSelectSkillList.children.map(x => x.active = false); - for (let i = 0; i < selectedSkillList.length; i++) { - const s2 = selectedSkillList[i]; - const w2 = gg.data.project.getWeaponData(s2.weapon); - let n: Node = null; - if (i < this.ui_waSelectSkillList.children.length) { - n = this.ui_waSelectSkillList.children[i]; - } - else { - n = instantiate(this.ui_waSelectSkillList.children[0]); - this.ui_waSelectSkillList.addChild(n); - } - n.active = true; - let bg = n.getChildByName('bg'); - let lbName = n.getChildByName('lbName'); - let lbDesc = n.getChildByName('lbDesc'); - let select = n.getChildByName('select'); - lbName.getComponent(Label).string = gg.lang.get(w2.name); - lbDesc.getComponent(RichText).string = gg.lang.get(s2.desc); - select.active = this.curentskillArr.includes(Number(s2.id)); - bg.color = this.colors[s2.quality - 1]; - n.targetOff(Node.EventType.TOUCH_END); - n.on(Node.EventType.TOUCH_END, this.onClickWpSelect.bind(this, n, s2), this); - } + this.curentskillArr.length = 0; } updateSetLevel() { diff --git a/settings/v2/packages/information.json b/settings/v2/packages/information.json index a231c25..7513fb4 100644 --- a/settings/v2/packages/information.json +++ b/settings/v2/packages/information.json @@ -7,7 +7,7 @@ "enable": true, "customSplash": { "complete": true, - "form": "https://creator-api.cocos.com/api/form/show?sid=ec6b43bddfc8957bdecb688b13a99021" + "form": "https://creator-api.cocos.com/api/form/show?sid=ee5002d3a748aae1e43db5c9cbeb0f5f" } }, "removeSplash": { @@ -16,7 +16,7 @@ "enable": true, "removeSplash": { "complete": true, - "form": "https://creator-api.cocos.com/api/form/show?sid=ec6b43bddfc8957bdecb688b13a99021" + "form": "https://creator-api.cocos.com/api/form/show?sid=ee5002d3a748aae1e43db5c9cbeb0f5f" } } } diff --git a/配置表/excelList/常量表.xlsx b/配置表/excelList/常量表.xlsx index ca757a3..944dd7d 100644 Binary files a/配置表/excelList/常量表.xlsx and b/配置表/excelList/常量表.xlsx differ