Merge remote-tracking branch 'Daivuk/subnautica_clean' into subnautica_test

This commit is contained in:
Fabian Dill 2021-07-23 15:49:23 +02:00
commit c99a689504
8 changed files with 976 additions and 0 deletions

View File

@ -27,6 +27,7 @@ game:
A Link to the Past: 1
Factorio: 1
Minecraft: 1
Subnautica: 1
requires:
version: 0.1.3 # Version of Archipelago required for this yaml to work as expected.
# Shared Options supported by all games:

View File

@ -0,0 +1,14 @@
import json
with open('worlds/subnautica/items.json', 'r') as file:
item_table = json.loads(file.read())
lookup_id_to_name = {}
lookup_name_to_item = {}
for item in item_table:
lookup_id_to_name[item["id"]] = item["name"]
lookup_name_to_item[item["name"]] = item
lookup_id_to_name[None] = "Victory"
lookup_name_to_id = {name: id for id, name in lookup_id_to_name.items()}

View File

@ -0,0 +1,11 @@
import json
with open('worlds/subnautica/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"]
lookup_id_to_name[None] = "Neptune Launch"
lookup_name_to_id = {name: id for id, name in lookup_id_to_name.items()}

View File

@ -0,0 +1,8 @@
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])
]

254
worlds/subnautica/Rules.py Normal file
View File

@ -0,0 +1,254 @@
from ..generic.Rules import set_rule
from .Locations import location_table
import logging
import math
def has_seaglide(state, player):
return state.has("Seaglide Fragment", player, 2)
def has_modification_station(state, player):
return state.has("Modification Station Fragment", player, 3)
def has_mobile_vehicle_bay(state, player):
return state.has("Mobile Vehicle Bay Fragment", player, 3)
def has_moonpool(state, player):
return state.has("Moonpool Fragment", player, 2)
def has_vehicle_upgrade_console(state, player):
return state.has("Vehicle Upgrade Console", player) and \
has_moonpool(state, player)
def has_seamoth(state, player):
return state.has("Seamoth Fragment", player, 3) and \
has_mobile_vehicle_bay(state, player)
def has_seamoth_depth_module_mk1(state, player):
return has_vehicle_upgrade_console(state, player)
def has_seamoth_depth_module_mk2(state, player):
return has_seamoth_depth_module_mk1(state, player) and \
has_modification_station(state, player)
def has_seamoth_depth_module_mk3(state, player):
return has_seamoth_depth_module_mk2(state, player) and \
has_modification_station(state, player)
def has_cyclops_bridge(state, player):
return state.has("Cyclops Bridge Fragment", player, 3)
def has_cyclops_engine(state, player):
return state.has("Cyclops Engine Fragment", player, 3)
def has_cyclops_hull(state, player):
return state.has("Cyclops Hull Fragment", player, 3)
def has_cyclops(state, player):
return has_cyclops_bridge(state, player) and \
has_cyclops_engine(state, player) and \
has_cyclops_hull(state, player) and \
has_mobile_vehicle_bay(state, player)
def has_cyclops_depth_module_mk1(state, player):
return state.has("Cyclops Depth Module MK1", player) and \
has_modification_station(state, player)
def has_cyclops_depth_module_mk2(state, player):
return has_cyclops_depth_module_mk1(state, player) and \
has_modification_station(state, player)
def has_cyclops_depth_module_mk3(state, player):
return has_cyclops_depth_module_mk2(state, player) and \
has_modification_station(state, player)
def has_prawn(state, player):
return state.has("Prawn Suit Fragment", player, 4) and \
has_mobile_vehicle_bay(state, player)
def has_praw_propulsion_arm(state, player):
return state.has("Prawn Suit Propulsion Cannon Fragment", player, 2) and \
has_vehicle_upgrade_console(state, player)
def has_prawn_depth_module_mk1(state, player):
return has_vehicle_upgrade_console(state, player)
def has_prawn_depth_module_mk2(state, player):
return has_prawn_depth_module_mk1(state, player) and \
has_modification_station(state, player)
def has_laser_cutter(state, player):
return state.has("Laser Cutter Fragment", player, 3)
# Either we have propulsion cannon, or prawn + propulsion cannon arm
def has_propulsion_cannon(state, player):
return state.has("Propulsion Cannon Fragment", player, 2) or \
(has_prawn(state, player) and has_praw_propulsion_arm(state, player))
def has_cyclops_shield(state, player):
return has_cyclops(state, player) and \
state.has("Cyclops Shield Generator", player)
# Swim depth rules:
# Rebreather, high capacity tank and fins are available from the start.
# All tests for those were done without inventory for light weight.
# Fins and ultra Fins are better than charge fins, so we ignore charge fins.
# We're ignoring lightweight tank in the chart, because the difference is
# negligeable with from high capacity tank. 430m -> 460m
# Fins are not used when using seaglide
#
def get_max_swim_depth(state, player):
#TODO, Make this a difficulty setting.
# Only go up to 200m without any submarines for now.
return 200
# Rules bellow, are what are technically possible
# has_ultra_high_capacity_tank = state.has("Ultra High Capacity Tank", player)
# has_ultra_glide_fins = state.has("Ultra Glide Fins", player)
# max_depth = 400 # More like 430m. Give some room
# if has_seaglide(state, player):
# if has_ultra_high_capacity_tank:
# max_depth = 750 # It's about 50m more. Give some room
# else:
# max_depth = 600 # It's about 50m more. Give some room
# elif has_ultra_high_capacity_tank:
# if has_ultra_glide_fins:
# pass
# else:
# pass
# elif has_ultra_glide_fins:
# max_depth = 500
# return max_depth
def get_seamoth_max_depth(state, player):
if has_seamoth(state, player):
if has_seamoth_depth_module_mk3(state, player):
return 900
elif has_seamoth_depth_module_mk2(state, player): # Will never be the case, 3 is craftable
return 500
elif has_seamoth_depth_module_mk1(state, player):
return 300
else:
return 200
else:
return 0
def get_cyclops_max_depth(state, player):
if has_cyclops(state, player):
if has_cyclops_depth_module_mk3(state, player):
return 1700
elif has_cyclops_depth_module_mk2(state, player): # Will never be the case, 3 is craftable
return 1300
elif has_cyclops_depth_module_mk1(state, player):
return 900
else:
return 500
else:
return 0
def get_prawn_max_depth(state, player):
if has_prawn(state, player):
if has_prawn_depth_module_mk2(state, player):
return 1700
elif has_prawn_depth_module_mk1(state, player):
return 1300
else:
return 900
else:
return 0
def get_max_depth(state, player):
#TODO, Difficulty option, we can add vehicle depth + swim depth
# But at this point, we have to consider traver distance in caves, not
# just depth
return max(get_max_swim_depth(state, player), \
get_seamoth_max_depth(state, player), \
get_cyclops_max_depth(state, player), \
get_prawn_max_depth(state, player))
def can_access_location(state, player, loc):
# Extract location from game id.
# Game id is in format: "(x, y, z)"
pos_raw = loc.get("game_id")[1:-1].split(', ')
pos_x = float(pos_raw[0])
pos_y = float(pos_raw[1])
pos_z = float(pos_raw[2])
depth = -pos_y # y-up
map_center_dist = math.sqrt(pos_x**2 + pos_z**2)
aurora_dist = math.sqrt((pos_x - 1040)**2 + (pos_z - -160)**2)
need_radiation_suit = aurora_dist < 940
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):
return False
if need_propulsion_cannon and not has_propulsion_cannon(state, player):
return False
# Seaglide doesn't unlock anything specific, but just allows for faster movement.
# Otherwise the game is painfully slow.
if (map_center_dist > 800 or pos_y < -200) and not has_seaglide(state, player):
return False
return get_max_depth(state, player) >= depth
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):
logging.warning(type(location_table))
for loc in location_table:
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 \
has_cyclops_shield(state, player))
world.completion_condition[player] = lambda state: state.has('Victory', player)

