Subnautica: group items and removal of item pool option

This commit is contained in:
Fabian Dill 2023-03-23 21:21:11 +01:00 committed by Fabian Dill
parent cdd460ae15
commit cbf72becc1
3 changed files with 52 additions and 33 deletions

View File

@ -40,8 +40,8 @@ item_table: Dict[int, ItemDict] = {
'tech_type': 'CyclopsThermalReactorModule'}, 'tech_type': 'CyclopsThermalReactorModule'},
35007: {'classification': ItemClassification.filler, 35007: {'classification': ItemClassification.filler,
'count': 1, 'count': 1,
'name': 'Stillsuit', 'name': 'Water Filtration Suit',
'tech_type': 'WaterFiltrationSuitFragment'}, 'tech_type': 'WaterFiltrationSuit'},
35008: {'classification': ItemClassification.progression, 35008: {'classification': ItemClassification.progression,
'count': 1, 'count': 1,
'name': 'Alien Containment', 'name': 'Alien Containment',
@ -359,6 +359,18 @@ item_table: Dict[int, ItemDict] = {
'count': 0, 'count': 0,
'name': 'Partition Door', 'name': 'Partition Door',
'tech_type': 'BasePartitionDoor'}, 'tech_type': 'BasePartitionDoor'},
# new items that the mod implements
# Awards all furniture as a bundle
35100: {'classification': ItemClassification.filler,
'count': 0,
'name': 'Furniture',
'tech_type': 'Furniture'},
# Awards all farming blueprints as a bundle
35101: {'classification': ItemClassification.filler,
'count': 0,
'name': 'Farming',
'tech_type': 'Farming'},
} }
advancement_item_names: Set[str] = set() advancement_item_names: Set[str] = set()
@ -371,8 +383,15 @@ for item_id, item_data in item_table.items():
else: else:
non_advancement_item_names.add(item_name) non_advancement_item_names.add(item_name)
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}
}
if False: # turn to True to export for Subnautica mod if False: # turn to True to export for Subnautica mod
from .Locations import location_table from .Locations import location_table
from NetUtils import encode
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()}
@ -380,3 +399,5 @@ if False: # turn to True to export for Subnautica mod
with open("items.json", "w") as f: with open("items.json", "w") as f:
json.dump(payload, f) json.dump(payload, f)
with open("group_items.json", "w") as f:
f.write(encode(group_items))

View File

@ -35,14 +35,6 @@ class EarlySeaglide(DefaultOnToggle):
display_name = "Early Seaglide" display_name = "Early Seaglide"
class ItemPool(Choice):
"""Valuable item pool leaves all filler items in their vanilla locations and
creates random duplicates of important items into freed spots."""
display_name = "Item Pool"
option_standard = 0
option_valuable = 1
class Goal(Choice): class Goal(Choice):
"""Goal to complete. """Goal to complete.
Launch: Leave the planet. Launch: Leave the planet.
@ -108,7 +100,6 @@ class SubnauticaDeathLink(DeathLink):
options = { options = {
"swim_rule": SwimRule, "swim_rule": SwimRule,
"early_seaglide": EarlySeaglide, "early_seaglide": EarlySeaglide,
"item_pool": ItemPool,
"goal": Goal, "goal": Goal,
"creature_scans": CreatureScans, "creature_scans": CreatureScans,
"creature_scan_logic": AggressiveScanLogic, "creature_scan_logic": AggressiveScanLogic,

View File

@ -1,4 +1,7 @@
from __future__ import annotations
import logging import logging
import itertools
from typing import List, Dict, Any from typing import List, Dict, Any
from BaseClasses import Region, Entrance, Location, Item, Tutorial, ItemClassification from BaseClasses import Region, Entrance, Location, Item, Tutorial, ItemClassification
@ -7,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 from .Items import item_table, group_items
from .Rules import set_rules from .Rules import set_rules
logger = logging.getLogger("Subnautica") logger = logging.getLogger("Subnautica")
@ -84,37 +87,41 @@ class SubnauticaWorld(World):
def create_items(self): def create_items(self):
# Generate item pool # Generate item pool
pool = [] pool: List[SubnauticaItem] = []
extras = self.multiworld.creature_scans[self.player].value extras = self.multiworld.creature_scans[self.player].value
valuable = self.multiworld.item_pool[self.player] == Options.ItemPool.option_valuable
for item in item_table.values(): grouped = set(itertools.chain.from_iterable(group_items.values()))
for item_id, item in item_table.items():
if item_id in grouped:
extras += item["count"]
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)
elif valuable and ItemClassification.filler == item["classification"]:
extras += 1
else: else:
pool.append(subnautica_item) pool.append(subnautica_item)
for item_name in self.multiworld.random.choices(sorted(Items.advancement_item_names - {"Neptune Launch Platform"}), group_amount: int = 3
k=extras): assert len(group_items) * group_amount <= extras
for name in ("Furniture", "Farming"):
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):
item = self.create_item(item_name) item = self.create_item(item_name)
item.classification = ItemClassification.filler # as it's an extra, just fast-fill it somewhere
pool.append(item) pool.append(item)
self.multiworld.itempool += pool self.multiworld.itempool += pool
def fill_slot_data(self) -> Dict[str, Any]: def fill_slot_data(self) -> Dict[str, Any]:
goal: Options.Goal = self.multiworld.goal[self.player] goal: Options.Goal = self.multiworld.goal[self.player]
item_pool: Options.ItemPool = self.multiworld.item_pool[self.player]
swim_rule: Options.SwimRule = self.multiworld.swim_rule[self.player] swim_rule: Options.SwimRule = self.multiworld.swim_rule[self.player]
vanilla_tech: List[str] = [] vanilla_tech: List[str] = []
if item_pool == Options.ItemPool.option_valuable:
for item in Items.item_table.values():
if item["classification"] == ItemClassification.filler:
vanilla_tech.append(item["tech_type"])
slot_data: Dict[str, Any] = { slot_data: Dict[str, Any] = {
"goal": goal.current_key, "goal": goal.current_key,
@ -126,7 +133,7 @@ class SubnauticaWorld(World):
return slot_data return slot_data
def create_item(self, name: str) -> Item: def create_item(self, name: str) -> SubnauticaItem:
item_id: int = self.item_name_to_id[name] item_id: int = self.item_name_to_id[name]
return SubnauticaItem(name, return SubnauticaItem(name,