From 69a5bf015926038c99a9d9419cd198de3d80b080 Mon Sep 17 00:00:00 2001 From: Fabian Dill Date: Thu, 15 Jul 2021 13:31:33 +0200 Subject: [PATCH] Add LogicMixin --- BaseClasses.py | 26 -------------------------- worlds/AutoWorld.py | 23 ++++++++++++++++++++--- worlds/hk/__init__.py | 25 +++++++++++++++++++++++-- 3 files changed, 43 insertions(+), 31 deletions(-) diff --git a/BaseClasses.py b/BaseClasses.py index a913026e..fd19d850 100644 --- a/BaseClasses.py +++ b/BaseClasses.py @@ -569,32 +569,6 @@ class CollectionState(object): def has_any(self, items: Set[str], player:int): return any(self.prog_items[item, player] for item in items) - def has_essence(self, player: int, count: int): - return self.prog_items["Dream_Nail", player] - # return self.prog_items["Essence", player] >= count - - def has_grubs(self, player: int, count: int): - from worlds.hk import Items as HKItems - found = 0 - - for item_name in HKItems.lookup_type_to_names["Grub"]: - found += self.prog_items[item_name, player] - if found >= count: - return True - - return False - - def has_flames(self, player: int, count: int): - from worlds.hk import Items as HKItems - found = 0 - - for item_name in HKItems.lookup_type_to_names["Flame"]: - found += self.prog_items[item_name, player] - if found >= count: - return True - - return False - def has_key(self, item, player, count: int = 1): if self.world.logic[player] == 'nologic': return True diff --git a/worlds/AutoWorld.py b/worlds/AutoWorld.py index 220c4418..b6d7dad7 100644 --- a/worlds/AutoWorld.py +++ b/worlds/AutoWorld.py @@ -21,6 +21,15 @@ class AutoWorldRegister(type): AutoWorldRegister.world_types[dct["game"]] = new_class return new_class +class AutoLogicRegister(type): + def __new__(cls, name, bases, dct): + new_class = super().__new__(cls, name, bases, dct) + for function_name, function in dct.items(): + if hasattr(function, "__call__"): # callable + if hasattr(CollectionState, function_name): + raise Exception(f"Name conflict on Logic Mixin {name} trying to overwrite {function_name}") + setattr(CollectionState, function_name, function) + return new_class def call_single(world: MultiWorld, method_name: str, player: int): method = getattr(world.worlds[player], method_name) @@ -36,9 +45,8 @@ class World(metaclass=AutoWorldRegister): """A World object encompasses a game's Items, Locations, Rules and additional data or functionality required. A Game should have its own subclass of World in which it defines the required data structures.""" - world: MultiWorld - player: int - options: dict = {} + options: dict = {} # link your Options mapping + game: str # name the game topology_present: bool = False # indicate if world type has any meaningful layout/pathing item_names: Set[str] = frozenset() # set of all potential item names # maps item group names to sets of items. Example: "Weapons" -> {"Sword", "Bow"} @@ -64,6 +72,10 @@ class World(metaclass=AutoWorldRegister): # the client finds its own items in its own world. remote_items: bool = True + # autoset on creation: + world: MultiWorld + player: int + def __init__(self, world: MultiWorld, player: int): self.world = world self.player = player @@ -102,3 +114,8 @@ class World(metaclass=AutoWorldRegister): """Create an item for this world type and player. Warning: this may be called with self.world = None, for example by MultiServer""" raise NotImplementedError + +# any methods attached to this can be used as part of CollectionState, +# please use a prefix as all of them get clobbered together +class LogicMixin(metaclass=AutoLogicRegister): + pass \ No newline at end of file diff --git a/worlds/hk/__init__.py b/worlds/hk/__init__.py index 57fe17bd..8321ca55 100644 --- a/worlds/hk/__init__.py +++ b/worlds/hk/__init__.py @@ -4,13 +4,13 @@ from typing import Set logger = logging.getLogger("Hollow Knight") from .Locations import lookup_name_to_id -from .Items import item_table +from .Items import item_table, lookup_type_to_names from .Regions import create_regions from .Rules import set_rules from .Options import hollow_knight_options from BaseClasses import Region, Entrance, Location, MultiWorld, Item -from ..AutoWorld import World +from ..AutoWorld import World, LogicMixin class HKWorld(World): game: str = "Hollow Knight" @@ -145,5 +145,26 @@ option_to_type_lookup = { } +class HKLogic(LogicMixin): + # these are all wip + def _hk_has_essence(self, player: int, count: int): + return self.prog_items["Dream_Nail", player] + # return self.prog_items["Essence", player] >= count + def _hk_has_grubs(self, player: int, count: int): + found = 0 + for item_name in lookup_type_to_names["Grub"]: + found += self.prog_items[item_name, player] + if found >= count: + return True + return False + + def _hk_has_flames(self, player: int, count: int): + found = 0 + for item_name in lookup_type_to_names["Flame"]: + found += self.prog_items[item_name, player] + if found >= count: + return True + + return False \ No newline at end of file