Preserve Fremen revival grant opportunity for bot allies
Verify and publish checkpoint container / container (push) Successful in 10m54s

This commit is contained in:
Quintine committed 2026-10-29 07:18:48 +11:00
1 parent 825f903cce
commit ac7db3cb35
7 files changed
+201 -2

No files matched your search

+20
View File
@@ -2,6 +2,7 @@ import { liveMovementExpressionPromises } from './movement-expression-promises';
import { isAlliedShipmentVisit } from './allied-separation';
import { discoveryBotActions } from './discovery-options';
import { normalAuctionHandBlock } from './normal-auction';
import { fremenRevivalGrantBlock } from './fremen-revival-grant';
import { atreidesFullPlanAction } from './atreides-full-plan';
import { liveMovementPromises } from './movement-promises';
import { ecazOccupyDialChoices, ecazOccupyOwnProfile, ecazOccupyPolicyActions } from './ecaz-occupy-options';
@@ -60,6 +61,8 @@ import { strongholdBattleEffects } from './stronghold-battle';
import {
eliteRevivalRemaining,
forceRevivalPrice,
freeRevivalRemaining,
revivalPrevented,
paidForceRevivalCost,
} from './revival';
import { controlsLeader, nativeAvailable } from './leader-control';
@@ -4661,6 +4664,21 @@ export function botActions(g: GameView): Action[] {
: [{ type: 'endMovement' }];
}
/** In concurrent Basic Revival, let a human Fremen decide its existing grant
* before its automated ally spends or finishes. Ready is the normal way to
* finish that decision; responses and unrelated actions remain available. */
function waitsForHumanFremenGrant(g: Game, player: Game['players'][number]): boolean {
if (g.status !== 'playing' || g.advanced || g.phase !== 4 || g.revivalOrder ||
g.coalitionState || player.tanks <= 0 || revivalPrevented(g, player.id)) return false;
const fremen = g.players.find(seat => seat.faction === 'fremen');
if (!fremen || fremen.bot || fremen.autopilot || fremen.ally !== player.id ||
player.ally !== fremen.id || g.ready.includes(fremen.id) ||
fremenRevivalGrantBlock(g, fremen.id) !== null) return false;
const current = freeRevivalRemaining(g, player);
const granted = freeRevivalRemaining({ ...g, freeRevival: [...g.freeRevival, player.id] }, player);
return Math.min(player.tanks, granted) > Math.min(player.tanks, current);
}
export function runBots(state: Game, limit = 96): Game {
const supplier = state.players.find((p) => p.faction === 'richese');
const unopenedAllyWindow =
@@ -4700,6 +4718,8 @@ export function runBots(state: Game, limit = 96): Game {
actors.sort((a, b) => Number(b.faction === 'guild') - Number(a.faction === 'guild'));
for (const p of actors) {
for (const action of botActions(viewGame(g, p.id))) {
if ((action.type === 'revive' || action.type === 'ready') && waitsForHumanFremenGrant(g, p))
continue;
try {
next = applyAction(g, p.id, action);
break;