Skip to content

Commit

Permalink
Merge branch 'ArchipelagoMW:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
BootsinSoots authored Oct 15, 2023
2 parents c8cc022 + 63c7f1d commit b5fea31
Show file tree
Hide file tree
Showing 10 changed files with 63 additions and 62 deletions.
5 changes: 3 additions & 2 deletions worlds/lufia2ac/Options.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
from itertools import accumulate, chain, combinations
from typing import Any, cast, Dict, Iterator, List, Mapping, Optional, Set, Tuple, Type, TYPE_CHECKING, Union

from Options import AssembleOptions, Choice, DeathLink, ItemDict, Range, SpecialRange, TextChoice, Toggle
from Options import AssembleOptions, Choice, DeathLink, ItemDict, PerGameCommonOptions, Range, SpecialRange, \
TextChoice, Toggle
from .Enemies import enemy_name_to_sprite

if TYPE_CHECKING:
Expand Down Expand Up @@ -697,7 +698,7 @@ def unlock(self) -> int:


@dataclass
class L2ACOptions:
class L2ACOptions(PerGameCommonOptions):
blue_chest_chance: BlueChestChance
blue_chest_count: BlueChestCount
boss: Boss
Expand Down
9 changes: 5 additions & 4 deletions worlds/lufia2ac/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
import itertools
import os
from enum import IntFlag
from typing import Any, ClassVar, Dict, get_type_hints, Iterator, List, Set, Tuple
from typing import Any, ClassVar, Dict, Iterator, List, Set, Tuple, Type

import settings
from BaseClasses import Item, ItemClassification, Location, MultiWorld, Region, Tutorial
from Options import AssembleOptions
from Options import PerGameCommonOptions
from Utils import __version__
from worlds.AutoWorld import WebWorld, World
from worlds.generic.Rules import add_rule, set_rule
Expand Down Expand Up @@ -54,7 +54,8 @@ class L2ACWorld(World):
game: ClassVar[str] = "Lufia II Ancient Cave"
web: ClassVar[WebWorld] = L2ACWeb()

option_definitions: ClassVar[Dict[str, AssembleOptions]] = get_type_hints(L2ACOptions)
options_dataclass: ClassVar[Type[PerGameCommonOptions]] = L2ACOptions
options: L2ACOptions
settings: ClassVar[L2ACSettings]
item_name_to_id: ClassVar[Dict[str, int]] = l2ac_item_name_to_id
location_name_to_id: ClassVar[Dict[str, int]] = l2ac_location_name_to_id
Expand Down Expand Up @@ -87,7 +88,7 @@ def generate_early(self) -> None:
bytearray(f"L2AC{__version__.replace('.', '')[:3]}_{self.player}_{self.multiworld.seed}", "utf8")[:21]
self.rom_name.extend([0] * (21 - len(self.rom_name)))

self.o = L2ACOptions(**{opt: getattr(self.multiworld, opt)[self.player] for opt in self.option_definitions})
self.o = self.options

if self.o.blue_chest_count < self.o.custom_item_pool.count:
raise ValueError(f"Number of items in custom_item_pool ({self.o.custom_item_pool.count}) is "
Expand Down
60 changes: 29 additions & 31 deletions worlds/subnautica/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@

from BaseClasses import Region, Entrance, Location, Item, Tutorial, ItemClassification
from worlds.AutoWorld import World, WebWorld
from . import Items
from . import Locations
from . import Creatures
from . import Options
from .Items import item_table, group_items, items_by_type, ItemType
from .Rules import set_rules
from . import items
from . import locations
from . import creatures
from . import options
from .items import item_table, group_items, items_by_type, ItemType
from .rules import set_rules

logger = logging.getLogger("Subnautica")

Expand All @@ -27,8 +27,8 @@ class SubnaticaWeb(WebWorld):
)]


all_locations = {data["name"]: loc_id for loc_id, data in Locations.location_table.items()}
all_locations.update(Creatures.creature_locations)
all_locations = {data["name"]: loc_id for loc_id, data in locations.location_table.items()}
all_locations.update(creatures.creature_locations)


class SubnauticaWorld(World):
Expand All @@ -40,55 +40,55 @@ class SubnauticaWorld(World):
game = "Subnautica"
web = SubnaticaWeb()

item_name_to_id = {data.name: item_id for item_id, data in Items.item_table.items()}
item_name_to_id = {data.name: item_id for item_id, data in items.item_table.items()}
location_name_to_id = all_locations
option_definitions = Options.options
option_definitions = options.option_definitions

