Archipelago/worlds/subnautica/__init__.py

157 lines
6.0 KiB
Python
Raw Normal View History

2021-07-17 16:07:45 +00:00
import logging
from typing import List, Dict, Any
from BaseClasses import Region, Entrance, Location, Item, Tutorial, ItemClassification, RegionType
from worlds.AutoWorld import World, WebWorld
from . import Items
from . import Locations
2022-07-16 14:45:40 +00:00
from . import Creatures
from . import Options
from .Items import item_table
2021-07-17 16:07:45 +00:00
from .Rules import set_rules
logger = logging.getLogger("Subnautica")
class SubnaticaWeb(WebWorld):
tutorials = [Tutorial(
"Multiworld Setup Guide",
"A guide to setting up the Subnautica randomizer connected to an Archipelago Multiworld",
"English",
"setup_en.md",
"setup/en",
["Berserker"]
)]
2021-07-17 16:07:45 +00:00
2022-07-16 14:45:40 +00:00
all_locations = {data["name"]: loc_id for loc_id, data in Locations.location_table.items()}
all_locations.update(Creatures.creature_locations)
2021-07-17 16:07:45 +00:00
class SubnauticaWorld(World):
"""
Subnautica is an undersea exploration game. Stranded on an alien world, you become infected by
an unknown bacteria. The planet's automatic quarantine will shoot you down if you try to leave.
You must find a cure for yourself, build an escape rocket, and leave the planet.
"""
2021-07-17 16:07:45 +00:00
game: str = "Subnautica"
web = SubnaticaWeb()
2021-07-17 16:07:45 +00:00
item_name_to_id = {data["name"]: item_id for item_id, data in Items.item_table.items()}
2022-07-16 14:45:40 +00:00
location_name_to_id = all_locations
option_definitions = Options.options
2021-07-17 16:07:45 +00:00
data_version = 7
2022-08-23 21:04:20 +00:00
required_client_version = (0, 3, 5)
2022-07-16 14:45:40 +00:00
creatures_to_scan: List[str]
def generate_early(self) -> None:
if "Seaglide Fragment" not in self.world.early_items[self.player]:
self.world.early_items[self.player].value["Seaglide Fragment"] = 2
scan_option: Options.AggressiveScanLogic = self.world.creature_scan_logic[self.player]
creature_pool = scan_option.get_pool()
self.world.creature_scans[self.player].value = min(
len(creature_pool),
self.world.creature_scans[self.player].value
)
self.creatures_to_scan = self.world.random.sample(creature_pool,
2022-07-16 14:45:40 +00:00
self.world.creature_scans[self.player].value)
def create_regions(self):
self.world.regions += [
self.create_region("Menu", None, ["Lifepod 5"]),
self.create_region("Planet 4546B",
2022-07-16 14:45:40 +00:00
Locations.events +
[location["name"] for location in Locations.location_table.values()] +
[creature+Creatures.suffix for creature in self.creatures_to_scan])
]
# refer to Rules.py
set_rules = set_rules
2021-07-17 16:07:45 +00:00
def generate_basic(self):
# Link regions
self.world.get_entrance("Lifepod 5", self.player).connect(self.world.get_region("Planet 4546B", self.player))
2021-07-17 16:07:45 +00:00
# Generate item pool
pool = []
neptune_launch_platform = None
2022-07-16 14:45:40 +00:00
extras = self.world.creature_scans[self.player].value
valuable = self.world.item_pool[self.player] == Options.ItemPool.option_valuable
for item in item_table.values():
2021-07-17 16:07:45 +00:00
for i in range(item["count"]):
subnautica_item = self.create_item(item["name"])
2021-07-17 16:07:45 +00:00
if item["name"] == "Neptune Launch Platform":
neptune_launch_platform = subnautica_item
elif valuable and ItemClassification.filler == item["classification"]:
2021-09-17 02:32:36 +00:00
extras += 1
2021-07-17 16:07:45 +00:00
else:
pool.append(subnautica_item)
for item_name in self.world.random.choices(sorted(Items.advancement_item_names - {"Neptune Launch Platform"}),
2021-09-17 02:32:36 +00:00
k=extras):
item = self.create_item(item_name)
item.classification = ItemClassification.filler # as it's an extra, just fast-fill it somewhere
pool.append(item)
2021-09-17 02:32:36 +00:00
2021-07-17 16:07:45 +00:00
self.world.itempool += pool
# Victory item
self.world.get_location("Aurora - Captain Data Terminal", self.player).place_locked_item(
neptune_launch_platform)
for event in Locations.events:
self.world.get_location(event, self.player).place_locked_item(
SubnauticaItem(event, ItemClassification.progression, None, player=self.player))
# make the goal event the victory "item"
self.world.get_location(self.world.goal[self.player].get_event_name(), self.player).item.name = "Victory"
def fill_slot_data(self) -> Dict[str, Any]:
goal: Options.Goal = self.world.goal[self.player]
item_pool: Options.ItemPool = self.world.item_pool[self.player]
vanilla_tech: List[str] = []
if item_pool == Options.ItemPool.option_valuable:
for item in Items.item_table.values():
if item["classification"] == ItemClassification.filler:
vanilla_tech.append(item["tech_type"])
slot_data: Dict[str, Any] = {
"goal": goal.current_key,
"vanilla_tech": vanilla_tech,
2022-07-21 13:39:34 +00:00
"creatures_to_scan": self.creatures_to_scan,
"death_link": self.world.death_link[self.player].value,
}
2021-07-17 16:07:45 +00:00
return slot_data
def create_item(self, name: str) -> Item:
item_id: int = self.item_name_to_id[name]
return SubnauticaItem(name,
item_table[item_id]["classification"],
item_id, player=self.player)
def create_region(self, name: str, locations=None, exits=None):
ret = Region(name, RegionType.Generic, name, self.player)
ret.world = self.world
if locations:
for location in locations:
loc_id = self.location_name_to_id.get(location, None)
location = SubnauticaLocation(self.player, location, loc_id, ret)
ret.locations.append(location)
if exits:
for region_exit in exits:
ret.exits.append(Entrance(self.player, region_exit, ret))
return ret
2021-07-17 16:07:45 +00:00
class SubnauticaLocation(Location):
game: str = "Subnautica"
class SubnauticaItem(Item):
game: str = "Subnautica"