Subnautica: updates (#759)

* Subnautica: add more goals

* Subnautica: fix wrongly positioned Databox

* Subnautica: allow techs to remain vanilla

* Subnautica: make zipimport compatible

* Subnautica: force two Seaglide fragments into local sphere 1
This commit is contained in:
Fabian Dill 2022-07-15 17:41:53 +02:00 committed by GitHub
parent 8e15fe51b6
commit 73fb1b8074
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 1059 additions and 715 deletions

View File

@ -363,7 +363,8 @@ def main(args, seed=None, baked_server_options: Optional[Dict[str, object]] = No
for location in world.get_filled_locations():
if type(location.address) == int:
assert location.item.code is not None, "item code None should be event, " \
"location.address should then also be None"
"location.address should then also be None. Location: " \
f" {location}"
locations_data[location.player][location.address] = \
location.item.code, location.item.player, location.item.flags
if location.name in world.start_location_hints[location.player]:

View File

@ -1,23 +1,353 @@
import json
import os
from BaseClasses import ItemClassification
from typing import TypedDict, Dict, Set
with open(os.path.join(os.path.dirname(__file__), 'items.json'), 'r') as file:
item_table = json.loads(file.read())
lookup_id_to_name = {}
lookup_name_to_item = {}
advancement_item_names = set()
non_advancement_item_names = set()
class ItemDict(TypedDict):
classification: ItemClassification
count: int
name: str
tech_type: str
for item in item_table:
item_name = item["name"]
lookup_id_to_name[item["id"]] = item_name
lookup_name_to_item[item_name] = item
if item["progression"]:
item_table: Dict[int, ItemDict] = {
35000: {'classification': ItemClassification.useful,
'count': 1,
'name': 'Compass',
'tech_type': 'Compass'},
35001: {'classification': ItemClassification.progression,
'count': 1,
'name': 'Lightweight High Capacity Tank',
'tech_type': 'PlasteelTank'},
35002: {'classification': ItemClassification.progression,
'count': 1,
'name': 'Vehicle Upgrade Console',
'tech_type': 'BaseUpgradeConsole'},
35003: {'classification': ItemClassification.progression,
'count': 1,
'name': 'Ultra Glide Fins',
'tech_type': 'UltraGlideFins'},
35004: {'classification': ItemClassification.useful,
'count': 1,
'name': 'Cyclops Sonar Upgrade',
'tech_type': 'CyclopsSonarModule'},
35005: {'classification': ItemClassification.useful,
'count': 1,
'name': 'Reinforced Dive Suit',
'tech_type': 'ReinforcedDiveSuit'},
35006: {'classification': ItemClassification.useful,
'count': 1,
'name': 'Cyclops Thermal Reactor Module',
'tech_type': 'CyclopsThermalReactorModule'},
35007: {'classification': ItemClassification.filler,
'count': 1,
'name': 'Stillsuit',
'tech_type': 'Stillsuit'},
35008: {'classification': ItemClassification.filler,
'count': 2,
'name': 'Alien Containment Fragment',
'tech_type': 'BaseWaterParkFragment'},
35009: {'classification': ItemClassification.useful,
'count': 1,
'name': 'Creature Decoy',
'tech_type': 'CyclopsDecoy'},
35010: {'classification': ItemClassification.useful,
'count': 1,
'name': 'Cyclops Fire Suppression System',
'tech_type': 'CyclopsFireSuppressionModule'},
35011: {'classification': ItemClassification.useful,
'count': 1,
'name': 'Swim Charge Fins',
'tech_type': 'SwimChargeFins'},
35012: {'classification': ItemClassification.useful,
'count': 1,
'name': 'Repulsion Cannon',
'tech_type': 'RepulsionCannon'},
35013: {'classification': ItemClassification.useful,
'count': 1,
'name': 'Cyclops Decoy Tube Upgrade',
'tech_type': 'CyclopsDecoyModule'},
35014: {'classification': ItemClassification.progression,
'count': 1,
'name': 'Cyclops Shield Generator',
'tech_type': 'CyclopsShieldModule'},
35015: {'classification': ItemClassification.progression,
'count': 1,
'name': 'Cyclops Depth Module MK1',
'tech_type': 'CyclopsHullModule1'},
35016: {'classification': ItemClassification.useful,
'count': 1,
'name': 'Cyclops Docking Bay Repair Module',
'tech_type': 'CyclopsSeamothRepairModule'},
35017: {'classification': ItemClassification.useful,
'count': 2,
'name': 'Battery Charger fragment',
'tech_type': 'BatteryChargerFragment'},
35018: {'classification': ItemClassification.filler,
'count': 2,
'name': 'Beacon Fragment',
'tech_type': 'BeaconFragment'},
35019: {'classification': ItemClassification.useful,
'count': 2,
'name': 'Bioreactor Fragment',
'tech_type': 'BaseBioReactorFragment'},
35020: {'classification': ItemClassification.progression,
'count': 3,
'name': 'Cyclops Bridge Fragment',
'tech_type': 'CyclopsBridgeFragment'},
35021: {'classification': ItemClassification.progression,
'count': 3,
'name': 'Cyclops Engine Fragment',
'tech_type': 'CyclopsEngineFragment'},
35022: {'classification': ItemClassification.progression,
'count': 3,
'name': 'Cyclops Hull Fragment',
'tech_type': 'CyclopsHullFragment'},
35023: {'classification': ItemClassification.filler,
'count': 2,
'name': 'Grav Trap Fragment',
'tech_type': 'GravSphereFragment'},
35024: {'classification': ItemClassification.progression,
'count': 3,
'name': 'Laser Cutter Fragment',
'tech_type': 'LaserCutterFragment'},
35025: {'classification': ItemClassification.filler,
'count': 1,
'name': 'Light Stick Fragment',
'tech_type': 'TechlightFragment'},
35026: {'classification': ItemClassification.progression,
'count': 3,
'name': 'Mobile Vehicle Bay Fragment',
'tech_type': 'ConstructorFragment'},
35027: {'classification': ItemClassification.progression,
'count': 3,
'name': 'Modification Station Fragment',
'tech_type': 'WorkbenchFragment'},
35028: {'classification': ItemClassification.progression,
'count': 2,
'name': 'Moonpool Fragment',
'tech_type': 'MoonpoolFragment'},
35029: {'classification': ItemClassification.useful,
'count': 3,
'name': 'Nuclear Reactor Fragment',
'tech_type': 'BaseNuclearReactorFragment'},
35030: {'classification': ItemClassification.useful,
'count': 2,
'name': 'Power Cell Charger Fragment',
'tech_type': 'PowerCellChargerFragment'},
35031: {'classification': ItemClassification.filler,
'count': 1,
'name': 'Power Transmitter Fragment',
'tech_type': 'PowerTransmitterFragment'},
35032: {'classification': ItemClassification.progression,
'count': 4,
'name': 'Prawn Suit Fragment',
'tech_type': 'ExosuitFragment'},
35033: {'classification': ItemClassification.useful,
'count': 2,
'name': 'Prawn Suit Drill Arm Fragment',
'tech_type': 'ExosuitDrillArmFragment'},
35034: {'classification': ItemClassification.useful,
'count': 2,
'name': 'Prawn Suit Grappling Arm Fragment',
'tech_type': 'ExosuitGrapplingArmFragment'},
35035: {'classification': ItemClassification.useful,
'count': 2,
'name': 'Prawn Suit Propulsion Cannon Fragment',
'tech_type': 'ExosuitPropulsionArmFragment'},
35036: {'classification': ItemClassification.useful,
'count': 2,
'name': 'Prawn Suit Torpedo Arm Fragment',
'tech_type': 'ExosuitTorpedoArmFragment'},
35037: {'classification': ItemClassification.useful,
'count': 3,
'name': 'Scanner Room Fragment',
'tech_type': 'BaseMapRoomFragment'},
35038: {'classification': ItemClassification.progression,
'count': 5,
'name': 'Seamoth Fragment',
'tech_type': 'SeamothFragment'},
35039: {'classification': ItemClassification.useful,
'count': 2,
'name': 'Stasis Rifle Fragment',
'tech_type': 'StasisRifleFragment'},
35040: {'classification': ItemClassification.useful,
'count': 2,
'name': 'Thermal Plant Fragment',
'tech_type': 'ThermalPlantFragment'},
35041: {'classification': ItemClassification.progression,
'count': 2,
'name': 'Seaglide Fragment',
'tech_type': 'SeaglideFragment'},
35042: {'classification': ItemClassification.progression,
'count': 1,
'name': 'Radiation Suit',
'tech_type': 'RadiationSuit'},
35043: {'classification': ItemClassification.progression,
'count': 2,
'name': 'Propulsion Cannon Fragment',
'tech_type': 'PropulsionCannonFragment'},
35044: {'classification': ItemClassification.progression,
'count': 1,
'name': 'Neptune Launch Platform',
'tech_type': 'RocketBase'},
35045: {'classification': ItemClassification.progression,
'count': 1,
'name': 'Ion Power Cell',
'tech_type': 'PrecursorIonPowerCell'},
35046: {'classification': ItemClassification.filler,
'count': 2,
'name': 'Exterior Growbed Fragment',
'tech_type': 'FarmingTrayFragment'},
35047: {'classification': ItemClassification.filler,
'count': 1,
'name': 'Picture Frame',
'tech_type': 'PictureFrameFragment'},
35048: {'classification': ItemClassification.filler,
'count': 2,
'name': 'Bench Fragment',
'tech_type': 'BenchFragment'},
35049: {'classification': ItemClassification.filler,
'count': 1,
'name': 'Basic Plant Pot',
'tech_type': 'PlanterPotFragment'},
35050: {'classification': ItemClassification.filler,
'count': 1,
'name': 'Interior Growbed',
'tech_type': 'PlanterBoxFragment'},
35051: {'classification': ItemClassification.filler,
'count': 1,
'name': 'Plant Shelf',
'tech_type': 'PlanterShelfFragment'},
35052: {'classification': ItemClassification.filler,
'count': 2,
'name': 'Observatory Fragment',
'tech_type': 'BaseObservatoryFragment'},
35053: {'classification': ItemClassification.filler,
'count': 2,
'name': 'Multipurpose Room Fragment',
'tech_type': 'BaseRoomFragment'},
35054: {'classification': ItemClassification.useful,
'count': 2,
'name': 'Bulkhead Fragment',
'tech_type': 'BaseBulkheadFragment'},
35055: {'classification': ItemClassification.filler,
'count': 1,
'name': 'Spotlight',
'tech_type': 'Spotlight'},
35056: {'classification': ItemClassification.filler,
'count': 2,
'name': 'Desk',
'tech_type': 'StarshipDesk'},
35057: {'classification': ItemClassification.filler,
'count': 1,
'name': 'Swivel Chair',
'tech_type': 'StarshipChair'},
35058: {'classification': ItemClassification.filler,
'count': 1,
'name': 'Office Chair',
'tech_type': 'StarshipChair2'},
35059: {'classification': ItemClassification.filler,
'count': 1,
'name': 'Command Chair',
'tech_type': 'StarshipChair3'},
35060: {'classification': ItemClassification.filler,
'count': 2,
'name': 'Counter',
'tech_type': 'LabCounter'},
35061: {'classification': ItemClassification.filler,
'count': 1,
'name': 'Single Bed',
'tech_type': 'NarrowBed'},
35062: {'classification': ItemClassification.filler,
'count': 1,
'name': 'Basic Double Bed',
'tech_type': 'Bed1'},
35063: {'classification': ItemClassification.filler,
'count': 1,
'name': 'Quilted Double Bed',
'tech_type': 'Bed2'},
35064: {'classification': ItemClassification.filler,
'count': 2,
'name': 'Coffee Vending Machine',
'tech_type': 'CoffeeVendingMachine'},
35065: {'classification': ItemClassification.filler,
'count': 2,
'name': 'Trash Can',
'tech_type': 'Trashcans'},
35066: {'classification': ItemClassification.filler,
'count': 1,
'name': 'Floodlight',
'tech_type': 'Techlight'},
35067: {'classification': ItemClassification.filler,
'count': 1,
'name': 'Bar Table',
'tech_type': 'BarTable'},
35068: {'classification': ItemClassification.filler,
'count': 1,
'name': 'Vending Machine',
'tech_type': 'VendingMachine'},
35069: {'classification': ItemClassification.filler,
'count': 1,
'name': 'Single Wall Shelf',
'tech_type': 'SingleWallShelf'},
35070: {'classification': ItemClassification.filler,
'count': 1,
'name': 'Wall Shelves',
'tech_type': 'WallShelves'},
35071: {'classification': ItemClassification.filler,
'count': 1,
'name': 'Round Plant Pot',
'tech_type': 'PlanterPot2'},
35072: {'classification': ItemClassification.filler,
'count': 1,
'name': 'Chic Plant Pot',
'tech_type': 'PlanterPot3'},
35073: {'classification': ItemClassification.filler,
'count': 1,
'name': 'Nuclear Waste Disposal',
'tech_type': 'LabTrashcan'},
35074: {'classification': ItemClassification.filler,
'count': 1,
'name': 'Wall Planter',
'tech_type': 'BasePlanter'},
35075: {'classification': ItemClassification.progression,
'count': 1,
'name': 'Ion Battery',
'tech_type': 'PrecursorIonBattery'},
35076: {'classification': ItemClassification.progression,
'count': 1,
'name': 'Neptune Gantry',
'tech_type': 'RocketBaseLadder'},
35077: {'classification': ItemClassification.progression,
'count': 1,
'name': 'Neptune Boosters',
'tech_type': 'RocketStage1'},
35078: {'classification': ItemClassification.progression,
'count': 1,
'name': 'Neptune Fuel Reserve',
'tech_type': 'RocketStage2'},
35079: {'classification': ItemClassification.progression,
'count': 1,
'name': 'Neptune Cockpit',
'tech_type': 'RocketStage3'},
35080: {'classification': ItemClassification.filler,
'count': 1,
'name': 'Water Filtration Machine',
'tech_type': 'BaseFiltrationMachine'}}
advancement_item_names: Set[str] = set()
non_advancement_item_names: Set[str] = set()
for item_id, item_data in item_table.items():
item_name = item_data["name"]
if ItemClassification.progression in item_data["classification"]:
advancement_item_names.add(item_name)
else:
non_advancement_item_names.add(item_name)
lookup_id_to_name[None] = "Victory"
if False: # turn to True to export for Subnautica mod
payload = {item_id: item_data["tech_type"] for item_id, item_data in item_table.items()}
import json
lookup_name_to_id = {name: id for id, name in lookup_id_to_name.items()}
with open("items.json", "w") as f:
json.dump(payload, f)

View File

@ -1,12 +1,570 @@
import json
import os
from typing import Dict, TypedDict, List
with open(os.path.join(os.path.dirname(__file__), 'locations.json'), 'r') as file:
location_table = json.loads(file.read())
lookup_id_to_name = {}
for item in location_table:
lookup_id_to_name[item["id"]] = item["name"]
class Vector(TypedDict):
x: float
y: float
z: float
lookup_id_to_name[None] = "Neptune Launch"
lookup_name_to_id = {name: id for id, name in lookup_id_to_name.items()}
class LocationDict(TypedDict, total=False):
name: str
can_slip_through: bool
need_laser_cutter: bool
position: Vector
need_propulsion_cannon: bool
events: List[str] = ["Neptune Launch", "Disable Quarantine", "Full Infection", "Repair Aurora Drive"]
location_table: Dict[int, LocationDict] = {
33000: {'can_slip_through': False,
'name': 'Blood Kelp Trench Wreck - Outside Databox',
'need_laser_cutter': False,
'position': {'x': -1234.3, 'y': -349.7, 'z': -396.0}},
33001: {'can_slip_through': False,
'name': 'Blood Kelp Trench Wreck - Inside Databox',
'need_laser_cutter': False,
'position': {'x': -1208.0, 'y': -349.6, 'z': -383.0}},
33002: {'can_slip_through': False,
'name': 'Blood Kelp Trench Wreck - PDA',
'need_laser_cutter': False,
'position': {'x': -1210.6, 'y': -340.7, 'z': -393.4}},
33003: {'can_slip_through': False,
'name': 'Bulb Zone West Wreck - Outside Databox',
'need_laser_cutter': False,
'position': {'x': 903.8, 'y': -220.3, 'z': 590.9}},
33004: {'can_slip_through': False,
'name': 'Bulb Zone West Wreck - Under Databox',
'need_laser_cutter': False,
'position': {'x': 910.9, 'y': -201.8, 'z': 623.5}},
33005: {'can_slip_through': False,
'name': 'Bulb Zone West Wreck - Inside Databox',
'need_laser_cutter': True,
'position': {'x': 914.9, 'y': -202.1, 'z': 611.8}},
33006: {'can_slip_through': False,
'name': 'Bulb Zone West Wreck - PDA',
'need_laser_cutter': True,
'position': {'x': 912.6, 'y': -202.0, 'z': 609.5}},
33007: {'can_slip_through': False,
'name': 'Bulb Zone East Wreck - Databox',
'need_laser_cutter': False,
'position': {'x': 1327.1, 'y': -234.9, 'z': 575.8}},
33008: {'can_slip_through': False,
'name': 'Dunes North Wreck - Outside Databox',
'need_laser_cutter': False,
'position': {'x': -1407.7, 'y': -344.2, 'z': 721.5}},
33009: {'can_slip_through': False,
'name': 'Dunes North Wreck - Office Databox',
'need_laser_cutter': False,
'position': {'x': -1393.9, 'y': -329.7, 'z': 733.5}},
33010: {'can_slip_through': False,
'name': 'Dunes North Wreck - PDA',
'need_laser_cutter': False,
'position': {'x': -1396.3, 'y': -330.8, 'z': 730.0}},
33011: {'can_slip_through': False,
'name': 'Dunes North Wreck - Cargo Databox',
'need_laser_cutter': True,
'position': {'x': -1409.8, 'y': -332.4, 'z': 706.9}},
33012: {'can_slip_through': False,
'name': 'Dunes West Wreck - Databox',
'need_laser_cutter': False,
'position': {'x': -1626.2, 'y': -357.5, 'z': 99.5}},
33013: {'can_slip_through': False,
'name': 'Dunes East Wreck - Outside Databox',
'need_laser_cutter': False,
'position': {'x': -1196.3, 'y': -223.0, 'z': 12.5}},
33014: {'can_slip_through': False,
'name': 'Dunes East Wreck - Inside Databox',
'need_laser_cutter': False,
'position': {'x': -1206.4, 'y': -225.6, 'z': 4.0}},
33015: {'can_slip_through': False,
'name': 'Grand Reef North Wreck - Outside Databox',
'need_laser_cutter': False,
'position': {'x': -269.7, 'y': -262.8, 'z': -764.3}},
33016: {'can_slip_through': False,
'name': 'Grand Reef North Wreck - Elevator Databox',
'need_laser_cutter': True,
'position': {'x': -285.8, 'y': -240.2, 'z': -786.5}},
33017: {'can_slip_through': False,
'name': 'Grand Reef North Wreck - Bottom Databox',
'need_laser_cutter': False,
'position': {'x': -285.2, 'y': -262.4, 'z': -788.4}},
33018: {'can_slip_through': False,
'name': 'Grand Reef North Wreck - Hangar PDA',
'need_laser_cutter': False,
'position': {'x': -272.5, 'y': -254.7, 'z': -788.5}},
33019: {'can_slip_through': False,
'name': 'Grand Reef South Wreck - Trench Databox',
'need_laser_cutter': False,
'position': {'x': -850.9, 'y': -473.2, 'z': -1414.6}},
33020: {'can_slip_through': False,
'name': 'Grand Reef South Wreck - Comms Databox',
'need_laser_cutter': True,
'position': {'x': -889.4, 'y': -433.8, 'z': -1424.8}},
33021: {'can_slip_through': False,
'name': 'Grand Reef South Wreck - Outside Databox',
'need_laser_cutter': False,
'position': {'x': -862.4, 'y': -437.5, 'z': -1444.1}},
33022: {'can_slip_through': False,
'name': 'Grand Reef South Wreck - PDA',
'need_laser_cutter': False,
'position': {'x': -887.9, 'y': -446.0, 'z': -1422.7}},
33023: {'can_slip_through': False,
'name': 'Grassy Plateaus South Wreck - Databox',
'need_laser_cutter': False,
'position': {'x': -23.3, 'y': -105.8, 'z': -604.2}},
33024: {'can_slip_through': False,
'name': 'Grassy Plateaus South Wreck - PDA',
'need_laser_cutter': False,
'position': {'x': -27.3, 'y': -106.8, 'z': -607.2}},
33025: {'can_slip_through': True,
'name': 'Grassy Plateaus East Wreck - Breach Databox',
'need_laser_cutter': True,
'position': {'x': 313.9, 'y': -91.8, 'z': 432.6}},
33026: {'can_slip_through': True,
'name': 'Grassy Plateaus East Wreck - Hangar Databox',
'need_laser_cutter': True,
'position': {'x': 319.4, 'y': -104.3, 'z': 441.5}},
33027: {'can_slip_through': False,
'name': 'Grassy Plateaus West Wreck - Locker PDA',
'need_laser_cutter': False,
'position': {'x': -632.3, 'y': -75.0, 'z': -8.9}},
33028: {'can_slip_through': False,
'name': 'Grassy Plateaus West Wreck - Data Terminal',
'need_laser_cutter': False,
'position': {'x': -664.4, 'y': -97.8, 'z': -8.0}},
33029: {'can_slip_through': False,
'name': 'Grassy Plateaus West Wreck - Databox',
'need_laser_cutter': True,
'position': {'x': -421.4, 'y': -107.8, 'z': -266.5}},
33030: {'can_slip_through': False,
'name': 'Safe Shallows Wreck - PDA',
'need_laser_cutter': False,
'position': {'x': -44.0, 'y': -29.1, 'z': -403.6}},
33031: {'can_slip_through': False,
'name': 'Kelp Forest Wreck - Databox',
'need_laser_cutter': False,
'position': {'x': -317.6, 'y': -78.8, 'z': 247.4}},
33032: {'can_slip_through': False,
'name': 'Kelp Forest Wreck - PDA',
'need_laser_cutter': False,
'position': {'x': 63.2, 'y': -38.5, 'z': 382.9}},
33033: {'can_slip_through': False,
'name': 'Mountains West Wreck - Outside Databox',
'need_laser_cutter': False,
'position': {'x': 740.3, 'y': -389.2, 'z': 1179.8}},
33034: {'can_slip_through': False,
'name': 'Mountains West Wreck - Data Terminal',
'need_laser_cutter': True,
'position': {'x': 703.7, 'y': -365.9, 'z': 1199.3}},
33035: {'can_slip_through': False,
'name': 'Mountains West Wreck - Hangar Databox',
'need_laser_cutter': True,
'position': {'x': 698.2, 'y': -350.8, 'z': 1186.9}},
33036: {'can_slip_through': False,
'name': 'Mountains West Wreck - Office Databox',
'need_laser_cutter': False,
'position': {'x': 676.3, 'y': -343.6, 'z': 1204.6}},
33037: {'can_slip_through': False,
'name': 'Mountains East Wreck - Comms Databox',
'need_laser_cutter': False,
'position': {'x': 1068.5, 'y': -283.4, 'z': 1345.3}},
33038: {'can_slip_through': False,
'name': 'Mountains East Wreck - Outside Databox',
'need_laser_cutter': False,
'position': {'x': 1075.7, 'y': -288.9, 'z': 1321.8}},
33039: {'can_slip_through': False,
'name': 'Northwestern Mushroom Forest Wreck - Cargo Databox',
'need_laser_cutter': True,
'position': {'x': -655.1, 'y': -109.6, 'z': 791.0}},
33040: {'can_slip_through': False,
'name': 'Northwestern Mushroom Forest Wreck - Office Databox',
'need_laser_cutter': False,
'position': {'x': -663.4, 'y': -111.9, 'z': 777.9}},
33041: {'can_slip_through': False,
'name': 'Northwestern Mushroom Forest Wreck - PDA',
'need_laser_cutter': False,
'position': {'x': -662.2, 'y': -113.4, 'z': 777.7}},
33042: {'can_slip_through': False,
'name': "Sea Treader's Path Wreck - Outside Databox",
'need_laser_cutter': False,
'position': {'x': -1161.1, 'y': -191.7, 'z': -758.3}},
33043: {'can_slip_through': False,
'name': "Sea Treader's Path Wreck - Hangar Databox",
'need_laser_cutter': True,
'position': {'x': -1129.5, 'y': -155.2, 'z': -729.3}},
33044: {'can_slip_through': False,
'name': "Sea Treader's Path Wreck - Lobby Databox",
'need_laser_cutter': False,
'position': {'x': -1115.9, 'y': -175.3, 'z': -724.5}},
33045: {'can_slip_through': False,
'name': "Sea Treader's Path Wreck - PDA",
'need_laser_cutter': False,
'position': {'x': -1136.8, 'y': -157.0, 'z': -734.6}},
33046: {'can_slip_through': False,
'name': 'Sparse Reef Wreck - Locker Databox',
'need_laser_cutter': True,
'position': {'x': -789.8, 'y': -216.1, 'z': -711.0}},
33047: {'can_slip_through': False,
'name': 'Sparse Reef Wreck - Outside Databox',
'need_laser_cutter': False,
'position': {'x': -810.7, 'y': -209.3, 'z': -685.5}},
33048: {'can_slip_through': False,
'name': 'Sparse Reef Wreck - Lab Databox',
'need_laser_cutter': True,
'position': {'x': -795.5, 'y': -204.1, 'z': -774.7}},
33049: {'can_slip_through': False,
'name': 'Underwater Islands Wreck - Outside Databox',
'need_laser_cutter': False,
'position': {'x': -170.8, 'y': -187.6, 'z': 880.7}},
33050: {'can_slip_through': False,
'name': 'Underwater Islands Wreck - Hangar Databox',
'need_laser_cutter': True,
'position': {'x': -138.4, 'y': -193.6, 'z': 888.7}},
33051: {'can_slip_through': False,
'name': 'Underwater Islands Wreck - Data Terminal',
'need_laser_cutter': True,
'position': {'x': -130.7, 'y': -193.2, 'z': 883.3}},
33052: {'can_slip_through': False,
'name': 'Underwater Islands Wreck - Cable Databox',
'need_laser_cutter': False,
'position': {'x': -137.8, 'y': -193.4, 'z': 879.4}},
33053: {'can_slip_through': False,
'name': 'Underwater Islands Wreck - Pipes Databox 1',
'need_laser_cutter': False,
'need_propulsion_cannon': True,
'position': {'x': -124.4, 'y': -200.7, 'z': 853.0}},
33054: {'can_slip_through': False,
'name': 'Underwater Islands Wreck - Pipes Databox 2',
'need_laser_cutter': False,
'need_propulsion_cannon': True,
'position': {'x': -126.8, 'y': -201.1, 'z': 852.1}},
33055: {'can_slip_through': False,
'name': 'Degasi Seabase - Deep Grand Reef - Bedroom Databox',
'need_laser_cutter': False,
'position': {'x': -643.8, 'y': -509.9, 'z': -941.9}},
33056: {'can_slip_through': False,
'name': 'Degasi Seabase - Deep Grand Reef - Observatory Databox',
'need_laser_cutter': False,
'position': {'x': -635.1, 'y': -502.7, 'z': -951.4}},
33057: {'can_slip_through': False,
'name': 'Degasi Seabase - Deep Grand Reef - Bedroom PDA',
'need_laser_cutter': False,
'position': {'x': -645.8, 'y': -508.7, 'z': -943.0}},
33058: {'can_slip_through': False,
'name': 'Degasi Seabase - Deep Grand Reef - Outside PDA',
'need_laser_cutter': False,
'position': {'x': -630.5, 'y': -511.1, 'z': -936.1}},
33059: {'can_slip_through': False,
'name': 'Degasi Seabase - Deep Grand Reef - Observatory PDA',
'need_laser_cutter': False,
'position': {'x': -647.7, 'y': -502.6, 'z': -935.8}},
33060: {'can_slip_through': False,
'name': 'Degasi Seabase - Deep Grand Reef - Lab PDA',
'need_laser_cutter': False,
'position': {'x': -639.6, 'y': -505.9, 'z': -946.6}},
33061: {'can_slip_through': False,
'name': 'Floating Island - Lake PDA',
'need_laser_cutter': False,
'position': {'x': -707.2, 'y': 0.5, 'z': -1096.7}},
33062: {'can_slip_through': False,
'name': 'Degasi Seabase - Floating Island - Databox',
'need_laser_cutter': False,
'position': {'x': -765.7, 'y': 17.6, 'z': -1116.4}},
33063: {'can_slip_through': False,
'name': 'Degasi Seabase - Floating Island - Room PDA',
'need_laser_cutter': False,
'position': {'x': -754.9, 'y': 14.6, 'z': -1108.9}},
33064: {'can_slip_through': False,
'name': 'Degasi Seabase - Floating Island - Green Wall PDA',
'need_laser_cutter': False,
'position': {'x': -765.3, 'y': 14.1, 'z': -1115.0}},
33065: {'can_slip_through': False,
'name': 'Degasi Seabase - Floating Island - Corridor PDA',
'need_laser_cutter': False,
'position': {'x': -758.6, 'y': 14.1, 'z': -1111.3}},
33066: {'can_slip_through': False,
'name': 'Degasi Seabase - Floating Island - North Observatory PDA',
'need_laser_cutter': False,
'position': {'x': -805.4, 'y': 76.9, 'z': -1055.7}},
33067: {'can_slip_through': False,
'name': 'Degasi Seabase - Floating Island - South Observatory PDA',
'need_laser_cutter': False,
'position': {'x': -715.9, 'y': 75.4, 'z': -1168.8}},
33068: {'can_slip_through': False,
'name': 'Jellyshroom Cave - PDA',
'need_laser_cutter': False,
'position': {'x': -540.5, 'y': -250.8, 'z': -83.4}},
33069: {'can_slip_through': False,
'name': 'Degasi Seabase - Jellyshroom Cave - Bedroom Databox',
'need_laser_cutter': False,
'position': {'x': 110.6, 'y': -264.9, 'z': -369.0}},
33070: {'can_slip_through': False,
'name': 'Degasi Seabase - Jellyshroom Cave - Detached PDA',
'need_laser_cutter': False,
'position': {'x': 80.6, 'y': -268.6, 'z': -358.3}},
33071: {'can_slip_through': False,
'name': 'Degasi Seabase - Jellyshroom Cave - Office PDA',
'need_laser_cutter': False,
'position': {'x': 78.2, 'y': -265.0, 'z': -373.4}},
33072: {'can_slip_through': False,
'name': 'Degasi Seabase - Jellyshroom Cave - Locker PDA',
'need_laser_cutter': False,
'position': {'x': 85.1, 'y': -264.1, 'z': -372.8}},
33073: {'can_slip_through': False,
'name': 'Degasi Seabase - Jellyshroom Cave - Bedroom PDA',
'need_laser_cutter': False,
'position': {'x': 112.3, 'y': -264.9, 'z': -369.3}},
33074: {'can_slip_through': False,
'name': 'Degasi Seabase - Jellyshroom Cave - Observatory PDA',
'need_laser_cutter': False,
'position': {'x': 95.5, 'y': -258.9, 'z': -366.5}},
33075: {'can_slip_through': False,
'name': 'Lifepod 2 - Databox',
'need_laser_cutter': False,
'position': {'x': -483.6, 'y': -504.7, 'z': 1326.6}},
33076: {'can_slip_through': False,
'name': 'Lifepod 2 - PDA',
'need_laser_cutter': False,
'position': {'x': -481.4, 'y': -503.6, 'z': 1324.1}},
33077: {'can_slip_through': False,
'name': 'Lifepod 3 - Databox',
'need_laser_cutter': False,
'position': {'x': -34.2, 'y': -22.4, 'z': 410.5}},
33078: {'can_slip_through': False,
'name': 'Lifepod 3 - PDA',
'need_laser_cutter': False,
'position': {'x': -33.8, 'y': -22.5, 'z': 408.8}},
33079: {'can_slip_through': False,
'name': 'Lifepod 4 - Databox',
'need_laser_cutter': False,
'position': {'x': 712.4, 'y': -3.4, 'z': 160.8}},
33080: {'can_slip_through': False,
'name': 'Lifepod 4 - PDA',
'need_laser_cutter': False,
'position': {'x': 712.0, 'y': -3.5, 'z': 161.5}},
33081: {'can_slip_through': False,
'name': 'Lifepod 6 - Databox',
'need_laser_cutter': False,
'position': {'x': 358.7, 'y': -117.1, 'z': 306.8}},
33082: {'can_slip_through': False,
'name': 'Lifepod 6 - Inside PDA',
'need_laser_cutter': False,
'position': {'x': 361.8, 'y': -116.2, 'z': 309.5}},
33083: {'can_slip_through': False,
'name': 'Lifepod 6 - Outside PDA',
'need_laser_cutter': False,
'position': {'x': 359.9, 'y': -117.0, 'z': 312.1}},
33084: {'can_slip_through': False,
'name': 'Lifepod 7 - PDA',
'need_laser_cutter': False,
'position': {'x': -56.0, 'y': -182.0, 'z': -1039.0}},
33085: {'can_slip_through': False,
'name': 'Lifepod 12 - Databox',
'need_laser_cutter': False,
'position': {'x': 1119.5, 'y': -271.7, 'z': 561.7}},
33086: {'can_slip_through': False,
'name': 'Lifepod 12 - PDA',
'need_laser_cutter': False,
'position': {'x': 1116.1, 'y': -271.3, 'z': 566.9}},
33087: {'can_slip_through': False,
'name': 'Lifepod 13 - Databox',
'need_laser_cutter': False,
'position': {'x': -926.4, 'y': -185.2, 'z': 501.8}},
33088: {'can_slip_through': False,
'name': 'Lifepod 13 - PDA',
'need_laser_cutter': False,
'position': {'x': -926.8, 'y': -184.4, 'z': 506.6}},
33089: {'can_slip_through': False,
'name': 'Lifepod 17 - PDA',
'need_laser_cutter': False,
'position': {'x': -514.5, 'y': -98.1, 'z': -56.5}},
33090: {'can_slip_through': False,
'name': 'Lifepod 19 - Databox',
'need_laser_cutter': False,
'position': {'x': -809.8, 'y': -302.2, 'z': -876.9}},
33091: {'can_slip_through': False,
'name': 'Lifepod 19 - Outside PDA',
'need_laser_cutter': False,
'position': {'x': -806.1, 'y': -294.1, 'z': -866.0}},
33092: {'can_slip_through': False,
'name': 'Lifepod 19 - Inside PDA',
'need_laser_cutter': False,
'position': {'x': -810.5, 'y': -299.4, 'z': -873.1}},
33093: {'can_slip_through': False,
'name': 'Aurora Seamoth Bay - Upgrade Console',
'need_laser_cutter': False,
'need_propulsion_cannon': True,
'position': {'x': 903.5, 'y': -0.2, 'z': 16.1}},
33094: {'can_slip_through': False,
'name': 'Aurora Drive Room - Upgrade Console',
'need_laser_cutter': False,
'need_propulsion_cannon': True,
'position': {'x': 872.5, 'y': 2.7, 'z': -0.7}},
33095: {'can_slip_through': False,
'name': 'Aurora Prawn Suit Bay - Upgrade Console',
'need_laser_cutter': True,
'need_propulsion_cannon': True,
'position': {'x': 991.6, 'y': 3.2, 'z': -31.0}},
33096: {'can_slip_through': False,
'name': 'Aurora - Office PDA',
'need_laser_cutter': False,
'position': {'x': 952.1, 'y': 41.2, 'z': 113.9}},
33097: {'can_slip_through': False,
'name': 'Aurora - Corridor PDA',
'need_laser_cutter': False,
'position': {'x': 977.2, 'y': 39.1, 'z': 83.0}},
33098: {'can_slip_through': False,
'name': 'Aurora - Cargo Bay PDA',
'need_laser_cutter': False,
'need_propulsion_cannon': True,
'position': {'x': 954.9, 'y': 11.2, 'z': 3.4}},
33099: {'can_slip_through': False,
'name': 'Aurora - Seamoth Bay PDA',
'need_laser_cutter': False,
'need_propulsion_cannon': True,
'position': {'x': 907.1, 'y': -1.5, 'z': 15.3}},
33100: {'can_slip_through': False,
'name': 'Aurora - Medkit Locker PDA',
'need_laser_cutter': True,
'need_propulsion_cannon': True,
'position': {'x': 951.8, 'y': -2.3, 'z': -34.7}},
33101: {'can_slip_through': False,
'name': 'Aurora - Locker PDA',
'need_laser_cutter': True,
'need_propulsion_cannon': True,
'position': {'x': 952.0, 'y': -3.7, 'z': -23.4}},
33102: {'can_slip_through': False,
'name': 'Aurora - Canteen PDA',
'need_laser_cutter': True,
'need_propulsion_cannon': True,
'position': {'x': 986.5, 'y': 9.6, 'z': -48.6}},
33103: {'can_slip_through': False,
'name': 'Aurora - Cabin 4 PDA',
'need_laser_cutter': True,
'need_propulsion_cannon': True,
'position': {'x': 951.3, 'y': 11.2, 'z': -51.0}},
33104: {'can_slip_through': False,
'name': 'Aurora - Cabin 7 PDA',
'need_laser_cutter': True,
'need_propulsion_cannon': True,
'position': {'x': 967.1, 'y': 10.4, 'z': -47.4}},
33105: {'can_slip_through': False,
'name': 'Aurora - Cabin 1 PDA',
'need_laser_cutter': True,
'need_propulsion_cannon': True,
'position': {'x': 964.1, 'y': 11.1, 'z': -61.9}},
33106: {'can_slip_through': False,
'name': 'Aurora - Captain PDA',
'need_laser_cutter': True,
'need_propulsion_cannon': True,
'position': {'x': 971.2, 'y': 10.8, 'z': -70.4}},
33107: {'can_slip_through': False,
'name': 'Aurora - Ring PDA',
'need_laser_cutter': False,
'need_propulsion_cannon': True,
'position': {'x': 1033.6, 'y': -8.5, 'z': 16.2}},
33108: {'can_slip_through': False,
'name': 'Aurora - Lab PDA',
'need_laser_cutter': False,
'need_propulsion_cannon': True,
'position': {'x': 1032.5, 'y': -7.8, 'z': 32.4}},
33109: {'can_slip_through': False,
'name': 'Aurora - Office Data Terminal',
'need_laser_cutter': False,
'position': {'x': 945.8, 'y': 40.8, 'z': 115.1}},
33110: {'can_slip_through': False,
'name': 'Aurora - Captain Data Terminal',
'need_laser_cutter': True,
'need_propulsion_cannon': True,
'position': {'x': 974.8, 'y': 10.0, 'z': -77.0}},
33111: {'can_slip_through': False,
'name': 'Aurora - Battery Room Data Terminal',
'need_laser_cutter': True,
'need_propulsion_cannon': True,
'position': {'x': 1040.8, 'y': -11.4, 'z': -3.4}},
33112: {'can_slip_through': False,
'name': 'Aurora - Lab Data Terminal',
'need_laser_cutter': False,
'need_propulsion_cannon': True,
'position': {'x': 1029.5, 'y': -8.7, 'z': 35.9}},
33113: {'can_slip_through': False,
'name': "Quarantine Enforcement Platform's - Upper Alien Data "
'Terminal',
'need_laser_cutter': False,
'position': {'x': 432.2, 'y': 3.0, 'z': 1193.2}},
33114: {'can_slip_through': False,
'name': "Quarantine Enforcement Platform's - Mid Alien Data Terminal",
'need_laser_cutter': False,
'position': {'x': 474.4, 'y': -4.5, 'z': 1224.4}},
33115: {'can_slip_through': False,
'name': 'Dunes Sanctuary - Alien Data Terminal',
'need_laser_cutter': False,
'position': {'x': -1224.2, 'y': -400.4, 'z': 1057.9}},
33116: {'can_slip_through': False,
'name': 'Deep Sparse Reef Sanctuary - Alien Data Terminal',
'need_laser_cutter': False,
'position': {'x': -895.5, 'y': -311.6, 'z': -838.1}},
33117: {'can_slip_through': False,
'name': 'Northern Blood Kelp Zone Sanctuary - Alien Data Terminal',
'need_laser_cutter': False,
'position': {'x': -642.9, 'y': -563.5, 'z': 1485.5}},
33118: {'can_slip_through': False,
'name': 'Lost River Laboratory Cache - Alien Data Terminal',
'need_laser_cutter': False,
'position': {'x': -1112.3, 'y': -687.3, 'z': -695.5}},
33119: {'can_slip_through': False,
'name': 'Disease Research Facility - Upper Alien Data Terminal',
'need_laser_cutter': False,
'position': {'x': -280.2, 'y': -804.3, 'z': 305.1}},
33120: {'can_slip_through': False,
'name': 'Disease Research Facility - Mid Alien Data Terminal',
'need_laser_cutter': False,
'position': {'x': -267.9, 'y': -806.6, 'z': 250.0}},
33121: {'can_slip_through': False,
'name': 'Disease Research Facility - Lower Alien Data Terminal',
'need_laser_cutter': False,
'position': {'x': -286.2, 'y': -815.6, 'z': 297.8}},
33122: {'can_slip_through': False,
'name': 'Alien Thermal Plant - Entrance Alien Data Terminal',
'need_laser_cutter': False,
'position': {'x': -71.3, 'y': -1227.2, 'z': 104.8}},
33123: {'can_slip_through': False,
'name': 'Alien Thermal Plant - Green Alien Data Terminal',
'need_laser_cutter': False,
'position': {'x': -38.7, 'y': -1226.6, 'z': 111.8}},
33124: {'can_slip_through': False,
'name': 'Alien Thermal Plant - Yellow Alien Data Terminal',
'need_laser_cutter': False,
'position': {'x': -30.4, 'y': -1220.3, 'z': 111.8}},
33125: {'can_slip_through': False,
'name': "Primary Containment Facility's Antechamber - Alien Data "
'Terminal',
'need_laser_cutter': False,
'position': {'x': 245.8, 'y': -1430.6, 'z': -311.5}},
33126: {'can_slip_through': False,
'name': "Primary Containment Facility's Egg Laboratory - Alien Data "
'Terminal',
'need_laser_cutter': False,
'position': {'x': 165.5, 'y': -1442.4, 'z': -385.8}},
33127: {'can_slip_through': False,
'name': "Primary Containment Facility's Pipe Room - Alien Data "
'Terminal',
'need_laser_cutter': False,
'position': {'x': 348.7, 'y': -1443.5, 'z': -291.9}},
33128: {'can_slip_through': False,
'name': 'Grassy Plateaus West Wreck - Beam PDA',
'need_laser_cutter': True,
'position': {'x': -641.8, 'y': -111.3, 'z': -19.7}},
33129: {'can_slip_through': False,
'name': 'Floating Island - Cave Entrance PDA',
'need_laser_cutter': False,
'position': {'x': -748.9, 'y': 14.4, 'z': -1179.5}}}
if False: # turn to True to export for Subnautica mod
payload = {location_id: location_data["position"] for location_id, location_data in location_table.items()}
import json
with open("locations.json", "w") as f:
json.dump(payload, f)

View File

@ -2,13 +2,36 @@ from Options import Choice
class ItemPool(Choice):
"""Valuable item pool moves all not progression relevant items to starting inventory and
creates random duplicates of important items in their place."""
"""Valuable item pool leaves all filler items in their vanilla locations and
creates random duplicates of important items into freed spots."""
display_name = "Item Pool"
option_standard = 0
option_valuable = 1
class Goal(Choice):
"""Goal to complete.
Launch: Leave the planet.
Free: Disable quarantine.
Infected: Reach maximum infection level.
Drive: Repair the Aurora's Drive Core"""
auto_display_name = True
display_name = "Goal"
option_launch = 0
option_free = 1
option_infected = 2
option_drive = 3
def get_event_name(self) -> str:
return {
self.option_launch: "Neptune Launch",
self.option_infected: "Full Infection",
self.option_free: "Disable Quarantine",
self.option_drive: "Repair Aurora Drive"
}[self.value]
options = {
"item_pool": ItemPool
"item_pool": ItemPool,
"goal": Goal,
}

View File

@ -1,8 +0,0 @@
def create_regions(world, player: int):
from . import create_region
from .Locations import lookup_name_to_id as location_lookup_name_to_id
world.regions += [
create_region(world, player, 'Menu', None, ['Lifepod 5']),
create_region(world, player, 'Planet 4546B', [location for location in location_lookup_name_to_id])
]

View File

@ -1,6 +1,5 @@
from ..generic.Rules import set_rule
from .Locations import location_table
import logging
from worlds.generic.Rules import set_rule
from .Locations import location_table, LocationDict
import math
@ -197,32 +196,32 @@ def get_max_depth(state, player):
get_prawn_max_depth(state, player))
def can_access_location(state, player, loc):
pos_x = loc.get("position").get("x")
pos_y = loc.get("position").get("y")
pos_z = loc.get("position").get("z")
depth = -pos_y # y-up
map_center_dist = math.sqrt(pos_x ** 2 + pos_z ** 2)
aurora_dist = math.sqrt((pos_x - 1038.0) ** 2 + (pos_y - -3.4) ** 2 + (pos_z - -163.1) ** 2)
need_radiation_suit = aurora_dist < 950
def can_access_location(state, player: int, loc: LocationDict):
need_laser_cutter = loc.get("need_laser_cutter", False)
need_propulsion_cannon = loc.get("need_propulsion_cannon", False)
if need_laser_cutter and not has_laser_cutter(state, player):
return False
if need_radiation_suit and not state.has("Radiation Suit", player):
need_propulsion_cannon = loc.get("need_propulsion_cannon", False)
if need_propulsion_cannon and not has_propulsion_cannon(state, player):
return False
if need_propulsion_cannon and not has_propulsion_cannon(state, player):
pos = loc["position"]
pos_x = pos["x"]
pos_y = pos["y"]
pos_z = pos["z"]
aurora_dist = math.sqrt((pos_x - 1038.0) ** 2 + (pos_y - -3.4) ** 2 + (pos_z - -163.1) ** 2)
need_radiation_suit = aurora_dist < 950
if need_radiation_suit and not state.has("Radiation Suit", player):
return False
# Seaglide doesn't unlock anything specific, but just allows for faster movement.
# Otherwise the game is painfully slow.
map_center_dist = math.sqrt(pos_x ** 2 + pos_z ** 2)
if (map_center_dist > 800 or pos_y < -200) and not has_seaglide(state, player):
return False
depth = -pos_y # y-up
return get_max_depth(state, player) >= depth
@ -230,21 +229,33 @@ def set_location_rule(world, player, loc):
set_rule(world.get_location(loc["name"], player), lambda state: can_access_location(state, player, loc))
def set_rules(world, player):
for loc in location_table:
def set_rules(subnautica_world):
player = subnautica_world.player
world = subnautica_world.world
for loc in location_table.values():
set_location_rule(world, player, loc)
# Victory location
set_rule(world.get_location("Neptune Launch", player), lambda state: \
get_max_depth(state, player) >= 1444 and \
has_mobile_vehicle_bay(state, player) and \
state.has('Neptune Launch Platform', player) and \
state.has('Neptune Gantry', player) and \
state.has('Neptune Boosters', player) and \
state.has('Neptune Fuel Reserve', player) and \
state.has('Neptune Cockpit', player) and \
state.has('Ion Power Cell', player) and \
state.has('Ion Battery', player) and \
# Victory locations
set_rule(world.get_location("Neptune Launch", player), lambda state:
get_max_depth(state, player) >= 1444 and
has_mobile_vehicle_bay(state, player) and
state.has("Neptune Launch Platform", player) and
state.has("Neptune Gantry", player) and
state.has("Neptune Boosters", player) and
state.has("Neptune Fuel Reserve", player) and
state.has("Neptune Cockpit", player) and
state.has("Ion Power Cell", player) and
state.has("Ion Battery", player) and
has_cyclops_shield(state, player))
world.completion_condition[player] = lambda state: state.has('Victory', player)
set_rule(world.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)
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))
world.completion_condition[player] = lambda state: state.has("Victory", player)