data_version = 10
required_client_version = (0, 4, 1)

creatures_to_scan: List[str]

def generate_early(self) -> None:
if self.multiworld.early_seaglide[self.player]:
if self.options.early_seaglide:
self.multiworld.local_early_items[self.player]["Seaglide Fragment"] = 2

scan_option: Options.AggressiveScanLogic = self.multiworld.creature_scan_logic[self.player]
scan_option: options.AggressiveScanLogic = self.options.creature_scan_logic
creature_pool = scan_option.get_pool()

self.multiworld.creature_scans[self.player].value = min(
self.options.creature_scans.value = min(
len(creature_pool),
self.multiworld.creature_scans[self.player].value
self.options.creature_scans.value
)

self.creatures_to_scan = self.multiworld.random.sample(
creature_pool, self.multiworld.creature_scans[self.player].value)
self.creatures_to_scan = self.random.sample(
creature_pool, self.options.creature_scans.value)

def create_regions(self):
self.multiworld.regions += [
self.create_region("Menu", None, ["Lifepod 5"]),
self.create_region("Planet 4546B",
Locations.events +
[location["name"] for location in Locations.location_table.values()] +
[creature+Creatures.suffix for creature in self.creatures_to_scan])
locations.events +
[location["name"] for location in locations.location_table.values()] +
[creature + creatures.suffix for creature in self.creatures_to_scan])
]

# Link regions
self.multiworld.get_entrance("Lifepod 5", self.player).connect(self.multiworld.get_region("Planet 4546B", self.player))

for event in Locations.events:
for event in locations.events:
self.multiworld.get_location(event, self.player).place_locked_item(
SubnauticaItem(event, ItemClassification.progression, None, player=self.player))
# make the goal event the victory "item"
self.multiworld.get_location(self.multiworld.goal[self.player].get_event_name(), self.player).item.name = "Victory"
self.multiworld.get_location(self.options.goal.get_event_name(), self.player).item.name = "Victory"

# refer to Rules.py
set_rules = set_rules

def create_items(self):
# Generate item pool
pool: List[SubnauticaItem] = []
extras = self.multiworld.creature_scans[self.player].value
extras = self.options.creature_scans.value

grouped = set(itertools.chain.from_iterable(group_items.values()))

Expand Down Expand Up @@ -139,17 +139,15 @@ def create_items(self):
self.multiworld.itempool += pool

def fill_slot_data(self) -> Dict[str, Any]:
goal: Options.Goal = self.multiworld.goal[self.player]
swim_rule: Options.SwimRule = self.multiworld.swim_rule[self.player]
vanilla_tech: List[str] = []

slot_data: Dict[str, Any] = {
"goal": goal.current_key,
"swim_rule": swim_rule.current_key,
"goal": self.options.goal.current_key,
"swim_rule": self.options.swim_rule.current_key,
"vanilla_tech": vanilla_tech,
"creatures_to_scan": self.creatures_to_scan,
"death_link": self.multiworld.death_link[self.player].value,
"free_samples": self.multiworld.free_samples[self.player].value,
"death_link": self.options.death_link.value,
"free_samples": self.options.free_samples.value,
}

return slot_data
Expand All @@ -161,10 +159,10 @@ def create_item(self, name: str) -> SubnauticaItem:
item_table[item_id].classification,
item_id, player=self.player)

def create_region(self, name: str, locations=None, exits=None):
def create_region(self, name: str, region_locations=None, exits=None):
ret = Region(name, self.player, self.multiworld)
if locations:
for location in locations:
if region_locations:
for location in region_locations:
loc_id = self.location_name_to_id.get(location, None)
location = SubnauticaLocation(self.player, location, loc_id, ret)
ret.locations.append(location)
Expand Down
File renamed without changes.
4 changes: 2 additions & 2 deletions worlds/subnautica/Exports.py → worlds/subnautica/exports.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
os.chdir(new_home)
sys.path.append(new_home)

from worlds.subnautica.Locations import Vector, location_table
from worlds.subnautica.Items import item_table, group_items, items_by_type
from worlds.subnautica.locations import Vector, location_table
from worlds.subnautica.items import item_table, group_items, items_by_type
from NetUtils import encode

export_folder = os.path.join(new_home, "Subnautica Export")
Expand Down
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions worlds/subnautica/Options.py → worlds/subnautica/options.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import typing

