From 22e9aa304de70b87d1bf841b6a7dd59b77a25f0b Mon Sep 17 00:00:00 2001 From: sganggs Date: Tue, 6 Oct 2026 01:28:31 +0800 Subject: [PATCH] =?UTF-8?q?feedback5:=20=E7=8F=8A=E6=AF=94=20S2=20/=20S3?= =?UTF-8?q?=20cast=20as=20soon=20as=20a=20ground=20enemy=20is=20on=20the?= =?UTF-8?q?=20glue=20/=20conveyor=20area=20(kit=20ACTIVE=5FRANGE=20on=20he?= =?UTF-8?q?r=20tile=20+=20the=20glue's=20first=20five=20tiles=20/=20the=20?= =?UTF-8?q?four=20ahead)=20=E2=80=94=20the=20owner's=20rule=20for=20a=20sk?= =?UTF-8?q?ill=20area=20larger=20than=20the=20range=20(her=20own=20tile),?= =?UTF-8?q?=20as=20=E4=BD=99=20S2's=20x-1;=20the=20data's=20=E9=87=8D?= =?UTF-8?q?=E8=A3=85=20DEFAULT=20only=20saw=20her=20tile=20(raised=20by=20?= =?UTF-8?q?O14);=20golden:=20only=20diy=20moved?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/sim/content/kits/ops/op-thumpy.js | 6 +++ test/content/op_thumpy.test.js | 15 +++--- test/golden/diy.json | 58 ++++++++++++------------ 3 files changed, 42 insertions(+), 37 deletions(-) diff --git a/server/sim/content/kits/ops/op-thumpy.js b/server/sim/content/kits/ops/op-thumpy.js index b458150c..0a93e5b2 100644 --- a/server/sim/content/kits/ops/op-thumpy.js +++ b/server/sim/content/kits/ops/op-thumpy.js @@ -176,6 +176,10 @@ export default { }, [S2]: { kind: 'duration', + // the owner's rule for a skill whose area is larger than her range (her tile): cast as soon as a ground enemy she + // can affect is on the glue's first five tiles — her tile, the front one, its two sides and the one beyond + // (glueTiles' PRTS order), as 余 S2's x-1 (§22.10); the data's DEFAULT (重装 exception) only saw her own tile + trigger: { rule: 'ACTIVE_RANGE', grid: [[0, 0], [0, 1], [1, 1], [-1, 1], [0, 2]] }, mods: nz({ atkPct: num(b2.atk), defPct: num(b2.def) }), onStart({ battle, unit }) { const keys = glueTiles(battle, unit, glueCount); @@ -195,6 +199,8 @@ export default { }, [S3]: { kind: 'duration', + // likewise on the conveyor: her tile and the four ahead (the owner's larger-area rule; 余 S2 precedent) + trigger: { rule: 'ACTIVE_RANGE', grid: [[0, 0], [0, 1], [0, 2], [0, 3], [0, 4]] }, mods: nz({ atkPct: num(b3.atk), defPct: num(b3.def), blockCnt: num(b3.block_cnt) }), attack: { hitAllBlocked: true }, onStart({ battle, unit }) { diff --git a/test/content/op_thumpy.test.js b/test/content/op_thumpy.test.js index e27eff72..49ec2636 100644 --- a/test/content/op_thumpy.test.js +++ b/test/content/op_thumpy.test.js @@ -84,21 +84,20 @@ test('a 自选 pick: 珊比 is offered at tiers 5 and 6 (she has a kit) and a ro { ok: true, picks: { [SLOT[5]]: { charId: THUMPY, skillIndex: 1, uniEquipId: PRPX } } }); }); -test('triggers: every skill is MANUAL with the data\'s DEFAULT (the owner\'s 重装 cast-in-range exception; rawRule TAKE_DAMAGE) — shot from afar she casts nothing, an enemy on her tile casts; a flyer on it is no target', () => { +test('triggers: every skill is MANUAL with the data\'s DEFAULT (the owner\'s 重装 exception; rawRule TAKE_DAMAGE); S1 casts with an enemy on her tile, S2 / S3 (areas larger than her range) as soon as a ground enemy is on the glue / conveyor — the kit\'s ACTIVE_RANGE; a flyer never counts', () => { for (const [tier, elite] of [[5, false], [6, true]]) { for (const skill of [0, 1, 2]) { const sk = formOf(tier, elite).skills[skill]; assert.deepEqual([sk.skillType, sk.trigger.rule, sk.trigger.rawRule], ['MANUAL', 'DEFAULT', 'TAKE_DAMAGE'], `T${tier} S${skill + 1}: data`); const { h, u } = field({ tier, elite, skill }); - assert.equal(u.skill.rule, 'DEFAULT'); - h.spawn('enemy_shooter', { pos: [10, 7] }); - h.spawn('enemy_fly', { pos: [10, 5] }); + assert.equal(u.skill.rule, skill === 0 ? 'DEFAULT' : 'ACTIVE_RANGE'); + h.spawn('enemy_fly', { pos: [10, 6] }); + if (skill === 0) h.spawn('enemy_shooter', { pos: [10, 7] }); u.skill.gainSp(999); h.run(3); - assert.ok(h.hooksOf('damaged').some((c) => c.target === u && c.source?.defId === 'enemy_shooter'), `T${tier} S${skill + 1}: she is being shot`); - assert.deepEqual([u.skill.activations, u.stats.attacks], [0, 0], `T${tier} S${skill + 1}: no cast, no attack on the flyer`); - h.spawn('enemy_dummy', { pos: [10, 5] }); - assert.ok(h.runUntil(() => u.skill.activations === 1, 3), `T${tier} S${skill + 1}: cast with an enemy on her tile`); + assert.deepEqual([u.skill.activations, u.stats.attacks], [0, 0], `T${tier} S${skill + 1}: no cast for a flyer (or a shooter off her tile for S1), no attack on the flyer`); + h.spawn('enemy_dummy', { pos: skill === 0 ? [10, 5] : [10, 7] }); + assert.ok(h.runUntil(() => u.skill.activations === 1, 3), `T${tier} S${skill + 1}: cast with a ground enemy ${skill === 0 ? 'on her tile' : 'on the skill area'}`); done(h); } } diff --git a/test/golden/diy.json b/test/golden/diy.json index b131e268..a4257084 100644 --- a/test/golden/diy.json +++ b/test/golden/diy.json @@ -2104,32 +2104,32 @@ "time": 230, "ticks": 6900, "reason": "timeout", - "killed": 23, + "killed": 21, "total": 123, "unspawned": 0, "bossHpLeft": null, "rngDraws": 0, "errors": {"count":0,"kinds":[]}, - "players": {"p1":{"killed":23,"total":123,"perfect":false,"leaks":100,"leaksUncounted":0,"coins":0,"dmg":780056,"bossDmg":0,"heal":14644,"deaths":16,"layerGains":{}}}, + "players": {"p1":{"killed":21,"total":123,"perfect":false,"leaks":102,"leaksUncounted":0,"coins":0,"dmg":798457,"bossDmg":0,"heal":14644,"deaths":16,"layerGains":{}}}, "units": [ - ["p1",1,"op","chess_char_6_diy1_b",0,"none",1,1,94,5,209942,6455,0,74,1], - ["p1",2,"op","chess_char_6_diy2_b",1,"none",2547.98,1,122,6,167130,15078,12998,55,3], - ["p1",3,"op","chess_char_6_diy1_b",2,"none",1,1,133,11,214459,8531,1646,64,2], - ["p1",4,"op","chess_char_6_diy2_b",0,"uniequip_002_hsgma2",1857.31,1,143,1,36153,5249,0,22,1], + ["p1",1,"op","chess_char_6_diy1_b",0,"none",1,1,94,5,218678,6455,0,79,2], + ["p1",2,"op","chess_char_6_diy2_b",1,"none",2547.98,1,122,6,167870,15078,12998,56,3], + ["p1",3,"op","chess_char_6_diy1_b",2,"none",1,1,133,7,163835,8532,1646,46,2], + ["p1",4,"op","chess_char_6_diy2_b",0,"uniequip_002_hsgma2",1857.31,1,143,1,32903,5249,0,18,1], ["p1",5,"op","chess_char_6_diy1_b",1,"uniequip_002_hsgma2",3553,1,144,0,7024,7106,0,6,0], - ["p1",6,"op","chess_char_6_diy2_b",2,"uniequip_002_hsgma2",0,0,5,0,127199,6040,0,18,1], + ["p1",6,"op","chess_char_6_diy2_b",2,"uniequip_002_hsgma2",0,0,5,2,136656,6040,0,21,1], ["p1",7,"op","chess_char_5_diy1_a",0,null,0,0,75,0,472,5130,0,2,0], - ["p1",8,"op","chess_char_5_diy2_a",1,null,0,0,1,0,10133,2565,0,2,1], - ["p1",9,"op","chess_char_5_diy1_a",2,null,0,0,2,0,2068,2565,0,2,1], + ["p1",8,"op","chess_char_5_diy2_a",1,null,0,0,1,0,46627,2565,0,3,1], + ["p1",9,"op","chess_char_5_diy1_a",2,null,0,0,2,0,18916,2565,0,3,1], ["p1",10,"op","chess_char_5_diy2_b",0,"none",0,0,6,0,556,3194,0,1,1], ["p1",11,"op","chess_char_5_diy1_b",1,"none",0,0,74,0,1625,6388,0,5,0], ["p1",12,"op","chess_char_5_diy2_b",2,"none",0,0,66,0,3295,6388,0,7,0] ], - "enemies": {"enemy_1019_jshoot_2":[57,16,40,20398,366623],"enemy_1299_ymkilr_2":[27,0,27,43104,118193],"enemy_1422_lrsldr_2":[39,7,31,11187,295240]}, - "hooks": [1,144,6900,930,930,1743,1805,496,39,137,11,9,0,5236,271,65,123,98,1,39,0,1,0], - "events": {"atk":995,"deploy":21,"die":39,"dmg":1523,"fx":401,"heal":160,"leak":98,"skill":20,"spawn":135,"status":168}, - "fx": {"burst":1,"counter":153,"shield":1,"strike":230,"undying":11,"zone":5}, - "snaps": "2bd122f0 4ac3385c 96a39114 a5893cd8 051e791a 5a5a93c5 e35983bb 9ff770c5 06c88612 31239379 f4bf2aa3 13c07a44 7ad6caf0 01eeb1c6 a69add99 acbe0984 39667970 60ffd978 4b7d264c 01ee3f5c 0db9891d 0cf72c7f 2513055f" + "enemies": {"enemy_1019_jshoot_2":[57,16,40,19520,370400],"enemy_1299_ymkilr_2":[27,0,27,45400,82470],"enemy_1422_lrsldr_2":[39,5,33,9769,345587]}, + "hooks": [1,144,6900,897,897,1833,1996,496,37,137,12,10,0,4815,357,66,123,100,1,37,0,7,0], + "events": {"atk":961,"deploy":21,"die":37,"dmg":1718,"fx":421,"heal":160,"leak":100,"skill":22,"spawn":135,"status":366}, + "fx": {"burst":7,"counter":157,"shield":11,"strike":230,"undying":11,"zone":5}, + "snaps": "2bd122f0 7f3a3e53 db83e114 83767c40 20d3f45c f4dfdeb2 340c122b 1f62dd45 ece8fd99 c7fcae44 0cda025a 6a2aee1b d3b6c592 4c333590 783eb54c e9147860 4c8c0043 449dd30f dfdf76aa b7c82e21 799e1452 8a4cf506 6311a530" }, "diy-053": { "about": "5_diy1_b=thumpy/S1/002_thumpy 5_diy2_b=thumpy/S2/002_thumpy 5_diy1_b=thumpy/S3/002_thumpy 6_diy1_a=thumpy/S1 6_diy2_a=thumpy/S2 6_diy1_a=thumpy/S3 6_diy2_b=thumpy/S1 6_diy1_b=thumpy/S2 6_diy2_b=thumpy/S3 6_diy1_b=thumpy/S1/002_thumpy 6_diy2_b=thumpy/S2/002_thumpy 6_diy1_b=thumpy/S3/002_thumpy", @@ -2140,8 +2140,8 @@ "round": 13, "seed": 2850577873, "waveId": "act1autochess_h06", - "time": 209.6, - "ticks": 6288, + "time": 206.4, + "ticks": 6192, "reason": "cleared", "killed": 114, "total": 114, @@ -2153,24 +2153,24 @@ "units": [ ["p1",1,"op","chess_char_5_diy1_b",0,"uniequip_002_thumpy",3444,1,3,0,0,0,0,0,0], ["p1",2,"op","chess_char_5_diy2_b",1,"uniequip_002_thumpy",3444,1,4,0,0,0,0,0,0], - ["p1",3,"op","chess_char_5_diy1_b",2,"uniequip_002_thumpy",3444,1,5,15,133079,0,0,9,1], - ["p1",4,"op","chess_char_6_diy1_a",0,null,2239.4,1,7,0,15316,326,0,16,1], - ["p1",5,"op","chess_char_6_diy2_a",1,null,2551.8,1,11,32,259439,13,0,34,3], - ["p1",6,"op","chess_char_6_diy1_a",2,null,2235,1,13,37,282521,330,0,95,2], - ["p1",7,"op","chess_char_6_diy2_b",0,"none",2784.8,1,14,12,115470,409,0,130,3], - ["p1",8,"op","chess_char_6_diy1_b",1,"none",3167.6,1,8,6,40542,26,0,2,1], - ["p1",9,"op","chess_char_6_diy2_b",2,"none",2886,1,12,12,112674,308,0,92,2], + ["p1",3,"op","chess_char_5_diy1_b",2,"uniequip_002_thumpy",3444,1,5,14,138371,0,0,0,2], + ["p1",4,"op","chess_char_6_diy1_a",0,null,2565,1,7,0,0,0,0,0,0], + ["p1",5,"op","chess_char_6_diy2_a",1,null,2565,1,11,26,250395,0,0,0,4], + ["p1",6,"op","chess_char_6_diy1_a",2,null,2450.6,1,13,28,224467,114,0,83,2], + ["p1",7,"op","chess_char_6_diy2_b",0,"none",2903.6,1,14,13,89503,290,0,128,3], + ["p1",8,"op","chess_char_6_diy1_b",1,"none",3194,1,8,5,65648,0,0,0,4], + ["p1",9,"op","chess_char_6_diy2_b",2,"none",3000.4,1,12,13,87568,194,0,79,2], ["p1",10,"op","chess_char_6_diy1_b",0,"uniequip_002_thumpy",3644,1,9,0,0,0,0,0,0], - ["p1",11,"op","chess_char_6_diy2_b",1,"uniequip_002_thumpy",3644,1,10,0,0,0,0,0,0], + ["p1",11,"op","chess_char_6_diy2_b",1,"uniequip_002_thumpy",3644,1,10,15,103089,0,0,0,2], ["p1",12,"op","chess_char_6_diy1_b",2,"uniequip_002_thumpy",3644,1,6,0,0,0,0,0,0], ["-","~1","device","trap_1105_accrate",null,null,100,1,1,0,0,0,0,0,null], ["-","~2","device","trap_1105_accrate",null,null,100,1,2,0,0,0,0,0,null] ], - "enemies": {"enemy_1381_winman":[27,27,0,436,150336],"enemy_1381_winman_2":[48,48,0,581,359424],"enemy_1387_winshd":[39,39,0,396,449280]}, - "hooks": [1,128,6288,1005,1005,3140,5232,0,114,114,13,13,0,18520,726,165,114,0,1,114,0,187,0], - "events": {"atk":1225,"deploy":12,"die":114,"dmg":4689,"fx":657,"skill":26,"spawn":128,"status":1799}, - "fx": {"burst":187,"displace":52,"shield":409,"zone":9}, - "snaps": "e16d0b90 705560d0 873d70c8 8336cfb8 6756edb4 df4b2178 eb458684 ddf18b37 9e09661f 83a30c0d 851d3cf5 2772710d 3183643a db6cc3d2 43b11e92 1b642500 ac4b6665 577c73aa 4d053ae7 13261199 fbb19022" + "enemies": {"enemy_1381_winman":[27,27,0,251,150336],"enemy_1381_winman_2":[48,48,0,194,359424],"enemy_1387_winshd":[39,39,0,154,449280]}, + "hooks": [1,128,6192,720,720,2873,4882,0,114,114,19,19,0,23406,929,121,114,0,1,114,0,190,0], + "events": {"atk":870,"deploy":12,"die":114,"dmg":4489,"fx":702,"skill":38,"spawn":128,"status":2065}, + "fx": {"burst":190,"displace":13,"shield":483,"zone":16}, + "snaps": "e16d0b90 f693a9bd 5dd37cf8 cfc3ad46 86781277 0cf687fc 6cb659b1 bea11a8b 531bad83 f4c188a4 0cc40431 c5bee9da 1dfca9f5 c0a3c672 c62826f9 91a3c8f1 ced13aba 2713fa0d ed8224a5 dbf85f5a a803461a" }, "diy-054": { "about": "5_diy1_a=cdfend 5_diy2_b=cdfend 5_diy1_a=cguard 5_diy2_b=cguard 5_diy1_a=csnipe 5_diy2_b=csnipe 5_diy1_a=ccast 5_diy2_b=ccast 5_diy1_a=cmedic 5_diy2_b=cmedic 5_diy1_a=csuppo 5_diy2_b=csuppo",