Subnautica: revamp filler item pool
This commit is contained in:
parent
b077b2aeef
commit
532c4c068f
|
@ -13,11 +13,17 @@ if __name__ == "__main__":
|
||||||
sys.path.append(new_home)
|
sys.path.append(new_home)
|
||||||
|
|
||||||
from worlds.subnautica.Locations import Vector, location_table
|
from worlds.subnautica.Locations import Vector, location_table
|
||||||
from worlds.subnautica.Items import item_table, group_items
|
from worlds.subnautica.Items import item_table, group_items, items_by_type
|
||||||
from NetUtils import encode
|
from NetUtils import encode
|
||||||
|
|
||||||
|
export_folder = os.path.join(new_home, "Subnautica Export")
|
||||||
|
os.makedirs(export_folder, exist_ok=True)
|
||||||
|
|
||||||
|
def in_export_folder(path: str) -> str:
|
||||||
|
return os.path.join(export_folder, path)
|
||||||
|
|
||||||
payload = {location_id: location_data["position"] for location_id, location_data in location_table.items()}
|
payload = {location_id: location_data["position"] for location_id, location_data in location_table.items()}
|
||||||
with open("locations.json", "w") as f:
|
with open(in_export_folder("locations.json"), "w") as f:
|
||||||
json.dump(payload, f)
|
json.dump(payload, f)
|
||||||
|
|
||||||
# copy-paste from Rules
|
# copy-paste from Rules
|
||||||
|
@ -49,17 +55,22 @@ if __name__ == "__main__":
|
||||||
"751": [location_id for location_id, location_data
|
"751": [location_id for location_id, location_data
|
||||||
in location_table.items() if far_away(location_data["position"])],
|
in location_table.items() if far_away(location_data["position"])],
|
||||||
}
|
}
|
||||||
with open("logic.json", "w") as f:
|
with open(in_export_folder("logic.json"), "w") as f:
|
||||||
json.dump(payload, f)
|
json.dump(payload, f)
|
||||||
|
|
||||||
itemcount = sum(item_data["count"] for item_data in item_table.values())
|
itemcount = sum(item_data.count for item_data in item_table.values())
|
||||||
assert itemcount == len(location_table), f"{itemcount} != {len(location_table)}"
|
assert itemcount == len(location_table), f"{itemcount} != {len(location_table)}"
|
||||||
payload = {item_id: item_data["tech_type"] for item_id, item_data in item_table.items()}
|
payload = {item_id: item_data.tech_type for item_id, item_data in item_table.items()}
|
||||||
import json
|
import json
|
||||||
|
|
||||||
with open("items.json", "w") as f:
|
with open(in_export_folder("items.json"), "w") as f:
|
||||||
json.dump(payload, f)
|
json.dump(payload, f)
|
||||||
with open("group_items.json", "w") as f:
|
|
||||||
|
with open(in_export_folder("group_items.json"), "w") as f:
|
||||||
|
# encode to convert set to list
|
||||||
f.write(encode(group_items))
|
f.write(encode(group_items))
|
||||||
|
|
||||||
print(f"Subnautica exports dumped to {new_home}")
|
with open(in_export_folder("item_types.json"), "w") as f:
|
||||||
|
json.dump(items_by_type, f)
|
||||||
|
|
||||||
|
print(f"Subnautica exports dumped to {in_export_folder('')}")
|
||||||
|
|
|
@ -1,390 +1,154 @@
|
||||||
from BaseClasses import ItemClassification
|
from BaseClasses import ItemClassification as IC
|
||||||
from typing import TypedDict, Dict, Set
|
from typing import NamedTuple, Dict, Set, List
|
||||||
|
from enum import IntEnum
|
||||||
|
|
||||||
|
|
||||||
class ItemDict(TypedDict):
|
class ItemType(IntEnum):
|
||||||
classification: ItemClassification
|
technology = 1
|
||||||
|
resource = 2
|
||||||
|
group = 3
|
||||||
|
|
||||||
|
|
||||||
|
class ItemData(NamedTuple):
|
||||||
|
classification: IC
|
||||||
count: int
|
count: int
|
||||||
name: str
|
name: str
|
||||||
tech_type: str
|
tech_type: str
|
||||||
|
type: ItemType = ItemType.technology
|
||||||
|
|
||||||
|
|
||||||
item_table: Dict[int, ItemDict] = {
|
def make_resource_bundle_data(display_name: str, internal_name: str = "") -> ItemData:
|
||||||
35000: {'classification': ItemClassification.useful,
|
if not internal_name:
|
||||||
'count': 1,
|
internal_name = display_name
|
||||||
'name': 'Compass',
|
return ItemData(IC.filler, 0, display_name, internal_name, ItemType.resource)
|
||||||
'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': 'Water Filtration Suit',
|
|
||||||
'tech_type': 'WaterFiltrationSuit'},
|
|
||||||
35008: {'classification': ItemClassification.progression,
|
|
||||||
'count': 1,
|
|
||||||
'name': 'Alien Containment',
|
|
||||||
'tech_type': 'BaseWaterPark'},
|
|
||||||
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': 4,
|
|
||||||
'name': 'Cyclops Bridge Fragment',
|
|
||||||
'tech_type': 'CyclopsBridgeFragment'},
|
|
||||||
35021: {'classification': ItemClassification.progression,
|
|
||||||
'count': 4,
|
|
||||||
'name': 'Cyclops Engine Fragment',
|
|
||||||
'tech_type': 'CyclopsEngineFragment'},
|
|
||||||
35022: {'classification': ItemClassification.progression,
|
|
||||||
'count': 4,
|
|
||||||
'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': 2,
|
|
||||||
'name': 'Light Stick Fragment',
|
|
||||||
'tech_type': 'TechlightFragment'},
|
|
||||||
35026: {'classification': ItemClassification.progression,
|
|
||||||
'count': 5,
|
|
||||||
'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': 6,
|
|
||||||
'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.progression,
|
|
||||||
'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': 4,
|
|
||||||
'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_skip_balancing,
|
|
||||||
'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',
|
|
||||||
'tech_type': 'FarmingTray'},
|
|
||||||
35047: {'classification': ItemClassification.filler,
|
|
||||||
'count': 1,
|
|
||||||
'name': 'Picture Frame',
|
|
||||||
'tech_type': 'PictureFrameFragment'},
|
|
||||||
35048: {'classification': ItemClassification.filler,
|
|
||||||
'count': 1,
|
|
||||||
'name': 'Bench',
|
|
||||||
'tech_type': 'Bench'},
|
|
||||||
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': 1,
|
|
||||||
'name': 'Observatory',
|
|
||||||
'tech_type': 'BaseObservatory'},
|
|
||||||
35053: {'classification': ItemClassification.progression,
|
|
||||||
'count': 1,
|
|
||||||
'name': 'Multipurpose Room',
|
|
||||||
'tech_type': 'BaseRoom'},
|
|
||||||
35054: {'classification': ItemClassification.useful,
|
|
||||||
'count': 1,
|
|
||||||
'name': 'Bulkhead',
|
|
||||||
'tech_type': 'BaseBulkhead'},
|
|
||||||
35055: {'classification': ItemClassification.filler,
|
|
||||||
'count': 1,
|
|
||||||
'name': 'Spotlight',
|
|
||||||
'tech_type': 'Spotlight'},
|
|
||||||
35056: {'classification': ItemClassification.filler,
|
|
||||||
'count': 1,
|
|
||||||
'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': 1,
|
|
||||||
'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': 1,
|
|
||||||
'name': 'Coffee Vending Machine',
|
|
||||||
'tech_type': 'CoffeeVendingMachine'},
|
|
||||||
35065: {'classification': ItemClassification.filler,
|
|
||||||
'count': 1,
|
|
||||||
'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_skip_balancing,
|
|
||||||
'count': 1,
|
|
||||||
'name': 'Neptune Gantry',
|
|
||||||
'tech_type': 'RocketBaseLadder'},
|
|
||||||
35077: {'classification': ItemClassification.progression_skip_balancing,
|
|
||||||
'count': 1,
|
|
||||||
'name': 'Neptune Boosters',
|
|
||||||
'tech_type': 'RocketStage1'},
|
|
||||||
35078: {'classification': ItemClassification.progression_skip_balancing,
|
|
||||||
'count': 1,
|
|
||||||
'name': 'Neptune Fuel Reserve',
|
|
||||||
'tech_type': 'RocketStage2'},
|
|
||||||
35079: {'classification': ItemClassification.progression_skip_balancing,
|
|
||||||
'count': 1,
|
|
||||||
'name': 'Neptune Cockpit',
|
|
||||||
'tech_type': 'RocketStage3'},
|
|
||||||
35080: {'classification': ItemClassification.filler,
|
|
||||||
'count': 1,
|
|
||||||
'name': 'Water Filtration Machine',
|
|
||||||
'tech_type': 'BaseFiltrationMachine'},
|
|
||||||
35081: {'classification': ItemClassification.progression,
|
|
||||||
'count': 1,
|
|
||||||
'name': 'Ultra High Capacity Tank',
|
|
||||||
'tech_type': 'HighCapacityTank'},
|
|
||||||
35082: {'classification': ItemClassification.progression,
|
|
||||||
'count': 1,
|
|
||||||
'name': 'Large Room',
|
|
||||||
'tech_type': 'BaseLargeRoom'},
|
|
||||||
# awarded with their rooms, keeping that as-is as they're cosmetic
|
|
||||||
35083: {'classification': ItemClassification.filler,
|
|
||||||
'count': 0,
|
|
||||||
'name': 'Large Room Glass Dome',
|
|
||||||
'tech_type': 'BaseLargeGlassDome'},
|
|
||||||
35084: {'classification': ItemClassification.filler,
|
|
||||||
'count': 0,
|
|
||||||
'name': 'Multipurpose Room Glass Dome',
|
|
||||||
'tech_type': 'BaseGlassDome'},
|
|
||||||
35085: {'classification': ItemClassification.filler,
|
|
||||||
'count': 0,
|
|
||||||
'name': 'Partition',
|
|
||||||
'tech_type': 'BasePartition'},
|
|
||||||
35086: {'classification': ItemClassification.filler,
|
|
||||||
'count': 0,
|
|
||||||
'name': 'Partition Door',
|
|
||||||
'tech_type': 'BasePartitionDoor'},
|
|
||||||
# new items that the mod implements
|
|
||||||
|
|
||||||
|
|
||||||
|
item_table: Dict[int, ItemData] = {
|
||||||
|
35000: ItemData(IC.useful, 1, "Compass", "Compass"),
|
||||||
|
35001: ItemData(IC.progression, 1, "Lightweight High Capacity Tank", "PlasteelTank"),
|
||||||
|
35002: ItemData(IC.progression, 1, "Vehicle Upgrade Console", "BaseUpgradeConsole"),
|
||||||
|
35003: ItemData(IC.progression, 1, "Ultra Glide Fins", "UltraGlideFins"),
|
||||||
|
35004: ItemData(IC.useful, 1, "Cyclops Sonar Upgrade", "CyclopsSonarModule"),
|
||||||
|
35005: ItemData(IC.useful, 1, "Reinforced Dive Suit", "ReinforcedDiveSuit"),
|
||||||
|
35006: ItemData(IC.useful, 1, "Cyclops Thermal Reactor Module", "CyclopsThermalReactorModule"),
|
||||||
|
35007: ItemData(IC.filler, 1, "Water Filtration Suit", "WaterFiltrationSuit"),
|
||||||
|
35008: ItemData(IC.progression, 1, "Alien Containment", "BaseWaterPark"),
|
||||||
|
35009: ItemData(IC.useful, 1, "Creature Decoy", "CyclopsDecoy"),
|
||||||
|
35010: ItemData(IC.useful, 1, "Cyclops Fire Suppression System", "CyclopsFireSuppressionModule"),
|
||||||
|
35011: ItemData(IC.useful, 1, "Swim Charge Fins", "SwimChargeFins"),
|
||||||
|
35012: ItemData(IC.useful, 1, "Repulsion Cannon", "RepulsionCannon"),
|
||||||
|
35013: ItemData(IC.useful, 1, "Cyclops Decoy Tube Upgrade", "CyclopsDecoyModule"),
|
||||||
|
35014: ItemData(IC.progression, 1, "Cyclops Shield Generator", "CyclopsShieldModule"),
|
||||||
|
35015: ItemData(IC.progression, 1, "Cyclops Depth Module MK1", "CyclopsHullModule1"),
|
||||||
|
35016: ItemData(IC.useful, 1, "Cyclops Docking Bay Repair Module", "CyclopsSeamothRepairModule"),
|
||||||
|
35017: ItemData(IC.useful, 2, "Battery Charger fragment", "BatteryChargerFragment"),
|
||||||
|
35018: ItemData(IC.filler, 2, "Beacon Fragment", "BeaconFragment"),
|
||||||
|
35019: ItemData(IC.useful, 2, "Bioreactor Fragment", "BaseBioReactorFragment"),
|
||||||
|
35020: ItemData(IC.progression, 4, "Cyclops Bridge Fragment", "CyclopsBridgeFragment"),
|
||||||
|
35021: ItemData(IC.progression, 4, "Cyclops Engine Fragment", "CyclopsEngineFragment"),
|
||||||
|
35022: ItemData(IC.progression, 4, "Cyclops Hull Fragment", "CyclopsHullFragment"),
|
||||||
|
35023: ItemData(IC.filler, 2, "Grav Trap Fragment", "GravSphereFragment"),
|
||||||
|
35024: ItemData(IC.progression, 3, "Laser Cutter Fragment", "LaserCutterFragment"),
|
||||||
|
35025: ItemData(IC.filler, 2, "Light Stick Fragment", "TechlightFragment"),
|
||||||
|
35026: ItemData(IC.progression, 5, "Mobile Vehicle Bay Fragment", "ConstructorFragment"),
|
||||||
|
35027: ItemData(IC.progression, 3, "Modification Station Fragment", "WorkbenchFragment"),
|
||||||
|
35028: ItemData(IC.progression, 2, "Moonpool Fragment", "MoonpoolFragment"),
|
||||||
|
35029: ItemData(IC.useful, 3, "Nuclear Reactor Fragment", "BaseNuclearReactorFragment"),
|
||||||
|
35030: ItemData(IC.useful, 2, "Power Cell Charger Fragment", "PowerCellChargerFragment"),
|
||||||
|
35031: ItemData(IC.filler, 1, "Power Transmitter Fragment", "PowerTransmitterFragment"),
|
||||||
|
35032: ItemData(IC.progression, 6, "Prawn Suit Fragment", "ExosuitFragment"),
|
||||||
|
35033: ItemData(IC.useful, 2, "Prawn Suit Drill Arm Fragment", "ExosuitDrillArmFragment"),
|
||||||
|
35034: ItemData(IC.useful, 2, "Prawn Suit Grappling Arm Fragment", "ExosuitGrapplingArmFragment"),
|
||||||
|
35035: ItemData(IC.useful, 2, "Prawn Suit Propulsion Cannon Fragment", "ExosuitPropulsionArmFragment"),
|
||||||
|
35036: ItemData(IC.useful, 2, "Prawn Suit Torpedo Arm Fragment", "ExosuitTorpedoArmFragment"),
|
||||||
|
35037: ItemData(IC.useful, 3, "Scanner Room Fragment", "BaseMapRoomFragment"),
|
||||||
|
35038: ItemData(IC.progression, 5, "Seamoth Fragment", "SeamothFragment"),
|
||||||
|
35039: ItemData(IC.progression, 2, "Stasis Rifle Fragment", "StasisRifleFragment"),
|
||||||
|
35040: ItemData(IC.useful, 2, "Thermal Plant Fragment", "ThermalPlantFragment"),
|
||||||
|
35041: ItemData(IC.progression, 4, "Seaglide Fragment", "SeaglideFragment"),
|
||||||
|
35042: ItemData(IC.progression, 1, "Radiation Suit", "RadiationSuit"),
|
||||||
|
35043: ItemData(IC.progression, 2, "Propulsion Cannon Fragment", "PropulsionCannonFragment"),
|
||||||
|
35044: ItemData(IC.progression_skip_balancing, 1, "Neptune Launch Platform", "RocketBase"),
|
||||||
|
35045: ItemData(IC.progression, 1, "Ion Power Cell", "PrecursorIonPowerCell"),
|
||||||
|
35046: ItemData(IC.filler, 2, "Exterior Growbed", "FarmingTray"),
|
||||||
|
35047: ItemData(IC.filler, 1, "Picture Frame", "PictureFrameFragment"),
|
||||||
|
35048: ItemData(IC.filler, 1, "Bench", "Bench"),
|
||||||
|
35049: ItemData(IC.filler, 1, "Basic Plant Pot", "PlanterPotFragment"),
|
||||||
|
35050: ItemData(IC.filler, 1, "Interior Growbed", "PlanterBoxFragment"),
|
||||||
|
35051: ItemData(IC.filler, 1, "Plant Shelf", "PlanterShelfFragment"),
|
||||||
|
35052: ItemData(IC.filler, 1, "Observatory", "BaseObservatory"),
|
||||||
|
35053: ItemData(IC.progression, 1, "Multipurpose Room", "BaseRoom"),
|
||||||
|
35054: ItemData(IC.useful, 1, "Bulkhead", "BaseBulkhead"),
|
||||||
|
35055: ItemData(IC.filler, 1, "Spotlight", "Spotlight"),
|
||||||
|
35056: ItemData(IC.filler, 1, "Desk", "StarshipDesk"),
|
||||||
|
35057: ItemData(IC.filler, 1, "Swivel Chair", "StarshipChair"),
|
||||||
|
35058: ItemData(IC.filler, 1, "Office Chair", "StarshipChair2"),
|
||||||
|
35059: ItemData(IC.filler, 1, "Command Chair", "StarshipChair3"),
|
||||||
|
35060: ItemData(IC.filler, 1, "Counter", "LabCounter"),
|
||||||
|
35061: ItemData(IC.filler, 1, "Single Bed", "NarrowBed"),
|
||||||
|
35062: ItemData(IC.filler, 1, "Basic Double Bed", "Bed1"),
|
||||||
|
35063: ItemData(IC.filler, 1, "Quilted Double Bed", "Bed2"),
|
||||||
|
35064: ItemData(IC.filler, 1, "Coffee Vending Machine", "CoffeeVendingMachine"),
|
||||||
|
35065: ItemData(IC.filler, 1, "Trash Can", "Trashcans"),
|
||||||
|
35066: ItemData(IC.filler, 1, "Floodlight", "Techlight"),
|
||||||
|
35067: ItemData(IC.filler, 1, "Bar Table", "BarTable"),
|
||||||
|
35068: ItemData(IC.filler, 1, "Vending Machine", "VendingMachine"),
|
||||||
|
35069: ItemData(IC.filler, 1, "Single Wall Shelf", "SingleWallShelf"),
|
||||||
|
35070: ItemData(IC.filler, 1, "Wall Shelves", "WallShelves"),
|
||||||
|
35071: ItemData(IC.filler, 1, "Round Plant Pot", "PlanterPot2"),
|
||||||
|
35072: ItemData(IC.filler, 1, "Chic Plant Pot", "PlanterPot3"),
|
||||||
|
35073: ItemData(IC.filler, 1, "Nuclear Waste Disposal", "LabTrashcan"),
|
||||||
|
35074: ItemData(IC.filler, 1, "Wall Planter", "BasePlanter"),
|
||||||
|
35075: ItemData(IC.progression, 1, "Ion Battery", "PrecursorIonBattery"),
|
||||||
|
35076: ItemData(IC.progression_skip_balancing, 1, "Neptune Gantry", "RocketBaseLadder"),
|
||||||
|
35077: ItemData(IC.progression_skip_balancing, 1, "Neptune Boosters", "RocketStage1"),
|
||||||
|
35078: ItemData(IC.progression_skip_balancing, 1, "Neptune Fuel Reserve", "RocketStage2"),
|
||||||
|
35079: ItemData(IC.progression_skip_balancing, 1, "Neptune Cockpit", "RocketStage3"),
|
||||||
|
35080: ItemData(IC.filler, 1, "Water Filtration Machine", "BaseFiltrationMachine"),
|
||||||
|
35081: ItemData(IC.progression, 1, "Ultra High Capacity Tank", "HighCapacityTank"),
|
||||||
|
35082: ItemData(IC.progression, 1, "Large Room", "BaseLargeRoom"),
|
||||||
|
# awarded with their rooms, keeping that as-is as they"re cosmetic
|
||||||
|
35083: ItemData(IC.filler, 0, "Large Room Glass Dome", "BaseLargeGlassDome"),
|
||||||
|
35084: ItemData(IC.filler, 0, "Multipurpose Room Glass Dome", "BaseGlassDome"),
|
||||||
|
35085: ItemData(IC.filler, 0, "Partition", "BasePartition"),
|
||||||
|
35086: ItemData(IC.filler, 0, "Partition Door", "BasePartitionDoor"),
|
||||||
|
|
||||||
|
# Bundles of items
|
||||||
# Awards all furniture as a bundle
|
# Awards all furniture as a bundle
|
||||||
35100: {'classification': ItemClassification.filler,
|
35100: ItemData(IC.filler, 0, "Furniture", "AP_Furniture", ItemType.group),
|
||||||
'count': 0,
|
|
||||||
'name': 'Furniture',
|
|
||||||
'tech_type': 'Furniture'},
|
|
||||||
# Awards all farming blueprints as a bundle
|
# Awards all farming blueprints as a bundle
|
||||||
35101: {'classification': ItemClassification.filler,
|
35101: ItemData(IC.filler, 0, "Farming", "AP_Farming", ItemType.group),
|
||||||
'count': 0,
|
|
||||||
'name': 'Farming',
|
# Awards multiple resources as a bundle
|
||||||
'tech_type': 'Farming'},
|
35102: ItemData(IC.filler, 0, "Resources Bundle", "AP_Resources", ItemType.group),
|
||||||
|
|
||||||
|
# resource bundles, as convenience/filler
|
||||||
|
|
||||||
|
# ores
|
||||||
|
35200: make_resource_bundle_data("Titanium"),
|
||||||
|
35201: make_resource_bundle_data("Copper Ore", "Copper"),
|
||||||
|
35202: make_resource_bundle_data("Silver Ore", "Silver"),
|
||||||
|
35203: make_resource_bundle_data("Gold"),
|
||||||
|
35204: make_resource_bundle_data("Lead"),
|
||||||
|
35205: make_resource_bundle_data("Diamond"),
|
||||||
|
35206: make_resource_bundle_data("Lithium"),
|
||||||
|
35207: make_resource_bundle_data("Ruby", "AluminumOxide"),
|
||||||
|
35208: make_resource_bundle_data("Nickel Ore", "Nickel"),
|
||||||
|
35209: make_resource_bundle_data("Crystalline Sulfur", "Sulphur"),
|
||||||
|
35210: make_resource_bundle_data("Salt Deposit", "Salt"),
|
||||||
|
35211: make_resource_bundle_data("Kyanite"),
|
||||||
|
35212: make_resource_bundle_data("Magnetite"),
|
||||||
|
35213: make_resource_bundle_data("Reactor Rod", "ReactorRod"),
|
||||||
}
|
}
|
||||||
|
|
||||||
advancement_item_names: Set[str] = set()
|
|
||||||
non_advancement_item_names: Set[str] = set()
|
|
||||||
|
|
||||||
|
items_by_type: Dict[ItemType, List[int]] = {item_type: [] for item_type in ItemType}
|
||||||
for item_id, item_data in item_table.items():
|
for item_id, item_data in item_table.items():
|
||||||
item_name = item_data["name"]
|
items_by_type[item_data.type].append(item_id)
|
||||||
if ItemClassification.progression in item_data["classification"]:
|
|
||||||
advancement_item_names.add(item_name)
|
|
||||||
else:
|
|
||||||
non_advancement_item_names.add(item_name)
|
|
||||||
|
|
||||||
group_items: Dict[int, Set[int]] = {
|
group_items: Dict[int, Set[int]] = {
|
||||||
35100: {35025, 35047, 35048, 35056, 35057, 35058, 35059, 35060, 35061, 35062, 35063, 35064, 35065, 35067, 35068,
|
35100: {35025, 35047, 35048, 35056, 35057, 35058, 35059, 35060, 35061, 35062, 35063, 35064, 35065, 35067, 35068,
|
||||||
35069, 35070, 35073, 35074},
|
35069, 35070, 35073, 35074},
|
||||||
35101: {35049, 35050, 35051, 35071, 35072, 35074}
|
35101: {35049, 35050, 35051, 35071, 35072, 35074},
|
||||||
|
35102: set(items_by_type[ItemType.resource]),
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import itertools
|
import itertools
|
||||||
from typing import List, Dict, Any
|
from typing import List, Dict, Any, cast
|
||||||
|
|
||||||
from BaseClasses import Region, Entrance, Location, Item, Tutorial, ItemClassification
|
from BaseClasses import Region, Entrance, Location, Item, Tutorial, ItemClassification
|
||||||
from worlds.AutoWorld import World, WebWorld
|
from worlds.AutoWorld import World, WebWorld
|
||||||
|
@ -10,7 +10,7 @@ from . import Items
|
||||||
from . import Locations
|
from . import Locations
|
||||||
from . import Creatures
|
from . import Creatures
|
||||||
from . import Options
|
from . import Options
|
||||||
from .Items import item_table, group_items
|
from .Items import item_table, group_items, items_by_type, ItemType
|
||||||
from .Rules import set_rules
|
from .Rules import set_rules
|
||||||
|
|
||||||
logger = logging.getLogger("Subnautica")
|
logger = logging.getLogger("Subnautica")
|
||||||
|
@ -40,12 +40,12 @@ class SubnauticaWorld(World):
|
||||||
game = "Subnautica"
|
game = "Subnautica"
|
||||||
web = SubnaticaWeb()
|
web = SubnaticaWeb()
|
||||||
|
|
||||||
item_name_to_id = {data["name"]: item_id for item_id, data in Items.item_table.items()}
|
item_name_to_id = {data.name: item_id for item_id, data in Items.item_table.items()}
|
||||||
location_name_to_id = all_locations
|
location_name_to_id = all_locations
|
||||||
option_definitions = Options.options
|
option_definitions = Options.options
|
||||||
|
|
||||||
data_version = 9
|
data_version = 10
|
||||||
required_client_version = (0, 4, 0)
|
required_client_version = (0, 4, 1)
|
||||||
|
|
||||||
creatures_to_scan: List[str]
|
creatures_to_scan: List[str]
|
||||||
|
|
||||||
|
@ -61,8 +61,8 @@ class SubnauticaWorld(World):
|
||||||
self.multiworld.creature_scans[self.player].value
|
self.multiworld.creature_scans[self.player].value
|
||||||
)
|
)
|
||||||
|
|
||||||
self.creatures_to_scan = self.multiworld.random.sample(creature_pool,
|
self.creatures_to_scan = self.multiworld.random.sample(
|
||||||
self.multiworld.creature_scans[self.player].value)
|
creature_pool, self.multiworld.creature_scans[self.player].value)
|
||||||
|
|
||||||
def create_regions(self):
|
def create_regions(self):
|
||||||
self.multiworld.regions += [
|
self.multiworld.regions += [
|
||||||
|
@ -94,27 +94,46 @@ class SubnauticaWorld(World):
|
||||||
|
|
||||||
for item_id, item in item_table.items():
|
for item_id, item in item_table.items():
|
||||||
if item_id in grouped:
|
if item_id in grouped:
|
||||||
extras += item["count"]
|
extras += item.count
|
||||||
else:
|
else:
|
||||||
for i in range(item["count"]):
|
for i in range(item.count):
|
||||||
subnautica_item = self.create_item(item["name"])
|
subnautica_item = self.create_item(item.name)
|
||||||
if item["name"] == "Neptune Launch Platform":
|
if item.name == "Neptune Launch Platform":
|
||||||
self.multiworld.get_location("Aurora - Captain Data Terminal", self.player).place_locked_item(
|
self.multiworld.get_location("Aurora - Captain Data Terminal", self.player).place_locked_item(
|
||||||
subnautica_item)
|
subnautica_item)
|
||||||
else:
|
else:
|
||||||
pool.append(subnautica_item)
|
pool.append(subnautica_item)
|
||||||
|
|
||||||
group_amount: int = 3
|
group_amount: int = 2
|
||||||
assert len(group_items) * group_amount <= extras
|
assert len(group_items) * group_amount <= extras
|
||||||
for name in ("Furniture", "Farming"):
|
for item_id in group_items:
|
||||||
|
name = item_table[item_id].name
|
||||||
for _ in range(group_amount):
|
for _ in range(group_amount):
|
||||||
pool.append(self.create_item(name))
|
pool.append(self.create_item(name))
|
||||||
extras -= group_amount
|
extras -= group_amount
|
||||||
|
|
||||||
for item_name in self.multiworld.random.choices(
|
for item_name in self.multiworld.random.sample(
|
||||||
sorted(Items.advancement_item_names - {"Neptune Launch Platform"}), k=extras):
|
# list of high-count important fragments as priority filler
|
||||||
|
[
|
||||||
|
"Cyclops Engine Fragment",
|
||||||
|
"Modification Station Fragment",
|
||||||
|
"Mobile Vehicle Bay Fragment",
|
||||||
|
"Seamoth Fragment",
|
||||||
|
"Cyclops Hull Fragment",
|
||||||
|
"Cyclops Bridge Fragment",
|
||||||
|
"Prawn Suit Fragment",
|
||||||
|
"Moonpool Fragment",
|
||||||
|
],
|
||||||
|
k=min(extras, 8)):
|
||||||
item = self.create_item(item_name)
|
item = self.create_item(item_name)
|
||||||
pool.append(item)
|
pool.append(item)
|
||||||
|
extras -= 1
|
||||||
|
|
||||||
|
# resource bundle filler
|
||||||
|
for _ in range(extras):
|
||||||
|
item = self.create_filler()
|
||||||
|
item = cast(SubnauticaItem, item)
|
||||||
|
pool.append(item)
|
||||||
|
|
||||||
self.multiworld.itempool += pool
|
self.multiworld.itempool += pool
|
||||||
|
|
||||||
|
@ -138,7 +157,7 @@ class SubnauticaWorld(World):
|
||||||
item_id: int = self.item_name_to_id[name]
|
item_id: int = self.item_name_to_id[name]
|
||||||
|
|
||||||
return SubnauticaItem(name,
|
return SubnauticaItem(name,
|
||||||
item_table[item_id]["classification"],
|
item_table[item_id].classification,
|
||||||
item_id, player=self.player)
|
item_id, player=self.player)
|
||||||
|
|
||||||
def create_region(self, name: str, locations=None, exits=None):
|
def create_region(self, name: str, locations=None, exits=None):
|
||||||
|
@ -153,6 +172,9 @@ class SubnauticaWorld(World):
|
||||||
ret.exits.append(Entrance(self.player, region_exit, ret))
|
ret.exits.append(Entrance(self.player, region_exit, ret))
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def get_filler_item_name(self) -> str:
|
||||||
|
return item_table[self.multiworld.random.choice(items_by_type[ItemType.resource])].name
|
||||||
|
|
||||||
|
|
||||||
class SubnauticaLocation(Location):
|
class SubnauticaLocation(Location):
|
||||||
game: str = "Subnautica"
|
game: str = "Subnautica"
|
||||||
|
|
|
@ -8,8 +8,18 @@ class SubnauticaTest(unittest.TestCase):
|
||||||
|
|
||||||
def testIDRange(self):
|
def testIDRange(self):
|
||||||
for name, id in subnautica.SubnauticaWorld.location_name_to_id.items():
|
for name, id in subnautica.SubnauticaWorld.location_name_to_id.items():
|
||||||
with self.subTest(item=name):
|
with self.subTest(location=name):
|
||||||
if "Scan" in name:
|
if "Scan" in name:
|
||||||
self.assertLess(self.scancutoff, id)
|
self.assertLess(self.scancutoff, id)
|
||||||
else:
|
else:
|
||||||
self.assertGreater(self.scancutoff, id)
|
self.assertGreater(self.scancutoff, id)
|
||||||
|
|
||||||
|
def testGroupAssociation(self):
|
||||||
|
from worlds.subnautica import Items
|
||||||
|
for item_id, item_data in Items.item_table.items():
|
||||||
|
if item_data.type == Items.ItemType.group:
|
||||||
|
with self.subTest(item=item_data.name):
|
||||||
|
self.assertIn(item_id, Items.group_items)
|
||||||
|
for item_id in Items.group_items:
|
||||||
|
with self.subTest(item_id=item_id):
|
||||||
|
self.assertEqual(Items.item_table[item_id].type, Items.ItemType.group)
|
||||||
|
|
Loading…
Reference in New Issue