mirror of
https://github.com/MarioSpore/Grinch-AP.git
synced 2025-10-21 20:21:32 -06:00
BaseRoomFragment doesn't exist in vanilla, so when valuable item pool marked it as scannable in vanilla location it did not work, as it's technically BaseRoom BaseRoom is also required to install other modules into, modules that are already marked as useful, so logically if it's required for other useful stuff it should also be marked as useful By switching from Fragment to non-fragment one now needs 1 out of 2 instead of 2 out of 2 items, which I consider a plus as well.
161 lines
6.1 KiB
Python
161 lines
6.1 KiB
Python
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
|
|
from . import Creatures
|
|
from . import Options
|
|
from .Items import item_table
|
|
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"]
|
|
)]
|
|
|
|
|
|
all_locations = {data["name"]: loc_id for loc_id, data in Locations.location_table.items()}
|
|
all_locations.update(Creatures.creature_locations)
|
|
|
|
|
|
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.
|
|
"""
|
|
game: str = "Subnautica"
|
|
web = SubnaticaWeb()
|
|
|
|
item_name_to_id = {data["name"]: item_id for item_id, data in Items.item_table.items()}
|
|
location_name_to_id = all_locations
|
|
options = Options.options
|
|
|
|
data_version = 5
|
|
required_client_version = (0, 3, 3)
|
|
|
|
prefill_items: List[Item]
|
|
creatures_to_scan: List[str]
|
|
|
|
def generate_early(self) -> None:
|
|
self.prefill_items = [
|
|
self.create_item("Seaglide Fragment"),
|
|
self.create_item("Seaglide Fragment")
|
|
]
|
|
self.creatures_to_scan = self.world.random.sample(Creatures.all_creatures_presorted,
|
|
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",
|
|
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
|
|
|
|
def generate_basic(self):
|
|
# Link regions
|
|
self.world.get_entrance("Lifepod 5", self.player).connect(self.world.get_region("Planet 4546B", self.player))
|
|
|
|
# Generate item pool
|
|
pool = []
|
|
neptune_launch_platform = None
|
|
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():
|
|
for i in range(item["count"]):
|
|
subnautica_item = self.create_item(item["name"])
|
|
if item["name"] == "Neptune Launch Platform":
|
|
neptune_launch_platform = subnautica_item
|
|
elif valuable and ItemClassification.filler == item["classification"]:
|
|
extras += 1
|
|
else:
|
|
pool.append(subnautica_item)
|
|
|
|
for item_name in self.world.random.choices(sorted(Items.advancement_item_names - {"Neptune Launch Platform"}),
|
|
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)
|
|
|
|
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,
|
|
"creatures_to_scan": self.creatures_to_scan,
|
|
"death_link": self.world.death_link[self.player].value,
|
|
}
|
|
|
|
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
|
|
|
|
def get_pre_fill_items(self) -> List[Item]:
|
|
return self.prefill_items
|
|
|
|
def pre_fill(self) -> None:
|
|
reachable = self.world.get_reachable_locations(player=self.player)
|
|
self.world.random.shuffle(reachable)
|
|
items = self.prefill_items.copy()
|
|
for item in items:
|
|
reachable.pop().place_locked_item(item)
|
|
|
|
|
|
class SubnauticaLocation(Location):
|
|
game: str = "Subnautica"
|
|
|
|
|
|
class SubnauticaItem(Item):
|
|
game: str = "Subnautica"
|