Reputation economy: rep-scaled buy/refuel discounts + job reward quality (ISS-072, v0.38.0)
CI / build + unit + e2e (pull_request) Successful in 9m3s
CI / build + unit + e2e (pull_request) Successful in 9m3s
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
import { useState } from 'react';
|
||||
import type { PackageState, PlaneState, StateSnapshot } from '@/lib/game/state';
|
||||
import { PLANE_TYPES, SELL_FRACTION } from '@/lib/game/catalog';
|
||||
import { MAX_PLANE_DISCOUNT, PLANE_DISCOUNT_PER_REP, PLANE_TYPES, repRate, SELL_FRACTION } from '@/lib/game/catalog';
|
||||
import { maxRangeKm } from '@/lib/sim/movement';
|
||||
import { formatCargo, formatCash, formatDeadlineRelative, formatSpecialLabel } from '@/lib/format';
|
||||
import { useGameAction } from '@/lib/useGameAction';
|
||||
@@ -151,6 +151,9 @@ export default function RightPane({ state, loading, applySnapshot, onHover, onEr
|
||||
// Previews computed client-side from the snapshot's catalog + economy constants (v0.10.0).
|
||||
const sellEntry = sellPlane ? catalog.find((e) => e.model === sellPlane.model) : undefined;
|
||||
const sellPayout = sellEntry ? Math.round(sellEntry.price * state.sellFraction * 100) / 100 : null;
|
||||
// v0.38.0 (ISS-072): the buy row shows the EFFECTIVE price — same rep-scaled formula as the server's buyPlane.
|
||||
const planeDiscountRate = repRate(state.account.reputation, PLANE_DISCOUNT_PER_REP, MAX_PLANE_DISCOUNT);
|
||||
const buyPrice = buyEntry ? Math.round(buyEntry.price * (1 - planeDiscountRate) * 100) / 100 : null;
|
||||
|
||||
return (
|
||||
<aside data-testid="right-pane" className="pane right-pane">
|
||||
@@ -265,8 +268,12 @@ export default function RightPane({ state, loading, applySnapshot, onHover, onEr
|
||||
))}
|
||||
</select>
|
||||
<span data-testid="market-buy-price" className="market-preview">
|
||||
{buyEntry ? formatCash(buyEntry.price) : ''}
|
||||
{buyPrice !== null ? formatCash(buyPrice) : ''}
|
||||
</span>
|
||||
{/* v0.38.0 (ISS-072): rep discount hint — only when the account actually gets one. */}
|
||||
{planeDiscountRate > 0 && (
|
||||
<span data-testid="market-buy-discount" className="special-badge">−{Math.round(planeDiscountRate * 100)}%</span>
|
||||
)}
|
||||
<button
|
||||
type="button"
|
||||
data-testid="market-buy"
|
||||
|
||||
Reference in New Issue
Block a user