Subnautica: filler items distribution (#3104)

This commit is contained in:
Fabian Dill 2024-04-14 20:36:25 +02:00 committed by GitHub
parent 7b3727e945
commit 1c14d1107f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 54 additions and 18 deletions

View File

@ -4,7 +4,7 @@ import logging
import itertools import itertools
from typing import List, Dict, Any, cast 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 worlds.AutoWorld import World, WebWorld
from . import items from . import items
from . import locations from . import locations
@ -42,14 +42,16 @@ class SubnauticaWorld(World):
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.option_definitions options_dataclass = options.SubnauticaOptions
options: options.SubnauticaOptions
data_version = 10 data_version = 10
required_client_version = (0, 4, 1) required_client_version = (0, 4, 1)
creatures_to_scan: List[str] creatures_to_scan: List[str]
def generate_early(self) -> None: 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: if self.options.early_seaglide:
self.multiworld.local_early_items[self.player]["Seaglide Fragment"] = 2 self.multiworld.local_early_items[self.player]["Seaglide Fragment"] = 2
@ -98,7 +100,7 @@ class SubnauticaWorld(World):
planet_region planet_region
] ]
# refer to Rules.py # refer to rules.py
set_rules = set_rules set_rules = set_rules
def create_items(self): def create_items(self):
@ -129,7 +131,7 @@ class SubnauticaWorld(World):
extras -= group_amount extras -= group_amount
for item_name in self.random.sample( 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 Engine Fragment",
"Cyclops Hull Fragment", "Cyclops Hull Fragment",
@ -140,7 +142,7 @@ class SubnauticaWorld(World):
"Modification Station Fragment", "Modification Station Fragment",
"Moonpool Fragment", "Moonpool Fragment",
"Laser Cutter Fragment", "Laser Cutter Fragment",
], ],
k=min(extras, 9)): k=min(extras, 9)):
item = self.create_item(item_name) item = self.create_item(item_name)
pool.append(item) pool.append(item)
@ -176,7 +178,10 @@ class SubnauticaWorld(World):
item_id, player=self.player) item_id, player=self.player)
def get_filler_item_name(self) -> str: 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): class SubnauticaLocation(Location):

View File

@ -145,6 +145,9 @@ item_table: Dict[int, ItemData] = {
items_by_type: Dict[ItemType, List[int]] = {item_type: [] for item_type in ItemType} 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():
items_by_type[item_data.type].append(item_id) 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]] = { 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,

View File

@ -1,7 +1,20 @@
import typing 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 .creatures import all_creatures, Definitions
from .items import ItemType, item_names_by_type
class SwimRule(Choice): class SwimRule(Choice):
@ -103,13 +116,28 @@ class SubnauticaDeathLink(DeathLink):
Note: can be toggled via in-game console command "deathlink".""" Note: can be toggled via in-game console command "deathlink"."""
option_definitions = { class FillerItemsDistribution(ItemDict):
"swim_rule": SwimRule, """Random chance weights of various filler resources that can be obtained.
"early_seaglide": EarlySeaglide, Available items: """
"free_samples": FreeSamples, __doc__ += ", ".join(f"\"{item_name}\"" for item_name in item_names_by_type[ItemType.resource])
"goal": Goal, _valid_keys = frozenset(item_names_by_type[ItemType.resource])
"creature_scans": CreatureScans, default = {item_name: 1 for item_name in item_names_by_type[ItemType.resource]}
"creature_scan_logic": AggressiveScanLogic, display_name = "Filler Items Distribution"
"death_link": SubnauticaDeathLink,
"start_inventory_from_pool": StartInventoryPool, @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