Support Planetologist range for concealed Richese No-Fields

This commit is contained in:
Quintine committed 2026-10-26 09:30:02 +11:00
1 parent 2c3dde51d4
commit f6e6671ac5
14 files changed
+1041 -181

No files matched your search

+12 -21
View File
@@ -52,7 +52,7 @@ import {
} from './homeworld-options';
import { matchesPlanClaim, respectsBattlePromises } from './battle-promises';
import { ecazOccupancyRelation } from './ecaz-occupy';
import { territoryEntryBlock, strongholdPathBlocked } from './occupancy';
import { territoryEntryBlock } from './occupancy';
import { strongholdBattleEffects } from './stronghold-battle';
import {
eliteRevivalRemaining,
@@ -3471,36 +3471,27 @@ function policyActions(g: GameView): Action[] {
}
if (marker && noField && !g.homeworldMobility?.noFieldMovementBlocked && (me.moved ?? 0) < (me.movesAllowed ?? 1)) {
const from = location(marker.location.territory, marker.location.sector);
const range =
fighterCount(me, 'arrakeen') || fighterCount(me, 'carthag') ? 3 : 1;
const markerPlanetologist = !!planetologistLeader(g, me.id) &&
!g.ornithopter?.active && planetologistMovementModeSupported(g);
let markerMoves = 0;
if (marker.location.sector !== g.storm)
for (const to of markerTargets.slice(0, 24)) {
for (const to of markerTargets) {
if (from === to.key || (materialized === 0 && to.enemy > 0)) continue;
if (
g.balisetRestrictions.some(
(b) => b.player === me.id && b.territory === to.t,
) &&
marker.location.territory !== to.t
)
continue;
if (
gameDistance(g, from, to.key, (key) => {
const loc = splitLocation(key);
return (
loc.sector === g.storm ||
strongholdPathBlocked(g.players, me.id, loc.territory)
);
}) > range
)
continue;
const ordinary = botGroundMoveAllowed(g, me, from, to.key, 0);
if (!ordinary && !(markerPlanetologist &&
botGroundMoveAllowed(g, me, from, to.key, 0, 'range'))) continue;
actions.push({
type: 'move',
...(!ordinary ? { planetologist: 'range' } : {}),
forces: {},
noField: marker.tokenId,
event: noField.event,
territory: to.t,
sector: to.s,
});
// Bound legal choices after reachability, so unreachable high-ranked
// destinations cannot hide the only usable ordinary/skill route.
if (++markerMoves === 24) break;
}
}
// Generate paid Guild-source candidates before applying ordinary prices or Fremen range.
+6 -2
View File
@@ -17364,8 +17364,12 @@ function validatePlanetologistMove(g: Game, p: Player, move: Pick<MovementOrder,
'This Planetologist movement no longer has its living, uncaptured skilled leader.');
requireRule(planetologistMovementModeSupported(g),
'Planetologist movement combined with expansion factions is still being implemented.');
requireRule(!move.noField && !move.ornithopterEvent && !move.discoveryFlight,
'Planetologist combined with special movement cards or No-Field is still being implemented.');
requireRule(!move.ornithopterEvent && !move.discoveryFlight,
'Planetologist combined with special movement cards is still being implemented.');
// Selected composition: the concealed marker moves as one force, so the
// ordinary extra-range band applies without revealing or materializing it.
requireRule(!move.noField || skill.mode === 'range',
'Planetologist gathering with a No-Field is still being implemented.');
requireRule(skill.mode === 'gather'
? Array.isArray(move.origins) && move.origins.length === 2 && new Set(move.origins).size === 2 && move.origins[0] === move.origin
: move.origins === undefined,
+14 -8
View File
@@ -1095,6 +1095,7 @@ export const RULE_TOPICS: RuleTopic[] = [
steps: [
'Richese has three No-Fields, numbered zero, three and five. A concealed token counts as one force. Only one may be deployed on Arrakis, and consecutive own or allied shipments cannot use the same token.',
'A normal No-Field shipment pays the one-force price. The concealed token moves like a force. Before Battle, Richese may reveal it voluntarily; a token involved in battle is revealed with the Battle Plan. Revelation brings the indicated forces from reserves, limited by what remains there.',
'With a living, uncaptured Planetologist, your own concealed marker may provisionally use the ordinary extra-range alternative: one territory farther, capped at three. Select the marker alone or with physical forces from its own territory. It stays concealed, including zero, and spends one movement without materializing reserves. Two-origin gathering and special flight combinations remain unfinished.',
'The revealed token stays face up until another token is placed. Revealing it does not clear the previous-shipment restriction. An allied No-Field shipment reveals immediately and uses the ally’s reserves; an existing token must be revealed before another shipment.',
'Before an eligible ally uses its shipment, the game holds an offer opportunity for Richese. Richese may pass or privately propose a token, destination and payment. The ally accepts the exact offer and chooses its permitted regular/elite mix, or declines without payment. Success consumes the ally’s shipment, not Richese’s shipment or either player’s movement.',
'Ordinary allied shipment costs one spice into a stronghold or two elsewhere. Guild recipients and active purchased prices use the existing provisional bank-only discount. Canceling a native Guild recipient’s rate charges one full-price marker, never zero/five materialized forces. A supplier’s original whole-fee1 approval cannot silently become2; release unchanged and obtain a new full-price offer/consent. Independent purchased price remains. Fremen on-planet reserves stay ineligible.',
@@ -1123,36 +1124,41 @@ export const RULE_TOPICS: RuleTopic[] = [
area: 'Implementation',
status: 'Partial',
detail:
'Native lifecycle, additive pools, card funding and distinct special inspection remain. Current printed-value Truthtrance now reads only the respondent’s original concealed token, never reserves, allied variable armies or last-used history. Existing physical-force facts remain separate; card disposal resumes the original parent without model/event mutation.',
evidence: ['game/shipment-price.ts', 'game/engine.ts', 'game/truthtrance.ts', 'game/truthtrance-no-field-value.ts'],
'Native lifecycle, additive pools, card funding, distinct special inspection and current printed-value Truthtrance remain. Own concealed Planetologist extra-range movement uses current trainer/token/event and ordinary path/entry, preserving one movement, denomination and physical stocks. Gather/flight combinations remain open.',
evidence: ['game/shipment-price.ts', 'game/engine.ts', 'game/planetologist-movement.ts', 'game/bot-mobility.ts', 'game/truthtrance.ts', 'game/truthtrance-no-field-value.ts'],
},
{
area: 'Player controls',
status: 'Partial',
detail:
'Original inventory/card/inspection controls remain. The shared current-fact selector adds static0/3/5 printed-value controls with explicit absent-versus-zero and printed-versus-materialized explanation. Four actual390px query journeys include concealed0, exhausted5 AND physical0, undeployed0 and revealed5; native public reply/disposal returns to the same Shipment turn.',
evidence: ['components/richese-allied-no-field.tsx', 'components/richese-no-field.tsx', 'components/harass-withdraw.tsx', 'components/game-table.tsx', 'components/private-battle-plan.tsx', 'components/mixed-shipment-fields.tsx', 'components/truthtrance-no-field-value.tsx'],
'Original inventory/card/inspection and current-fact controls remain. Planetologist exposes the owner’s marker separately from same-origin counters, with provisional guidance and guarded actual submission. Marker-only selection creates no physical force count.',
evidence: ['components/richese-allied-no-field.tsx', 'components/richese-no-field.tsx', 'components/planetologist-movement.tsx', 'components/planetologist-movement-action.tsx', 'components/harass-withdraw.tsx', 'components/game-table.tsx', 'components/private-battle-plan.tsx', 'components/mixed-shipment-fields.tsx', 'components/truthtrance-no-field-value.tsx'],
},
{
area: 'AI',
status: 'Partial',
detail:
'Existing own/allied and special-inspection policies remain. All four profiles pass native Truthtrance priority and use the owner-only aggregate truthAnswer. Sixteen current programs accept48 policy actions, then continue original shipment, voluntary reveal or full-plan/battle into Collection. Question strategy and calibration remain deferred.',
'Existing own/allied, inspection and truthAnswer policies remain. All four minimal profiles may offer boosted own-marker routes through the shared normal geometry/entry quote and living trainer. Strategy and calibration remain deferred.',
evidence: ['game/bots.ts'],
},
{
area: 'Documentation',
status: 'Partial',
detail:
'The broad game-related yes/no authority and explicit current-observation/information-versus-component-revelation composition are recorded. Printed value, reserve cap, physical counter exclusion, ordinary Prescience, distinct special inspection and remaining future/module boundaries stay separate.',
evidence: ['docs/RICHESE_ALLIED_SHIPMENT_AUDIT.md', 'docs/GUILD_RATE_KARAMA_RULES.md', 'docs/RICHESE_NO_FIELD_RULES.md', 'docs/ATREIDES_FULL_PLAN_TIMING.md', 'docs/TRUTHTRANCE_FORCE_FACTS.md'],
'Current-observation, printed value and physical counter distinctions remain recorded. The marker-as-one-force plus Planetologist ordinary-range composition is explicitly provisional; no joint FAQ or complete combinations are claimed.',
evidence: ['docs/RICHESE_ALLIED_SHIPMENT_AUDIT.md', 'docs/GUILD_RATE_KARAMA_RULES.md', 'docs/RICHESE_NO_FIELD_RULES.md', 'docs/PLANETOLOGIST_RULES.md', 'docs/ATREIDES_FULL_PLAN_TIMING.md', 'docs/TRUTHTRANCE_FORCE_FACTS.md'],
},
{
area: 'Verification',
status: 'Partial',
detail:
'Twenty-three new focused/native fact cases and the23-file228/228 union cover0/3/5, empty/capped reserves, absence/history, actual allied owner isolation, truthful/compound replies and original continuation. Four mobile and16 policy programs are scoped current proof. Earlier inspection/allied/recovery evidence remains historical; no new complete-mode/deployed assurance.',
'Native trained-leader/shipment/movement cases and controlled submit callbacks cover the concealed Planetologist range route and legal continuation. Earlier scoped Truthtrance, inspection, allied and recovery evidence remains historical. Complete modes, broader combinations, browser/mobile/deployed and final assurance remain due.',
evidence: [
'tests/fixture-planetologist-no-field.ts',
'tests/planetologist-no-field-engine.test.ts',
'tests/planetologist-no-field-controls.test.tsx',
'tests/planetologist-movement.test.ts',
'tests/planetologist-movement-controls.test.tsx',
'tests/richese-no-field.test.ts',
'tests/richese-no-field-engine.test.ts',
'tests/richese-no-field-review.test.ts',