View File

@ -1,18 +1,16 @@
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 Options
from .Items import item_table
from .Rules import set_rules
logger = logging.getLogger("Subnautica")
from .Locations import lookup_name_to_id as locations_lookup_name_to_id
from .Items import item_table, lookup_name_to_item, advancement_item_names
from .Items import lookup_name_to_id as items_lookup_name_to_id
from .Regions import create_regions
from .Rules import set_rules
from .Options import options
from BaseClasses import Region, Entrance, Location, MultiWorld, Item, Tutorial, ItemClassification, RegionType
from ..AutoWorld import World, WebWorld
class SubnaticaWeb(WebWorld):
tutorials = [Tutorial(
@ -34,34 +32,51 @@ class SubnauticaWorld(World):
game: str = "Subnautica"
web = SubnaticaWeb()
item_name_to_id = items_lookup_name_to_id
location_name_to_id = locations_lookup_name_to_id
options = options
item_name_to_id = {data["name"]: item_id for item_id, data in Items.item_table.items()}
location_name_to_id = {data["name"]: loc_id for loc_id, data in Locations.location_table.items()}
options = Options.options
data_version = 2
required_client_version = (0, 1, 9)
required_client_version = (0, 3, 3)
prefill_items: List[Item]
def generate_early(self) -> None:
self.prefill_items = [
self.create_item("Seaglide Fragment"),
self.create_item("Seaglide Fragment")
]
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()])
]
# 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))
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 = 0
valuable = self.world.item_pool[self.player] == "valuable"
for item in item_table:
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 not item["progression"]:
self.world.push_precollected(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(advancement_item_names - {"Neptune Launch Platform"}),
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
@ -72,39 +87,57 @@ class SubnauticaWorld(World):
# Victory item
self.world.get_location("Aurora - Captain Data Terminal", self.player).place_locked_item(
neptune_launch_platform)
self.world.get_location("Neptune Launch", self.player).place_locked_item(
SubnauticaItem("Victory", ItemClassification.progression, None, player=self.player))
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 set_rules(self):
set_rules(self.world, self.player)
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"])
def create_regions(self):
create_regions(self.world, self.player)
slot_data: Dict[str, Any] = {
"goal": goal.current_key,
"vanilla_tech": vanilla_tech,
}
def fill_slot_data(self):
slot_data = {}
return slot_data
def create_item(self, name: str) -> Item:
item = lookup_name_to_item[name]
item_id: int = self.item_name_to_id[name]
return SubnauticaItem(name,
ItemClassification.progression if item["progression"] else ItemClassification.filler,
item["id"], player=self.player)
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 create_region(world: MultiWorld, player: int, name: str, locations=None, exits=None):
ret = Region(name, RegionType.Generic, name, player)
ret.world = world
if locations:
for location in locations:
loc_id = locations_lookup_name_to_id.get(location, 0)
location = SubnauticaLocation(player, location, loc_id, ret)
ret.locations.append(location)
if exits:
for exit in exits:
ret.exits.append(Entrance(player, exit, ret))
def get_pre_fill_items(self) -> List[Item]:
return self.prefill_items
return ret
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):
@ -112,4 +145,4 @@ class SubnauticaLocation(Location):
class SubnauticaItem(Item):
game = "Subnautica"
game: str = "Subnautica"

