Subnautica: cleanup pass (#2293)
This commit is contained in:
		
							parent
							
								
									8fc304269e
								
							
						
					
					
						commit
						fffbe68428
					
				| 
						 | 
				
			
			@ -6,12 +6,12 @@ from typing import List, Dict, Any, cast
 | 
			
		|||
 | 
			
		||||
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")
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -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):
 | 
			
		||||
| 
						 | 
				
			
			@ -40,9 +40,9 @@ 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)
 | 
			
		||||
| 
						 | 
				
			
			@ -50,37 +50,37 @@ class SubnauticaWorld(World):
 | 
			
		|||
    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
 | 
			
		||||
| 
						 | 
				
			
			@ -88,7 +88,7 @@ class SubnauticaWorld(World):
 | 
			
		|||
    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()))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -139,17 +139,15 @@ class SubnauticaWorld(World):
 | 
			
		|||
        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
 | 
			
		||||
| 
						 | 
				
			
			@ -161,10 +159,10 @@ class SubnauticaWorld(World):
 | 
			
		|||
                              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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,8 +12,8 @@ if __name__ == "__main__":
 | 
			
		|||
    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")
 | 
			
		||||
| 
						 | 
				
			
			@ -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):
 | 
			
		||||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			@ -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:
 | 
			
		||||
| 
						 | 
				
			
			@ -290,16 +290,16 @@ aggression_rules: Dict[int, Callable[["CollectionState", int], bool]] = {
 | 
			
		|||
 | 
			
		||||
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:
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			@ -15,11 +15,11 @@ class SubnauticaTest(unittest.TestCase):
 | 
			
		|||
                    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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue