wip(calc): world step calculation

This commit is contained in:
283375 2023-09-18 09:25:15 +08:00
parent c6014bd1b6
commit a97031e717
Signed by: 283375
SSH Key Fingerprint: SHA256:UcX0qg6ZOSDOeieKPGokA5h7soykG61nz2uxuQgVLSk

View File

@ -0,0 +1,150 @@
from decimal import Decimal
from typing import Literal, Optional, Union
class PlayResults:
def __init__(
self,
*,
potential: Union[Decimal, str, float, int],
partner_step: Union[Decimal, str, float, int],
):
self.__potential = potential
self.__partner_step = partner_step
@property
def potential(self):
return Decimal(self.__potential)
@property
def partner_step(self):
return Decimal(self.__partner_step)
class PartnerBonus:
def __init__(
self,
*,
step_bonus: Union[Decimal, str, float, int] = Decimal("1.0"),
final_multiplier: Union[Decimal, str, float, int] = Decimal("1.0"),
):
self.__step_bonus = step_bonus
self.__final_multiplier = final_multiplier
@property
def step_bonus(self):
return Decimal(self.__step_bonus)
@property
def final_multiplier(self):
return Decimal(self.__final_multiplier)
AwakenedIlithPartnerBonus = PartnerBonus(step_bonus="6.0")
AwakenedEtoPartnerBonus = PartnerBonus(step_bonus="7.0")
AwakenedLunaPartnerBonus = PartnerBonus(step_bonus="7.0")
class AwakenedAyuPartnerBonus(PartnerBonus):
def __init__(self, step_bonus: Union[Decimal, str, float, int]):
super().__init__(step_bonus=step_bonus)
AmaneBelowExPartnerBonus = PartnerBonus(final_multiplier="0.5")
class MithraTerceraPartnerBonus(PartnerBonus):
def __init__(self, step_bonus: int):
super().__init__(step_bonus=step_bonus)
MayaPartnerBonus = PartnerBonus(final_multiplier="2.0")
class StepBooster:
def final_value(self) -> Decimal:
raise NotImplementedError()
class LegacyMapStepBooster(StepBooster):
def __init__(
self,
stamina: Literal[2, 4, 6],
fragments: Literal[100, 250, 500, None],
):
self.stamina = stamina
self.fragments = fragments
@property
def stamina(self):
return self.__stamina
@stamina.setter
def stamina(self, value: Literal[2, 4, 6]):
if value not in [2, 4, 6]:
raise ValueError("stamina can only be one of [2, 4, 6]")
self.__stamina = value
@property
def fragments(self):
return self.__fragments
@fragments.setter
def fragments(self, value: Literal[100, 250, 500, None]):
if value not in [100, 250, 500, None]:
raise ValueError("fragments can only be one of [100, 250, 500, None]")
self.__fragments = value
def final_value(self) -> Decimal:
stamina_multiplier = Decimal(self.stamina)
if self.fragments is None:
fragments_multiplier = Decimal(1)
elif self.fragments == 100:
fragments_multiplier = Decimal("1.1")
elif self.fragments == 250:
fragments_multiplier = Decimal("1.25")
elif self.fragments == 500:
fragments_multiplier = Decimal("1.5")
return stamina_multiplier * fragments_multiplier
class MemoriesStepBooster(StepBooster):
def final_value(self) -> Decimal:
return Decimal("4.0")
def calculate_step_original(
play_results: PlayResults,
*,
partner_bonus: Optional[PartnerBonus] = None,
booster: Optional[StepBooster] = None,
):
ptt = play_results.potential
step = play_results.partner_step
if partner_bonus:
partner_bonus_step = partner_bonus.step_bonus
partner_bonus_multiplier = partner_bonus.final_multiplier
else:
partner_bonus_step = Decimal("0")
partner_bonus_multiplier = Decimal("1.0")
play_result = (Decimal("2.45") * ptt.sqrt() + Decimal("2.5")) * (step / 50)
play_result += partner_bonus_step
play_result *= partner_bonus_multiplier
if booster:
play_result *= booster.final_value()
return play_result
def calculate_step(
play_results: PlayResults,
*,
partner_bonus: Optional[PartnerBonus] = None,
booster: Optional[StepBooster] = None,
):
play_result_original = calculate_step_original(
play_results, partner_bonus=partner_bonus, booster=booster
)
return round(play_result_original, 1)