0.2.5-dev: 萨卡兹枯朽战士 (and every enemy sharing its death fog) leaves no 污秽侵蚀 when it dies silenced — the owner's official-play recall, against the PRTS / in-game wording (#470); the 调度中心 5 / 6 promotion reward includes 自选 operators of the newly reached tier (#515, after research; the owner's decision); golden: unchanged
This commit is contained in:
1 parent
a8ff5e7c1d
commit
9b37a68fcf
15 files changed
+157
-49
No files matched your search
@@ -2,7 +2,8 @@
|
||||
// the picks (room.diy → seats[].diy) are checked leniently, fixed for the match and applied to that player only — the
|
||||
// player's data view makes a slotted slot the operator (name, class, bonds from its factions, no 特质, the pick's skill
|
||||
// and module; the slot's tier, price and merge), each slotted piece has its own stock (8 at tier 5, 5 at tier 6), never
|
||||
// enters the shared pool, joins only its player's shop once the 调度中心 reaches the slot's level, leaves the shop when
|
||||
// enters the shared pool, joins only its player's shop once the 调度中心 reaches the slot's level, joins that player's
|
||||
// promotion reward at the reward tier (one shop level earlier: shop 4 → tier 5, shop 5 → tier 6), leaves the shop when
|
||||
// every bond of it is banned, merges 3 → elite, and fields its operator in battle (PlayerBattleInput `diy`), client-run
|
||||
// and server-run identical; prep scouting and the result name the operator.
|
||||
import { test } from 'node:test';
|
||||
@@ -177,16 +178,35 @@ test('buy → 3 copies merge into the elite (the stock pays the copies); sell /
|
||||
assert.equal(p0.allChess().filter(p => p0.gd.baseIdOf(p.id) === T5A).reduce((n, p) => n + p.poolCopies, 0), 9);
|
||||
assert.equal(p0.diyStock.left(T5A), 0, 'the extra copy does not reopen available stock');
|
||||
h.invariants();
|
||||
// reward offers (the temporary refresh) draw it once the 调度中心 is at the slot's level
|
||||
// The promotion reward draws 自选 of the reward tier (shop 4 → tier 5, shop 5 → tier 6), one shop level before the
|
||||
// ordinary shop (owner 2026-10-12, #515). clear() returned the drained T5A copies; the loops roll this stock.
|
||||
clear(p0);
|
||||
p0.offers = [];
|
||||
let hit = 0;
|
||||
p0.shop.level = 4;
|
||||
for (let i = 0; i < 200; i++) { const o = p0.pushRewardOffer('merge'); if (o && o.slots.some((s) => /_diy/.test(s.id))) hit++; p0.offers = []; }
|
||||
assert.equal(hit, 0, 'a level-4 promotion reward (tier 5) never holds a tier-5 自选 piece');
|
||||
p0.shop.level = 6;
|
||||
for (let i = 0; i < 300; i++) { const o = p0.pushRewardOffer('merge'); if (o && o.slots.some((s) => s.id === T6A)) hit++; p0.offers = []; }
|
||||
assert.ok(hit > 0, 'a level-6 reward can hold the tier-6 piece');
|
||||
assert.deepEqual(p0.diyStock.snapshot(), { [T5A]: 8, [T5B]: 8, [T6A]: 5 });
|
||||
const tally = (level, n) => {
|
||||
p0.shop.level = level;
|
||||
const c = { t5: 0, t6: 0, any: 0 };
|
||||
for (let i = 0; i < n; i++) {
|
||||
const o = p0.pushRewardOffer('merge');
|
||||
if (o) {
|
||||
const ids = o.slots.map((s) => s.id);
|
||||
if (ids.some((id) => id === T5A || id === T5B)) c.t5++;
|
||||
if (ids.some((id) => id === T6A || id === T6B)) c.t6++;
|
||||
if (ids.some((id) => /_diy/.test(id))) c.any++;
|
||||
}
|
||||
p0.offers = [];
|
||||
}
|
||||
return c;
|
||||
};
|
||||
assert.equal(tally(3, 80).any, 0, 'a level-3 promotion reward (tier 4) holds no 自选 piece');
|
||||
const lv4 = tally(4, 200);
|
||||
assert.ok(lv4.t5 > 0, 'a level-4 promotion reward (tier 5) can hold a tier-5 自选 piece');
|
||||
assert.equal(lv4.t6, 0, 'a level-4 promotion reward never holds a tier-6 自选 piece');
|
||||
const lv5 = tally(5, 300);
|
||||
assert.ok(lv5.t6 > 0, 'a level-5 promotion reward (tier 6) can hold the tier-6 piece');
|
||||
assert.equal(lv5.t5, 0, 'while tier 6 still has copies, a level-5 reward does not walk down to a tier-5 自选 piece');
|
||||
const lv6 = tally(6, 300);
|
||||
assert.ok(lv6.t6 > 0, 'a level-6 reward can still hold the tier-6 piece');
|
||||
// elimination returns everything
|
||||
gain(p0, T6A);
|
||||
p0.eliminate(m.round);
|
||||
@@ -211,6 +231,12 @@ test('bans: a 自选 piece whose every bond is off this match has no stock (out
|
||||
h.toPrep(1);
|
||||
p0.shop.level = 5;
|
||||
for (let i = 0; i < 300; i++) { p0.rollShop(); assert.ok(!p0.shop.slots.some((s) => s && s.id === T5A)); }
|
||||
p0.shop.level = 4;
|
||||
for (let i = 0; i < 40; i++) {
|
||||
const o = p0.pushRewardOffer('merge');
|
||||
assert.ok(!o || !o.slots.some((s) => s.id === T5A), 'a banned slot has no stock, so the tier-5 reward never holds it');
|
||||
p0.offers = [];
|
||||
}
|
||||
h.m.flush(true);
|
||||
assert.deepEqual(h.lastTo('p_0', 'm.private').diyBanned, [T5A]);
|
||||
h.invariants();
|
||||
|
||||
Reference in new issue
Block a user