Files
Flight-Ops/lib/game/penalty.ts
T

33 lines
1.7 KiB
TypeScript
Raw Permalink 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.
// Abandon penalty (v0.12.0) — dropping a loaded package costs a fraction of its
// payout that grows with time pressure: 15% right after creation, up to 60% at
// the deadline. Pure function shared by the server action (lib/game/actions.ts)
// and the client-side preview in components/RightPane.tsx so both always agree.
export const ABANDON_PENALTY_MIN = 0.15; // fraction of the payout, at creation time
export const ABANDON_PENALTY_SPAN = 0.45; // added across the package's lifetime → max 60% at the deadline
// The penalty fraction for a given elapsedFraction ∈ [0, 1] (clamped).
export function abandonPenaltyPct(elapsedFraction: number): number {
const f = Math.min(1, Math.max(0, elapsedFraction));
return ABANDON_PENALTY_MIN + ABANDON_PENALTY_SPAN * f;
}
// How much of the package's lifetime has elapsed at clockMs (clamped to [0, 1]).
export function elapsedFractionFor(createdSimTime: number, deadlineSimTime: number, clockMs: number): number {
const span = deadlineSimTime - createdSimTime;
if (span <= 0) return 1; // degenerate — treat as fully elapsed (max penalty)
return Math.min(1, Math.max(0, (clockMs - createdSimTime) / span));
}
// The exact € penalty for abandoning `pkg` at game time clockMs. An already-
// EXPIRED package abandons for free; cash is floored at 0 by the caller
// (account.cash = max(0, cash − penalty)). Rounded to cents like all money math.
export function abandonPenalty(
pkg: { status: string; reward: number; createdSimTime: number; deadlineSimTime: number },
clockMs: number,
): number {
if (pkg.status === 'expired') return 0;
const pct = abandonPenaltyPct(elapsedFractionFor(pkg.createdSimTime, pkg.deadlineSimTime, clockMs));
return Math.round(pkg.reward * pct * 100) / 100;
}