View File

@ -1,83 +0,0 @@
[
{ "id": 35000, "count": 1, "progression": false, "tech_type": "Compass", "name": "Compass" },
{ "id": 35001, "count": 1, "progression": true, "tech_type": "PlasteelTank", "name": "Lightweight High Capacity Tank" },
{ "id": 35002, "count": 1, "progression": true, "tech_type": "BaseUpgradeConsole", "name": "Vehicle Upgrade Console" },
{ "id": 35003, "count": 1, "progression": true, "tech_type": "UltraGlideFins", "name": "Ultra Glide Fins" },
{ "id": 35004, "count": 1, "progression": false, "tech_type": "CyclopsSonarModule", "name": "Cyclops Sonar Upgrade" },
{ "id": 35005, "count": 1, "progression": false, "tech_type": "ReinforcedDiveSuit", "name": "Reinforced Dive Suit" },
{ "id": 35006, "count": 1, "progression": false, "tech_type": "CyclopsThermalReactorModule", "name": "Cyclops Thermal Reactor Module" },
{ "id": 35007, "count": 1, "progression": false, "tech_type": "Stillsuit", "name": "Stillsuit" },
{ "id": 35008, "count": 2, "progression": false, "tech_type": "BaseWaterParkFragment", "name": "Alien Containment Fragment" },
{ "id": 35009, "count": 1, "progression": false, "tech_type": "CyclopsDecoy", "name": "Creature Decoy" },
{ "id": 35010, "count": 1, "progression": false, "tech_type": "CyclopsFireSuppressionModule", "name": "Cyclops Fire Suppression System" },
{ "id": 35011, "count": 1, "progression": false, "tech_type": "SwimChargeFins", "name": "Swim Charge Fins" },
{ "id": 35012, "count": 1, "progression": false, "tech_type": "RepulsionCannon", "name": "Repulsion Cannon" },
{ "id": 35013, "count": 1, "progression": false, "tech_type": "CyclopsDecoyModule", "name": "Cyclops Decoy Tube Upgrade" },
{ "id": 35014, "count": 1, "progression": true, "tech_type": "CyclopsShieldModule", "name": "Cyclops Shield Generator" },
{ "id": 35015, "count": 1, "progression": true, "tech_type": "CyclopsHullModule1", "name": "Cyclops Depth Module MK1" },
{ "id": 35016, "count": 1, "progression": false, "tech_type": "CyclopsSeamothRepairModule", "name": "Cyclops Docking Bay Repair Module" },
{ "id": 35017, "count": 2, "progression": false, "tech_type": "BatteryChargerFragment", "name": "Battery Charger fragment" },
{ "id": 35018, "count": 2, "progression": false, "tech_type": "BeaconFragment", "name": "Beacon Fragment" },
{ "id": 35019, "count": 2, "progression": false, "tech_type": "BaseBioReactorFragment", "name": "Bioreactor Fragment" },
{ "id": 35020, "count": 3, "progression": true, "tech_type": "CyclopsBridgeFragment", "name": "Cyclops Bridge Fragment" },
{ "id": 35021, "count": 3, "progression": true, "tech_type": "CyclopsEngineFragment", "name": "Cyclops Engine Fragment" },
{ "id": 35022, "count": 3, "progression": true, "tech_type": "CyclopsHullFragment", "name": "Cyclops Hull Fragment" },
{ "id": 35023, "count": 2, "progression": false, "tech_type": "GravSphereFragment", "name": "Grav Trap Fragment" },
{ "id": 35024, "count": 3, "progression": true, "tech_type": "LaserCutterFragment", "name": "Laser Cutter Fragment" },
{ "id": 35025, "count": 1, "progression": false, "tech_type": "TechlightFragment", "name": "Light Stick Fragment" },
{ "id": 35026, "count": 3, "progression": true, "tech_type": "ConstructorFragment", "name": "Mobile Vehicle Bay Fragment" },
{ "id": 35027, "count": 3, "progression": true, "tech_type": "WorkbenchFragment", "name": "Modification Station Fragment" },
{ "id": 35028, "count": 2, "progression": true, "tech_type": "MoonpoolFragment", "name": "Moonpool Fragment" },
{ "id": 35029, "count": 3, "progression": false, "tech_type": "BaseNuclearReactorFragment", "name": "Nuclear Reactor Fragment" },
{ "id": 35030, "count": 2, "progression": false, "tech_type": "PowerCellChargerFragment", "name": "Power Cell Charger Fragment" },
{ "id": 35031, "count": 1, "progression": false, "tech_type": "PowerTransmitterFragment", "name": "Power Transmitter Fragment" },
{ "id": 35032, "count": 4, "progression": true, "tech_type": "ExosuitFragment", "name": "Prawn Suit Fragment" },
{ "id": 35033, "count": 2, "progression": false, "tech_type": "ExosuitDrillArmFragment", "name": "Prawn Suit Drill Arm Fragment" },
{ "id": 35034, "count": 2, "progression": false, "tech_type": "ExosuitGrapplingArmFragment", "name": "Prawn Suit Grappling Arm Fragment" },
{ "id": 35035, "count": 2, "progression": false, "tech_type": "ExosuitPropulsionArmFragment", "name": "Prawn Suit Propulsion Cannon Fragment" },
{ "id": 35036, "count": 2, "progression": false, "tech_type": "ExosuitTorpedoArmFragment", "name": "Prawn Suit Torpedo Arm Fragment" },
{ "id": 35037, "count": 3, "progression": false, "tech_type": "BaseMapRoomFragment", "name": "Scanner Room Fragment" },
{ "id": 35038, "count": 5, "progression": true, "tech_type": "SeamothFragment", "name": "Seamoth Fragment" },
{ "id": 35039, "count": 2, "progression": false, "tech_type": "StasisRifleFragment", "name": "Stasis Rifle Fragment" },
{ "id": 35040, "count": 2, "progression": false, "tech_type": "ThermalPlantFragment", "name": "Thermal Plant Fragment" },
{ "id": 35041, "count": 4, "progression": true, "tech_type": "SeaglideFragment", "name": "Seaglide Fragment" },
{ "id": 35042, "count": 1, "progression": true, "tech_type": "RadiationSuit", "name": "Radiation Suit" },
{ "id": 35043, "count": 2, "progression": true, "tech_type": "PropulsionCannonFragment", "name": "Propulsion Cannon Fragment" },
{ "id": 35044, "count": 1, "progression": true, "tech_type": "RocketBase", "name": "Neptune Launch Platform" },
{ "id": 35045, "count": 1, "progression": true, "tech_type": "PrecursorIonPowerCell", "name": "Ion Power Cell" },
{ "id": 35046, "count": 2, "progression": false, "tech_type": "FarmingTrayFragment", "name": "Exterior Growbed Fragment" },
{ "id": 35047, "count": 1, "progression": false, "tech_type": "PictureFrameFragment", "name": "Picture Frame" },
{ "id": 35048, "count": 2, "progression": false, "tech_type": "BenchFragment", "name": "Bench Fragment" },
{ "id": 35049, "count": 1, "progression": false, "tech_type": "PlanterPotFragment", "name": "Basic Plant Pot" },
{ "id": 35050, "count": 1, "progression": false, "tech_type": "PlanterBoxFragment", "name": "Interior Growbed" },
{ "id": 35051, "count": 1, "progression": false, "tech_type": "PlanterShelfFragment", "name": "Plant Shelf" },
{ "id": 35052, "count": 2, "progression": false, "tech_type": "BaseObservatoryFragment", "name": "Observatory Fragment" },
{ "id": 35053, "count": 2, "progression": false, "tech_type": "BaseRoomFragment", "name": "Multipurpose Room Fragment" },
{ "id": 35054, "count": 2, "progression": false, "tech_type": "BaseBulkheadFragment", "name": "Bulkhead Fragment" },
{ "id": 35055, "count": 1, "progression": false, "tech_type": "Spotlight", "name": "Spotlight" },
{ "id": 35056, "count": 2, "progression": false, "tech_type": "StarshipDesk", "name": "Desk" },
{ "id": 35057, "count": 1, "progression": false, "tech_type": "StarshipChair", "name": "Swivel Chair" },
{ "id": 35058, "count": 1, "progression": false, "tech_type": "StarshipChair2", "name": "Office Chair" },
{ "id": 35059, "count": 1, "progression": false, "tech_type": "StarshipChair3", "name": "Command Chair" },
{ "id": 35060, "count": 2, "progression": false, "tech_type": "LabCounter", "name": "Counter" },
{ "id": 35061, "count": 1, "progression": false, "tech_type": "NarrowBed", "name": "Single Bed" },
{ "id": 35062, "count": 1, "progression": false, "tech_type": "Bed1", "name": "Basic Double Bed" },
{ "id": 35063, "count": 1, "progression": false, "tech_type": "Bed2", "name": "Quilted Double Bed" },
{ "id": 35064, "count": 2, "progression": false, "tech_type": "CoffeeVendingMachine", "name": "Coffee Vending Machine" },
{ "id": 35065, "count": 2, "progression": false, "tech_type": "Trashcans", "name": "Trash Can" },
{ "id": 35066, "count": 1, "progression": false, "tech_type": "Techlight", "name": "Floodlight" },
{ "id": 35067, "count": 1, "progression": false, "tech_type": "BarTable", "name": "Bar Table" },
{ "id": 35068, "count": 1, "progression": false, "tech_type": "VendingMachine", "name": "Vending Machine" },
{ "id": 35069, "count": 1, "progression": false, "tech_type": "SingleWallShelf", "name": "Single Wall Shelf" },
{ "id": 35070, "count": 1, "progression": false, "tech_type": "WallShelves", "name": "Wall Shelves" },
{ "id": 35071, "count": 1, "progression": false, "tech_type": "PlanterPot2", "name": "Round Plant Pot" },
{ "id": 35072, "count": 1, "progression": false, "tech_type": "PlanterPot3", "name": "Chic Plant Pot" },
{ "id": 35073, "count": 1, "progression": false, "tech_type": "LabTrashcan", "name": "Nuclear Waste Disposal" },
{ "id": 35074, "count": 1, "progression": false, "tech_type": "BasePlanter", "name": "Wall Planter" },
{ "id": 35075, "count": 1, "progression": true, "tech_type": "PrecursorIonBattery", "name": "Ion Battery" },
{ "id": 35076, "count": 1, "progression": true, "tech_type": "RocketBaseLadder", "name": "Neptune Gantry" },
{ "id": 35077, "count": 1, "progression": true, "tech_type": "RocketStage1", "name": "Neptune Boosters" },
{ "id": 35078, "count": 1, "progression": true, "tech_type": "RocketStage2", "name": "Neptune Fuel Reserve" },
{ "id": 35079, "count": 1, "progression": true, "tech_type": "RocketStage3", "name": "Neptune Cockpit" },
{ "id": 35080, "count": 1, "progression": false, "tech_type": "BaseFiltrationMachine", "name": "Water Filtration Machine" }
]

