import type { CargoType, GameConfig } from "@deadhead/content"; import type { RealTime } from "./clock"; export interface Contract { id: string; originId: string; destinationId: string; cargoTypeId: string; /** 0 for Standard; 1–5 otherwise, and equal to the required cargo-skill level (decision 0.5.6). */ tier: number; massTonnes: number; /** Credits, fixed at offer time (decision 0.5.11). */ payout: number; /** Cargo skill and level needed; null for Standard. */ requiredSkill: { skillId: string; level: number } | null; requiredLongHaulLevel: number; offeredAt: RealTime; /** End of the board period the contract was offered in. */ expiresAt: RealTime; firstContact: boolean; } export interface PayoutInput { cargoType: CargoType; tier: number; massTonnes: number; /** Route distance at offer time. */ distanceMillionKm: number; firstContact: boolean; } /** * Payout in whole credits: base pay per tonne per million km × tierMultiplier^tier * × mass × distance, × the first-contact multiplier when flagged. */ export function contractPayout(input: PayoutInput, config: GameConfig): number { const { cargoType, tier, massTonnes, distanceMillionKm, firstContact } = input; const pay = cargoType.basePayPerTonnePerMillionKm * cargoType.tierPayMultiplier ** tier * massTonnes * distanceMillionKm * (firstContact ? config.firstContactPayoutMultiplier : 1); return Math.round(pay); }