Connect optional Smuggler reserve shipment and saved interception
Prototype one free accompanying force into an empty territory with explicit opt-out, shared human/AI pricing, physical elite custody and Guild recipient accounting. Bind pending quotes to their unique saved Guild decision; preserve legacy unstamped full-price declarations. Smuggler battle collection and combined modules remain unfinished and gated. Repair a randomly dealt-out Karama fixture by relocating its actual physical card without changing inventory. Validation: 70 focused tests; typecheck, lint, 4477 offline tests, production build and 43 HTTP tests passed. Independent rules/persistence review completed, including interruption and cancellation. Browser checked the price toggle, three arrivals for two spice, and refresh with unchanged private cards. Two genuine four-profile Basic/Advanced samples completed without rejected candidates but did not use Smuggler. Preserved all 427 opening rooms and original seat/recovery rows (461 rooms after QA/HTTP). SQLite integrity and foreign keys passed. Server remained healthy after the reported power outage; no restart or reset. Verified source tree: bf6e02bf6873ca6d6b01c83481489f55b2c7db0184a7056364343440dae88803
This commit is contained in:
1 parent
06f46c6f79
commit
9381ef140d
18 files changed
+1015
-25
No files matched your search
@@ -0,0 +1,39 @@
|
||||
import type { Game, GameView } from './engine';
|
||||
import { presenceAt } from './force-presence';
|
||||
|
||||
/** The amount is the entire physical shipment, including its one free companion. */
|
||||
export type SmugglerShipment = { leader: string; amount: number };
|
||||
|
||||
/** Public leader custody and whole-territory presence suffice; no private hand is read. */
|
||||
export function quoteSmugglerShipment(
|
||||
game: Game | GameView,
|
||||
player: string,
|
||||
territory: string,
|
||||
amount: number,
|
||||
): SmugglerShipment | null {
|
||||
if (!Number.isSafeInteger(amount) || amount < 2) return null;
|
||||
// Classic Fremen reserves are on-planet; their normal reinforcement is not off-planet shipping.
|
||||
if (game.players.find((p) => p.id === player)?.faction === 'fremen')
|
||||
return null;
|
||||
const assignment = game.leaderSkills?.assignments.find(
|
||||
(a) => a.owner === player && a.skill === 'smuggler',
|
||||
);
|
||||
if (
|
||||
!assignment ||
|
||||
('controller' in assignment && assignment.controller !== player) ||
|
||||
('faceUp' in assignment && !assignment.faceUp)
|
||||
)
|
||||
return null;
|
||||
const leader = game.players
|
||||
.find((p) => p.id === player)
|
||||
?.leaders.find((l) => l.id === assignment.leader);
|
||||
if (
|
||||
!leader ||
|
||||
leader.dead ||
|
||||
leader.capturedBy ||
|
||||
leader.gholaBy ||
|
||||
game.players.some((p) => presenceAt(p, territory) > 0)
|
||||
)
|
||||
return null;
|
||||
return { leader: leader.id, amount };
|
||||
}
|
||||
Reference in new issue
Block a user