+145
-2
@@ -107,6 +107,42 @@ const speedStrategyPhaseCoeff = [
|
||||
|
||||
const distanceProficiencyMod = [0.1, 0.2, 0.4, 0.6, 0.8, 0.9, 1.0, 1.05] as const;
|
||||
|
||||
/**
|
||||
* Get a horse's base target speed outside of late race.
|
||||
* @param raceLen Length of the race in meters
|
||||
* @param style Horse's running style
|
||||
* @param phase Phase to calculate for
|
||||
*/
|
||||
export function baseTargetSpeed(raceLen: number, style: RunningStyle, phase: Exclude<Phase, Phase.LateRace>): number;
|
||||
/**
|
||||
* Get a horse's base target speed when not spurting during late race.
|
||||
* @param raceLen Length of the race in meters
|
||||
* @param style Horse's running style
|
||||
* @param phase Phase to calculate for
|
||||
* @param speedStat Final speed stat
|
||||
* @param distanceApt Horse's aptitude for the distance
|
||||
*/
|
||||
export function baseTargetSpeed(
|
||||
raceLen: number,
|
||||
style: RunningStyle,
|
||||
phase: Phase.LateRace,
|
||||
speedStat: number,
|
||||
distanceApt: AptitudeLevel,
|
||||
): number;
|
||||
export function baseTargetSpeed(
|
||||
raceLen: number,
|
||||
style: RunningStyle,
|
||||
phase: Phase,
|
||||
speedStat?: number,
|
||||
distanceApt?: number,
|
||||
): number {
|
||||
const base = baseSpeed(raceLen);
|
||||
const baseTarget = base * speedStrategyPhaseCoeff[style][phase];
|
||||
const late =
|
||||
phase === Phase.LateRace ? (math.sqrt(500 * speedStat!) as number) * distanceProficiencyMod[distanceApt!] * 0.002 : 0;
|
||||
return baseTarget + late;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the range of section speed values for a horse in early or mid race.
|
||||
* @param raceLen Length of the race in meters
|
||||
@@ -224,6 +260,25 @@ export function inverseSpurtSpeed(
|
||||
return Math.round(r);
|
||||
}
|
||||
|
||||
const hpStrategyCoeff = {
|
||||
[RunningStyle.FrontRunner]: 0.95,
|
||||
[RunningStyle.PaceChaser]: 0.89,
|
||||
[RunningStyle.LateSurger]: 1.0,
|
||||
[RunningStyle.EndCloser]: 0.995,
|
||||
[RunningStyle.GreatEscape]: 0.86,
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* Calculate a horse's max HP (starting HP) for a race.
|
||||
* @param raceLen Length of the race in meters
|
||||
* @param style Horse's running style
|
||||
* @param stamStat Final stamina stat
|
||||
* @returns Max HP
|
||||
*/
|
||||
export function maxHP(raceLen: number, style: RunningStyle, stamStat: number): number {
|
||||
return 0.8 * hpStrategyCoeff[style] * stamStat + raceLen;
|
||||
}
|
||||
|
||||
/** Meters per horse length (馬身). */
|
||||
export const HORSE_LENGTH = 2.5;
|
||||
/** Meters per course width (a constant unit of measure). */
|
||||
@@ -295,6 +350,57 @@ export function deceleration(phase: Phase, pdm?: boolean, dead?: boolean): numbe
|
||||
return phaseDecel[phase];
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate a horse's lane change target speed before the first move lane point.
|
||||
* @param powerStat Final power stat
|
||||
* @param maxLane Max lane value on the race track in CW
|
||||
* @param currentLane Current lane on the race track in CW
|
||||
* @returns Lane change speed in CW/s
|
||||
*/
|
||||
export function laneChangeSpeed(powerStat: number, maxLane: number, currentLane: number): number;
|
||||
/**
|
||||
* Calculate a horse's lane change target speed during late race and final spurt phase.
|
||||
* @param powerStat Final power stat
|
||||
* @param order Current order on the field
|
||||
* @returns Lane change speed in CW/s
|
||||
*/
|
||||
export function laneChangeSpeed(powerStat: number, order: number): number;
|
||||
/**
|
||||
* Calculate a horse's lane change target speed between the first move lane point and late race.
|
||||
* @param powerStat Final power stat
|
||||
* @returns Lane change speed in CW/s
|
||||
*/
|
||||
export function laneChangeSpeed(powerStat: number): number;
|
||||
export function laneChangeSpeed(powerStat: number, maxLaneOrOrder?: number, currentLane?: number): number {
|
||||
const laneMod = currentLane != null ? 1 + (currentLane / maxLaneOrOrder!) * 0.05 : 1;
|
||||
const orderMod = currentLane == null ? 1 + (maxLaneOrOrder ?? 0) * 0.05 : 1;
|
||||
return 0.02 * (0.3 + 0.001 * powerStat) * laneMod * orderMod;
|
||||
}
|
||||
|
||||
/**
|
||||
* Acceleration of lane change (horizontal) current speed.
|
||||
*/
|
||||
export const LANE_CHANGE_ACCEL = 0.03;
|
||||
|
||||
/**
|
||||
* Calculate a horse's minimum speed for a race.
|
||||
* @param raceLen Length of the race in meters
|
||||
* @param gutsStat Final guts stat
|
||||
* @returns Minimum speed in m/s
|
||||
*/
|
||||
export function minSpeed(raceLen: number, gutsStat: number): number {
|
||||
return 0.85 * baseSpeed(raceLen) + Math.sqrt(200 * gutsStat) * 0.001;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate a horse's HP consumption multiplier for late race and last spurt phase.
|
||||
* @param gutsStat Final guts stat
|
||||
* @returns HP consumption multiplier
|
||||
*/
|
||||
export function spurtHPRateMod(gutsStat: number): number {
|
||||
return 1 + 200 / Math.sqrt(600 * gutsStat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the speed boost gained from spot struggle.
|
||||
* @param gutsStat Final guts stat
|
||||
@@ -319,6 +425,24 @@ export function spotStruggleDuration(gutsStat: number, frontAptitude: AptitudeLe
|
||||
return Math.sqrt(700 * gutsStat) * 0.012 * strategyProficiencyMod[frontAptitude];
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the target speed bonus of dueling.
|
||||
* @param gutsStat Final guts stat
|
||||
* @returns Modifier to target speed while dueling in m/s
|
||||
*/
|
||||
export function duelSpeedMod(gutsStat: number): number {
|
||||
return Math.pow(200 * gutsStat, 0.708) * 0.0001;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the acceleration bonus of dueling.
|
||||
* @param gutsStat Final guts stat
|
||||
* @returns Modifier to acceleration while dueling in m/s²
|
||||
*/
|
||||
export function duelAccelMod(gutsStat: number): number {
|
||||
return Math.pow(160 * gutsStat, 0.59) * 0.0001;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the speed modifier for running uphill.
|
||||
* Contrary to the race mechanics document, this is expressed as a negative number.
|
||||
@@ -348,7 +472,7 @@ export function moveLaneModifier(powerStat: number): number {
|
||||
* @returns Probability of exactly n skills out of N passing wit checks
|
||||
*/
|
||||
export function skillWitCheck(baseWit: number, N?: number, n?: number): number {
|
||||
const p = Math.max(0.2, 1 - 90 / baseWit);
|
||||
const p = Math.ceil(Math.max(20, 100 - 9000 / baseWit)) / 100;
|
||||
return binomPMF(p, N ?? 1, n ?? 1);
|
||||
}
|
||||
|
||||
@@ -389,13 +513,22 @@ export function speedGain(speedBonus: number, dur: number, accel: number | null,
|
||||
return speedBonus * (dur + 0.5 * (decelTime - accelTime));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the probability of accepting a reduced spurt candidate.
|
||||
* @param witStat Final wit stat
|
||||
* @returns Probability per candidate to accept
|
||||
*/
|
||||
export function reducedSpurtChance(witStat: number): number {
|
||||
return Math.ceil(15 + 0.05 * witStat) / 100;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the chance to enter downhill accel mode each second while running downhill.
|
||||
* @param witStat Final wit stat, including style aptitude modifier
|
||||
* @returns Probability each eligible tick to enter downhill accel mode
|
||||
*/
|
||||
export function downhillAccelEnterChance(witStat: number): number {
|
||||
return witStat * 0.0004;
|
||||
return Math.ceil(witStat * 0.04) / 100;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -415,3 +548,13 @@ export function frontModeEnterChance(witStat: number): number {
|
||||
export function paceUpEnterChance(witStat: number): number {
|
||||
return 0.15 * math.log10(witStat) - 0.15;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the chance for a horse to become rushed during a given race.
|
||||
* @param witStat Final wit stat, including style aptitude modifier
|
||||
* @returns Probability to become rushed during the race
|
||||
*/
|
||||
export function rushedChance(witStat: number): number {
|
||||
const r = 6.5 / Math.log10(0.1 * witStat + 1);
|
||||
return Math.ceil(r * r) / 100;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user