2022-10-21 21:26:40 +00:00
|
|
|
from typing import Protocol, Set
|
|
|
|
|
2021-09-29 07:12:23 +00:00
|
|
|
from BaseClasses import MultiWorld
|
2022-10-21 21:26:40 +00:00
|
|
|
from worlds.AutoWorld import LogicMixin
|
|
|
|
from . import pyevermizer
|
2023-10-08 15:27:05 +00:00
|
|
|
from .Options import EnergyCore, OutOfBounds, SequenceBreaks
|
2021-09-29 07:12:23 +00:00
|
|
|
|
2022-10-21 21:26:40 +00:00
|
|
|
# TODO: Options may preset certain progress steps (i.e. P_ROCK_SKIP), set in generate_early?
|
2021-09-29 07:12:23 +00:00
|
|
|
|
|
|
|
# TODO: resolve/flatten/expand rules to get rid of recursion below where possible
|
|
|
|
# Logic.rules are all rules including locations, excluding those with no progress (i.e. locations that only drop items)
|
|
|
|
rules = [rule for rule in pyevermizer.get_logic() if len(rule.provides) > 0]
|
2022-07-15 16:01:07 +00:00
|
|
|
# Logic.items are all items and extra items excluding non-progression items and duplicates
|
2021-09-29 07:12:23 +00:00
|
|
|
item_names: Set[str] = set()
|
2022-07-15 16:01:07 +00:00
|
|
|
items = [item for item in filter(lambda item: item.progression, pyevermizer.get_items() + pyevermizer.get_extra_items())
|
2021-09-29 07:12:23 +00:00
|
|
|
if item.name not in item_names and not item_names.add(item.name)]
|
|
|
|
|
|
|
|
|
2022-10-21 21:26:40 +00:00
|
|
|
class LogicProtocol(Protocol):
|
|
|
|
def has(self, name: str, player: int) -> bool: ...
|
2023-11-23 23:35:37 +00:00
|
|
|
def count(self, name: str, player: int) -> int: ...
|
2022-10-21 21:26:40 +00:00
|
|
|
def soe_has(self, progress: int, world: MultiWorld, player: int, count: int) -> bool: ...
|
|
|
|
def _soe_count(self, progress: int, world: MultiWorld, player: int, max_count: int) -> int: ...
|
|
|
|
|
|
|
|
|
2021-09-29 07:12:23 +00:00
|
|
|
# when this module is loaded, this mixin will extend BaseClasses.CollectionState
|
|
|
|
class SecretOfEvermoreLogic(LogicMixin):
|
2022-10-21 21:26:40 +00:00
|
|
|
def _soe_count(self: LogicProtocol, progress: int, world: MultiWorld, player: int, max_count: int = 0) -> int:
|
2021-09-29 07:12:23 +00:00
|
|
|
"""
|
2021-11-07 14:38:02 +00:00
|
|
|
Returns reached count of one of evermizer's progress steps based on collected items.
|
|
|
|
i.e. returns 0-3 for P_DE based on items providing CHECK_BOSS,DIAMOND_EYE_DROP
|
2021-09-29 07:12:23 +00:00
|
|
|
"""
|
|
|
|
n = 0
|
|
|
|
for item in items:
|
|
|
|
for pvd in item.provides:
|
|
|
|
if pvd[1] == progress:
|
|
|
|
if self.has(item.name, player):
|
2023-11-23 23:35:37 +00:00
|
|
|
n += self.count(item.name, player) * pvd[0]
|
2021-09-29 07:12:23 +00:00
|
|
|
if n >= max_count > 0:
|
|
|
|
return n
|
|
|
|
for rule in rules:
|
|
|
|
for pvd in rule.provides:
|
|
|
|
if pvd[1] == progress and pvd[0] > 0:
|
|
|
|
has = True
|
|
|
|
for req in rule.requires:
|
2022-09-25 16:00:22 +00:00
|
|
|
if not self.soe_has(req[1], world, player, req[0]):
|
2021-09-29 07:12:23 +00:00
|
|
|
has = False
|
|
|
|
break
|
|
|
|
if has:
|
|
|
|
n += pvd[0]
|
|
|
|
if n >= max_count > 0:
|
|
|
|
return n
|
|
|
|
return n
|
|
|
|
|
2022-10-21 21:26:40 +00:00
|
|
|
def soe_has(self: LogicProtocol, progress: int, world: MultiWorld, player: int, count: int = 1) -> bool:
|
2021-09-29 07:12:23 +00:00
|
|
|
"""
|
2021-11-07 14:38:02 +00:00
|
|
|
Returns True if count of one of evermizer's progress steps is reached based on collected items. i.e. 2 * P_DE
|
2021-09-29 07:12:23 +00:00
|
|
|
"""
|
2022-07-15 16:01:07 +00:00
|
|
|
if progress == pyevermizer.P_ENERGY_CORE: # logic is shared between worlds, so we override in the call
|
|
|
|
w = world.worlds[player]
|
|
|
|
if w.energy_core == EnergyCore.option_fragments:
|
|
|
|
progress = pyevermizer.P_CORE_FRAGMENT
|
|
|
|
count = w.required_fragments
|
2023-10-08 15:27:05 +00:00
|
|
|
elif progress == pyevermizer.P_ALLOW_OOB:
|
|
|
|
if world.worlds[player].out_of_bounds == OutOfBounds.option_logic:
|
|
|
|
return True
|
|
|
|
elif progress == pyevermizer.P_ALLOW_SEQUENCE_BREAKS:
|
|
|
|
if world.worlds[player].sequence_breaks == SequenceBreaks.option_logic:
|
|
|
|
return True
|
2021-09-29 07:12:23 +00:00
|
|
|
return self._soe_count(progress, world, player, count) >= count
|