Resolve definite Orgiz payers and prove native shared Collection

This commit is contained in:
Quintine committed 2026-10-14 19:13:41 +11:00
1 parent 388c5fa8d5
commit bc09ac3cfd
11 files changed
+310 -292

No files matched your search

+27 -13
View File
@@ -131,9 +131,9 @@ function transferOrgiz(
receipts: DiscoveryBaseCollectionReceipt[],
effects: DiscoveryCollectionQuote['effects'],
) {
if (!collector || collector.id === ownerReceipt.player) return;
if (!collector || collector.id === ownerReceipt.player) return false;
const collectorReceipt = receipts.find(entry => entry.player === collector.id)!;
if (collectorReceipt.balance === 0) return;
if (collectorReceipt.balance === 0) return false;
requireCollection(
Number.isSafeInteger(ownerReceipt.balance + 1),
'Orgiz theft would invalidate a player spice balance.',
@@ -144,6 +144,7 @@ function transferOrgiz(
kind: 'orgiz', player: ownerReceipt.player, from: collector.id,
location: key, amount: 1, source: 'player',
});
return true;
}
/**
@@ -151,10 +152,10 @@ function transferOrgiz(
* over the canonical ordinary quote. Ordinary `collected` and `desert` remain
* factual: Cistern is bank income; Orgiz transfers available player spice.
*
* Owners resolve in original storm order. Advanced uses territory Collection;
* Basic retains the provisional positive-deposit trigger. Ambiguous collectors
* and shared lots still withhold only their uncertain effect. Empty purses
* cannot create debt or block ordinary Collection.
* Owners resolve in original storm order. Advanced chooses one actual foreign
* collector per territory in storm order; Basic retains the provisional
* positive-deposit trigger. Ambiguous collected sectors withhold the territory
* effect. Shared lots settle after bilateral allocation, not in this quote.
*/
export function quoteDiscoveryCollection(
context: DiscoveryCollectionContext,
@@ -271,7 +272,10 @@ export function quoteDiscoveryCollection(
if (orgiz.length) {
const ownerReceipts = orgiz.map(owner => receipts.find(entry => entry.player === owner.id)!);
const transfers = context.advanced
? new Map<string, { location: string; collector: DiscoveryCollectionSeat | undefined }>()
? new Map<string, {
collectors: { location: string; collector: DiscoveryCollectionSeat }[];
ambiguous: boolean;
}>()
: undefined;
for (const key of sourceKeys) {
if (context.spice[key] <= collection.spice[key]) continue;
@@ -287,15 +291,25 @@ export function quoteDiscoveryCollection(
transferOrgiz(key, collector, ownerReceipt, receipts, effects);
continue;
}
const pending = transfers.get(territory);
if (!pending) transfers.set(territory, { location: key, collector });
else if (pending.collector?.id !== collector?.id)
pending.collector = undefined;
let pending = transfers.get(territory);
if (!pending) {
pending = { collectors: [], ambiguous: false };
transfers.set(territory, pending);
}
if (!collector) pending.ambiguous = true;
else if (!pending.collectors.some(entry => entry.collector.id === collector.id))
pending.collectors.push({ location: key, collector });
}
if (transfers)
for (const pending of transfers.values())
for (const pending of transfers.values()) {
if (pending.ambiguous) continue;
pending.collectors.sort((left, right) =>
context.order.indexOf(left.collector.id) - context.order.indexOf(right.collector.id));
for (const ownerReceipt of ownerReceipts)
transferOrgiz(pending.location, pending.collector, ownerReceipt, receipts, effects);
for (const candidate of pending.collectors)
if (transferOrgiz(candidate.location, candidate.collector, ownerReceipt, receipts, effects))
break;
}
}
return { receipts, effects };
+4 -3
View File
@@ -4226,7 +4226,7 @@ export const RULE_TOPICS: RuleTopic[] = [
'The five revealed location tokens become separate, initially empty territories inside their surroundings. A private peek does not open the location. Normal ground movement enters through the surrounding territory, shipment uses stronghold prices, at most two factions may occupy it, and forces inside are protected from storms and sandworms. Only Jacurutu Sietch counts toward stronghold victory.',
'Native typed forces enter as their actual ordinary and elite groups, never as passengers from the mobile stronghold or the concealed value of a No-Field. Richese may ship or move a concealed marker into an actually revealed nested location at sector zero; it remains one effective presence until its original reveal materializes available reserves. CHOAM Card Stash uses its five-card limit, drawing first and choosing any held discard afterward.',
'At the start of the next turn, before the storm and mobile stronghold movement, each eligible faction may move any positive subset of its non-advisor groups from the surrounding territory into the newly revealed location. The signed choice preserves ordinary and elite forces across sectors, normal source storm and occupancy restrictions, and costs no spice, shipment or normal movement. The printed text gives no sequence and does not restate the source-storm restriction; processing tokens in reveal order and factions in storm order while excluding storm sources are source inferences.',
'During Collection, after ordinary advisor releases, each fighter occupant of Cistern receives two bank spice, and each fighter occupant of Orgiz takes one spice from the unique rival collector of a qualifying deposit. Orgiz owners resolve in original storm order; an empty purse cannot pay and creates no debt. Advanced uses the supplied territory Collection event and Basic keeps the provisional one-per-positive-deposit mapping. When Ecaz and its ally share a collected territory, the real allocation settles first and the Orgiz owner then takes from the first actual positive foreign recipient. Contested ownership, different payers and unresolved Cistern ownership contests remain guarded; ordinary Collection continues.',
'During Collection, after ordinary advisor releases, every Cistern fighter occupant receives two bank spice. Orgiz fighter occupants resolve in original storm order. Advanced charges once per territory from the first definite actual foreign collector in storm order that can pay; Basic keeps one transfer per positive deposit with a unique rival collector. Empty purses never create debt. Shared Ecaz desert lots wait for their actual bilateral split, then consider positive foreign recipients Ecaz first, ally second, excluding self and zero shares. Payer and occupant ordering remain provisional. Ambiguous collected-sector payers still withhold their territory effect without blocking ordinary Collection.',
'Jacurutu pays one bank spice for each opposing undialed physical force actually sent to the Tanks. Where an Advanced dial admits different physical counts, the defeated player chooses an exact ordinary/elite/paid reading before support, casualties or rewards settle; unique readings remain automatic. This choice timing is a visibly provisional implementation interpretation. Original Harass returns bind their physical dial and actual withdrawal/retreat counters do not earn spice.',
'Each non-advisor Testing Station occupant may decrease ordinary storm movement by one, keep it or increase it by one. The provisional order is the original storm order, once per owner, with cumulative adjustments on current distance. Choose after the ordinary card window; traversal/protection starts only after all choices. Weather Control is unaffected. Original natural source/base and existing sole-frame history remain authoritative; legacy movement without a source is not invented.',
'A current non-advisor Shrine occupant may play a physical Truthtrance card as Karama, or a physical Karama as Truthtrance, within the implemented timing and effect paths. The printed identity and actual card custody remain unchanged; a committed Truthtrance conversion survives departure. This does not create missing Karama powers or settle their pending rules.',
@@ -4251,14 +4251,15 @@ export const RULE_TOPICS: RuleTopic[] = [
},
{
area: 'Documentation', status: 'Partial',
detail: 'Sourced identities and native/classic-skill boundaries are recorded. Advanced Orgiz follows territory Collection; Basic remains provisional per deposit. Recommended defeated-player physical Jacurutu allocation and cumulative storm-order Testing Station choices are explicit, visible prototype interpretations, not new publisher rulings. Great Maker, entry and source-storm inferences remain; contested Cistern/Orgiz and shared-lot theft stay open.',
detail: 'Sourced identities and native/classic-skill boundaries are recorded. Advanced Orgiz follows territory Collection; Basic remains provisional per deposit. Recommended Discovery occupant/payer ordering, defeated-player Jacurutu allocation and cumulative Testing Station choices are explicit visible interpretations, not publisher rulings. Great Maker, entry, source-storm inferences and ambiguous collected-sector Orgiz sources remain open.',
evidence: ['docs/DISCOVERY_COMPONENTS.md', 'docs/DISCOVERY_PROTOTYPE.md'],
},
{
area: 'Verification', status: 'Partial',
detail: 'Current recommended Jacurutu/Testing Station batch passes104/104 in12 related files, types/lint and build. Genuine Advanced dial2/support1 produces1-or0 reward with the same original losses, support and later Collection; unique readings stay automatic. Original Basic/Advanced station sources, real alliance/garrisons and390px first/second cumulative choices preserve one final traversal, source and Weather exclusion. All four legal policies are exercised. Earlier native-family evidence remains source-bound; broader combinations, assurance, strategy and deployed acceptance stay open.',
detail: 'Current Collection batch passes27/27 in3 related files, types/lint and build. Genuine setup, token reveal/entry, alliance, departure and paid shipments produce actual shared desert allocation; equal/full/zero shares, acceptance timing, wrong actor, stale allocation, payer order and depletion are exercised. Actual390px proposal4/0 preserves wallets until acceptance, then produces Ecaz10/Guild12 and one Orgiz transfer with Ready restored. The earlier Jacurutu/Testing Station batch passes104/104 in12 files with native dial/sole-source/two-owner traversal evidence. Broader combinations, assurance, strategy and deployed acceptance remain open.',
evidence: ['tests/mixed-nexus-modules-runtime.test.ts', 'tests/paired-e3-nexus-modules-runtime.test.ts', 'tests/sample-custody.test.ts', 'tests/ambassador-terror-overlap-engine.test.ts', 'tests/e3-nexus-ecaz-runtime.test.ts', 'tests/e3-nexus-moritani-runtime.test.ts', 'tests/single-nexus-e1-runtime.test.ts', 'tests/single-nexus-e2-runtime.test.ts', 'tests/homeworld-paired-nexus-runtime.test.ts', 'tests/homeworld-standalone-nexus-runtime.test.ts',
'tests/fixture-jacurutu-mixed-dial.ts', 'tests/jacurutu-mixed-dial-runtime.test.ts', 'tests/fixture-testing-station-contest.ts', 'tests/testing-station-contest-runtime.test.ts',
'tests/fixture-discovery-occupied-collection.ts', 'tests/discovery-occupied-collection-runtime.test.ts', 'tests/fixture-discovery-shared-orgiz.ts', 'tests/discovery-shared-orgiz-runtime.test.ts',
'tests/homeworld-classic-nexus-skills-runtime.test.ts', 'tests/homeworld-classic-discovery-nexus-runtime.test.ts', 'tests/homeworld-native-e1e2-modules-runtime.test.ts', 'tests/homeworld-native-e3-modules-runtime.test.ts', 'tests/homeworld-classic-discovery-runtime.test.ts', 'tests/homeworld-skills-discovery-runtime.test.ts', 'tests/homeworld-optional-modules-runtime.test.ts', 'tests/discovery-native-e1-skills-runtime.test.ts', 'tests/discovery-native-e2-skills-runtime.test.ts', 'tests/discovery-native-e3-skills-runtime.test.ts', 'tests/discovery-skills-strongholds-runtime.test.ts', 'tests/discovery-native-strongholds-runtime.test.ts', 'tests/ecaz-stronghold-runtime.test.ts', 'tests/e3-native-tech-runtime.test.ts', 'tests/discovery-classic-nexus-lifecycle.test.ts', 'tests/discovery-classic-nexus-effects.test.ts', 'tests/discovery-orgiz-advanced-runtime.test.ts', 'tests/discovery-classic-skills-runtime.test.ts', 'tests/discovery-module-profile.test.ts', 'tests/discovery-native-typed-runtime.test.ts', 'tests/discovery-native-marker-runtime.test.ts', 'tests/discovery-native-e3-runtime.test.ts', 'tests/discoveries.test.ts', 'tests/discovery-runtime.test.ts', 'tests/great-maker.test.ts', 'tests/discovery-board.test.ts', 'tests/discovery-admission.test.ts', 'tests/discovery-controls.test.ts', 'tests/discovery-entry.test.ts', 'tests/discovery-entry-runtime.test.ts', 'tests/discovery-entry-controls.test.ts', 'tests/discovery-entry-review.test.ts', 'tests/discovery-collection.test.ts', 'tests/discovery-flight.test.ts', 'tests/discovery-flight-engine.test.ts', 'tests/discovery-flight-recovery.test.ts', 'tests/discovery-battle.test.ts', 'tests/discovery-battle-recovery.test.ts', 'tests/discovery-storm.test.ts', 'tests/discovery-storm-recovery.test.ts', 'tests/discovery-shrine-engine.test.ts', 'tests/discovery-shrine-recovery.test.ts', 'docs/HOMEWORLD_RUNTIME_IMPLEMENTATION.md'],
},
],