| 
									
										
										
										
											2022-10-21 23:26:40 +02:00
										 |  |  | from typing import Protocol, Set | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-29 09:12:23 +02:00
										 |  |  | from BaseClasses import MultiWorld | 
					
						
							| 
									
										
										
										
											2022-10-21 23:26:40 +02:00
										 |  |  | from worlds.AutoWorld import LogicMixin | 
					
						
							|  |  |  | from . import pyevermizer | 
					
						
							| 
									
										
										
										
											2022-07-15 18:01:07 +02:00
										 |  |  | from .Options import EnergyCore | 
					
						
							| 
									
										
										
										
											2021-09-29 09:12:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-21 23:26:40 +02:00
										 |  |  | # TODO: Options may preset certain progress steps (i.e. P_ROCK_SKIP), set in generate_early? | 
					
						
							| 
									
										
										
										
											2021-09-29 09:12:23 +02: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 18:01:07 +02:00
										 |  |  | # Logic.items are all items and extra items excluding non-progression items and duplicates | 
					
						
							| 
									
										
										
										
											2021-09-29 09:12:23 +02:00
										 |  |  | item_names: Set[str] = set() | 
					
						
							| 
									
										
										
										
											2022-07-15 18:01:07 +02:00
										 |  |  | items = [item for item in filter(lambda item: item.progression, pyevermizer.get_items() + pyevermizer.get_extra_items()) | 
					
						
							| 
									
										
										
										
											2021-09-29 09:12:23 +02:00
										 |  |  |          if item.name not in item_names and not item_names.add(item.name)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-21 23:26:40 +02:00
										 |  |  | class LogicProtocol(Protocol): | 
					
						
							|  |  |  |     def has(self, name: str, player: int) -> bool: ... | 
					
						
							|  |  |  |     def item_count(self, name: str, player: int) -> int: ... | 
					
						
							|  |  |  |     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 09:12:23 +02:00
										 |  |  | # when this module is loaded, this mixin will extend BaseClasses.CollectionState | 
					
						
							|  |  |  | class SecretOfEvermoreLogic(LogicMixin): | 
					
						
							| 
									
										
										
										
											2022-10-21 23:26:40 +02:00
										 |  |  |     def _soe_count(self: LogicProtocol, progress: int, world: MultiWorld, player: int, max_count: int = 0) -> int: | 
					
						
							| 
									
										
										
										
											2021-09-29 09:12:23 +02:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2021-11-07 15:38:02 +01: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 09:12:23 +02:00
										 |  |  |         """
 | 
					
						
							|  |  |  |         n = 0 | 
					
						
							|  |  |  |         for item in items: | 
					
						
							|  |  |  |             for pvd in item.provides: | 
					
						
							|  |  |  |                 if pvd[1] == progress: | 
					
						
							|  |  |  |                     if self.has(item.name, player): | 
					
						
							|  |  |  |                         n += self.item_count(item.name, player) * pvd[0] | 
					
						
							|  |  |  |                         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 18:00:22 +02:00
										 |  |  |                         if not self.soe_has(req[1], world, player, req[0]): | 
					
						
							| 
									
										
										
										
											2021-09-29 09:12:23 +02:00
										 |  |  |                             has = False | 
					
						
							|  |  |  |                             break | 
					
						
							|  |  |  |                     if has: | 
					
						
							|  |  |  |                         n += pvd[0] | 
					
						
							|  |  |  |                         if n >= max_count > 0: | 
					
						
							|  |  |  |                             return n | 
					
						
							|  |  |  |         return n | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-21 23:26:40 +02:00
										 |  |  |     def soe_has(self: LogicProtocol, progress: int, world: MultiWorld, player: int, count: int = 1) -> bool: | 
					
						
							| 
									
										
										
										
											2021-09-29 09:12:23 +02:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2021-11-07 15:38:02 +01: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 09:12:23 +02:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2022-07-15 18:01:07 +02: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 | 
					
						
							| 
									
										
										
										
											2021-09-29 09:12:23 +02:00
										 |  |  |         return self._soe_count(progress, world, player, count) >= count |