fix: correct community-reported combat and strategy draft behavior
Guard lethal stuns against a replacement deployment; keep bard auras running through stun; require an active Aegir bond for Clementia's strategy; allow Compass SP to bypass recovery locks; and refresh Hidden Core gun mitigation against current gun/spring companions. Set multiplayer strategy picks to 50s and describe renderer fallback without diagnosing unsupported hardware. Golden moves (full 285-scenario regeneration): - roster-008: inactive Aegir no longer gains 18 strategy layers. - boss-boss_4-solo: bard regeneration continues through stun. - hidden-boss_9-pair: mitigation covers first hits/current companions. - standin-07: hammer stun cannot follow an immediate revival deployment. No ending-reason changes. Sources and report-by-report findings: DESIGN 28.25.
This commit is contained in:
1 parent
77cd29f07a
commit
708caf7d06
37 files changed
+277
-103
No files matched your search
@@ -84,7 +84,7 @@ const BY_KEY = {
|
||||
}, { priority: PRIO_BAND_REVIVE });
|
||||
},
|
||||
|
||||
// 克莱门莎 崇高牺牲
|
||||
// 克莱门莎 崇高牺牲: PRTS requires the 阿戈尔 bond to be active.
|
||||
act1autochess_band13_buff(battle, ps, p, bandId) {
|
||||
const bond = typeof p.bond_id === 'string' && p.bond_id ? p.bond_id : null;
|
||||
if (!bond) return;
|
||||
@@ -93,7 +93,7 @@ const BY_KEY = {
|
||||
const u = c.unit;
|
||||
if (c.reason !== 'killed' || !isOp(u) || u.ownerId !== ps.playerId || !unitBonds(u).includes(bond)) return;
|
||||
const n = byLevel ? tierOf(u) : Math.max(1, Math.floor(num(p.value, 1)));
|
||||
if (gainLayers(battle, { playerId: ps.playerId, bonds: bond, n, requireActive: false, source: u, reason: 'band' }) > 0) {
|
||||
if (gainLayers(battle, { playerId: ps.playerId, bonds: bond, n, requireActive: true, source: u, reason: 'band' }) > 0) {
|
||||
fxOn(battle, 'layer', u, keyOf(bandId), bandId, { bond, n });
|
||||
}
|
||||
});
|
||||
|
||||
@@ -621,13 +621,16 @@ function kitGun(ab, e, b) {
|
||||
},
|
||||
];
|
||||
if (hidden) {
|
||||
list.push({
|
||||
iv: 0.25,
|
||||
tick(b2, e2) { // 【未尽的告解】 physical / arts damage taken ×4.damage_scale while the 碎铳之簧 it came with remain
|
||||
const springs = b2.enemies.some((o) => o.alive && isSpring(o));
|
||||
if (springs) { const m = T(ab, '4.damage_scale') ?? 1; b2.addBuff(e2, { key: 'boss:confession', duration: 0.35, refresh: 'replace', mods: { physTakenMul: m, artsTakenMul: m } }); }
|
||||
},
|
||||
});
|
||||
// PRTS 未尽的告解: another gun OR spring keeps the reduction. Refresh on hit as well so the first hit and
|
||||
// a hit immediately after the last companion dies see the current condition, not a stale polling result.
|
||||
const confession = (b2, e2) => {
|
||||
const other = b2.enemies.some((o) => o !== e2 && o.alive && (isGun(o) || isSpring(o)));
|
||||
if (other) {
|
||||
const m = T(ab, '4.damage_scale') ?? 1;
|
||||
b2.addBuff(e2, { key: 'boss:confession', duration: 0.35, refresh: 'replace', mods: { physTakenMul: m, artsTakenMul: m } });
|
||||
} else b2.removeBuff(e2, 'boss:confession');
|
||||
};
|
||||
list.push({ iv: 0.25, tick: confession, hitIn(c, b2, e2) { confession(b2, e2); } });
|
||||
if (s3) list.push({
|
||||
iv: s3.bb.interval ?? 1,
|
||||
tick(b2, e2) { // 【盲信之誓】 links: phys per second on operators standing on a line ("无视无法选择、迷彩": 起飞 too)
|
||||
|
||||
@@ -138,7 +138,10 @@ const nthAttackStatus = (n, key, dur, sil = true) => ({
|
||||
attack(c, b, e, a) {
|
||||
a.n++;
|
||||
if (a.n % n) return;
|
||||
for (const t of c.targets) if (t.alive && dur > 0) b.applyStatus(t, key, { duration: dur, source: e });
|
||||
for (const t of c.targets) {
|
||||
if (!t.alive || !(dur > 0) || (c.targetDeployments && c.targetDeployments.get(t) !== t.deploySeq)) continue;
|
||||
b.applyStatus(t, key, { duration: dur, source: e });
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -735,7 +735,7 @@ const BY_ITEM = {
|
||||
}
|
||||
});
|
||||
},
|
||||
// 黄沙罗盘: 初始技力 +init_sp each deploy; (萨尔贡) first skill end +sp; + 萨尔贡浓茶: each cast all 萨尔贡 +addition_sp
|
||||
// 黄沙罗盘 (PRTS: all its SP ignores 阻回): 初始技力 +init_sp each deploy; (萨尔贡) first skill end +sp; + 萨尔贡浓茶: each cast all 萨尔贡 +addition_sp
|
||||
chess_item_6_07_e(battle, u, rec, S) {
|
||||
const p = bp(rec, 'act1autochess_equip_acarm103_global_buff');
|
||||
if (!p) return;
|
||||
@@ -749,14 +749,14 @@ const BY_ITEM = {
|
||||
S.on('skillEnd', (c) => {
|
||||
if (c.unit !== u || firstDone || c.reason === 'death' || !memberOf(battle, u, 'sargonShip')) return;
|
||||
firstDone = true;
|
||||
if (u.skill && u.alive) u.skill.gainSp(num(p.sp), 'item');
|
||||
if (u.skill && u.alive) u.skill.gainSp(num(p.sp), 'item', false, { ignoreLock: true });
|
||||
});
|
||||
S.on('skillStart', (c) => {
|
||||
if (c.unit !== u || !partner || !memberOf(battle, u, 'sargonShip') || !carries(battle, u, partner)) return;
|
||||
const n = num(p.addition_sp);
|
||||
if (!(n > 0)) return;
|
||||
for (const a of battle.allyUnits) {
|
||||
if (a.kind === 'op' && a.ownerId === u.ownerId && onField(a) && a.skill && memberOf(battle, a, 'sargonShip')) a.skill.gainSp(n, 'item');
|
||||
if (a.kind === 'op' && a.ownerId === u.ownerId && onField(a) && a.skill && memberOf(battle, a, 'sargonShip')) a.skill.gainSp(n, 'item', false, { ignoreLock: true });
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
@@ -82,7 +82,7 @@ function skadi2(bb, chess, def) {
|
||||
if (unit.skill) unit.skill.addTriggerRange(() => seaborns(battle, unit));
|
||||
let n = 0;
|
||||
battle.every(0.5, () => {
|
||||
if (!unit.canAct) return;
|
||||
if (!live(unit)) return; // the continuous trait (including its skill conversion) survives stun
|
||||
for (let i = unit.buffs.length - 1; i >= 0; i--) if (isInspire(unit.buffs[i])) battle.removeBuff(unit, unit.buffs[i]);
|
||||
n++;
|
||||
const toks = seaborns(battle, unit);
|
||||
|
||||
@@ -19,7 +19,7 @@ const GROUND = Object.freeze({ canHitFly: false, groundOnly: true });
|
||||
const AIR = Object.freeze({ canHitFly: true });
|
||||
const SPEED = 2, DISTANCE = 3, CATCH_HALF = 0.55, VORTEX_RADIUS = 1.5;
|
||||
const SPLASH_RADIUS = 1.5; // [ASSUMED] PRTS has not published S2's normal attack splash radius.
|
||||
const FIRST_BOMB = 0.5; // [ASSUMED] PRTS lists the landing delay as unknown.
|
||||
const FIRST_BOMB = 0.5; // [ASSUMED] Neither PRTS nor the edited official demo settles the first landing offset.
|
||||
const CAST = 'clemnt:cast', CARRY = 'clemnt:carry:';
|
||||
const skillBb = (raw, id) => skillRec(raw, id)?.bb ?? {};
|
||||
const tile = (u) => [Math.round(u.y), Math.round(u.x)];
|
||||
|
||||
Reference in new issue
Block a user