forked from fribbels/hsr-optimizer
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: prototype for the new optimizer system
see fribbels#173 for more details
- Loading branch information
Hà Trung Kiên
committed
Mar 15, 2024
1 parent
372f58f
commit 9c80f26
Showing
3 changed files
with
685 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
import { FinalStats } from './stats/stat' | ||
|
||
/** | ||
* Formula contains all the metadata that makes up the computation of an | ||
* {@link OptimizationTarget}. In particular, each formula provides information | ||
* about: | ||
* - How many calculation steps are there? | ||
* - How is each step computed? | ||
*/ | ||
export class Formula { | ||
/** | ||
* @param steps all {@link Step} that makes up this calculation | ||
*/ | ||
constructor(readonly steps: Step[]) {} | ||
|
||
/** | ||
* This method assumes the supplied multipliers array is always correct to | ||
* skip validations. | ||
* @param muls the final {@link FinalStats} to be used with each steps | ||
* @returns a result that can be used for comparision the value of a build | ||
* created by aggregating the result of each step. | ||
*/ | ||
calculate(muls: FinalStats[]): number { | ||
return this.steps.reduce( | ||
(prev, step, index) => prev + step.calculate(muls[index]), | ||
0, | ||
) | ||
} | ||
} | ||
|
||
export type StepBuilder = { | ||
// TODO | ||
} | ||
/** | ||
* A step contains the instruction to get the optimization target index that | ||
* could be used for comparision. Each step has a single final | ||
* {@link FinalStats} that it could works with, it cannot modify any stats. | ||
*/ | ||
type Step = { | ||
calculate(stat: FinalStats): number | ||
} | ||
|
||
export abstract class DamageStep implements Step { | ||
constructor(private broken: boolean) {} | ||
/* eslint-disable @stylistic/operator-linebreak */ | ||
calculate(stat: FinalStats): number { | ||
return ( | ||
this.base(stat) * | ||
this.def( | ||
stat.basic.lv, | ||
stat.targetDef.baseDef, | ||
stat.targetDef.percent, | ||
stat.targetDef.flat, | ||
) * | ||
Math.min(Math.max(1 - stat.res, 0.1), 2) * | ||
this.dmgBoost(stat.dmgBoost) * | ||
Math.min(1 + stat.vulnerability, 3.5) * | ||
(this.broken ? 1 : 0.9) * | ||
this.crit(stat.crit.critRate, stat.crit.critDmg) * | ||
this.dmgReduction(stat.dmgReductions) | ||
) | ||
} | ||
/* eslint-enable @stylistic/operator-linebreak */ | ||
|
||
protected abstract base(stat: FinalStats): number | ||
|
||
protected dmgBoost(percent: number) { | ||
return 1 + percent | ||
} | ||
|
||
protected dmgReduction(reductions: number[]) { | ||
return reductions.reduce((prev, val) => prev * (1 - val), 1) | ||
} | ||
|
||
protected crit(critRate: number, critDmg: number) { | ||
return 1 + Math.min(1, critRate) * critDmg | ||
} | ||
|
||
private def( | ||
sourceLv: number, | ||
baseDef: number, | ||
percent: number, | ||
flat: number, | ||
) { | ||
const def = Math.max(baseDef * (1 + percent) + flat, 0) | ||
return 1 - def / (def + 200 + 10 * sourceLv) | ||
} | ||
} | ||
|
||
export class NormalDamageStep extends DamageStep { | ||
constructor( | ||
broken: boolean, | ||
private multiplier: number, | ||
private type: 'ATK' | 'HP' | 'DEF', | ||
private flat: number, | ||
) { | ||
super(broken) | ||
} | ||
|
||
protected override base(stat: FinalStats): number { | ||
return this.multiplier * stat.basic[this.type] + this.flat | ||
} | ||
} | ||
|
||
/* eslint-disable @typescript-eslint/no-unused-vars */ | ||
// This rule is poorly configured | ||
export class DotDamageStep extends NormalDamageStep { | ||
protected override crit(_cr: number, _cd: number): number { | ||
return 1 | ||
} | ||
} | ||
|
||
export class BreakDamage extends DotDamageStep { | ||
protected dmgBoost(_: number): number { | ||
return 1 | ||
} | ||
|
||
protected dmgReduction(_s: number[]): number { | ||
return 1 | ||
} | ||
} | ||
/* eslint-enable @typescript-eslint/no-unused-vars */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
type __Elements = { | ||
physical | ||
lightning | ||
fire | ||
wind | ||
ice | ||
quantum | ||
imaginary | ||
} | ||
|
||
export enum Elements { | ||
PHYSICAL, | ||
LIGHTING, | ||
FIRE, | ||
WIND, | ||
ICE, | ||
QUANTUM, | ||
IMAGINARY, | ||
} | ||
|
||
export enum Traits { | ||
NORMAL, | ||
SKILL, | ||
ULTIMATE, | ||
FOLLOW_UP, | ||
DOT, | ||
DOT_BLEED, | ||
DOT_BURN, | ||
DOT_WIND_SHEAR, | ||
DOT_SHOCK, | ||
DELAY, | ||
DELAY_FREEZE, | ||
DELAY_ENTANGLEMENT, | ||
} | ||
|
||
type __Traits = { | ||
normal | ||
skill | ||
ultimate | ||
followUp | ||
dot: { | ||
all | ||
bleed | ||
burn | ||
windShear | ||
shock | ||
} | ||
delayDamage: { | ||
all | ||
freeze | ||
entanglement | ||
} | ||
} | ||
export type Conditional<TRAIT, ELEMENT> = { | ||
traits: { | ||
[K in keyof __Traits]: K extends 'dot' | 'delayDamage' | ||
? { [T in keyof __Traits[K]]: TRAIT } | ||
: TRAIT | ||
} | ||
elements: { | ||
[K in keyof __Elements]: ELEMENT | ||
} | ||
} |
Oops, something went wrong.