deadhead-space-freight-tycoon/packages/sim/src/contract.ts

69 lines
2.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import type { CargoType, GameConfig } from "@deadhead/content";
import type { RealTime } from "./clock";
export interface Contract {
id: string;
originId: string;
destinationId: string;
/** The cargo class (decision 0.5.6). */
cargoTypeId: string;
/** The named good (CR-007, decision 0.5.54); its class is `cargoTypeId`. */
goodId: string;
/** Flavor: the company shipping it, from the origin's list (decision 0.5.58). */
shipper: string;
/** A Priority contract must arrive within its delivery window (decision 0.5.56). */
priority: boolean;
/** Priority only: the longest trip allowed, in game hours; null otherwise. */
deliveryWindowGameHours: number | null;
/**
* 0 for Standard; 1–5 otherwise, and equal to the required cargo-skill level
* (decision 0.5.6). High-Value and Dangerous take it from the good (0.5.55).
*/
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;
/** Set on a scripted tutorial contract (decision 0.5.33): its content id. */
scriptedId?: string;
}
export interface PayoutInput {
cargoType: CargoType;
/** The good's pay multiplier (CR-007). */
payMultiplier: number;
tier: number;
massTonnes: number;
/** Route distance at offer time. */
distanceMillionKm: number;
firstContact: boolean;
priority: boolean;
/** This contract's market rate around 1 (decision 0.5.60); 1 when absent. */
marketRate?: number;
}
/**
* Payout in whole credits: class base pay per tonne per million km × the good's
* pay multiplier × tierMultiplier^tier × mass × distance, × the first-contact
* multiplier and the Priority bonus when flagged (CR-007), × its market rate (CR-008).
*/
export function contractPayout(input: PayoutInput, config: GameConfig): number {
const { cargoType, payMultiplier, tier, massTonnes, distanceMillionKm, firstContact } = input;
const pay =
cargoType.basePayPerTonnePerMillionKm *
payMultiplier *
cargoType.tierPayMultiplier ** tier *
massTonnes *
distanceMillionKm *
(firstContact ? config.firstContactPayoutMultiplier : 1) *
(input.priority ? config.priorityPayoutMultiplier : 1) *
(input.marketRate ?? 1);
return Math.round(pay);
}