from Options import Choice, Range, DeathLink, Toggle, DefaultOnToggle, StartInventoryPool
from .Creatures import all_creatures, Definitions
from .creatures import all_creatures, Definitions


class SwimRule(Choice):
Expand Down Expand Up @@ -103,7 +103,7 @@ class SubnauticaDeathLink(DeathLink):
Note: can be toggled via in-game console command "deathlink"."""


options = {
option_definitions = {
"swim_rule": SwimRule,
"early_seaglide": EarlySeaglide,
"free_samples": FreeSamples,
Expand Down
31 changes: 16 additions & 15 deletions worlds/subnautica/Rules.py → worlds/subnautica/rules.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from typing import TYPE_CHECKING, Dict, Callable, Optional

from worlds.generic.Rules import set_rule, add_rule
from .Locations import location_table, LocationDict
from .Creatures import all_creatures, aggressive, suffix, hatchable, containment
from .Options import AggressiveScanLogic, SwimRule
from .locations import location_table, LocationDict
from .creatures import all_creatures, aggressive, suffix, hatchable, containment
from .options import AggressiveScanLogic, SwimRule
import math

if TYPE_CHECKING:
Expand Down Expand Up @@ -290,16 +290,16 @@ def get_aggression_rule(option: AggressiveScanLogic, creature_name: str) -> \

def set_rules(subnautica_world: "SubnauticaWorld"):
player = subnautica_world.player
world = subnautica_world.multiworld
multiworld = subnautica_world.multiworld

for loc in location_table.values():
set_location_rule(world, player, loc)
set_location_rule(multiworld, player, loc)

if subnautica_world.creatures_to_scan:
option = world.creature_scan_logic[player]
option = multiworld.creature_scan_logic[player]

for creature_name in subnautica_world.creatures_to_scan:
location = set_creature_rule(world, player, creature_name)
location = set_creature_rule(multiworld, player, creature_name)
if creature_name in containment: # there is no other way, hard-required containment
add_rule(location, lambda state: has_containment(state, player))
elif creature_name in aggressive:
Expand All @@ -309,7 +309,7 @@ def set_rules(subnautica_world: "SubnauticaWorld"):
lambda state, loc_rule=get_aggression_rule(option, creature_name): loc_rule(state, player))

# Victory locations
set_rule(world.get_location("Neptune Launch", player),
set_rule(multiworld.get_location("Neptune Launch", player),
lambda state:
get_max_depth(state, player) >= 1444 and
has_mobile_vehicle_bay(state, player) and
Expand All @@ -322,13 +322,14 @@ def set_rules(subnautica_world: "SubnauticaWorld"):
state.has("Ion Battery", player) and
has_cyclops_shield(state, player))

set_rule(world.get_location("Disable Quarantine", player), lambda state:
get_max_depth(state, player) >= 1444)
set_rule(multiworld.get_location("Disable Quarantine", player),
lambda state: get_max_depth(state, player) >= 1444)

set_rule(world.get_location("Full Infection", player), lambda state:
get_max_depth(state, player) >= 900)
set_rule(multiworld.get_location("Full Infection", player),
lambda state: get_max_depth(state, player) >= 900)

room = world.get_location("Aurora Drive Room - Upgrade Console", player)
set_rule(world.get_location("Repair Aurora Drive", player), lambda state: room.can_reach(state))
room = multiworld.get_location("Aurora Drive Room - Upgrade Console", player)
set_rule(multiworld.get_location("Repair Aurora Drive", player),
lambda state: room.can_reach(state))

world.completion_condition[player] = lambda state: state.has("Victory", player)
multiworld.completion_condition[player] = lambda state: state.has("Victory", player)
12 changes: 6 additions & 6 deletions worlds/subnautica/test/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ def testIDRange(self):
self.assertGreater(self.scancutoff, id)

def testGroupAssociation(self):
from worlds.subnautica import Items
for item_id, item_data in Items.item_table.items():
if item_data.type == Items.ItemType.group:
from worlds.subnautica import items
for item_id, item_data in items.item_table.items():
if item_data.type == items.ItemType.group:
with self.subTest(item=item_data.name):
self.assertIn(item_id, Items.group_items)
for item_id in Items.group_items:
self.assertIn(item_id, items.group_items)
for item_id in items.group_items:
with self.subTest(item_id=item_id):
self.assertEqual(Items.item_table[item_id].type, Items.ItemType.group)
self.assertEqual(items.item_table[item_id].type, items.ItemType.group)

0 comments on commit b5fea31

Please sign in to comment.