View File

@ -1,521 +0,0 @@
[
{ "id": 33000, "position": { "x": -1234.3, "y": -349.7, "z": -396.0},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Blood Kelp Trench Wreck - Outside Databox" },
{ "id": 33001, "position": { "x": -1208.0, "y": -349.6, "z": -383.0},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Blood Kelp Trench Wreck - Inside Databox" },
{ "id": 33002, "position": { "x": -1210.6, "y": -340.7, "z": -393.4},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Blood Kelp Trench Wreck - PDA" },
{ "id": 33003, "position": { "x": 903.8, "y": -220.3, "z": 590.9},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Bulb Zone West Wreck - Outside Databox" },
{ "id": 33004, "position": { "x": 910.9, "y": -201.8, "z": 623.5},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Bulb Zone West Wreck - Under Databox" },
{ "id": 33005, "position": { "x": 914.9, "y": -202.1, "z": 611.8},
"need_laser_cutter": true, "can_slip_through": false,
"name": "Bulb Zone West Wreck - Inside Databox" },
{ "id": 33006, "position": { "x": 912.6, "y": -202.0, "z": 609.5},
"need_laser_cutter": true, "can_slip_through": false,
"name": "Bulb Zone West Wreck - PDA" },
{ "id": 33007, "position": { "x": 1327.1, "y": -234.9, "z": 575.8},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Bulb Zone East Wreck - Databox" },
{ "id": 33008, "position": { "x": -1407.7, "y": -344.2, "z": 721.5},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Dunes North Wreck - Outside Databox" },
{ "id": 33009, "position": { "x": -1393.9, "y": -329.7, "z": 733.5},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Dunes North Wreck - Office Databox" },
{ "id": 33010, "position": { "x": -1396.3, "y": -330.8, "z": 730.0},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Dunes North Wreck - PDA" },
{ "id": 33011, "position": { "x": -1409.8, "y": -332.4, "z": 706.9},
"need_laser_cutter": true, "can_slip_through": false,
"name": "Dunes North Wreck - Cargo Databox" },
{ "id": 33012, "position": { "x": -1626.2, "y": -357.5, "z": 99.5},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Dunes West Wreck - Databox" },
{ "id": 33013, "position": { "x": -1196.3, "y": -223.0, "z": 12.5},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Dunes East Wreck - Outside Databox" },
{ "id": 33014, "position": { "x": -1206.4, "y": -225.6, "z": 4.0},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Dunes East Wreck - Inside Databox" },
{ "id": 33015, "position": { "x": -269.7, "y": -262.8, "z": -764.3},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Grand Reef North Wreck - Outside Databox" },
{ "id": 33016, "position": { "x": -285.8, "y": -240.2, "z": -786.5},
"need_laser_cutter": true, "can_slip_through": false,
"name": "Grand Reef North Wreck - Elevator Databox" },
{ "id": 33017, "position": { "x": -285.2, "y": -262.4, "z": -788.4},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Grand Reef North Wreck - Bottom Databox" },
{ "id": 33018, "position": { "x": -272.5, "y": -254.7, "z": -788.5},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Grand Reef North Wreck - Hangar PDA" },
{ "id": 33019, "position": { "x": -850.9, "y": -473.2, "z": -1414.6},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Grand Reef South Wreck - Trench Databox" },
{ "id": 33020, "position": { "x": -889.4, "y": -433.8, "z": -1424.8},
"need_laser_cutter": true, "can_slip_through": false,
"name": "Grand Reef South Wreck - Comms Databox" },
{ "id": 33021, "position": { "x": -862.4, "y": -437.5, "z": -1444.1},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Grand Reef South Wreck - Outside Databox" },
{ "id": 33022, "position": { "x": -887.9, "y": -446.0, "z": -1422.7},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Grand Reef South Wreck - PDA" },
{ "id": 33023, "position": { "x": -23.3, "y": -105.8, "z": -604.2},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Grassy Plateaus South Wreck - Databox" },
{ "id": 33024, "position": { "x": -27.3, "y": -106.8, "z": -607.2},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Grassy Plateaus South Wreck - PDA" },
{ "id": 33025, "position": { "x": 313.9, "y": -91.8, "z": 432.6},
"need_laser_cutter": true, "can_slip_through": true,
"name": "Grassy Plateaus East Wreck - Breach Databox" },
{ "id": 33026, "position": { "x": 319.4, "y": -104.3, "z": 441.5},
"need_laser_cutter": true, "can_slip_through": true,
"name": "Grassy Plateaus East Wreck - Hangar Databox" },
{ "id": 33027, "position": { "x": -632.3, "y": -75.0, "z": -8.9},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Grassy Plateaus West Wreck - Locker PDA" },
{ "id": 33028, "position": { "x": -664.4, "y": -97.8, "z": -8.0},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Grassy Plateaus West Wreck - Data Terminal" },
{ "id": 33029, "position": { "x": -421.4, "y": -107.8, "z": -266.5},
"need_laser_cutter": true, "can_slip_through": false,
"name": "Grassy Plateaus West Wreck - Databox" },
{ "id": 33030, "position": { "x": -44.0, "y": -29.1, "z": -403.6},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Safe Shallows Wreck - PDA" },
{ "id": 33031, "position": { "x": -317.1, "y": -79.0, "z": 248.5},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Kelp Forest Wreck - Databox" },
{ "id": 33032, "position": { "x": 63.2, "y": -38.5, "z": 382.9},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Kelp Forest Wreck - PDA" },
{ "id": 33033, "position": { "x": 740.3, "y": -389.2, "z": 1179.8},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Mountains West Wreck - Outside Databox" },
{ "id": 33034, "position": { "x": 703.7, "y": -365.9, "z": 1199.3},
"need_laser_cutter": true, "can_slip_through": false,
"name": "Mountains West Wreck - Data Terminal" },
{ "id": 33035, "position": { "x": 698.2, "y": -350.8, "z": 1186.9},
"need_laser_cutter": true, "can_slip_through": false,
"name": "Mountains West Wreck - Hangar Databox" },
{ "id": 33036, "position": { "x": 676.3, "y": -343.6, "z": 1204.6},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Mountains West Wreck - Office Databox" },
{ "id": 33037, "position": { "x": 1068.5, "y": -283.4, "z": 1345.3},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Mountains East Wreck - Comms Databox" },
{ "id": 33038, "position": { "x": 1075.7, "y": -288.9, "z": 1321.8},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Mountains East Wreck - Outside Databox" },
{ "id": 33039, "position": { "x": -655.1, "y": -109.6, "z": 791.0},
"need_laser_cutter": true, "can_slip_through": false,
"name": "Northwestern Mushroom Forest Wreck - Cargo Databox" },
{ "id": 33040, "position": { "x": -663.4, "y": -111.9, "z": 777.9},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Northwestern Mushroom Forest Wreck - Office Databox" },
{ "id": 33041, "position": { "x": -662.2, "y": -113.4, "z": 777.7},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Northwestern Mushroom Forest Wreck - PDA" },
{ "id": 33042, "position": { "x": -1161.1, "y": -191.7, "z": -758.3},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Sea Treader's Path Wreck - Outside Databox" },
{ "id": 33043, "position": { "x": -1129.5, "y": -155.2, "z": -729.3},
"need_laser_cutter": true, "can_slip_through": false,
"name": "Sea Treader's Path Wreck - Hangar Databox" },
{ "id": 33044, "position": { "x": -1115.9, "y": -175.3, "z": -724.5},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Sea Treader's Path Wreck - Lobby Databox" },
{ "id": 33045, "position": { "x": -1136.8, "y": -157.0, "z": -734.6},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Sea Treader's Path Wreck - PDA" },
{ "id": 33046, "position": { "x": -789.8, "y": -216.1, "z": -711.0},
"need_laser_cutter": true, "can_slip_through": false,
"name": "Sparse Reef Wreck - Locker Databox" },
{ "id": 33047, "position": { "x": -810.7, "y": -209.3, "z": -685.5},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Sparse Reef Wreck - Outside Databox" },
{ "id": 33048, "position": { "x": -795.5, "y": -204.1, "z": -774.7},
"need_laser_cutter": true, "can_slip_through": false,
"name": "Sparse Reef Wreck - Lab Databox" },
{ "id": 33049, "position": { "x": -170.8, "y": -187.6, "z": 880.7},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Underwater Islands Wreck - Outside Databox" },
{ "id": 33050, "position": { "x": -138.4, "y": -193.6, "z": 888.7},
"need_laser_cutter": true, "can_slip_through": false,
"name": "Underwater Islands Wreck - Hangar Databox" },
{ "id": 33051, "position": { "x": -130.7, "y": -193.2, "z": 883.3},
"need_laser_cutter": true, "can_slip_through": false,
"name": "Underwater Islands Wreck - Data Terminal" },
{ "id": 33052, "position": { "x": -137.8, "y": -193.4, "z": 879.4},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Underwater Islands Wreck - Cable Databox" },
{ "id": 33053, "position": { "x": -124.4, "y": -200.7, "z": 853.0},
"need_laser_cutter": false, "can_slip_through": false, "need_propulsion_cannon": true,
"name": "Underwater Islands Wreck - Pipes Databox 1" },
{ "id": 33054, "position": { "x": -126.8, "y": -201.1, "z": 852.1},
"need_laser_cutter": false, "can_slip_through": false, "need_propulsion_cannon": true,
"name": "Underwater Islands Wreck - Pipes Databox 2" },
{ "id": 33055, "position": { "x": -643.8, "y": -509.9, "z": -941.9},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Degasi Seabase - Deep Grand Reef - Bedroom Databox" },
{ "id": 33056, "position": { "x": -635.1, "y": -502.7, "z": -951.4},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Degasi Seabase - Deep Grand Reef - Observatory Databox" },
{ "id": 33057, "position": { "x": -645.8, "y": -508.7, "z": -943.0},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Degasi Seabase - Deep Grand Reef - Bedroom PDA" },
{ "id": 33058, "position": { "x": -630.5, "y": -511.1, "z": -936.1},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Degasi Seabase - Deep Grand Reef - Outside PDA" },
{ "id": 33059, "position": { "x": -647.7, "y": -502.6, "z": -935.8},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Degasi Seabase - Deep Grand Reef - Observatory PDA" },
{ "id": 33060, "position": { "x": -639.6, "y": -505.9, "z": -946.6},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Degasi Seabase - Deep Grand Reef - Lab PDA" },
{ "id": 33061, "position": { "x": -707.2, "y": 0.5, "z": -1096.7},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Floating Island - Lake PDA" },
{ "id": 33062, "position": { "x": -765.7, "y": 17.6, "z": -1116.4},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Degasi Seabase - Floating Island - Databox" },
{ "id": 33063, "position": { "x": -754.9, "y": 14.6, "z": -1108.9},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Degasi Seabase - Floating Island - Room PDA" },
{ "id": 33064, "position": { "x": -765.3, "y": 14.1, "z": -1115.0},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Degasi Seabase - Floating Island - Green Wall PDA" },
{ "id": 33065, "position": { "x": -758.6, "y": 14.1, "z": -1111.3},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Degasi Seabase - Floating Island - Corridor PDA" },
{ "id": 33066, "position": { "x": -805.4, "y": 76.9, "z": -1055.7},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Degasi Seabase - Floating Island - North Observatory PDA" },
{ "id": 33067, "position": { "x": -715.9, "y": 75.4, "z": -1168.8},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Degasi Seabase - Floating Island - South Observatory PDA" },
{ "id": 33068, "position": { "x": -540.5, "y": -250.8, "z": -83.4},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Jellyshroom Cave - PDA" },
{ "id": 33069, "position": { "x": 110.6, "y": -264.9, "z": -369.0},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Degasi Seabase - Jellyshroom Cave - Bedroom Databox" },
{ "id": 33070, "position": { "x": 80.6, "y": -268.6, "z": -358.3},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Degasi Seabase - Jellyshroom Cave - Detached PDA" },
{ "id": 33071, "position": { "x": 78.2, "y": -265.0, "z": -373.4},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Degasi Seabase - Jellyshroom Cave - Office PDA" },
{ "id": 33072, "position": { "x": 85.1, "y": -264.1, "z": -372.8},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Degasi Seabase - Jellyshroom Cave - Locker PDA" },
{ "id": 33073, "position": { "x": 112.3, "y": -264.9, "z": -369.3},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Degasi Seabase - Jellyshroom Cave - Bedroom PDA" },
{ "id": 33074, "position": { "x": 95.5, "y": -258.9, "z": -366.5},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Degasi Seabase - Jellyshroom Cave - Observatory PDA" },
{ "id": 33075, "position": { "x": -483.6, "y": -504.7, "z": 1326.6},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Lifepod 2 - Databox" },
{ "id": 33076, "position": { "x": -481.4, "y": -503.6, "z": 1324.1},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Lifepod 2 - PDA" },
{ "id": 33077, "position": { "x": -34.2, "y": -22.4, "z": 410.5},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Lifepod 3 - Databox" },
{ "id": 33078, "position": { "x": -33.8, "y": -22.5, "z": 408.8},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Lifepod 3 - PDA" },
{ "id": 33079, "position": { "x": 712.4, "y": -3.4, "z": 160.8},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Lifepod 4 - Databox" },
{ "id": 33080, "position": { "x": 712.0, "y": -3.5, "z": 161.5},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Lifepod 4 - PDA" },
{ "id": 33081, "position": { "x": 358.7, "y": -117.1, "z": 306.8},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Lifepod 6 - Databox" },
{ "id": 33082, "position": { "x": 361.8, "y": -116.2, "z": 309.5},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Lifepod 6 - Inside PDA" },
{ "id": 33083, "position": { "x": 359.9, "y": -117.0, "z": 312.1},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Lifepod 6 - Outside PDA" },
{ "id": 33084, "position": { "x": -56.0, "y": -182.0, "z": -1039.0},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Lifepod 7 - PDA" },
{ "id": 33085, "position": { "x": 1119.5, "y": -271.7, "z": 561.7},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Lifepod 12 - Databox" },
{ "id": 33086, "position": { "x": 1116.1, "y": -271.3, "z": 566.9},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Lifepod 12 - PDA" },
{ "id": 33087, "position": { "x": -926.4, "y": -185.2, "z": 501.8},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Lifepod 13 - Databox" },
{ "id": 33088, "position": { "x": -926.8, "y": -184.4, "z": 506.6},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Lifepod 13 - PDA" },
{ "id": 33089, "position": { "x": -514.5, "y": -98.1, "z": -56.5},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Lifepod 17 - PDA" },
{ "id": 33090, "position": { "x": -809.8, "y": -302.2, "z": -876.9},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Lifepod 19 - Databox" },
{ "id": 33091, "position": { "x": -806.1, "y": -294.1, "z": -866.0},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Lifepod 19 - Outside PDA" },
{ "id": 33092, "position": { "x": -810.5, "y": -299.4, "z": -873.1},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Lifepod 19 - Inside PDA" },
{ "id": 33093, "position": { "x": 903.5, "y": -0.2, "z": 16.1},
"need_laser_cutter": false, "can_slip_through": false, "need_propulsion_cannon": true,
"name": "Aurora Seamoth Bay - Upgrade Console" },
{ "id": 33094, "position": { "x": 872.5, "y": 2.7, "z": -0.7},
"need_laser_cutter": false, "can_slip_through": false, "need_propulsion_cannon": true,
"name": "Aurora Drive Room - Upgrade Console" },
{ "id": 33095, "position": { "x": 991.6, "y": 3.2, "z": -31.0},
"need_laser_cutter": true, "can_slip_through": false, "need_propulsion_cannon": true,
"name": "Aurora Prawn Suit Bay - Upgrade Console" },
{ "id": 33096, "position": { "x": 952.1, "y": 41.2, "z": 113.9},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Aurora - Office PDA" },
{ "id": 33097, "position": { "x": 977.2, "y": 39.1, "z": 83.0},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Aurora - Corridor PDA" },
{ "id": 33098, "position": { "x": 954.9, "y": 11.2, "z": 3.4},
"need_laser_cutter": false, "can_slip_through": false, "need_propulsion_cannon": true,
"name": "Aurora - Cargo Bay PDA" },
{ "id": 33099, "position": { "x": 907.1, "y": -1.5, "z": 15.3},
"need_laser_cutter": false, "can_slip_through": false, "need_propulsion_cannon": true,
"name": "Aurora - Seamoth Bay PDA" },
{ "id": 33100, "position": { "x": 951.8, "y": -2.3, "z": -34.7},
"need_laser_cutter": true, "can_slip_through": false, "need_propulsion_cannon": true,
"name": "Aurora - Medkit Locker PDA" },
{ "id": 33101, "position": { "x": 952.0, "y": -3.7, "z": -23.4},
"need_laser_cutter": true, "can_slip_through": false, "need_propulsion_cannon": true,
"name": "Aurora - Locker PDA" },
{ "id": 33102, "position": { "x": 986.5, "y": 9.6, "z": -48.6},
"need_laser_cutter": true, "can_slip_through": false, "need_propulsion_cannon": true,
"name": "Aurora - Canteen PDA" },
{ "id": 33103, "position": { "x": 951.3, "y": 11.2, "z": -51.0},
"need_laser_cutter": true, "can_slip_through": false, "need_propulsion_cannon": true,
"name": "Aurora - Cabin 4 PDA" },
{ "id": 33104, "position": { "x": 967.1, "y": 10.4, "z": -47.4},
"need_laser_cutter": true, "can_slip_through": false, "need_propulsion_cannon": true,
"name": "Aurora - Cabin 7 PDA" },
{ "id": 33105, "position": { "x": 964.1, "y": 11.1, "z": -61.9},
"need_laser_cutter": true, "can_slip_through": false, "need_propulsion_cannon": true,
"name": "Aurora - Cabin 1 PDA" },
{ "id": 33106, "position": { "x": 971.2, "y": 10.8, "z": -70.4},
"need_laser_cutter": true, "can_slip_through": false, "need_propulsion_cannon": true,
"name": "Aurora - Captain PDA" },
{ "id": 33107, "position": { "x": 1033.6, "y": -8.5, "z": 16.2},
"need_laser_cutter": false, "can_slip_through": false, "need_propulsion_cannon": true,
"name": "Aurora - Ring PDA" },
{ "id": 33108, "position": { "x": 1032.5, "y": -7.8, "z": 32.4},
"need_laser_cutter": false, "can_slip_through": false, "need_propulsion_cannon": true,
"name": "Aurora - Lab PDA" },
{ "id": 33109, "position": { "x": 945.8, "y": 40.8, "z": 115.1},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Aurora - Office Data Terminal" },
{ "id": 33110, "position": { "x": 974.8, "y": 10.0, "z": -77.0},
"need_laser_cutter": true, "can_slip_through": false, "need_propulsion_cannon": true,
"name": "Aurora - Captain Data Terminal" },
{ "id": 33111, "position": { "x": 1040.8, "y": -11.4, "z": -3.4},
"need_laser_cutter": true, "can_slip_through": false, "need_propulsion_cannon": true,
"name": "Aurora - Battery Room Data Terminal" },
{ "id": 33112, "position": { "x": 1029.5, "y": -8.7, "z": 35.9},
"need_laser_cutter": false, "can_slip_through": false, "need_propulsion_cannon": true,
"name": "Aurora - Lab Data Terminal" },
{ "id": 33113, "position": { "x": 432.2, "y": 3.0, "z": 1193.2},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Quarantine Enforcement Platform's - Upper Alien Data Terminal" },
{ "id": 33114, "position": { "x": 474.4, "y": -4.5, "z": 1224.4},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Quarantine Enforcement Platform's - Mid Alien Data Terminal" },
{ "id": 33115, "position": { "x": -1224.2, "y": -400.4, "z": 1057.9},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Dunes Sanctuary - Alien Data Terminal" },
{ "id": 33116, "position": { "x": -895.5, "y": -311.6, "z": -838.1},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Deep Sparse Reef Sanctuary - Alien Data Terminal" },
{ "id": 33117, "position": { "x": -642.9, "y": -563.5, "z": 1485.5},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Northern Blood Kelp Zone Sanctuary - Alien Data Terminal" },
{ "id": 33118, "position": { "x": -1112.3, "y": -687.3, "z": -695.5},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Lost River Laboratory Cache - Alien Data Terminal" },
{ "id": 33119, "position": { "x": -280.2, "y": -804.3, "z": 305.1},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Disease Research Facility - Upper Alien Data Terminal" },
{ "id": 33120, "position": { "x": -267.9, "y": -806.6, "z": 250.0},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Disease Research Facility - Mid Alien Data Terminal" },
{ "id": 33121, "position": { "x": -286.2, "y": -815.6, "z": 297.8},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Disease Research Facility - Lower Alien Data Terminal" },
{ "id": 33122, "position": { "x": -71.3, "y": -1227.2, "z": 104.8},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Alien Thermal Plant - Entrance Alien Data Terminal" },
{ "id": 33123, "position": { "x": -38.7, "y": -1226.6, "z": 111.8},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Alien Thermal Plant - Green Alien Data Terminal" },
{ "id": 33124, "position": { "x": -30.4, "y": -1220.3, "z": 111.8},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Alien Thermal Plant - Yellow Alien Data Terminal" },
{ "id": 33125, "position": { "x": 245.8, "y": -1430.6, "z": -311.5},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Primary Containment Facility's Antechamber - Alien Data Terminal" },
{ "id": 33126, "position": { "x": 165.5, "y": -1442.4, "z": -385.8},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Primary Containment Facility's Egg Laboratory - Alien Data Terminal" },
{ "id": 33127, "position": { "x": 348.7, "y": -1443.5, "z": -291.9},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Primary Containment Facility's Pipe Room - Alien Data Terminal" },
{ "id": 33128, "position": { "x": -641.8, "y": -111.3, "z": -19.7},
"need_laser_cutter": true, "can_slip_through": false,
"name": "Grassy Plateaus West Wreck - Beam PDA" },
{ "id": 33129, "position": { "x": -748.9, "y": 14.4, "z": -1179.5},
"need_laser_cutter": false, "can_slip_through": false,
"name": "Floating Island - Cave Entrance PDA" }
]