Prototype unlimited alliance variant
Verify and publish checkpoint container / container (push) Canceled after 0s
Verify and publish checkpoint container / container (push) Canceled after 0s
This commit is contained in:
1 parent
37acaeb9d2
commit
9cb65a21f5
23 files changed
+677
-52
No files matched your search
@@ -10,6 +10,8 @@ export type CoalitionNexusView = {
|
||||
groups: readonly CoalitionGroup[];
|
||||
proposal: CoalitionAdmission | null;
|
||||
revision: number;
|
||||
/** Absent preserves the original, at-most-three alliance prototype. */
|
||||
variant?: 'unlimited';
|
||||
};
|
||||
|
||||
export type CoalitionNexusIntent =
|
||||
@@ -28,7 +30,7 @@ export function coalitionNexusOptions(view: CoalitionNexusView): {
|
||||
const ownGroup = view.groups.find(group => group.members.includes(view.me));
|
||||
const occupied = new Set(view.groups.flatMap(group => group.members));
|
||||
const invitations = !seated || view.proposal ? [] : view.groups.flatMap(group =>
|
||||
group.members.length !== 2 ? [] : view.players
|
||||
(group.members.length < 2 || group.members.length >= (view.variant === 'unlimited' ? 6 : 3)) ? [] : view.players
|
||||
.filter(player => !occupied.has(player.id) &&
|
||||
(player.id === view.me || group.members.includes(view.me)))
|
||||
.map(player => ({ groupId: group.id, entrant: player.id, members: group.members })));
|
||||
@@ -57,8 +59,10 @@ export function CoalitionNexus({ view, disabled = false, onIntent }: {
|
||||
const submit = (intent: CoalitionNexusIntent) => { if (!disabled) onIntent(intent); };
|
||||
return <section aria-label="Group alliance negotiations" className="notice min-w-0 space-y-3 break-words">
|
||||
<h3>Group alliance negotiations</h3>
|
||||
<p>All three players must agree before an invitation forms an alliance.
|
||||
The existing pair remains allied while an invitation is pending.</p>
|
||||
{view.variant === 'unlimited' ? <p>Every current member and the invited player must agree.
|
||||
The existing alliance remains in place while an invitation is pending.</p> :
|
||||
<p>All three players must agree before an invitation forms an alliance.
|
||||
The existing pair remains allied while an invitation is pending.</p>}
|
||||
{view.groups.length ? <ul>{view.groups.map(group =>
|
||||
<li key={group.id}>{names(group.members)}</li>)}</ul> : <p>There are no alliances yet.</p>}
|
||||
{proposal ? <div aria-live="polite">
|
||||
@@ -77,7 +81,9 @@ export function CoalitionNexus({ view, disabled = false, onIntent }: {
|
||||
proposal.approvals.includes(view.me) ? 'Withdraw approval and cancel invitation' :
|
||||
'Decline and cancel invitation'}</button>}
|
||||
</div> : <div>
|
||||
{options.invitations.length > 0 && <p>Invite an unallied player to an existing pair, or ask to join a pair.</p>}
|
||||
{options.invitations.length > 0 && <p>{view.variant === 'unlimited'
|
||||
? 'Invite an unallied player to an existing alliance, or ask to join one.'
|
||||
: 'Invite an unallied player to an existing pair, or ask to join a pair.'}</p>}
|
||||
{options.invitations.map(option => <button className="game-action" disabled={disabled}
|
||||
key={JSON.stringify([option.groupId, option.entrant])} onClick={() => submit({
|
||||
kind: 'propose', groupId: option.groupId, entrant: option.entrant, expectedRevision: view.revision,
|
||||
@@ -87,6 +93,8 @@ export function CoalitionNexus({ view, disabled = false, onIntent }: {
|
||||
kind: 'leave', expectedRevision: view.revision,
|
||||
})}>Leave {names(ownGroup!.members)}</button>}
|
||||
{ownGroup?.members.length === 3 && <p>Leaving keeps the other two players allied under the provisional online policy.</p>}
|
||||
{view.variant === 'unlimited' && (ownGroup?.members.length ?? 0) > 3 &&
|
||||
<p>Leaving keeps the other players allied under the provisional online policy.</p>}
|
||||
</div>}
|
||||
</section>;
|
||||
}
|
||||
@@ -306,7 +306,7 @@ export function GameTable({
|
||||
}) {
|
||||
const me = g.players.find((p) => p.id === g.me)!;
|
||||
const groupNexus = g.coalitionNexus;
|
||||
const inGroup = groupNexus?.groups.some(group => group.members.length === 3 && group.members.includes(me.id));
|
||||
const inGroup = groupNexus?.groups.some(group => group.members.length >= 3 && group.members.includes(me.id));
|
||||
const outgoingAlliance = g.allianceOffers[me.id];
|
||||
const outgoingAllianceName = g.players.find((p) => p.id === outgoingAlliance)?.name;
|
||||
const shipmentAvailable = nexusGuildShipmentAvailable(g);
|
||||
@@ -4395,7 +4395,7 @@ export function GameTable({
|
||||
<option value="">Choose a player</option>
|
||||
{g.players
|
||||
.filter((p) => p.id !== me.id && !groupNexus?.groups.some(group =>
|
||||
group.members.length === 3 && group.members.includes(p.id)))
|
||||
group.members.length >= 3 && group.members.includes(p.id)))
|
||||
.map((p) => (
|
||||
<option value={p.id} key={p.id}
|
||||
disabled={!!g.homeworldAllianceBlocks?.[p.id]}>
|
||||
|
||||
Reference in new issue
Block a user