View File

@ -0,0 +1,89 @@
import logging
from typing import Set
logger = logging.getLogger("Subnautica")
from .Locations import lookup_name_to_id as locations_lookup_name_to_id
from .Items import item_table
from .Items import lookup_name_to_id as items_lookup_name_to_id
from .Regions import create_regions
from .Rules import set_rules
from BaseClasses import Region, Entrance, Location, MultiWorld, Item
from ..AutoWorld import World
class SubnauticaWorld(World):
game: str = "Subnautica"
item_names: Set[str] = frozenset(items_lookup_name_to_id)
location_names: Set[str] = frozenset(locations_lookup_name_to_id)
item_name_to_id = items_lookup_name_to_id
location_name_to_id = locations_lookup_name_to_id
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
for item in item_table:
for i in range(item["count"]):
subnautica_item = SubnauticaItem(item["name"], item["progression"], item["id"], player = self.player)
if item["name"] == "Neptune Launch Platform":
neptune_launch_platform = subnautica_item
else:
pool.append(subnautica_item)
self.world.itempool += pool
# 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", True, None, player = self.player))
def set_rules(self):
set_rules(self.world, self.player)
def create_regions(self):
create_regions(self.world, self.player)
def generate_output(self, output_directory: str):
pass
def fill_slot_data(self):
slot_data = {}
return slot_data
def create_region(world: MultiWorld, player: int, name: str, locations=None, exits=None):
ret = Region(name, None, 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))
return ret
class SubnauticaLocation(Location):
game: str = "Subnautica"
def __init__(self, player: int, name: str, address=None, parent=None):
super(SubnauticaLocation, self).__init__(player, name, address, parent)
class SubnauticaItem(Item):
game = "Subnautica"
def __init__(self, name, advancement, code, player: int = None):
super(SubnauticaItem, self).__init__(name, advancement, code, player)

