feedback5 O18: 傀影's 镜中虚影 holds 禁疗 and is withdrawn (not knocked out) when he leaves the field
PRTS 镜中虚影 备注 "持有禁疗" / "傀影退场时强制撤退场上的镜中虚影" and the twin's prefab (CommonAbilities charge_token[finish] carrying abnormal flag 7 = 禁疗): the twin's kit gives it 禁疗 (the data's `abnormal` lacks it — given by the kit, as the 凯尔希 / 机械师 kits do for their summons) and his leaving withdraws it (reason 'retreat') instead of a kill. test/content/op_phatom.test.js checks both (8 tests). Golden unchanged (the diy family places no summon).
This commit is contained in:
1 parent
b55d4f9d04
commit
ba8c2d9f03
2 files changed
+30
-18
No files matched your search
@@ -9,9 +9,11 @@
|
||||
// character_table / skill_table / battle_equip_table / token_table (zh_CN, as built into backups.json); PRTS 傀影 (镜中虚影
|
||||
// 备注 "虚影再部署与拥有复数召唤物的干员相同,即“部署召唤物后立刻开始计算再部署时间,结束后可以部署下一个”"; 血色乐章 备注 "触发消耗
|
||||
// 层数效果的行动节点为“成功造成伤害后”。若造成的伤害被伤判效果归零则不会消耗层数"; 夜幕突袭 备注 "不可对空"; EXE-X "撤退时返还大量
|
||||
// (80%)该次部署费用"); PRTS 分支特性信息 处决者; the client's battle data — charpack char_250_phatom (Talents/1:
|
||||
// (80%)该次部署费用"); PRTS 镜中虚影 (备注 "持有禁疗", "可以且优先攻击自身阻挡的单位", "退场时返还1个可部署的镜中虚影", "傀影退场时
|
||||
// 强制撤退场上的镜中虚影"); PRTS 分支特性信息 处决者; the client's battle data — charpack char_250_phatom (Talents/1:
|
||||
// charge_token[born] (RechargeToken on his deployment) + die_to_kill_token (KillTokens when he leaves), CommonAbilities
|
||||
// KillTokens; modes S2 / S3), token prefab token_10007_phatom_twin (charge_token[finish]; the same modes), the skill
|
||||
// KillTokens; modes S2 / S3), token prefab token_10007_phatom_twin (CommonAbilities: charge_token[finish] carrying abnormal
|
||||
// flag 7 = 禁疗; Talents/2: phatom_twin_t, RESPAWN_TIME + respawn_time; the same modes), the skill
|
||||
// prefabs skchr_phatom_1 / _2 / _3 and sktok_phatom_1 / _2 / _3 (S1: evade_physical + phatom_s_1[shield_physical] = a
|
||||
// shield_physical of hp_ratio × max HP, both `duration`; S2: phatom_s_2 = `times` stacked phatom_s_2[atk] (ATK MULTIPLIER
|
||||
// `atk`), one stack finished per ON_AFTER_OUTPUT_DAMAGE; S3: RandomCastAbility of the sluggish / stun / root attack
|
||||
@@ -31,14 +33,16 @@
|
||||
// - T1 镜中虚影 "可以使用一个属性更强的虚影,虚影拥有和自己一样的技能,拥有独立的再部署时间": the twin is a hand piece the player
|
||||
// places (a talent summon: tokens `placeable`, not owner-range); it deploys with the board after the operators and fights
|
||||
// with its own stats (the variant of his form; EXE-Y stage 3: "属性进一步增强" = the byModule stats) as an executor (melee,
|
||||
// blocks 1, ground-only), its copy of his picked skill (bySkill sktok_phatom_1 / 2 / 3) running at each of its own
|
||||
// deployments. When he leaves the field (knocked out, withdrawn, forced out) it is killed (KillTokens); a fallen twin comes
|
||||
// back on its tile — paying its cost (5 DP) as a deployment, the 卫戍 auto redeploy of a placed summon [ASSUMED, as 鸿雪's
|
||||
// 打字机 / 凯尔希's Mon3tr] — once its redeploy time has passed since its LAST DEPLOYMENT (PRTS 备注: the timer starts at the
|
||||
// summon's deployment) and only while he stands (it is recharged by his deployment and killed by his leaving)
|
||||
// [ASSUMED: his redeployment does not cut the twin's own timer short — the client's RechargeToken NORMAL; the 凯尔希 kit
|
||||
// reads the same charge_token[born] as "readies at once"]. EXE-Y stage 2+ "本体和虚影同时在场时,攻击力各+10%": the twin's
|
||||
// hidden module talent `atk` — ATK +atk on both while both are on the field.
|
||||
// blocks 1, ground-only) holding 禁疗 (PRTS; the client's flag 7 — the data's `abnormal` lacks it [ASSUMED: given here, as
|
||||
// the 凯尔希 / 机械师 kits do for their summons]), its copy of his picked skill (bySkill sktok_phatom_1 / 2 / 3) running at
|
||||
// each of its own deployments. When he leaves the field (knocked out, withdrawn, forced out) it is withdrawn (PRTS "强制
|
||||
// 撤退"; the client's KillTokens); a twin off the field comes back on its tile — paying its cost (5 DP) as a deployment,
|
||||
// the 卫戍 auto redeploy of a placed summon [ASSUMED, as 鸿雪's 打字机 / 凯尔希's Mon3tr] — once its redeploy time has
|
||||
// passed since its LAST DEPLOYMENT (PRTS 备注: the timer starts at the summon's deployment) and only while he stands (it
|
||||
// is recharged by his deployment, withdrawn by his leaving) [ASSUMED: his redeployment does not cut the twin's own timer
|
||||
// short — the client's RechargeToken NORMAL; 虚影精通 / EXE-X would matter little otherwise; the 凯尔希 kit reads the same
|
||||
// charge_token[born] as "readies at once"]. EXE-Y stage 2+ "本体和虚影同时在场时,攻击力各+10%": the twin's hidden module
|
||||
// talent `atk` — ATK +atk on both while both are on the field.
|
||||
// - T2 虚影精通 "虚影的再部署时间-10秒" (EXE-X stage 3: −16): the twin's own talent respawn_time, added to its 45 s.
|
||||
// - S1 暗夜魅影 (被动, at each deployment): physical dodge `prob` and a 屏障 of hp_ratio × max HP that absorbs physical damage
|
||||
// only (shieldType 'phys'), both for `duration` (10) s.
|
||||
@@ -148,8 +152,8 @@ function deployEffect(battle, u, rec, key) {
|
||||
}
|
||||
|
||||
/**
|
||||
* The twin's kit (`owner` = 傀影): its skill copy at each of its deployments, EXE-Y stage 2+'s shared ATK, and its own
|
||||
* redeploys (killed with him; back on its tile once its timer has run from its last deployment, he stands and the DP is
|
||||
* The twin's kit (`owner` = 傀影): 禁疗, its skill copy at each of its deployments, EXE-Y stage 2+'s shared ATK, and its own
|
||||
* redeploys (withdrawn with him; back on its tile once its timer has run from its last deployment, he stands and the DP is
|
||||
* there).
|
||||
*/
|
||||
function twinKit(t, owner) {
|
||||
@@ -160,6 +164,7 @@ function twinKit(t, owner) {
|
||||
return {
|
||||
skill: { kind: 'passive' },
|
||||
install(battle, unit) {
|
||||
battle.addBuff(unit, { key: 'phatom:twin:abnormal', flags: { noHeal: true }, persist: true, allowDead: true }); // 持有禁疗
|
||||
if (rec?.id === TS2) installOpusUse(battle, unit, key);
|
||||
battle.on('deploy', (c) => {
|
||||
if (c.unit !== unit || c.move || !up(unit)) return;
|
||||
@@ -194,7 +199,7 @@ export default {
|
||||
[S3]: { kind: 'passive' },
|
||||
},
|
||||
talents: [
|
||||
{ install(battle, unit) { // 镜中虚影: his twin pieces run the twin's kit; killed when he leaves; EXE-Y stage 2+: both +ATK
|
||||
{ install(battle, unit) { // 镜中虚影: his twin pieces run the twin's kit; withdrawn when he leaves; EXE-Y stage 2+: both +ATK
|
||||
for (const t of twinsOf(battle, unit)) {
|
||||
if (t.alive || t.deployed) continue;
|
||||
if (t.kit) battle.offOwner(t); // a piece set up before him: drop its generic kit's hooks
|
||||
@@ -202,7 +207,8 @@ export default {
|
||||
}
|
||||
battle.on('death', (c) => {
|
||||
if (c.unit !== unit) return;
|
||||
for (const t of twinsOf(battle, unit)) if (t.alive) battle.kill(t, null); // KillTokens
|
||||
// "傀影退场时强制撤退场上的镜中虚影" (KillTokens): a withdrawal, not a knock-out
|
||||
for (const t of twinsOf(battle, unit)) if (t.alive) battle.retreat(t, { reason: 'retreat' });
|
||||
}, { owner: unit });
|
||||
// 本体和虚影同时在场时,攻击力各+N%: the twin's hidden module talent (his text when no twin def resolves)
|
||||
const both = num(tokTalentBb(battle.tokenDef(TWIN, unit), 'atk').atk, /本体和虚影同时在场时/.test(t0desc)
|
||||
|
||||
@@ -68,7 +68,7 @@ function redeployNow(h, u) {
|
||||
assert.ok(h.b.redeploy(u, { free: true }), `${u.name} redeployed`);
|
||||
}
|
||||
|
||||
test('傀影 in every 自选 form: his operator kit (all three skills authored), the form\'s stats + module attributes, 1-1, blocks 1, melee ground-only, 18 s redeploy, 维多利亚, no 特质; his placed 镜中虚影 deploys after him with the variant\'s stats and its copy of his skill', () => {
|
||||
test('傀影 in every 自选 form: his operator kit (all three skills authored), the form\'s stats + module attributes, 1-1, blocks 1, melee ground-only, 18 s redeploy, 维多利亚, no 特质; his placed 镜中虚影 deploys after him with the variant\'s stats, 禁疗 and its copy of his skill', () => {
|
||||
assert.equal(OPERATOR_KITS[PHATOM], KITS[PHATOM]);
|
||||
for (const f of FORMS_ALL) {
|
||||
const [tier, elite, mod] = f;
|
||||
@@ -87,6 +87,7 @@ test('傀影 in every 自选 form: his operator kit (all three skills authored),
|
||||
assert.deepEqual([t.base.maxHp, t.base.atk, t.base.def, t.base.respawnTime, t.base.cost], [tw.stats.maxHp, tw.stats.atk, tw.stats.def, 45, 5], `${label(f)}: twin stats`);
|
||||
assert.deepEqual([t.def.skill.id, t.skill.kind], [tw.skillOf(skill).skillId, 'passive'], `${label(f)}: twin skill copy`);
|
||||
assert.deepEqual([t.s.blockCnt, t.profile.attack, t.profile.canHitFly, t.liveRangeGrid], [1, 'melee', false, [[0, 0], [0, 1]]], `${label(f)}: twin executor`);
|
||||
assert.ok(t.s.flags.noHeal, `${label(f)}: twin 持有禁疗`);
|
||||
done(h);
|
||||
}
|
||||
}
|
||||
@@ -203,13 +204,17 @@ test('S3 夜幕突袭 (被动): at each deployment 210 % / 240 % ATK physical to
|
||||
}
|
||||
});
|
||||
|
||||
test('T1 镜中虚影 / T2 虚影精通: the twin is killed when he leaves the field and comes back on its tile 35 s (45 − 10; EXE-X stage 3: 45 − 16) after its LAST deployment, paying 5 DP, only while he stands', () => {
|
||||
test('T1 镜中虚影 / T2 虚影精通: the twin (禁疗: no heal reaches it) is withdrawn when he leaves the field and comes back on its tile 35 s (45 − 10; EXE-X stage 3: 45 − 16) after its LAST deployment, paying 5 DP, only while he stands', () => {
|
||||
for (const f of [[5, false, null], [5, true, EX], [6, true, EX]]) {
|
||||
const [tier, elite, mod] = f;
|
||||
const cut = twinOf(tier, elite, mod).talents.find((x) => x.bb.respawn_time != null).bb.respawn_time;
|
||||
assert.equal(cut, tier === 6 && mod === EX ? -16 : -10, label(f));
|
||||
const { h, u, t } = field({ tier, elite, mod, skill: 1, dp: 50 });
|
||||
const wait = 45 + cut;
|
||||
// 禁疗: an ally heal does not reach it
|
||||
t.hp = 100;
|
||||
h.b.heal(u, t, 500);
|
||||
assert.equal(t.hp, 100, `${label(f)}: 禁疗`);
|
||||
// knocked out while he stands: back `wait` s after its deployment at 0 s, 5 DP paid
|
||||
h.run(5);
|
||||
h.b.kill(t, null);
|
||||
@@ -219,10 +224,11 @@ test('T1 镜中虚影 / T2 虚影精通: the twin is killed when he leaves the f
|
||||
assert.ok(h.runUntil(() => t.alive, 1.5), `${label(f)}: back at ${wait} s`);
|
||||
assert.deepEqual([t.tileR, t.tileC, h.b.players[0].dp], [12, 4, 45], `${label(f)}: its tile, 5 DP`);
|
||||
const at = h.b.time;
|
||||
// he is knocked out: the twin is killed with him (KillTokens) and waits for him
|
||||
// he is knocked out: the twin is withdrawn with him (强制撤退 — KillTokens) and waits for him
|
||||
h.b.kill(u, null);
|
||||
u.respawnAt = Infinity; // he stays down until the test brings him back
|
||||
assert.ok(!t.alive, `${label(f)}: killed with him`);
|
||||
assert.ok(!t.alive, `${label(f)}: withdrawn with him`);
|
||||
assert.equal(h.hooksOf('death').filter((c) => c.unit === t).slice(-1)[0].reason, 'retreat', `${label(f)}: a withdrawal, not a knock-out`);
|
||||
h.run(wait + 1);
|
||||
assert.ok(!t.alive && !u.alive, `${label(f)}: no return while he is down`);
|
||||
assert.ok(h.b.redeploy(u, { free: true }));
|
||||
|
||||
Reference in new issue
Block a user