|
1 |
| -import typing |
| 1 | +from dataclasses import dataclass, fields |
| 2 | +from typing import Any, cast, Dict, Iterator, List, Tuple, Protocol |
2 | 3 |
|
3 |
| -from Options import Range, Choice, Toggle, DefaultOnToggle, AssembleOptions, DeathLink, ProgressionBalancing |
| 4 | +from Options import AssembleOptions, Choice, DeathLink, DefaultOnToggle, PerGameCommonOptions, ProgressionBalancing, \ |
| 5 | + Range, Toggle |
4 | 6 |
|
5 | 7 |
|
6 | 8 | # typing boilerplate
|
7 |
| -class FlagsProtocol(typing.Protocol): |
| 9 | +class FlagsProtocol(Protocol): |
8 | 10 | value: int
|
9 | 11 | default: int
|
10 |
| - flags: typing.List[str] |
| 12 | + flags: List[str] |
11 | 13 |
|
12 | 14 |
|
13 |
| -class FlagProtocol(typing.Protocol): |
| 15 | +class FlagProtocol(Protocol): |
14 | 16 | value: int
|
15 | 17 | default: int
|
16 | 18 | flag: str
|
17 | 19 |
|
18 | 20 |
|
19 | 21 | # meta options
|
20 | 22 | class EvermizerFlags:
|
21 |
| - flags: typing.List[str] |
| 23 | + flags: List[str] |
22 | 24 |
|
23 | 25 | def to_flag(self: FlagsProtocol) -> str:
|
24 | 26 | return self.flags[self.value]
|
@@ -200,13 +202,13 @@ class TrapCount(Range):
|
200 | 202 |
|
201 | 203 | # more meta options
|
202 | 204 | class ItemChanceMeta(AssembleOptions):
|
203 |
| - def __new__(mcs, name, bases, attrs): |
| 205 | + def __new__(mcs, name: str, bases: Tuple[type], attrs: Dict[Any, Any]) -> "ItemChanceMeta": |
204 | 206 | if 'item_name' in attrs:
|
205 | 207 | attrs["display_name"] = f"{attrs['item_name']} Chance"
|
206 | 208 | attrs["range_start"] = 0
|
207 | 209 | attrs["range_end"] = 100
|
208 |
| - |
209 |
| - return super(ItemChanceMeta, mcs).__new__(mcs, name, bases, attrs) |
| 210 | + cls = super(ItemChanceMeta, mcs).__new__(mcs, name, bases, attrs) |
| 211 | + return cast(ItemChanceMeta, cls) |
210 | 212 |
|
211 | 213 |
|
212 | 214 | class TrapChance(Range, metaclass=ItemChanceMeta):
|
@@ -247,33 +249,50 @@ class SoEProgressionBalancing(ProgressionBalancing):
|
247 | 249 | special_range_names = {**ProgressionBalancing.special_range_names, "normal": default}
|
248 | 250 |
|
249 | 251 |
|
250 |
| -soe_options: typing.Dict[str, AssembleOptions] = { |
251 |
| - "difficulty": Difficulty, |
252 |
| - "energy_core": EnergyCore, |
253 |
| - "required_fragments": RequiredFragments, |
254 |
| - "available_fragments": AvailableFragments, |
255 |
| - "money_modifier": MoneyModifier, |
256 |
| - "exp_modifier": ExpModifier, |
257 |
| - "sequence_breaks": SequenceBreaks, |
258 |
| - "out_of_bounds": OutOfBounds, |
259 |
| - "fix_cheats": FixCheats, |
260 |
| - "fix_infinite_ammo": FixInfiniteAmmo, |
261 |
| - "fix_atlas_glitch": FixAtlasGlitch, |
262 |
| - "fix_wings_glitch": FixWingsGlitch, |
263 |
| - "shorter_dialogs": ShorterDialogs, |
264 |
| - "short_boss_rush": ShortBossRush, |
265 |
| - "ingredienizer": Ingredienizer, |
266 |
| - "sniffamizer": Sniffamizer, |
267 |
| - "callbeadamizer": Callbeadamizer, |
268 |
| - "musicmizer": Musicmizer, |
269 |
| - "doggomizer": Doggomizer, |
270 |
| - "turdo_mode": TurdoMode, |
271 |
| - "death_link": DeathLink, |
272 |
| - "trap_count": TrapCount, |
273 |
| - "trap_chance_quake": TrapChanceQuake, |
274 |
| - "trap_chance_poison": TrapChancePoison, |
275 |
| - "trap_chance_confound": TrapChanceConfound, |
276 |
| - "trap_chance_hud": TrapChanceHUD, |
277 |
| - "trap_chance_ohko": TrapChanceOHKO, |
278 |
| - "progression_balancing": SoEProgressionBalancing, |
279 |
| -} |
| 252 | +# noinspection SpellCheckingInspection |
| 253 | +@dataclass |
| 254 | +class SoEOptions(PerGameCommonOptions): |
| 255 | + difficulty: Difficulty |
| 256 | + energy_core: EnergyCore |
| 257 | + required_fragments: RequiredFragments |
| 258 | + available_fragments: AvailableFragments |
| 259 | + money_modifier: MoneyModifier |
| 260 | + exp_modifier: ExpModifier |
| 261 | + sequence_breaks: SequenceBreaks |
| 262 | + out_of_bounds: OutOfBounds |
| 263 | + fix_cheats: FixCheats |
| 264 | + fix_infinite_ammo: FixInfiniteAmmo |
| 265 | + fix_atlas_glitch: FixAtlasGlitch |
| 266 | + fix_wings_glitch: FixWingsGlitch |
| 267 | + shorter_dialogs: ShorterDialogs |
| 268 | + short_boss_rush: ShortBossRush |
| 269 | + ingredienizer: Ingredienizer |
| 270 | + sniffamizer: Sniffamizer |
| 271 | + callbeadamizer: Callbeadamizer |
| 272 | + musicmizer: Musicmizer |
| 273 | + doggomizer: Doggomizer |
| 274 | + turdo_mode: TurdoMode |
| 275 | + death_link: DeathLink |
| 276 | + trap_count: TrapCount |
| 277 | + trap_chance_quake: TrapChanceQuake |
| 278 | + trap_chance_poison: TrapChancePoison |
| 279 | + trap_chance_confound: TrapChanceConfound |
| 280 | + trap_chance_hud: TrapChanceHUD |
| 281 | + trap_chance_ohko: TrapChanceOHKO |
| 282 | + progression_balancing: SoEProgressionBalancing |
| 283 | + |
| 284 | + @property |
| 285 | + def trap_chances(self) -> Iterator[TrapChance]: |
| 286 | + for field in fields(self): |
| 287 | + option = getattr(self, field.name) |
| 288 | + if isinstance(option, TrapChance): |
| 289 | + yield option |
| 290 | + |
| 291 | + @property |
| 292 | + def flags(self) -> str: |
| 293 | + flags = '' |
| 294 | + for field in fields(self): |
| 295 | + option = getattr(self, field.name) |
| 296 | + if isinstance(option, (EvermizerFlag, EvermizerFlags)): |
| 297 | + flags += getattr(self, field.name).to_flag() |
| 298 | + return flags |
0 commit comments