View File

@ -0,0 +1,82 @@
[
{ "id": 35000, "count": 1, "progression": true, "tech_type": "Compass", "name": "Subnautica 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": true, "tech_type": "CyclopsSonarModule", "name": "Cyclops Sonar Upgrade" },
{ "id": 35005, "count": 1, "progression": true, "tech_type": "ReinforcedDiveSuit", "name": "Reinforced Dive Suit" },
{ "id": 35006, "count": 1, "progression": true, "tech_type": "CyclopsThermalReactorModule", "name": "Cyclops Thermal Reactor Module" },
{ "id": 35007, "count": 1, "progression": true, "tech_type": "Stillsuit", "name": "Stillsuit" },
{ "id": 35008, "count": 2, "progression": false, "tech_type": "BaseWaterParkFragment", "name": "Alien Containment Fragment" },
{ "id": 35009, "count": 1, "progression": true, "tech_type": "CyclopsDecoy", "name": "Creature Decoy" },
{ "id": 35010, "count": 1, "progression": true, "tech_type": "CyclopsFireSuppressionModule", "name": "Cyclops Fire Suppression System" },
{ "id": 35011, "count": 1, "progression": true, "tech_type": "SwimChargeFins", "name": "Swim Charge Fins" },
{ "id": 35012, "count": 1, "progression": true, "tech_type": "RepulsionCannon", "name": "Repulsion Cannon" },
{ "id": 35013, "count": 1, "progression": true, "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": true, "tech_type": "CyclopsSeamothRepairModule", "name": "Cyclops Docking Bay Repair Module" },
{ "id": 35017, "count": 2, "progression": true, "tech_type": "BatteryChargerFragment", "name": "Battery Charger fragment" },
{ "id": 35018, "count": 2, "progression": true, "tech_type": "BeaconFragment", "name": "Beacon Fragment" },
{ "id": 35019, "count": 2, "progression": true, "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": true, "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": true, "tech_type": "BaseNuclearReactorFragment", "name": "Nuclear Reactor Fragment" },
{ "id": 35030, "count": 2, "progression": true, "tech_type": "PowerCellChargerFragment", "name": "Power Cell Charger Fragment" },
{ "id": 35031, "count": 1, "progression": true, "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": true, "tech_type": "ExosuitDrillArmFragment", "name": "Prawn Suit Drill Arm Fragment" },
{ "id": 35034, "count": 2, "progression": true, "tech_type": "ExosuitGrapplingArmFragment", "name": "Prawn Suit Grappling Arm Fragment" },
{ "id": 35035, "count": 2, "progression": true, "tech_type": "ExosuitPropulsionArmFragment", "name": "Prawn Suit Propulsion Cannon Fragment" },
{ "id": 35036, "count": 2, "progression": true, "tech_type": "ExosuitTorpedoArmFragment", "name": "Prawn Suit Torpedo Arm Fragment" },
{ "id": 35037, "count": 3, "progression": true, "tech_type": "BaseMapRoomFragment", "name": "Scanner Room Fragment" },
{ "id": 35038, "count": 3, "progression": true, "tech_type": "SeamothFragment", "name": "Seamoth Fragment" },
{ "id": 35039, "count": 2, "progression": true, "tech_type": "StasisRifleFragment", "name": "Stasis Rifle Fragment" },
{ "id": 35040, "count": 2, "progression": true, "tech_type": "ThermalPlantFragment", "name": "Thermal Plant Fragment" },
{ "id": 35041, "count": 2, "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": true, "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": "Bend Fragment" },
{ "id": 35049, "count": 1, "progression": true, "tech_type": "PlanterPotFragment", "name": "Basic Plant Pot" },
{ "id": 35050, "count": 1, "progression": true, "tech_type": "PlanterBoxFragment", "name": "Interior Growbed" },
{ "id": 35051, "count": 1, "progression": true, "tech_type": "PlanterShelfFragment", "name": "Plant Shelf" },
{ "id": 35052, "count": 2, "progression": false, "tech_type": "BaseObservatoryFragment", "name": "Observatory Fragment" },
{ "id": 35053, "count": 2, "progression": true, "tech_type": "BaseRoomFragment", "name": "Multipurpose Room Fragment" },
{ "id": 35054, "count": 2, "progression": false, "tech_type": "BaseBulkheadFragment", "name": "Bulkhead Fragment" },
{ "id": 35055, "count": 1, "progression": true, "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": 2, "progression": false, "tech_type": "NarrowBed", "name": "Single Bed" },
{ "id": 35062, "count": 2, "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": 2, "progression": false, "tech_type": "Techlight", "name": "Floodlight" },
{ "id": 35067, "count": 1, "progression": false, "tech_type": "BarTable", "name": "Bar Table" },
{ "id": 35068, "count": 2, "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": true, "tech_type": "PlanterPot2", "name": "Round Plant Pot" },
{ "id": 35072, "count": 1, "progression": true, "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" }
]

View File

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