Subnautica: revamp filler item pool

This commit is contained in:
Fabian Dill 2023-05-25 22:57:15 +02:00 committed by Fabian Dill
parent b077b2aeef
commit 532c4c068f
4 changed files with 203 additions and 396 deletions

View File

@ -13,11 +13,17 @@ if __name__ == "__main__":
sys.path.append(new_home)
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
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()}
with open("locations.json", "w") as f:
with open(in_export_folder("locations.json"), "w") as f:
json.dump(payload, f)
# copy-paste from Rules
@ -49,17 +55,22 @@ if __name__ == "__main__":
"751": [location_id for location_id, location_data
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)
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)}"
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
with open("items.json", "w") as f:
with open(in_export_folder("items.json"), "w") as 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))
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('')}")

View File

@ -1,390 +1,154 @@
from BaseClasses import ItemClassification
from typing import TypedDict, Dict, Set
from BaseClasses import ItemClassification as IC
from typing import NamedTuple, Dict, Set, List
from enum import IntEnum
class ItemDict(TypedDict):
classification: ItemClassification
class ItemType(IntEnum):
technology = 1
resource = 2
group = 3
class ItemData(NamedTuple):
classification: IC
count: int
name: str
tech_type: str
type: ItemType = ItemType.technology
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': '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
def make_resource_bundle_data(display_name: str, internal_name: str = "") -> ItemData:
if not internal_name:
internal_name = display_name
return ItemData(IC.filler, 0, display_name, internal_name, ItemType.resource)
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
35100: {'classification': ItemClassification.filler,
'count': 0,
'name': 'Furniture',
'tech_type': 'Furniture'},
35100: ItemData(IC.filler, 0, "Furniture", "AP_Furniture", ItemType.group),
# Awards all farming blueprints as a bundle
35101: {'classification': ItemClassification.filler,
'count': 0,
'name': 'Farming',
'tech_type': 'Farming'},
35101: ItemData(IC.filler, 0, "Farming", "AP_Farming", ItemType.group),
# Awards multiple resources as a bundle
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():
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)
items_by_type[item_data.type].append(item_id)
group_items: Dict[int, Set[int]] = {
35100: {35025, 35047, 35048, 35056, 35057, 35058, 35059, 35060, 35061, 35062, 35063, 35064, 35065, 35067, 35068,
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]),
}

View File

@ -2,7 +2,7 @@ from __future__ import annotations
import logging
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 worlds.AutoWorld import World, WebWorld
@ -10,7 +10,7 @@ from . import Items
from . import Locations
from . import Creatures
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
logger = logging.getLogger("Subnautica")
@ -40,12 +40,12 @@ class SubnauticaWorld(World):
game = "Subnautica"
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
option_definitions = Options.options
data_version = 9
required_client_version = (0, 4, 0)
data_version = 10
required_client_version = (0, 4, 1)
creatures_to_scan: List[str]
@ -61,8 +61,8 @@ class SubnauticaWorld(World):
self.multiworld.creature_scans[self.player].value
)
self.creatures_to_scan = self.multiworld.random.sample(creature_pool,
self.multiworld.creature_scans[self.player].value)
self.creatures_to_scan = self.multiworld.random.sample(
creature_pool, self.multiworld.creature_scans[self.player].value)
def create_regions(self):
self.multiworld.regions += [
@ -94,27 +94,46 @@ class SubnauticaWorld(World):
for item_id, item in item_table.items():
if item_id in grouped:
extras += item["count"]
extras += item.count
else:
for i in range(item["count"]):
subnautica_item = self.create_item(item["name"])
if item["name"] == "Neptune Launch Platform":
for i in range(item.count):
subnautica_item = self.create_item(item.name)
if item.name == "Neptune Launch Platform":
self.multiworld.get_location("Aurora - Captain Data Terminal", self.player).place_locked_item(
subnautica_item)
else:
pool.append(subnautica_item)
group_amount: int = 3
group_amount: int = 2
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):
pool.append(self.create_item(name))
extras -= group_amount
for item_name in self.multiworld.random.choices(
sorted(Items.advancement_item_names - {"Neptune Launch Platform"}), k=extras):
for item_name in self.multiworld.random.sample(
# 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)
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
@ -138,7 +157,7 @@ class SubnauticaWorld(World):
item_id: int = self.item_name_to_id[name]
return SubnauticaItem(name,
item_table[item_id]["classification"],
item_table[item_id].classification,
item_id, player=self.player)
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))
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):
game: str = "Subnautica"

View File

@ -8,8 +8,18 @@ class SubnauticaTest(unittest.TestCase):
def testIDRange(self):
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:
self.assertLess(self.scancutoff, id)
else:
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)