Add LogicMixin
This commit is contained in:
parent
01f0f309d1
commit
69a5bf0159
|
@ -569,32 +569,6 @@ class CollectionState(object):
|
||||||
def has_any(self, items: Set[str], player:int):
|
def has_any(self, items: Set[str], player:int):
|
||||||
return any(self.prog_items[item, player] for item in items)
|
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):
|
def has_key(self, item, player, count: int = 1):
|
||||||
if self.world.logic[player] == 'nologic':
|
if self.world.logic[player] == 'nologic':
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -21,6 +21,15 @@ class AutoWorldRegister(type):
|
||||||
AutoWorldRegister.world_types[dct["game"]] = new_class
|
AutoWorldRegister.world_types[dct["game"]] = new_class
|
||||||
return 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):
|
def call_single(world: MultiWorld, method_name: str, player: int):
|
||||||
method = getattr(world.worlds[player], method_name)
|
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 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."""
|
A Game should have its own subclass of World in which it defines the required data structures."""
|
||||||
|
|
||||||
world: MultiWorld
|
options: dict = {} # link your Options mapping
|
||||||
player: int
|
game: str # name the game
|
||||||
options: dict = {}
|
|
||||||
topology_present: bool = False # indicate if world type has any meaningful layout/pathing
|
topology_present: bool = False # indicate if world type has any meaningful layout/pathing
|
||||||
item_names: Set[str] = frozenset() # set of all potential item names
|
item_names: Set[str] = frozenset() # set of all potential item names
|
||||||
# maps item group names to sets of items. Example: "Weapons" -> {"Sword", "Bow"}
|
# 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.
|
# the client finds its own items in its own world.
|
||||||
remote_items: bool = True
|
remote_items: bool = True
|
||||||
|
|
||||||
|
# autoset on creation:
|
||||||
|
world: MultiWorld
|
||||||
|
player: int
|
||||||
|
|
||||||
def __init__(self, world: MultiWorld, player: int):
|
def __init__(self, world: MultiWorld, player: int):
|
||||||
self.world = world
|
self.world = world
|
||||||
self.player = player
|
self.player = player
|
||||||
|
@ -102,3 +114,8 @@ class World(metaclass=AutoWorldRegister):
|
||||||
"""Create an item for this world type and player.
|
"""Create an item for this world type and player.
|
||||||
Warning: this may be called with self.world = None, for example by MultiServer"""
|
Warning: this may be called with self.world = None, for example by MultiServer"""
|
||||||
raise NotImplementedError
|
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
|
|
@ -4,13 +4,13 @@ from typing import Set
|
||||||
logger = logging.getLogger("Hollow Knight")
|
logger = logging.getLogger("Hollow Knight")
|
||||||
|
|
||||||
from .Locations import lookup_name_to_id
|
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 .Regions import create_regions
|
||||||
from .Rules import set_rules
|
from .Rules import set_rules
|
||||||
from .Options import hollow_knight_options
|
from .Options import hollow_knight_options
|
||||||
|
|
||||||
from BaseClasses import Region, Entrance, Location, MultiWorld, Item
|
from BaseClasses import Region, Entrance, Location, MultiWorld, Item
|
||||||
from ..AutoWorld import World
|
from ..AutoWorld import World, LogicMixin
|
||||||
|
|
||||||
class HKWorld(World):
|
class HKWorld(World):
|
||||||
game: str = "Hollow Knight"
|
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
|
Loading…
Reference in New Issue