You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
75 lines
2.9 KiB
75 lines
2.9 KiB
import { oppositePlayer, PlayerSide, RoundStarter } from './gameState'
|
|
|
|
export function calculateDamage(
|
|
delta: number,
|
|
player: { readonly damageBonuses: number },
|
|
difficulty: { readonly damageBonusBase?: number; readonly damageBonusIncrement?: number },
|
|
): number {
|
|
return Math.round(
|
|
(delta *
|
|
((difficulty.damageBonusBase ?? 100) + player.damageBonuses * (difficulty.damageBonusIncrement ?? 10))) /
|
|
100,
|
|
)
|
|
}
|
|
|
|
export function calculateStops(
|
|
player: { readonly stopCount: number },
|
|
difficulty: { readonly maxStopCount?: number },
|
|
): number {
|
|
return Math.min(player.stopCount + 1, difficulty.maxStopCount ?? Number.MAX_SAFE_INTEGER)
|
|
}
|
|
|
|
export function calculateFails(
|
|
player: { readonly failCount: number },
|
|
difficulty: { readonly minFailCount?: number },
|
|
): number {
|
|
return Math.max(player.failCount - 1, difficulty.minFailCount ?? 1)
|
|
}
|
|
|
|
export function calculateBonuses(
|
|
player: { readonly damageBonuses: number },
|
|
difficulty: { readonly maxDamageBonuses?: number },
|
|
): number {
|
|
return Math.max(player.damageBonuses + 1, difficulty.maxDamageBonuses ?? Number.MAX_SAFE_INTEGER)
|
|
}
|
|
|
|
export function calculateRecovery(
|
|
victim: { readonly damageTotal: number },
|
|
recoverer: { readonly damage: number; readonly nextRecoverAt: number; readonly timesRecovered: number },
|
|
difficulty: {
|
|
readonly recoverBase?: number
|
|
readonly recoverIncrement?: number
|
|
readonly recoverPercentBase?: number
|
|
readonly recoverPercentIncrement?: number
|
|
},
|
|
): number {
|
|
const { damageTotal } = victim
|
|
let { damage, nextRecoverAt, timesRecovered } = recoverer
|
|
const { recoverBase = 0, recoverIncrement = 0, recoverPercentBase = 50, recoverPercentIncrement = 0 } = difficulty
|
|
let recoverPercent = Math.max(0, recoverPercentBase + recoverPercentIncrement * timesRecovered)
|
|
while (nextRecoverAt !== 0 && damageTotal >= nextRecoverAt && recoverPercent > 0) {
|
|
recoverPercent = Math.max(0, recoverPercentBase + recoverPercentIncrement * timesRecovered)
|
|
nextRecoverAt = recoverBase === 0 ? 0 : nextRecoverAt + recoverBase + recoverIncrement * timesRecovered
|
|
timesRecovered += 1
|
|
damage = Math.max(0, Math.round((damage * (100 - recoverPercent)) / 100))
|
|
}
|
|
return damage
|
|
}
|
|
|
|
export function determineNextRoundStarter(
|
|
game: { readonly phaseOwner: PlayerSide; readonly roundOwner: PlayerSide },
|
|
difficulty: { readonly roundStarter?: PlayerSide | RoundStarter },
|
|
): PlayerSide {
|
|
switch (difficulty.roundStarter ?? RoundStarter.ALTERNATE) {
|
|
case PlayerSide.TOP:
|
|
return PlayerSide.TOP
|
|
case PlayerSide.BOTTOM:
|
|
return PlayerSide.BOTTOM
|
|
case RoundStarter.LAST_ROUND_LOSER:
|
|
return game.phaseOwner
|
|
case RoundStarter.LAST_ROUND_WINNER:
|
|
return oppositePlayer(game.phaseOwner)
|
|
case RoundStarter.ALTERNATE:
|
|
return oppositePlayer(game.roundOwner)
|
|
}
|
|
}
|
|
|