Connect group allied transit custody
Verify and publish checkpoint container / container (push) Successful in 10m27s
Verify and publish checkpoint container / container (push) Successful in 10m27s
This commit is contained in:
1 parent
ea3b21f92c
commit
4798a3579b
5 files changed
+152
-23
No files matched your search
@@ -101,14 +101,14 @@ export function makeBasicAlliedShipment(
|
||||
...(allies.length > 1 ? { allies: witnesses } : {}) };
|
||||
}
|
||||
|
||||
/** Quote physical visitors remaining alongside a current ally; territory is an ID. */
|
||||
export function quoteBasicAlliedShipment(
|
||||
/** A live witness is also needed for a concealed zero-force marker. */
|
||||
export function basicAlliedShipmentHasWitness(
|
||||
context: ShipmentContext & Readonly<{ turn: number }>, player: ShipmentPlayer,
|
||||
visit: BasicAlliedShipment | null | undefined,
|
||||
): { territory: string; normal: number; elite: number } | null {
|
||||
): boolean {
|
||||
const allies = currentShipmentAllies(context, player);
|
||||
if (!visit || context.advanced || context.phase !== 5 || visit.player !== player.id ||
|
||||
visit.turn !== context.turn) return null;
|
||||
visit.turn !== context.turn) return false;
|
||||
if (visit.allies !== undefined) {
|
||||
if (context.coalitionState === undefined || !Array.isArray(visit.allies) || !visit.allies.length ||
|
||||
visit.allies.some(id => typeof id !== 'string' || !id || id === player.id) ||
|
||||
@@ -119,7 +119,15 @@ export function quoteBasicAlliedShipment(
|
||||
// For group receipts the original witnesses may leave while another current
|
||||
// ally remains, so consider the complete current membership instead.
|
||||
const candidates = visit.allies === undefined ? allies.filter(id => id === visit.ally) : allies;
|
||||
if (!presentShipmentAllies(context, player, visit.territory, candidates).length) return null;
|
||||
return presentShipmentAllies(context, player, visit.territory, candidates).length > 0;
|
||||
}
|
||||
|
||||
/** Quote physical visitors remaining alongside a current ally; territory is an ID. */
|
||||
export function quoteBasicAlliedShipment(
|
||||
context: ShipmentContext & Readonly<{ turn: number }>, player: ShipmentPlayer,
|
||||
visit: BasicAlliedShipment | null | undefined,
|
||||
): { territory: string; normal: number; elite: number } | null {
|
||||
if (!visit || !basicAlliedShipmentHasWitness(context, player, visit)) return null;
|
||||
const pool = alliedShipmentPhysicalPool(player, visit.territory);
|
||||
const normal = Math.max(0, pool.normal - visit.baseline.normal);
|
||||
const elite = Math.max(0, pool.elite - visit.baseline.elite);
|
||||
|
||||
+6
-6
@@ -748,8 +748,9 @@ import {
|
||||
settleAdvisors,
|
||||
arrivalAsAdvisor,
|
||||
} from './advisors';
|
||||
import { isAlliedShipmentVisit, makeBasicAlliedShipment, quoteBasicAlliedShipment,
|
||||
import { isAlliedShipmentVisit, makeBasicAlliedShipment, quoteBasicAlliedShipment, basicAlliedShipmentHasWitness,
|
||||
type BasicAlliedShipment } from './allied-separation';
|
||||
import type { CoalitionState } from './coalition-alliance';
|
||||
import { casualtyOptions, maxCombatDial, maxCombatSupport, validCombatForces, type Casualties, type CombatForces } from './combat';
|
||||
import { FACTIONS, faction, type FactionId } from './catalog';
|
||||
import { quoteLobbyBotConfiguration } from './lobby-bot-configuration';
|
||||
@@ -1430,6 +1431,8 @@ type RicheseAllyOffer = {
|
||||
payer: string;
|
||||
};
|
||||
export type Game = {
|
||||
/** Unexposed group-alliance integration state; absent in existing games. */
|
||||
coalitionState?: CoalitionState;
|
||||
/** Public written agreements. Their prose is honored by players, not parsed. */
|
||||
deals?: PublicDeal[];
|
||||
/** A human-to-human lobby offer, pending the recipient's consent. */
|
||||
@@ -19742,7 +19745,7 @@ function allowedEntry(
|
||||
'That sector is in storm.',
|
||||
);
|
||||
const blocked = occupancyRule(() =>
|
||||
territoryEntryBlock(g.players, p.id, t, advisors, temporaryAlliedShipment),
|
||||
territoryEntryBlock(g.players, p.id, t, advisors, temporaryAlliedShipment, g.coalitionState),
|
||||
);
|
||||
requireRule(!blocked, blocked ?? 'This territory cannot be entered.');
|
||||
}
|
||||
@@ -23121,10 +23124,7 @@ function alliedSeparationView(g: Game, p: Player): {territories: string[]; noFie
|
||||
|
||||
function basicAlliedShipmentView(g: Game, p: Player) {
|
||||
const visit = g.basicAlliedShipment;
|
||||
if (g.advanced || g.phase !== 5 || !visit || visit.player !== p.id ||
|
||||
visit.turn !== g.turn || p.ally !== visit.ally) return null;
|
||||
const ally = getPlayer(g, visit.ally);
|
||||
if (ally.ally !== p.id || !at(ally, visit.territory) || sharesEcazOccupation(g, p, visit.territory)) return null;
|
||||
if (!visit || !occupancyRule(() => basicAlliedShipmentHasWitness(g, p, visit))) return null;
|
||||
const quote = occupancyRule(() => quoteBasicAlliedShipment(g, p, visit));
|
||||
const deployed = p.noField?.deployed;
|
||||
const noField = !!visit.noField && deployed?.tokenId === visit.noField && deployed.controller === p.id &&
|
||||
|
||||
Reference in new issue
Block a user