Add signature gemstone as guaranteed local buy in every shop
- Ensure each class's gemstone (tier 3–4 producer good) always appears on the shop floor, swapping into the least-important slot when at max stock to preserve size and avoid duplicates. - Add a test sweeping every system/class to verify the world's "jewel" is present, produced, and premium in all shops.
This commit is contained in:
parent
36ef43119d
commit
05b6f573c3
|
|
@ -189,6 +189,25 @@ const classFor = (sysId, good, list) => (list ?? []).find((c) => g.economy.class
|
|||
const cshop = E.shopFor('capital', capSys, g);
|
||||
check('a capital buys back EVERYTHING (universal sink)', cshop.sell.length === goods.length);
|
||||
check('a capital floor is 8–16 goods', cshop.buy.length >= 8 && cshop.buy.length <= 16);
|
||||
|
||||
// THE WORLD'S JEWEL (§4/§6): every shop carries ITS class's signature gem —
|
||||
// a guaranteed premium good + a guaranteed local buy in every shop. Sweep
|
||||
// every system of every class (a gem that's only present by catalog luck
|
||||
// would fail here: the floor must always include the class's gemstone).
|
||||
let gemWorlds = 0;
|
||||
let gemMissing = 0;
|
||||
for (const [id, set] of g.economy.classBySystem) {
|
||||
for (const cls of set) {
|
||||
const gem = goods.find((x) => x.category === 'gemstone' && Array.isArray(x.producer) && x.producer.includes(cls));
|
||||
if (!gem) continue;
|
||||
gemWorlds++;
|
||||
const shop = E.shopFor(cls, id, g);
|
||||
const row = shop.buy.find((b) => b.id === gem.id);
|
||||
// the jewel is a premium good (tier 3–4) + a local buy (produced).
|
||||
if (!row || row.produced !== true || (Number(gem.tier) || 0) < 3) gemMissing++;
|
||||
}
|
||||
}
|
||||
check(`every shop carries its class's signature gem (${gemWorlds - gemMissing}/${gemWorlds} worlds)`, gemWorlds > 0 && gemMissing === 0);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -184,6 +184,8 @@ function seededSelect(items, n, seed, cls, systemId) {
|
|||
* · plain world: its produced goods (abundant, cheap)
|
||||
* · station: produced (≤ half) + a seeded selection of resold goods (variety)
|
||||
* · capital: produced (≤ half) + a seeded selection of premium goods (tier 3–4)
|
||||
* · the class's SIGNATURE GEM is ALWAYS on the floor (the world's
|
||||
* "jewel" — a guaranteed premium good + a guaranteed local buy)
|
||||
* sell — goods the shop BUYS BACK (what you can sell), each { id, price }
|
||||
* · plain world / station: the goods the class wants
|
||||
* · capital: EVERYTHING (the universal sink)
|
||||
|
|
@ -227,6 +229,20 @@ export function shopFor(cls, systemId, galaxy) {
|
|||
}
|
||||
}
|
||||
|
||||
// THE WORLD'S JEWEL (goods.json gemstones, §4/§6): the class's signature
|
||||
// gem is ALWAYS on the shelf — a guaranteed premium good (tier 3–4) and a
|
||||
// guaranteed local buy in every shop, whatever the seeded floor picked.
|
||||
// It's a produced good of `cls`, so it prices at the producer discount;
|
||||
// swap it into the least-important slot (a hub's resold filler, or an
|
||||
// extra local good on a plain world) keeping the 8–16 floor size + no dups.
|
||||
const gem = goods.find(
|
||||
(g) => g.category === 'gemstone' && Array.isArray(g.producer) && g.producer.includes(cls),
|
||||
);
|
||||
if (gem && !buyIds.includes(gem.id)) {
|
||||
if (buyIds.length < maxStock) buyIds.push(gem.id);
|
||||
else buyIds[buyIds.length - 1] = gem.id;
|
||||
}
|
||||
|
||||
const buy = buyIds.map((id) => ({
|
||||
id,
|
||||
name: goodById(id)?.name ?? id,
|
||||
|
|
|
|||
Loading…
Reference in New Issue