74 lines
2.6 KiB
TypeScript
74 lines
2.6 KiB
TypeScript
const placementPms = [1000, 400, 250, 150, 100, 90, 80, 70, 60, 50, 40, 30, 25, 20, 15, 10, 10, 10] as const;
|
|
|
|
/**
|
|
* Calculate base fans for a given placement in a race.
|
|
* @param winBase Base fans for a win, as displayed in the race menu
|
|
* @param finishOrder Placement of the trainee, with winner being 1
|
|
* @returns Base fans for the race and placement together
|
|
*/
|
|
export function baseFans(winBase: number, finishOrder: number): number {
|
|
return Math.round(winBase * placementPms[finishOrder - 1] / 1000);
|
|
}
|
|
|
|
const margins = [
|
|
[0.75, 0.0, 0.09],
|
|
[2.5, 0.02, 0.06],
|
|
[4, 0.04, 0.04],
|
|
[6, 0.06, 0.02],
|
|
[Infinity, 0.09, 0.0],
|
|
] as const;
|
|
|
|
/**
|
|
* Calculate fans gained from a career race due to the margin of the finish.
|
|
* @param baseFans Base fans from the race and finish order
|
|
* @param finishOrder Placement of the trainee, with winner being 1
|
|
* @param margin Margin in lengths between the trainee and second if a win, or the winner and trainee if a loss
|
|
* @returns Fans gained due to finish margin
|
|
*/
|
|
export function marginFans(baseFans: number, finishOrder: number, margin: number): number {
|
|
if (finishOrder > 5) {
|
|
return 0;
|
|
}
|
|
const [, wb, lb] = margins.find(([m]) => margin <= m)!;
|
|
const b = finishOrder === 1 ? wb : lb;
|
|
return Math.floor(baseFans * b);
|
|
}
|
|
|
|
const skills = [
|
|
[0, 0.0],
|
|
[3, 0.02],
|
|
[6, 0.03],
|
|
[9, 0.05],
|
|
[Infinity, 0.08],
|
|
] as const;
|
|
|
|
/**
|
|
* Calculate the fans gained from a career race due to skills activated.
|
|
* @param baseFans Base fans from the race and finish order
|
|
* @param skillsActivated Number of skills the trainee activated during the race
|
|
* @returns Fans gained due to skill activations
|
|
*/
|
|
export function skillFans(baseFans: number, skillsActivated: number): number {
|
|
const [, b] = skills.find(([n]) => skillsActivated <= n)!;
|
|
return Math.floor(baseFans * b);
|
|
}
|
|
|
|
/**
|
|
* Calculate fan gain from a career race.
|
|
* @param baseFans Base fans from the race and finish order
|
|
* @param marginFans Fans gained due to finish margin
|
|
* @param skillFans Fans gained due to skill activations
|
|
* @param fanBonus Total fan bonus from support cards
|
|
* @param itemBonus Fan bonus from items (MANT glowsticks)
|
|
* @returns Total fans gained
|
|
*/
|
|
export function gained(baseFans: number, marginFans: number, skillFans: number, fanBonus: number, itemBonus?: number): number {
|
|
const f = baseFans + marginFans + skillFans;
|
|
const s = Math.fround(f * Math.fround(1 + fanBonus / 100));
|
|
const p = Math.exp((4 - Math.floor(Math.log10(s))) * Math.LN10);
|
|
// Add half a significant figure to account for precision.
|
|
const d = Math.floor(Math.round(s * p + 5e-6) / p + 5e-6);
|
|
const b = itemBonus ?? 0;
|
|
return Math.floor(d * (1 + b / 100));
|
|
}
|