feedback5 WE1: 链愈师 heal jumps within the 3×3 around the last one healed (x-4), a full-HP ally included (follow-up 27)
PRTS 分支特性信息 链愈师: "跳跃范围为x-4…不会对已跳跃过的单位重复跳跃", "优先跳跃至范围内生命比例最低>部署时间点最晚的我方单位。 可选择满生命我方单位为跳跃目标,但仍受禁疗制约" (range_table x-4 = the 3×3 around the unit). - ai.js chainHealNext: an ally on the 3×3 of tiles around the last one healed, not yet in the chain, no device / hidden / 孤立 / 禁疗 unit (the healer's healThrough summon excepted), the lowest HP ratio first — a full-HP ally too, the chain goes on from it — then the latest deployed. doHeal (莎草) and Mon3tr's chainFrom both use it (her fullProsts case is now general and gone). It used to be the most injured ally within 2.5 tiles. [ASSUMED] 禁疗 = not selected. Golden: roster-004, roster-005, roster-023, roster-024, bond-sargonShip-low (莎草's chains: other jump targets, full-HP links); diy-133, diy-134 (Mon3tr). Others unchanged (no match fields a chain healer). Tests: test/sim/feedback5-chain-heal.test.js (new, 3); op_monstr, kits_t1t2, feedback2-surtr-stealth pass. Docs: SIM.md §Professions (chainhealer row).
This commit is contained in:
1 parent
027c8477eb
commit
e1a7920482
7 files changed
+227
-166
No files matched your search
+1
-1
@@ -1213,7 +1213,7 @@ header of professions.js).
|
||||
| phalanx | no attack & DEF +200 %, RES +20 (bb) while the skill is off; while on, `rangeAoe`: each attack strikes every selectable enemy on its range at once (blocked enemies included; a stealthed one only when revealed or blocked), the same damage near and far, instant (`'beam'`) — "群体法术伤害" (secondary: Terra Wiki, Phalanx Caster: "attacks hit all enemies within their range"; supporting: PRTS 林 S3 备注 "单次普攻最多触发1次效果" — one normal attack can kill several — the same 锁定攻击范围 shape as the 轰击术师, and PRTS 溅射半径一览 documents no splash radius for it (it omits the 撼地者 too, so this is not proof); no primary source states a target cap; community report E3: it used to be one bolt + a 1.1 splash). 卡涅利安's charged S1 keeps the skill-off trait, 不攻击 included (kit `canAttack`, PRTS 备注) |
|
||||
| physician | heal the lowest HP% injured ally in range (a skill `targeting.maxTargets` widens any heal profile) |
|
||||
| ringhealer | heal 3 allies |
|
||||
| chainhealer | heal bounces 3× (−25 %, bb chain.*) within 2.5 tiles |
|
||||
| chainhealer | the heal jumps on to 3 units in all (−25 % per jump, bb chain.*), each jump inside the 3×3 of tiles around the last one healed (range x-4), never twice to one unit, the lowest HP ratio first — a full-HP ally too (healed for nothing, the chain goes on from it) — then the latest deployed; no 禁疗 / 孤立 unit (a healer's `healThrough` summon excepted) — PRTS 分支特性信息 链愈师 (`ai.js chainHealNext`, shared with Mon3tr's kit; until 0.2.0: the most injured ally within 2.5 tiles) |
|
||||
| healer (流明) | heal ×0.8 (bb heal_scale) beyond 2 tiles |
|
||||
| wandermedic | heal + reduce element gauges by 50 % ATK (bb ep_heal_ratio); also targets uninjured allies with gauge |
|
||||
| incantationmedic | arts attack; EVERY damage the unit deals heals the lowest ally in range for 50 % (bb scale) of it — the official trait buff (`vendla_tr` / `reed2_tr` / `titi_tr`) is ON_AFTER_OUTPUT_DAMAGE, so skill and DoT damage heals too (缇缇's 凝固的时光 ticks, 焰影苇草's S2 fireballs while she is disarmed); a skill that triggers it for one named ally says so ("仅对该角色触发…特性") and the damage instance carries that ally (`DamageInfo.traitAlly`) |
|
||||
|
||||
+22
-7
@@ -333,6 +333,27 @@ export function resolveHit(b, u, prof, target, info, x, y) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The next unit of a 链愈师 heal chain of `healer` from `prev` — PRTS 分支特性信息 链愈师: "跳跃范围为x-4,无特殊说明的场合一次
|
||||
* 治疗链不会对已跳跃过的单位重复跳跃", "优先跳跃至范围内生命比例最低>部署时间点最晚的我方单位。可选择满生命我方单位为跳跃目标,但仍受
|
||||
* 禁疗制约": an ally on the 3×3 of tiles around prev's (range x-4), not yet in this chain (`seen` ids), no device, no hidden
|
||||
* or 孤立 unit, no 禁疗 / 无法被治疗 one (as Battle.injuredAlliesInKeys: the healer's `healThrough` lets its own summon in —
|
||||
* 凯尔希 / Mon3tr); the lowest HP ratio first — a full-HP ally too, healed for nothing, and the chain jumps on from it —,
|
||||
* then the latest deployed (aggroSeq). Null when none. Shared by the profession (doHeal) and Mon3tr's kit.
|
||||
*/
|
||||
export function chainHealNext(b, healer, prev, seen) {
|
||||
const through = healer && healer.profile && typeof healer.profile.healThrough === 'function' ? healer.profile.healThrough : null;
|
||||
const r0 = prev.tileR, c0 = prev.tileC;
|
||||
let best = null;
|
||||
for (const a of b.allyUnits) {
|
||||
if (!a.alive || !a.deployed || a.hidden || a.kind === 'device' || seen.has(a.id)) continue;
|
||||
if (Math.abs(a.tileR - r0) > 1 || Math.abs(a.tileC - c0) > 1) continue;
|
||||
if (a !== healer && (a.s.flags.isolated || (a.s.flags.noHeal && !(through && through(healer, a))) || (a.profile && a.profile.noHeal))) continue;
|
||||
if (!best || a.hpRatio < best.hpRatio - 1e-12 || (Math.abs(a.hpRatio - best.hpRatio) <= 1e-12 && a.aggroSeq > best.aggroSeq)) best = a;
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
function doHeal(b, u, prof, t) {
|
||||
const atk = u.s.atk;
|
||||
const scale = (prof.atkScale ?? 1) * (prof.healScale ?? 1) * u.s.atkScaleMul;
|
||||
@@ -346,13 +367,7 @@ function doHeal(b, u, prof, t) {
|
||||
let prev = t;
|
||||
const n = Math.max(1, h.count || 3);
|
||||
for (let k = 1; k < n; k++) {
|
||||
let best = null, bd = Infinity;
|
||||
for (const a of b.alliesInRadius(prev.x, prev.y, 2.5, null)) {
|
||||
// 禁疗 / noHeal units are no heal target for the bounces either (as injuredAlliesInKeys; 史尔特尔's 余烬, GitHub #52)
|
||||
if (seen.has(a.id) || a.hp >= a.s.maxHp || a.kind === 'device' || a.s.flags.noHeal || (a.profile && a.profile.noHeal)) continue;
|
||||
const d = a.hpRatio;
|
||||
if (d < bd) { bd = d; best = a; }
|
||||
}
|
||||
const best = chainHealNext(b, u, prev, seen);
|
||||
if (!best) break;
|
||||
seen.add(best.id);
|
||||
b._ev(['atk', prev.id, best.id, 'chainHeal']);
|
||||
|
||||
@@ -27,8 +27,9 @@
|
||||
// prosts_t_1[born_charge] BLOCK_CNT ×0, interval 0.1, firstTriggerInterval 1, FixedValueDamage PURE `damage` on itself);
|
||||
// buff_template_data (monstr_t_2[atk_spd] ON_OUTPUT_MODIFIER IsHeal; monstr_s_3[undead] ON_BEFORE_TRY_SET_HP_ZERO).
|
||||
// - Trait (链愈师) "恢复友方单位生命,且会在3个友方单位间跳跃,每次跳跃治疗量降低25%" — the chain is this kit's (the profession's
|
||||
// 2.5-tile chain is replaced: heal mode single + `chainFrom`), as her heal projectiles have it: after the heal on the main
|
||||
// target the heal jumps to the lowest-HP-ratio injured ally of the 3×3 around the last one healed (x-4), each jump ×
|
||||
// chain is replaced: heal mode single + `chainFrom`, its links the profession's — ai.js chainHealNext): after the heal on
|
||||
// the main target the heal jumps to the lowest-HP-ratio ally (a full-HP one too — PRTS 分支特性信息 链愈师; ties: the latest
|
||||
// deployed) of the 3×3 around the last one healed (x-4), each jump ×
|
||||
// attack@chain.atk_scale (0.75; XAH-X 0.85), up to attack@chain.max_target units healed (3). A 重构体 (and she herself while S3
|
||||
// runs: monstr[free_jump]) is a free link: healing it uses no target of the count and the next jump does not decay (XAH-X
|
||||
// stage 3: the next attack@chain.extra_cnt jumps after that neither). Her heals pass 禁疗 ("治疗效果无视禁疗"); her selection
|
||||
@@ -63,6 +64,7 @@
|
||||
|
||||
import { num, talentBb, traitBb, skillRec, batMod, installAura, up } from '../shared/tier1.js';
|
||||
import { COLS } from '../../../constants.js';
|
||||
import { chainHealNext } from '../../../ai.js';
|
||||
|
||||
const S1 = 'skchr_monstr_1';
|
||||
const S2 = 'skchr_monstr_2';
|
||||
@@ -101,28 +103,13 @@ const prostsInRange = (battle, unit) => prostsOf(battle, unit).find((t) => up(t)
|
||||
/** `a` stands on the 3×3 around `b` (x-4: a heal jump's reach, the 重构体's aura). */
|
||||
const nearX4 = (a, b) => Math.abs(a.tileR - b.tileR) <= 1 && Math.abs(a.tileC - b.tileC) <= 1;
|
||||
|
||||
/**
|
||||
* The next link of a chain heal from `cur`: the lowest-HP-ratio injured ally of its 3×3 not healed yet by this chain (her
|
||||
* own 重构体 even at full HP when `fullProsts`); never a 禁疗 unit but her 重构体.
|
||||
*/
|
||||
function nextLink(battle, unit, cur, seen, fullProsts) {
|
||||
let best = null;
|
||||
for (const a of battle.allyUnits) {
|
||||
if (!a.alive || !a.deployed || a.hidden || a.kind === 'device' || seen.has(a.id) || !nearX4(a, cur)) continue;
|
||||
const mine = isProstsOf(a, unit);
|
||||
if (a !== unit && ((a.s.flags.noHeal && !mine) || (a.profile && a.profile.noHeal))) continue;
|
||||
if (!(a.hp < a.s.maxHp - 1e-6) && !(fullProsts && mine)) continue;
|
||||
if (!best || a.hpRatio < best.hpRatio - 1e-12 || (Math.abs(a.hpRatio - best.hpRatio) <= 1e-12 && a.deploySeq < best.deploySeq)) best = a;
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
/**
|
||||
* A chain heal of hers from `main` (already healed by her attack when `mainDone`): up to `count` units healed, × `step` per
|
||||
* jump; a free link (her 重构体; herself with `selfFree`) uses no target of the count and the next 1 + `extra` jumps keep the
|
||||
* amount.
|
||||
* amount. Each link is the 链愈师 one (ai.js chainHealNext — the 3×3 around the last one healed, the lowest HP ratio a
|
||||
* full-HP ally included, then the latest deployed; no 禁疗 unit but her 重构体, her `healThrough`).
|
||||
*/
|
||||
function chainFrom(battle, unit, main, base, { count, step, extra, fullProsts = false, mainDone = false, selfFree = false }) {
|
||||
function chainFrom(battle, unit, main, base, { count, step, extra, mainDone = false, selfFree = false }) {
|
||||
const free = (t) => isProstsOf(t, unit) || (selfFree && t === unit);
|
||||
let amount = base;
|
||||
if (!mainDone) battle.heal(unit, main, amount, HEAL_OPTS);
|
||||
@@ -131,7 +118,7 @@ function chainFrom(battle, unit, main, base, { count, step, extra, fullProsts =
|
||||
const seen = new Set([main.id]);
|
||||
let cur = main;
|
||||
while (counted < count) {
|
||||
const next = nextLink(battle, unit, cur, seen, fullProsts);
|
||||
const next = chainHealNext(battle, unit, cur, seen);
|
||||
if (!next) break;
|
||||
seen.add(next.id);
|
||||
if (calm > 0) calm--; else amount *= step;
|
||||
@@ -280,12 +267,12 @@ export default {
|
||||
const base = unit.s.atk * (prof.atkScale ?? 1) * (prof.healScale ?? 1) * unit.s.atkScaleMul;
|
||||
for (const t of c.targets || []) {
|
||||
if (!t || t.side !== 'ally') continue;
|
||||
chainFrom(battle, unit, t, base, { ...chain, count: s1on ? s1Count : chain.count, fullProsts: s2on, mainDone: true });
|
||||
chainFrom(battle, unit, t, base, { ...chain, count: s1on ? s1Count : chain.count, mainDone: true });
|
||||
// S2: 0.6 s after her attack healed her 重构体, a second chain on it (her ATK × 1)
|
||||
if (s2on && isProstsOf(t, unit)) {
|
||||
battle.after(S2_EXTRA_DELAY, () => {
|
||||
if (!unit.alive || !up(t)) return;
|
||||
chainFrom(battle, unit, t, unit.s.atk * unit.s.atkScaleMul, { ...chain, fullProsts: skillOn(unit, S2) });
|
||||
chainFrom(battle, unit, t, unit.s.atk * unit.s.atkScaleMul, chain);
|
||||
}, { owner: unit });
|
||||
}
|
||||
}
|
||||
|
||||
+13
-13
@@ -1065,23 +1065,23 @@
|
||||
"rngDraws": 2,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {
|
||||
"p1": {"killed":15,"total":17,"perfect":false,"leaks":2,"leaksUncounted":0,"coins":0,"dmg":70415,"bossDmg":0,"heal":16499,"deaths":0,"layerGains":{"sargonShip":5}}
|
||||
"p1": {"killed":15,"total":17,"perfect":false,"leaks":2,"leaksUncounted":0,"coins":0,"dmg":70415,"bossDmg":0,"heal":16347,"deaths":0,"layerGains":{"sargonShip":5}}
|
||||
},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_2_08_a",1,null,2300.11,1,2,2,2745,6042,2156,34,1],
|
||||
["p1",2,"op","chess_char_1_12_a",1,null,1840,1,1,0,0,0,63,0,0],
|
||||
["p1",3,"op","chess_char_4_22_a",2,null,2022,1,3,3,30743,1182,694,23,1],
|
||||
["p1",4,"op","chess_char_2_06_a",0,null,1440,1,4,0,0,916,6860,31,15],
|
||||
["p1",5,"op","chess_char_4_21_a",1,null,1271,1,7,0,0,2019,3276,40,1],
|
||||
["p1",6,"op","chess_char_4_25_a",2,null,1221,1,5,0,0,2137,698,0,1],
|
||||
["p1",7,"op","chess_char_4_26_a",0,null,1368,1,8,0,0,3145,2223,13,0],
|
||||
["p1",8,"op","chess_char_3_01_a",2,null,1471.8,1,6,10,36927,1389,530,51,1]
|
||||
["p1",1,"op","chess_char_2_08_a",1,null,2300.11,1,2,2,2745,6110,2375,34,1],
|
||||
["p1",2,"op","chess_char_1_12_a",1,null,1840,1,1,0,0,0,111,0,0],
|
||||
["p1",3,"op","chess_char_4_22_a",2,null,2022,1,3,3,30743,1232,716,23,1],
|
||||
["p1",4,"op","chess_char_2_06_a",0,null,1440,1,4,0,0,797,6475,32,15],
|
||||
["p1",5,"op","chess_char_4_21_a",1,null,1271,1,7,0,0,1951,3665,43,1],
|
||||
["p1",6,"op","chess_char_4_25_a",2,null,1221,1,5,0,0,2053,696,0,1],
|
||||
["p1",7,"op","chess_char_4_26_a",0,null,1368,1,8,0,0,3044,1697,15,0],
|
||||
["p1",8,"op","chess_char_3_01_a",2,null,1471.8,1,6,10,36927,1490,613,51,1]
|
||||
],
|
||||
"enemies": {"enemy_1267_nhpbr":[11,10,0,4553,43172],"enemy_1267_nhpbr_2":[5,5,0,1783,24750],"enemy_1272_nhtank":[1,0,0,10494,2493]},
|
||||
"hooks": [1,25,3300,234,234,523,523,2355,15,15,20,20,0,14437,0,5,17,0,1,15,1,0,0],
|
||||
"events": {"atk":316,"deploy":8,"die":15,"dmg":483,"engage":3,"fx":112,"heal":156,"layer":1,"skill":40,"spawn":25,"status":235},
|
||||
"enemies": {"enemy_1267_nhpbr":[11,10,0,4678,43172],"enemy_1267_nhpbr_2":[5,5,0,1676,24750],"enemy_1272_nhtank":[1,0,0,10323,2493]},
|
||||
"hooks": [1,25,3300,240,240,523,523,2589,15,15,20,20,0,14437,0,5,17,0,1,15,1,0,0],
|
||||
"events": {"atk":332,"deploy":8,"die":15,"dmg":481,"engage":3,"fx":112,"heal":155,"layer":1,"skill":40,"spawn":25,"status":247},
|
||||
"fx": {"buff":1,"counter":15,"garrison":1,"healField":1,"mote":38,"redistribute":15,"reweave":1,"slash":17,"spGift":1,"truesilver":1,"zone":21},
|
||||
"snaps": "0bdd9351 b24b323e bd7fa0e6 4703d650 28cb05fc cf42c370 8691643e b07ee7e3 98f5edc6 aed38d5e c73b513b"
|
||||
"snaps": "0bdd9351 b24b323e ab95517a c55fba39 176cd8a6 f77ba7e2 c1b9c3f4 2b4fa92b 246b1e91 0f8ceadd 18c1b994"
|
||||
},
|
||||
"bond-sargonShip-high": {
|
||||
"about": "萨尔贡 high: tier 2 layers 999; chess_char_1_12_b chess_char_2_08_b chess_char_3_06_b chess_char_4_23_b chess_char_4_22_b chess_char_2_06_b chess_char_3_13_b chess_char_4_25_b",
|
||||
|
||||
+30
-30
@@ -5782,35 +5782,35 @@
|
||||
"time": 230,
|
||||
"ticks": 6900,
|
||||
"reason": "timeout",
|
||||
"killed": 69,
|
||||
"killed": 70,
|
||||
"total": 123,
|
||||
"unspawned": 0,
|
||||
"bossHpLeft": null,
|
||||
"rngDraws": 0,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {"p1":{"killed":69,"total":123,"perfect":false,"leaks":54,"leaksUncounted":0,"coins":0,"dmg":1779789,"bossDmg":0,"heal":458058,"deaths":1,"layerGains":{}}},
|
||||
"players": {"p1":{"killed":70,"total":123,"perfect":false,"leaks":53,"leaksUncounted":0,"coins":0,"dmg":1791852,"bossDmg":0,"heal":430240,"deaths":1,"layerGains":{}}},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_6_diy1_a",0,null,1741.25,1,4,0,0,0,35265,71,3],
|
||||
["p1",2,"op","chess_char_6_diy2_a",1,null,1741.25,1,5,49,1130811,0,13326,72,4],
|
||||
["p1",3,"op","chess_char_6_diy1_a",2,null,1741.25,1,11,0,0,0,48902,100,2],
|
||||
["p1",4,"op","chess_char_6_diy2_b",0,"none",1928.75,1,13,0,0,0,40135,79,3],
|
||||
["p1",5,"op","chess_char_6_diy1_b",1,"none",1928.75,1,6,20,648978,0,15029,60,3],
|
||||
["p1",6,"op","chess_char_6_diy2_b",2,"none",1928.75,1,14,0,0,0,31322,80,3],
|
||||
["p1",7,"op","chess_char_5_diy1_a",0,null,0,0,7,0,0,77284,43526,67,11],
|
||||
["p1",8,"op","chess_char_5_diy2_a",1,null,1492,1,9,0,0,98191,56296,94,4],
|
||||
["p1",9,"op","chess_char_5_diy1_a",2,null,1113.03,1,10,0,0,107130,55404,89,0],
|
||||
["p1",10,"op","chess_char_5_diy2_b",0,"none",1653,1,12,0,0,22049,49896,78,19],
|
||||
["p1",11,"op","chess_char_5_diy1_b",1,"none",1653,1,15,0,0,64626,22045,53,3],
|
||||
["p1",12,"op","chess_char_5_diy2_b",2,"none",1653,1,8,0,0,90649,46914,80,0],
|
||||
["p1",1,"op","chess_char_6_diy1_a",0,null,1741.25,1,4,0,0,0,34388,69,3],
|
||||
["p1",2,"op","chess_char_6_diy2_a",1,null,1741.25,1,5,52,1139811,0,13928,72,4],
|
||||
["p1",3,"op","chess_char_6_diy1_a",2,null,1741.25,1,11,0,0,0,56572,116,2],
|
||||
["p1",4,"op","chess_char_6_diy2_b",0,"none",1928.75,1,13,0,0,0,43866,93,4],
|
||||
["p1",5,"op","chess_char_6_diy1_b",1,"none",1928.75,1,6,18,652042,0,16199,65,3],
|
||||
["p1",6,"op","chess_char_6_diy2_b",2,"none",1928.75,1,14,0,0,0,24897,85,3],
|
||||
["p1",7,"op","chess_char_5_diy1_a",0,null,1492,1,139,0,0,49198,26898,47,7],
|
||||
["p1",8,"op","chess_char_5_diy2_a",1,null,1492,1,9,0,0,98191,48518,91,4],
|
||||
["p1",9,"op","chess_char_5_diy1_a",2,null,1415.53,1,10,0,0,107130,46829,85,0],
|
||||
["p1",10,"op","chess_char_5_diy2_b",0,"none",1653,1,12,0,0,22049,56243,75,18],
|
||||
["p1",11,"op","chess_char_5_diy1_b",1,"none",1653,1,15,0,0,64626,22341,51,2],
|
||||
["p1",12,"op","chess_char_5_diy2_b",2,"none",1617.78,1,8,0,0,90649,39561,82,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],
|
||||
["-","~3","device","trap_1105_accrate",null,null,100,1,3,0,0,0,0,0,null]
|
||||
],
|
||||
"enemies": {"enemy_1006_shield_3":[21,0,17,367121,555485],"enemy_1043_zomsbr":[66,60,5,22690,476621],"enemy_1402_tgshd_2":[36,9,20,70117,747683]},
|
||||
"hooks": [1,138,6900,1402,1402,1128,1128,13267,70,112,55,52,70,22887,578,8,123,42,1,70,0,0,0],
|
||||
"events": {"atk":1777,"deploy":12,"die":70,"dmg":1118,"engage":2,"fx":458,"heal":1235,"leak":42,"skill":107,"spawn":138,"status":184},
|
||||
"fx": {"aoe":69,"expose":274,"healAoe":69,"shield":40,"takeoff":6},
|
||||
"snaps": "10b9b952 5a9c72b0 63328571 c14679f9 6590e801 46960fe3 e8ef4c65 d292fcf9 a7316f10 feac6b4b a477a19f 09fa6c39 ee21d1da 779f3d36 9390eeb1 5ae18e38 143ac30c 9f960c8a 88a1a740 47c6d6cd 5abd21eb 3f870752 b34f3d2c"
|
||||
"enemies": {"enemy_1006_shield_3":[21,0,18,335375,546424],"enemy_1043_zomsbr":[66,61,4,22690,482592],"enemy_1402_tgshd_2":[36,9,20,73778,762837]},
|
||||
"hooks": [1,139,6900,1392,1392,1111,1111,13434,71,113,50,46,69,22945,578,9,123,42,1,71,0,0,0],
|
||||
"events": {"atk":2285,"deploy":13,"die":71,"dmg":1100,"engage":2,"fx":461,"heal":1136,"leak":42,"skill":96,"spawn":138,"status":196},
|
||||
"fx": {"aoe":68,"expose":276,"healAoe":68,"shield":43,"takeoff":6},
|
||||
"snaps": "10b9b952 5a9c72b0 a18bcace ad14730d 2738cb6e b6480676 ce3143fe 8325b936 65ce32cb e08469c0 e89b323b ef437c41 2c092c6c 276a47df ec4d8626 4df04cb8 9b1aa959 6947de2d 09278232 1248b5da 89e60aa4 cc242745 850b5133"
|
||||
},
|
||||
"diy-134": {
|
||||
"about": "5_diy1_b=monstr/S1/002_monstr 5_diy2_b=monstr/S2/002_monstr 5_diy1_b=monstr/S3/002_monstr 6_diy1_a=monstr/S1 6_diy2_a=monstr/S2 6_diy1_a=monstr/S3 6_diy2_b=monstr/S1 6_diy1_b=monstr/S2 6_diy2_b=monstr/S3 6_diy1_b=monstr/S1/002_monstr 6_diy2_b=monstr/S2/002_monstr 6_diy1_b=monstr/S3/002_monstr",
|
||||
@@ -5832,24 +5832,24 @@
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {"p1":{"killed":0,"total":87,"perfect":false,"leaks":87,"leaksUncounted":0,"coins":0,"dmg":0,"bossDmg":0,"heal":114994,"deaths":14,"layerGains":{}}},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_5_diy1_b",0,"uniequip_002_monstr",1653,1,4,0,0,1184,27568,59,14],
|
||||
["p1",1,"op","chess_char_5_diy1_b",0,"uniequip_002_monstr",1653,1,4,0,0,1184,27652,59,14],
|
||||
["p1",2,"op","chess_char_5_diy2_b",1,"uniequip_002_monstr",1653,1,109,0,0,5064,13988,43,3],
|
||||
["p1",3,"op","chess_char_5_diy1_b",2,"uniequip_002_monstr",1653,1,5,0,0,0,8140,16,0],
|
||||
["p1",4,"op","chess_char_6_diy1_a",0,null,1492,1,8,0,0,2368,2773,3,0],
|
||||
["p1",5,"op","chess_char_6_diy2_a",1,null,0,0,91,0,0,11963,7318,19,2],
|
||||
["p1",6,"op","chess_char_6_diy1_a",2,null,0,0,87,0,0,11963,7558,18,0],
|
||||
["p1",7,"op","chess_char_6_diy2_b",0,"none",1653,1,67,0,0,22845,11839,31,7],
|
||||
["p1",4,"op","chess_char_6_diy1_a",0,null,1492,1,8,0,0,2368,2736,3,0],
|
||||
["p1",5,"op","chess_char_6_diy2_a",1,null,0,0,91,0,0,11963,6982,19,2],
|
||||
["p1",6,"op","chess_char_6_diy1_a",2,null,0,0,87,0,0,11963,7534,18,0],
|
||||
["p1",7,"op","chess_char_6_diy2_b",0,"none",1653,1,67,0,0,22845,12161,31,7],
|
||||
["p1",8,"op","chess_char_6_diy1_b",1,"none",1653,1,110,0,0,11254,7251,27,2],
|
||||
["p1",9,"op","chess_char_6_diy2_b",2,"none",1653,1,103,0,0,18899,10855,43,0],
|
||||
["p1",10,"op","chess_char_6_diy1_b",0,"uniequip_002_monstr",1653,1,59,0,0,22285,10465,41,9],
|
||||
["p1",9,"op","chess_char_6_diy2_b",2,"none",1653,1,103,0,0,18899,11054,42,0],
|
||||
["p1",10,"op","chess_char_6_diy1_b",0,"uniequip_002_monstr",1653,1,59,0,0,22285,9926,41,9],
|
||||
["p1",11,"op","chess_char_6_diy2_b",1,"uniequip_002_monstr",0,0,97,0,0,12660,3464,12,1],
|
||||
["p1",12,"op","chess_char_6_diy1_b",2,"uniequip_002_monstr",1653,1,108,0,0,17008,3775,16,0]
|
||||
["p1",12,"op","chess_char_6_diy1_b",2,"uniequip_002_monstr",1653,1,108,0,0,17008,4107,16,0]
|
||||
],
|
||||
"enemies": {"enemy_10065_ftzlc":[51,0,48,51035,0],"enemy_10067_ftsjc":[36,0,36,86456,0]},
|
||||
"hooks": [1,110,6900,607,607,311,398,371,14,98,38,37,0,234,0,16,87,84,1,14,0,14,0],
|
||||
"events": {"atk":650,"deploy":23,"die":14,"dmg":398,"fx":46,"heal":371,"leak":84,"skill":75,"spawn":99,"status":28},
|
||||
"hooks": [1,110,6900,606,606,311,398,832,14,98,38,37,0,234,0,16,87,84,1,14,0,14,0],
|
||||
"events": {"atk":1111,"deploy":23,"die":14,"dmg":398,"fx":46,"heal":370,"leak":84,"skill":75,"spawn":99,"status":28},
|
||||
"fx": {"burst":14,"explode":6,"ignite":26},
|
||||
"snaps": "aa8c2889 84dd5395 436c2e1a db08ee72 fca93f07 733c2a97 a8318be6 26978ed8 3aa1f439 f0f47853 ed44b5d5 873c241d 88686c26 cee18565 630d1823 3aeb0532 c16f713b 188da44a 227babd7 16a63da4 23e05e48 7234fd43 57257e52"
|
||||
"snaps": "aa8c2889 28ac65ad 6c156e1f 0313ba2d e88ae5bc 503ddf10 7a3e79f5 5b384e0f 0a95ba3e 52107200 87a44c5a 9f1db072 78e294b9 bf8f3de2 02649f88 e742948d c4c8db4c 25ffa105 2059891c 259b3e43 371952cb 22f79984 36d42c19"
|
||||
},
|
||||
"diy-135": {
|
||||
"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",
|
||||
|
||||
+93
-92
@@ -204,19 +204,19 @@
|
||||
"bossHpLeft": null,
|
||||
"rngDraws": 2,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {"p1":{"killed":9,"total":36,"perfect":false,"leaks":27,"leaksUncounted":0,"coins":2,"dmg":103318,"bossDmg":0,"heal":20175,"deaths":13,"layerGains":{}}},
|
||||
"players": {"p1":{"killed":9,"total":36,"perfect":false,"leaks":27,"leaksUncounted":0,"coins":2,"dmg":112604,"bossDmg":0,"heal":20365,"deaths":13,"layerGains":{}}},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_2_08_a",1,null,0,0,8,1,4451,9857,148,4,0],
|
||||
["p1",2,"op","chess_char_2_17_a",1,null,0,0,6,1,4245,7897,1734,3,2],
|
||||
["p1",3,"op","chess_char_2_18_a",0,null,0,0,9,0,18340,7055,147,11,1],
|
||||
["p1",4,"op","chess_char_2_07_a",1,null,0,0,10,0,6974,6231,0,9,1],
|
||||
["p1",1,"op","chess_char_2_08_a",1,null,0,0,8,1,5701,10301,148,4,0],
|
||||
["p1",2,"op","chess_char_2_17_a",1,null,0,0,6,0,3626,7897,1734,2,2],
|
||||
["p1",3,"op","chess_char_2_18_a",0,null,0,0,9,0,26482,8005,147,14,1],
|
||||
["p1",4,"op","chess_char_2_07_a",1,null,0,0,10,0,6924,6231,0,9,1],
|
||||
["p1",5,"op","chess_char_2_09_a",1,null,1513.21,1,56,0,6902,5702,1638,19,1],
|
||||
["p1",6,"op","chess_char_2_11_a",1,null,0,0,12,1,18402,8304,113,26,1],
|
||||
["p1",6,"op","chess_char_2_11_a",1,null,0,0,12,1,18832,7470,113,25,1],
|
||||
["p1",7,"op","chess_char_2_13_a",1,null,3122.65,1,57,2,10661,3169,22,20,1],
|
||||
["p1",8,"op","chess_char_2_16_a",1,null,3098.43,1,54,0,5438,4790,139,15,0],
|
||||
["p1",9,"op","chess_char_2_12_a",1,null,0,0,52,4,11743,4506,0,40,2],
|
||||
["p1",10,"op","chess_char_2_06_a",0,null,0,0,4,0,0,3150,11880,22,7],
|
||||
["p1",11,"op","chess_char_2_10_a",1,null,0,0,5,0,10120,2406,0,51,1],
|
||||
["p1",9,"op","chess_char_2_12_a",1,null,0,0,52,4,12322,4404,0,42,2],
|
||||
["p1",10,"op","chess_char_2_06_a",0,null,0,0,4,0,0,3062,12070,22,7],
|
||||
["p1",11,"op","chess_char_2_10_a",1,null,0,0,5,1,9674,2406,0,51,1],
|
||||
["p1",12,"op","chess_char_2_14_a",1,null,2131.36,1,55,0,0,3763,4306,9,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],
|
||||
@@ -224,26 +224,26 @@
|
||||
["p1","~1","token","token_10022_kazema_shadow",null,null,0,0,26,0,6042,1864,48,6,null]
|
||||
],
|
||||
"enemies": {
|
||||
"enemy_1001_bigbo": [1,0,1,6870,6391],
|
||||
"enemy_1006_shield": [1,0,1,3430,6233],
|
||||
"enemy_10118_ymgprc": [1,0,1,6271,8291],
|
||||
"enemy_1041_lazerd_2": [1,0,1,6316,4317],
|
||||
"enemy_1118_lidbox_2": [1,1,0,4232,16416],
|
||||
"enemy_1158_divman": [18,8,10,7018,62451],
|
||||
"enemy_1160_hvyslr": [3,0,3,3830,9897],
|
||||
"enemy_1161_tidmag": [3,0,2,7246,8350],
|
||||
"enemy_1169_duphlx_2": [1,0,1,621,6838],
|
||||
"enemy_1001_bigbo": [1,0,1,6870,4832],
|
||||
"enemy_1006_shield": [1,0,1,3483,9381],
|
||||
"enemy_10118_ymgprc": [1,0,1,6271,9669],
|
||||
"enemy_1041_lazerd_2": [1,0,1,6338,4317],
|
||||
"enemy_1118_lidbox_2": [1,1,0,3643,16416],
|
||||
"enemy_1158_divman": [18,8,10,6618,62957],
|
||||
"enemy_1160_hvyslr": [3,0,3,3906,11840],
|
||||
"enemy_1161_tidmag": [3,0,2,6444,10438],
|
||||
"enemy_1169_duphlx_2": [1,0,1,1292,9579],
|
||||
"enemy_1200_msfjin_2": [1,0,1,0,21],
|
||||
"enemy_1249_lysdb_2": [1,0,1,0,1249],
|
||||
"enemy_1249_lysdb_2": [1,0,1,0,1467],
|
||||
"enemy_1299_ymkilr": [1,0,1,0,560],
|
||||
"enemy_1389_winbab_2": [1,0,1,942,1330],
|
||||
"enemy_1504_cqbw": [1,0,1,207,630],
|
||||
"enemy_1389_winbab_2": [1,0,1,1089,1330],
|
||||
"enemy_1504_cqbw": [1,0,1,652,630],
|
||||
"enemy_2009_csaudc": [1,0,1,0,490]
|
||||
},
|
||||
"hooks": [1,57,3300,438,438,1364,1385,1339,23,49,17,17,0,10847,31,30,36,26,1,28,0,2,0],
|
||||
"events": {"atk":492,"bounty":1,"deploy":18,"die":23,"dmg":1318,"engage":11,"fx":20,"heal":85,"leak":26,"skill":34,"spawn":52,"status":157},
|
||||
"hooks": [1,57,3300,442,442,1430,1450,1360,23,49,17,17,0,10816,33,32,36,26,1,28,0,2,0],
|
||||
"events": {"atk":515,"bounty":1,"deploy":18,"die":23,"dmg":1381,"engage":11,"fx":20,"heal":87,"leak":26,"skill":34,"spawn":52,"status":171},
|
||||
"fx": {"aoe":4,"burst":2,"camouflage":2,"dodge":3,"dollEnd":1,"liberate":1,"overload":1,"shield":2,"shieldBreak":1,"substitute":1,"summon":1,"takeoff":1},
|
||||
"snaps": "78c9be45 59671eba dea6e147 ecf77961 f0504ef1 7c7c3e8c 51d85363 171262cf f3ae9337 f8af7602 bab13f4b"
|
||||
"snaps": "95c7197d e941625e 33d925c4 1e508419 2508f788 7d3585ce 94e8c1e6 d30888a6 6fa26a6a 3cc039cd 59559726"
|
||||
},
|
||||
"roster-005": {
|
||||
"about": "pass 0 band 3: chess_char_2_07_b chess_char_2_08_b chess_char_2_09_b chess_char_2_11_b chess_char_2_12_b chess_char_2_19_a chess_char_2_01_b chess_char_2_02_b chess_char_2_04_b chess_char_2_05_b chess_char_2_06_b chess_char_2_10_b token_10000_silent_healrb",
|
||||
@@ -261,44 +261,44 @@
|
||||
"total": 84,
|
||||
"unspawned": 0,
|
||||
"bossHpLeft": null,
|
||||
"rngDraws": 331,
|
||||
"rngDraws": 333,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {"p1":{"killed":84,"total":84,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":12,"dmg":308157,"bossDmg":0,"heal":37346,"deaths":0,"layerGains":{}}},
|
||||
"players": {"p1":{"killed":84,"total":84,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":12,"dmg":308197,"bossDmg":0,"heal":36826,"deaths":0,"layerGains":{}}},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_2_07_b",1,"uniequip_002_ghost",2664.2,1,2,0,0,1707,1103,0,0],
|
||||
["p1",1,"op","chess_char_2_07_b",1,"uniequip_002_ghost",2664.2,1,2,0,0,1707,1318,0,0],
|
||||
["p1",2,"op","chess_char_2_08_b",1,"uniequip_002_bubble",3373,1,4,0,49,1818,0,0,1],
|
||||
["p1",3,"op","chess_char_2_09_b",1,"uniequip_002_humus",2133,1,6,32,85807,0,0,56,2],
|
||||
["p1",4,"op","chess_char_2_11_b",1,"uniequip_002_kazema",2214,1,8,11,87316,15458,0,89,3],
|
||||
["p1",5,"op","chess_char_2_12_b",1,"uniequip_002_gravel",1452,1,10,2,7115,9463,0,124,1],
|
||||
["p1",6,"op","chess_char_2_19_a",1,null,1021.2,1,11,1,14957,1433,314,26,3],
|
||||
["p1",7,"op","chess_char_2_01_b",1,"uniequip_002_excu",2146,1,12,20,36079,4543,0,22,1],
|
||||
["p1",8,"op","chess_char_2_02_b",1,"uniequip_002_silent",1614,1,1,0,0,0,8988,27,4],
|
||||
["p1",9,"op","chess_char_2_04_b",1,"uniequip_002_grabds",1270,1,3,6,39117,2115,0,51,3],
|
||||
["p1",10,"op","chess_char_2_05_b",1,"uniequip_002_harold",1971.2,1,5,0,0,0,11003,40,2],
|
||||
["p1",11,"op","chess_char_2_06_b",0,"uniequip_002_papyrs",1639,1,7,0,0,0,13785,27,12],
|
||||
["p1",3,"op","chess_char_2_09_b",1,"uniequip_002_humus",2133,1,6,31,86159,0,0,56,2],
|
||||
["p1",4,"op","chess_char_2_11_b",1,"uniequip_002_kazema",2214,1,8,11,87383,15748,0,89,3],
|
||||
["p1",5,"op","chess_char_2_12_b",1,"uniequip_002_gravel",1452,1,10,2,7115,8923,0,124,1],
|
||||
["p1",6,"op","chess_char_2_19_a",1,null,1021.2,1,11,1,14957,1523,407,26,3],
|
||||
["p1",7,"op","chess_char_2_01_b",1,"uniequip_002_excu",2146,1,12,20,36079,4183,0,22,1],
|
||||
["p1",8,"op","chess_char_2_02_b",1,"uniequip_002_silent",1614,1,1,0,0,0,9551,28,5],
|
||||
["p1",9,"op","chess_char_2_04_b",1,"uniequip_002_grabds",1270,1,3,7,38738,2115,0,51,3],
|
||||
["p1",10,"op","chess_char_2_05_b",1,"uniequip_002_harold",1971.2,1,5,0,0,0,11743,39,2],
|
||||
["p1",11,"op","chess_char_2_06_b",0,"uniequip_002_papyrs",1639,1,7,0,0,0,11657,25,11],
|
||||
["p1",12,"op","chess_char_2_10_b",1,"uniequip_002_rockr",1406,1,9,6,37719,810,0,107,2],
|
||||
["p1",13,"token","token_10000_silent_healrb",null,null,1000,0,97,0,0,0,2153,21,null]
|
||||
["p1",13,"token","token_10000_silent_healrb",null,null,1000,1,103,0,0,0,2150,21,null]
|
||||
],
|
||||
"enemies": {
|
||||
"enemy_10027_vtsk": [1,1,0,10598,24000],
|
||||
"enemy_10027_vtsk": [1,1,0,10058,24000],
|
||||
"enemy_1006_shield_2": [1,1,0,0,8000],
|
||||
"enemy_10122_uacann_2": [1,1,0,3386,8000],
|
||||
"enemy_10122_uacann_2": [1,1,0,3476,8000],
|
||||
"enemy_1042_frostd": [1,1,0,0,5200],
|
||||
"enemy_1119_vofsd": [1,1,0,125,8800],
|
||||
"enemy_1170_dushld": [1,1,0,221,5600],
|
||||
"enemy_1202_msfzhi": [1,1,0,0,3],
|
||||
"enemy_1249_lysdb_2": [15,15,0,198,72000],
|
||||
"enemy_1249_lysdb_2": [15,15,0,310,72000],
|
||||
"enemy_1251_lysyta": [52,52,0,50,114400],
|
||||
"enemy_1299_ymkilr_2": [1,1,0,1178,8800],
|
||||
"enemy_1328_cbjedi": [6,6,0,7780,48000],
|
||||
"enemy_1402_tgshd_2": [1,1,0,110,10400],
|
||||
"enemy_1509_mousek": [1,1,0,7838,17600],
|
||||
"enemy_2010_csdcr": [1,1,0,2542,9600]
|
||||
"enemy_1328_cbjedi": [6,6,0,8244,48000],
|
||||
"enemy_1402_tgshd_2": [1,1,0,200,10400],
|
||||
"enemy_1509_mousek": [1,1,0,7192,17600],
|
||||
"enemy_2010_csdcr": [1,1,0,2452,9600]
|
||||
},
|
||||
"hooks": [1,101,4063,685,685,1621,1615,920,84,89,34,33,0,27121,145,51,84,0,1,84,0,0,0],
|
||||
"events": {"atk":874,"bounty":6,"deploy":17,"die":89,"dmg":1572,"engage":7,"fx":64,"heal":131,"skill":67,"spawn":97,"status":420},
|
||||
"fx": {"counter":2,"explode":3,"expose":9,"overload":2,"phase":1,"shield":8,"shieldBreak":16,"sleep":7,"summon":4,"telegraph":6,"zone":6},
|
||||
"snaps": "de0d6fce aa9dbd18 24c987bd 0f416484 692cfae7 3f26cb76 377b5a69 9d5ebf16 9df2f8fe bb2d9188 246affc9 69fd644b 837cdc8a 5814f3d6"
|
||||
"hooks": [1,102,4063,682,682,1618,1612,1098,84,89,34,33,0,26938,145,50,84,0,1,84,0,0,0],
|
||||
"events": {"atk":896,"bounty":6,"deploy":18,"die":89,"dmg":1572,"engage":7,"fx":65,"heal":123,"skill":67,"spawn":97,"status":430},
|
||||
"fx": {"counter":2,"explode":3,"expose":9,"overload":2,"phase":1,"shield":8,"shieldBreak":16,"sleep":7,"summon":5,"telegraph":6,"zone":6},
|
||||
"snaps": "de0d6fce aa9dbd18 e5f78211 369608f9 eaf0206b 8ca00225 56597ada 3c3af39f 867867b0 406379b7 654df676 66745bf5 fdd72e8b 1ff822b8"
|
||||
},
|
||||
"roster-006": {
|
||||
"about": "pass 0 band 3: chess_char_2_17_b chess_char_2_18_b chess_char_3_06_a chess_char_2_13_b chess_char_2_16_b chess_char_3_02_a chess_char_3_03_a chess_char_3_04_a chess_char_3_05_a chess_char_2_14_b chess_char_2_19_b chess_char_3_01_a",
|
||||
@@ -1470,47 +1470,48 @@
|
||||
"time": 110,
|
||||
"ticks": 3300,
|
||||
"reason": "timeout",
|
||||
"killed": 31,
|
||||
"total": 35,
|
||||
"killed": 33,
|
||||
"total": 36,
|
||||
"unspawned": 0,
|
||||
"bossHpLeft": null,
|
||||
"rngDraws": 0,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {"p1":{"killed":31,"total":35,"perfect":false,"leaks":4,"leaksUncounted":0,"coins":4,"dmg":150801,"bossDmg":0,"heal":24108,"deaths":4,"layerGains":{}}},
|
||||
"players": {"p1":{"killed":33,"total":36,"perfect":false,"leaks":3,"leaksUncounted":0,"coins":6,"dmg":160899,"bossDmg":0,"heal":23475,"deaths":4,"layerGains":{}}},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_2_08_a",0,null,1382.46,1,7,1,3411,5678,321,4,1],
|
||||
["p1",2,"op","chess_char_2_17_a",0,null,0,0,11,7,29473,7967,4343,19,4],
|
||||
["p1",3,"op","chess_char_2_18_a",1,null,0,0,12,12,43236,7352,323,19,2],
|
||||
["p1",4,"op","chess_char_2_07_a",0,null,2806.23,1,52,4,19876,9391,361,35,1],
|
||||
["p1",5,"op","chess_char_2_09_a",0,null,2208.44,1,50,6,46469,3673,1465,37,7],
|
||||
["p1",6,"op","chess_char_2_11_a",0,null,2404.18,1,8,0,711,90,6,1,0],
|
||||
["p1",7,"op","chess_char_2_13_a",0,null,2472.85,1,9,1,1566,0,0,4,1],
|
||||
["p1",8,"op","chess_char_2_16_a",0,null,2453.67,1,6,0,0,0,0,0,0],
|
||||
["p1",9,"op","chess_char_2_12_a",0,null,1516.59,1,10,0,0,0,0,0,1],
|
||||
["p1",10,"op","chess_char_2_06_a",1,null,1972.8,1,4,0,0,0,11343,26,2],
|
||||
["p1",11,"op","chess_char_2_10_a",0,null,1476.86,1,5,0,6057,0,0,35,1],
|
||||
["p1",12,"op","chess_char_2_14_a",0,null,1687.84,1,13,0,0,3611,5947,20,2],
|
||||
["p1",1,"op","chess_char_2_08_a",0,null,2984.92,1,7,3,9513,6371,340,21,1],
|
||||
["p1",2,"op","chess_char_2_17_a",0,null,0,0,11,6,28522,7736,4112,21,3],
|
||||
["p1",3,"op","chess_char_2_18_a",1,null,0,0,12,13,47196,8094,566,20,2],
|
||||
["p1",4,"op","chess_char_2_07_a",0,null,1401.83,1,53,4,22612,7936,390,37,1],
|
||||
["p1",5,"op","chess_char_2_09_a",0,null,2208.44,1,50,5,46192,3668,1459,36,7],
|
||||
["p1",6,"op","chess_char_2_11_a",0,null,2487.92,1,8,0,4,249,0,4,1],
|
||||
["p1",7,"op","chess_char_2_13_a",0,null,2472.85,1,9,0,11,0,0,11,1],
|
||||
["p1",8,"op","chess_char_2_16_a",0,null,2453.67,1,6,1,8,0,0,8,0],
|
||||
["p1",9,"op","chess_char_2_12_a",0,null,1516.59,1,10,0,5,0,0,5,1],
|
||||
["p1",10,"op","chess_char_2_06_a",1,null,1972.8,1,4,0,0,0,5989,31,2],
|
||||
["p1",11,"op","chess_char_2_10_a",0,null,1476.86,1,5,1,6835,0,0,42,1],
|
||||
["p1",12,"op","chess_char_2_14_a",0,null,1039.13,1,13,0,0,3442,10617,21,2],
|
||||
["-","~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],
|
||||
["-","~3","device","trap_1105_accrate",null,null,100,1,3,0,0,0,0,0,null]
|
||||
],
|
||||
"enemies": {
|
||||
"enemy_10034_cnvsax": [1,1,0,2873,8000],
|
||||
"enemy_1010_demon": [6,6,0,1712,36000],
|
||||
"enemy_1010_demon_2": [3,2,0,3600,25901],
|
||||
"enemy_10034_cnvsax": [1,1,0,2870,8000],
|
||||
"enemy_1010_demon": [6,6,0,2281,36000],
|
||||
"enemy_1010_demon_2": [3,2,0,4743,27107],
|
||||
"enemy_10112_ymgds": [1,1,0,22,4000],
|
||||
"enemy_1067_snslime": [1,1,0,419,2600],
|
||||
"enemy_1071_dftman": [18,18,0,288,40320],
|
||||
"enemy_1170_dushld": [1,1,0,1215,5600],
|
||||
"enemy_1209_sfden_2": [1,0,0,8494,10199],
|
||||
"enemy_1305_mhslim_2": [1,1,0,294,1440],
|
||||
"enemy_1439_dslntf_2": [1,0,0,646,11814],
|
||||
"enemy_2048_smgrd": [1,0,0,8843,4925]
|
||||
"enemy_1067_snslime": [1,1,0,462,2600],
|
||||
"enemy_1071_dftman": [18,18,0,211,40320],
|
||||
"enemy_1170_dushld": [1,1,0,1813,5600],
|
||||
"enemy_1209_sfden_2": [1,1,0,5807,14400],
|
||||
"enemy_1210_msfden_2": [1,1,0,0,45],
|
||||
"enemy_1305_mhslim_2": [1,1,0,333,1440],
|
||||
"enemy_1439_dslntf_2": [1,0,0,960,13867],
|
||||
"enemy_2048_smgrd": [1,0,0,8683,7520]
|
||||
},
|
||||
"hooks": [1,52,3300,358,358,827,942,1960,35,35,22,20,0,10743,62,45,35,0,1,35,0,3,0],
|
||||
"events": {"atk":497,"bounty":2,"deploy":14,"die":35,"dmg":827,"engage":8,"fx":65,"heal":116,"skill":42,"spawn":50,"status":256},
|
||||
"fx": {"beam":51,"buff":3,"burst":3,"explode":1,"takeoff":1,"telegraph":6},
|
||||
"snaps": "dd24c30b 998fef35 67166def b786a3cd 7dfcb3ef de9df651 3687ea1a 38be8416 332a7a64 b8e90f9d 99c0ed59"
|
||||
"hooks": [1,53,3300,409,409,877,983,2396,37,37,22,20,0,10966,74,43,36,0,1,37,0,3,0],
|
||||
"events": {"atk":594,"bounty":3,"deploy":14,"die":37,"dmg":909,"engage":10,"fx":64,"heal":90,"skill":42,"spawn":51,"status":184},
|
||||
"fx": {"beam":51,"buff":3,"burst":3,"explode":1,"summon":1,"takeoff":1,"telegraph":4},
|
||||
"snaps": "dd24c30b 998fef35 285beff0 28c4534a be20f6d2 b0466f87 88bdd89e b929dbdd 78371cf9 0f00293b 91358da2"
|
||||
},
|
||||
"roster-024": {
|
||||
"about": "pass 1 band 3: chess_char_2_07_b chess_char_2_08_b chess_char_2_09_b chess_char_2_11_b chess_char_2_12_b chess_char_2_19_a chess_char_2_01_b chess_char_2_02_b chess_char_2_04_b chess_char_2_05_b chess_char_2_06_b chess_char_2_10_b",
|
||||
@@ -1530,41 +1531,41 @@
|
||||
"bossHpLeft": null,
|
||||
"rngDraws": 11,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {"p1":{"killed":150,"total":191,"perfect":false,"leaks":41,"leaksUncounted":0,"coins":6,"dmg":194174,"bossDmg":0,"heal":22504,"deaths":2,"layerGains":{}}},
|
||||
"players": {"p1":{"killed":150,"total":191,"perfect":false,"leaks":41,"leaksUncounted":0,"coins":6,"dmg":194174,"bossDmg":0,"heal":20762,"deaths":2,"layerGains":{}}},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_2_07_b",0,"none",0,0,3,28,65300,6473,3522,59,2],
|
||||
["p1",1,"op","chess_char_2_07_b",0,"none",0,0,3,28,65300,6609,3945,59,2],
|
||||
["p1",2,"op","chess_char_2_08_b",0,"none",3193,1,1,0,0,0,0,0,0],
|
||||
["p1",3,"op","chess_char_2_09_b",0,"none",0,0,4,1,1,2079,46,1,0],
|
||||
["p1",4,"op","chess_char_2_11_b",0,"none",2214,1,7,13,4490,2214,0,31,10],
|
||||
["p1",5,"op","chess_char_2_12_b",0,"none",1352,1,10,19,23053,2207,0,61,1],
|
||||
["p1",4,"op","chess_char_2_11_b",0,"none",1992.6,1,7,13,4490,2214,0,31,10],
|
||||
["p1",5,"op","chess_char_2_12_b",0,"none",1352,1,10,19,23053,2194,0,61,1],
|
||||
["p1",6,"op","chess_char_2_19_a",0,null,1021.2,1,5,49,33272,0,0,73,10],
|
||||
["p1",7,"op","chess_char_2_01_b",0,"none",2146,1,8,15,3240,0,0,19,2],
|
||||
["p1",8,"op","chess_char_2_02_b",0,"none",2624.8,1,6,0,0,264,868,9,1],
|
||||
["p1",9,"op","chess_char_2_04_b",0,"none",1180,1,9,24,57718,753,0,65,32],
|
||||
["p1",10,"op","chess_char_2_05_b",0,"none",1873.2,1,11,0,0,7611,4583,46,3],
|
||||
["p1",11,"op","chess_char_2_06_b",1,"none",1639,1,12,0,0,5599,13485,63,4],
|
||||
["p1",8,"op","chess_char_2_02_b",0,"none",2624.8,1,6,0,0,400,1289,9,1],
|
||||
["p1",9,"op","chess_char_2_04_b",0,"none",1180,1,9,24,57718,889,0,65,32],
|
||||
["p1",10,"op","chess_char_2_05_b",0,"none",1873.2,1,11,0,0,6919,3700,46,3],
|
||||
["p1",11,"op","chess_char_2_06_b",1,"none",1639,1,12,0,0,4376,11782,61,4],
|
||||
["p1",12,"op","chess_char_2_10_b",0,"none",1356,1,2,1,7101,0,0,77,3]
|
||||
],
|
||||
"enemies": {
|
||||
"enemy_1006_shield": [1,1,0,0,5760],
|
||||
"enemy_1019_jshoot": [1,1,0,748,1728],
|
||||
"enemy_1019_jshoot": [1,1,0,721,1728],
|
||||
"enemy_1121_lifbos_2": [1,1,0,1001,24000],
|
||||
"enemy_1195_sfyin": [36,34,0,13160,65280],
|
||||
"enemy_1195_sfyin_2": [15,13,2,124,41210],
|
||||
"enemy_1195_sfyin": [36,34,0,11258,65280],
|
||||
"enemy_1195_sfyin_2": [15,13,2,140,41210],
|
||||
"enemy_1196_msfyin": [68,61,7,0,126],
|
||||
"enemy_1196_msfyin_2": [26,14,11,0,56],
|
||||
"enemy_1197_sfshu": [9,9,0,91,21600],
|
||||
"enemy_1197_sfshu_2": [1,1,0,14,3216],
|
||||
"enemy_1198_msfshu": [27,10,17,0,56],
|
||||
"enemy_1198_msfshu_2": [3,3,0,0,12],
|
||||
"enemy_1267_nhpbr_2": [1,1,0,865,5280],
|
||||
"enemy_1267_nhpbr_2": [1,1,0,1256,5280],
|
||||
"enemy_1381_winman_2": [1,1,0,30,7488],
|
||||
"enemy_1535_wlfmster": [1,0,1,8955,18362]
|
||||
},
|
||||
"hooks": [1,203,4200,763,763,1020,1087,2166,152,190,68,67,0,13939,1140,53,191,38,1,160,0,0,0],
|
||||
"events": {"atk":892,"bounty":3,"deploy":12,"die":152,"dmg":1043,"engage":8,"fx":77,"heal":169,"leak":38,"skill":135,"spawn":203,"status":542},
|
||||
"hooks": [1,203,4200,761,761,1020,1087,2427,152,190,68,65,0,13911,1140,53,191,38,1,160,0,0,0],
|
||||
"events": {"atk":919,"bounty":3,"deploy":12,"die":152,"dmg":1040,"engage":8,"fx":77,"heal":151,"leak":38,"skill":133,"spawn":203,"status":548},
|
||||
"fx": {"beam":3,"buff":5,"summon":57,"undying":1,"zone":11},
|
||||
"snaps": "5aee07b4 43516039 123ac569 7e5abe04 0078416f cb4c36c7 279569a2 a39cd06e dd946a0a 753030d4 47fceaec 24a8f1a0 8923779d 317bf2ff"
|
||||
"snaps": "3528dfb7 48905850 aff1c414 d9acb51f ff5e053b 66e23a01 ad945452 7b153731 2b2109c6 09f352e7 7e7ed5ff 28419b29 50075fae 2743a756"
|
||||
},
|
||||
"roster-025": {
|
||||
"about": "pass 1 band 3: chess_char_2_17_b chess_char_2_18_b chess_char_3_06_a chess_char_2_13_b chess_char_2_16_b chess_char_3_02_a chess_char_3_03_a chess_char_3_04_a chess_char_3_05_a chess_char_2_14_b chess_char_2_19_b chess_char_3_01_a",
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// test/sim/feedback5-chain-heal.test.js — the 链愈师 heal chain (follow-up 27; PRTS 分支特性信息 链愈师 "跳跃范围为x-4,无特殊说明
|
||||
// 的场合一次治疗链不会对已跳跃过的单位重复跳跃", "优先跳跃至范围内生命比例最低>部署时间点最晚的我方单位。可选择满生命我方单位为跳跃目标,
|
||||
// 但仍受禁疗制约") — server/sim/ai.js chainHealNext / doHeal (莎草's profession chain; Mon3tr's kit uses the same links). It used
|
||||
// to jump to the most injured ally within 2.5 tiles (never a full-HP one, ties by list order).
|
||||
// Run: node --test test/sim/feedback5-chain-heal.test.js
|
||||
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { makeBattle, chessRec, checkInvariants } from '../helpers/battleHarness.js';
|
||||
|
||||
const GRID = []; for (let r = -2; r <= 2; r++) for (let c = 0; c <= 6; c++) GRID.push([r, c]);
|
||||
const HEALER = chessRec({ id: 't_chain', profession: 'MEDIC', subProfessionId: 'chainhealer', stats: { maxHp: 1e4, atk: 100, bat: 1 }, skill: null, rangeGrid: GRID });
|
||||
const wall = (id) => chessRec({ id, stats: { maxHp: 1e4, atk: 0, def: 0 }, skill: null });
|
||||
|
||||
/** The healer on (10, 2) and walls at `at` = { id: [row, col, hpRatio] }; returns the chain of its first heal (ids → wall ids). */
|
||||
function firstChain(at, setup = null) {
|
||||
const ids = Object.keys(at);
|
||||
const h = makeBattle({
|
||||
defs: { chess: { t_chain: HEALER, ...Object.fromEntries(ids.map((id) => [id, wall(id)])) } },
|
||||
units: [{ chessId: 't_chain', row: 10, col: 2 }, ...ids.map((id) => ({ chessId: id, row: at[id][0], col: at[id][1] }))],
|
||||
content: 'none', autoFinish: false, timeLimit: 30, seed: 3,
|
||||
});
|
||||
h.step(); // deployed (the healer heals nobody yet: everyone is at full HP)
|
||||
for (const id of ids) { const u = h.unit(id); u.hp = u.s.maxHp * at[id][2]; }
|
||||
if (setup) setup(h);
|
||||
const n0 = h.events.length;
|
||||
for (let i = 0; i < 90 && !h.events.slice(n0).some((e) => e[0] === 'atk'); i++) h.step(); // (step drains the events)
|
||||
const name = new Map(h.b.allyUnits.map((u) => [u.id, u.defId]));
|
||||
const ev = h.events.slice(n0).filter((e) => e[0] === 'atk');
|
||||
checkInvariants(h.b);
|
||||
return { h, main: name.get(ev.find((e) => e[3] !== 'chainHeal')[2]), jumps: ev.filter((e) => e[3] === 'chainHeal').map((e) => [name.get(e[1]), name.get(e[2])]) };
|
||||
}
|
||||
|
||||
test('the jump reaches the 3×3 around the last one healed (x-4), not an ally two tiles away; each jump goes on from where it landed', () => {
|
||||
// A (most injured) on (10, 5); B two tiles right of it (inside 2.5 tiles, outside its 3×3), C on its diagonal
|
||||
const r = firstChain({ t_a: [10, 5, 0.5], t_b: [10, 7, 0.6], t_c: [11, 6, 0.7] });
|
||||
assert.equal(r.main, 't_a');
|
||||
assert.deepEqual(r.jumps, [['t_a', 't_c'], ['t_c', 't_b']], 'A → C (its 3×3) → B (C\'s 3×3); it used to jump A → B → C');
|
||||
});
|
||||
|
||||
test('a full-HP ally is a jump target when no injured one is in reach — healed for nothing, the chain jumps on from it', () => {
|
||||
const r = firstChain({ t_a: [10, 5, 0.5], t_d: [10, 6, 1], t_e: [10, 7, 0.6] });
|
||||
assert.equal(r.main, 't_a');
|
||||
assert.deepEqual(r.jumps, [['t_a', 't_d'], ['t_d', 't_e']], 'A → D (full HP) → E');
|
||||
assert.equal(r.h.unit('t_d').hp, r.h.unit('t_d').s.maxHp);
|
||||
});
|
||||
|
||||
test('ties of the HP ratio: the latest deployed first; a 禁疗 unit is never a jump target', () => {
|
||||
const tie = firstChain({ t_a: [10, 5, 0.5], t_f: [9, 5, 0.8], t_g: [11, 5, 0.8] });
|
||||
const [f, g] = [tie.h.unit('t_f'), tie.h.unit('t_g')];
|
||||
const later = f.aggroSeq > g.aggroSeq ? 't_f' : 't_g';
|
||||
assert.deepEqual(tie.jumps[0], ['t_a', later], 'the later deployed of the two');
|
||||
const banned = firstChain({ t_a: [10, 5, 0.5], t_n: [10, 6, 0.2], t_m: [11, 5, 0.9] }, (h) => {
|
||||
h.b.addBuff(h.unit('t_n'), { key: 'test:healFree', status: 'healFree', flags: { noHeal: true, healFree: true } });
|
||||
});
|
||||
assert.equal(banned.main, 't_a', 'the 禁疗 unit is no main target either');
|
||||
assert.deepEqual(banned.jumps[0], ['t_a', 't_m'], 'the 禁疗 unit is skipped');
|
||||
});
|
||||
Reference in new issue
Block a user