Skip to content

Commit

Permalink
Subnautica: filler items distribution (#3104)
Browse files Browse the repository at this point in the history
  • Loading branch information
Berserker66 authored Apr 14, 2024
1 parent 7b3727e commit 1c14d11
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 18 deletions.
19 changes: 12 additions & 7 deletions worlds/subnautica/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import itertools
from typing import List, Dict, Any, cast

from BaseClasses import Region, Entrance, Location, Item, Tutorial, ItemClassification
from BaseClasses import Region, Location, Item, Tutorial, ItemClassification
from worlds.AutoWorld import World, WebWorld
from . import items
from . import locations
Expand Down Expand Up @@ -42,14 +42,16 @@ class SubnauticaWorld(World):

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.option_definitions

options_dataclass = options.SubnauticaOptions
options: options.SubnauticaOptions
data_version = 10
required_client_version = (0, 4, 1)

creatures_to_scan: List[str]

def generate_early(self) -> None:
if not self.options.filler_items_distribution.weights_pair[1][-1]:
raise Exception("Filler Items Distribution needs at least one positive weight.")
if self.options.early_seaglide:
self.multiworld.local_early_items[self.player]["Seaglide Fragment"] = 2

Expand Down Expand Up @@ -98,7 +100,7 @@ def create_regions(self):
planet_region
]

# refer to Rules.py
# refer to rules.py
set_rules = set_rules

def create_items(self):
Expand Down Expand Up @@ -129,7 +131,7 @@ def create_items(self):
extras -= group_amount

for item_name in self.random.sample(
# list of high-count important fragments as priority filler
# list of high-count important fragments as priority filler
[
"Cyclops Engine Fragment",
"Cyclops Hull Fragment",
Expand All @@ -140,7 +142,7 @@ def create_items(self):
"Modification Station Fragment",
"Moonpool Fragment",
"Laser Cutter Fragment",
],
],
k=min(extras, 9)):
item = self.create_item(item_name)
pool.append(item)
Expand Down Expand Up @@ -176,7 +178,10 @@ def create_item(self, name: str) -> SubnauticaItem:
item_id, player=self.player)

def get_filler_item_name(self) -> str:
return item_table[self.multiworld.random.choice(items_by_type[ItemType.resource])].name
item_names, cum_item_weights = self.options.filler_items_distribution.weights_pair
return self.random.choices(item_names,
cum_weights=cum_item_weights,
k=1)[0]


class SubnauticaLocation(Location):
Expand Down
3 changes: 3 additions & 0 deletions worlds/subnautica/items.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ def make_resource_bundle_data(display_name: str, internal_name: str = "") -> Ite
items_by_type: Dict[ItemType, List[int]] = {item_type: [] for item_type in ItemType}
for item_id, item_data in item_table.items():
items_by_type[item_data.type].append(item_id)
item_names_by_type: Dict[ItemType, List[str]] = {
item_type: sorted(item_table[item_id].name for item_id in item_ids) for item_type, item_ids in items_by_type.items()
}

group_items: Dict[int, Set[int]] = {
35100: {35025, 35047, 35048, 35056, 35057, 35058, 35059, 35060, 35061, 35062, 35063, 35064, 35065, 35067, 35068,
Expand Down
50 changes: 39 additions & 11 deletions worlds/subnautica/options.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
import typing
from dataclasses import dataclass
from functools import cached_property

from Options import (
Choice,
Range,
DeathLink,
Toggle,
DefaultOnToggle,
StartInventoryPool,
ItemDict,
PerGameCommonOptions,
)

from Options import Choice, Range, DeathLink, Toggle, DefaultOnToggle, StartInventoryPool
from .creatures import all_creatures, Definitions
from .items import ItemType, item_names_by_type


class SwimRule(Choice):
Expand Down Expand Up @@ -103,13 +116,28 @@ class SubnauticaDeathLink(DeathLink):
Note: can be toggled via in-game console command "deathlink"."""


option_definitions = {
"swim_rule": SwimRule,
"early_seaglide": EarlySeaglide,
"free_samples": FreeSamples,
"goal": Goal,
"creature_scans": CreatureScans,
"creature_scan_logic": AggressiveScanLogic,
"death_link": SubnauticaDeathLink,
"start_inventory_from_pool": StartInventoryPool,
}
class FillerItemsDistribution(ItemDict):
"""Random chance weights of various filler resources that can be obtained.
Available items: """
__doc__ += ", ".join(f"\"{item_name}\"" for item_name in item_names_by_type[ItemType.resource])
_valid_keys = frozenset(item_names_by_type[ItemType.resource])
default = {item_name: 1 for item_name in item_names_by_type[ItemType.resource]}
display_name = "Filler Items Distribution"

@cached_property
def weights_pair(self) -> typing.Tuple[typing.List[str], typing.List[int]]:
from itertools import accumulate
return list(self.value.keys()), list(accumulate(self.value.values()))


@dataclass
class SubnauticaOptions(PerGameCommonOptions):
swim_rule: SwimRule
early_seaglide: EarlySeaglide
free_samples: FreeSamples
goal: Goal
creature_scans: CreatureScans
creature_scan_logic: AggressiveScanLogic
death_link: SubnauticaDeathLink
start_inventory_from_pool: StartInventoryPool
filler_items_distribution: FillerItemsDistribution

0 comments on commit 1c14d11

Please sign in to comment.