Subnautica: filler items distribution (#3104)
This commit is contained in:
parent
7b3727e945
commit
1c14d1107f
|
@ -4,7 +4,7 @@ import logging
|
|||
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
|
||||
|
@ -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
|
||||
|
||||
|
@ -98,7 +100,7 @@ class SubnauticaWorld(World):
|
|||
planet_region
|
||||
]
|
||||
|
||||
# refer to Rules.py
|
||||
# refer to rules.py
|
||||
set_rules = set_rules
|
||||
|
||||
def create_items(self):
|
||||
|
@ -129,7 +131,7 @@ class SubnauticaWorld(World):
|
|||
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",
|
||||
|
@ -140,7 +142,7 @@ class SubnauticaWorld(World):
|
|||
"Modification Station Fragment",
|
||||
"Moonpool Fragment",
|
||||
"Laser Cutter Fragment",
|
||||
],
|
||||
],
|
||||
k=min(extras, 9)):
|
||||
item = self.create_item(item_name)
|
||||
pool.append(item)
|
||||
|
@ -176,7 +178,10 @@ class SubnauticaWorld(World):
|
|||
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):
|
||||
|
|
|
@ -145,6 +145,9 @@ item_table: Dict[int, ItemData] = {
|
|||
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,
|
||||
|
|
|
@ -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):
|
||||
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue