Stardew Valley: Move filler pool generation out of the world class (#4372)
* merge group options so specific handling is not needed when generating filler pool * fix * remove unneeded imports * self review * remove unneeded imports * looks like typing was missing woopsi
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import logging
|
||||
import typing
|
||||
from random import Random
|
||||
from typing import Dict, Any, Iterable, Optional, List, TextIO, cast
|
||||
|
||||
@@ -9,14 +10,15 @@ from .bundles.bundle_room import BundleRoom
|
||||
from .bundles.bundles import get_all_bundles
|
||||
from .content import StardewContent, create_content
|
||||
from .early_items import setup_early_items
|
||||
from .items import item_table, create_items, ItemData, Group, items_by_group, get_all_filler_items, remove_limited_amount_packs
|
||||
from .items import item_table, create_items, ItemData, Group, items_by_group, generate_filler_choice_pool
|
||||
from .locations import location_table, create_locations, LocationData, locations_by_tag
|
||||
from .logic.logic import StardewLogic
|
||||
from .options import StardewValleyOptions, SeasonRandomization, Goal, BundleRandomization, EnabledFillerBuffs, NumberOfMovementBuffs, \
|
||||
BuildingProgression, ExcludeGingerIsland, TrapItems, EntranceRandomization, FarmType
|
||||
BuildingProgression, EntranceRandomization, FarmType
|
||||
from .options.forced_options import force_change_options_if_incompatible
|
||||
from .options.option_groups import sv_option_groups
|
||||
from .options.presets import sv_options_presets
|
||||
from .options.worlds_group import apply_most_restrictive_options
|
||||
from .regions import create_regions
|
||||
from .rules import set_rules
|
||||
from .stardew_rule import True_, StardewRule, HasProgressionPercent
|
||||
@@ -89,6 +91,16 @@ class StardewValleyWorld(World):
|
||||
|
||||
total_progression_items: int
|
||||
|
||||
@classmethod
|
||||
def create_group(cls, multiworld: MultiWorld, new_player_id: int, players: set[int]) -> World:
|
||||
world_group = super().create_group(multiworld, new_player_id, players)
|
||||
|
||||
group_options = typing.cast(StardewValleyOptions, world_group.options)
|
||||
worlds_options = [typing.cast(StardewValleyOptions, multiworld.worlds[player].options) for player in players]
|
||||
apply_most_restrictive_options(group_options, worlds_options)
|
||||
|
||||
return world_group
|
||||
|
||||
def __init__(self, multiworld: MultiWorld, player: int):
|
||||
super().__init__(multiworld, player)
|
||||
self.filler_item_pool_names = []
|
||||
@@ -299,32 +311,9 @@ class StardewValleyWorld(World):
|
||||
|
||||
def get_filler_item_name(self) -> str:
|
||||
if not self.filler_item_pool_names:
|
||||
self.generate_filler_item_pool_names()
|
||||
self.filler_item_pool_names = generate_filler_choice_pool(self.options)
|
||||
return self.random.choice(self.filler_item_pool_names)
|
||||
|
||||
def generate_filler_item_pool_names(self):
|
||||
include_traps, exclude_island = self.get_filler_item_rules()
|
||||
available_filler = get_all_filler_items(include_traps, exclude_island)
|
||||
available_filler = remove_limited_amount_packs(available_filler)
|
||||
self.filler_item_pool_names = [item.name for item in available_filler]
|
||||
|
||||
def get_filler_item_rules(self):
|
||||
if self.player in self.multiworld.groups:
|
||||
link_group = self.multiworld.groups[self.player]
|
||||
include_traps = True
|
||||
exclude_island = False
|
||||
for player in link_group["players"]:
|
||||
if self.multiworld.game[player] != self.game:
|
||||
continue
|
||||
player_options = cast(StardewValleyOptions, self.multiworld.worlds[player].options)
|
||||
if player_options.trap_items == TrapItems.option_no_traps:
|
||||
include_traps = False
|
||||
if player_options.exclude_ginger_island == ExcludeGingerIsland.option_true:
|
||||
exclude_island = True
|
||||
return include_traps, exclude_island
|
||||
else:
|
||||
return self.options.trap_items != TrapItems.option_no_traps, self.options.exclude_ginger_island == ExcludeGingerIsland.option_true
|
||||
|
||||
def write_spoiler_header(self, spoiler_handle: TextIO) -> None:
|
||||
"""Write to the spoiler header. If individual it's right at the end of that player's options,
|
||||
if as stage it's right under the common header before per-player options."""
|
||||
|
||||
@@ -808,6 +808,16 @@ def remove_excluded_items_island_mods(items, exclude_ginger_island: bool, mods:
|
||||
return mod_filter
|
||||
|
||||
|
||||
def generate_filler_choice_pool(options: StardewValleyOptions) -> list[str]:
|
||||
include_traps = options.trap_items != TrapItems.option_no_traps
|
||||
exclude_island = options.exclude_ginger_island == ExcludeGingerIsland.option_true
|
||||
|
||||
available_filler = get_all_filler_items(include_traps, exclude_island)
|
||||
available_filler = remove_limited_amount_packs(available_filler)
|
||||
|
||||
return [item.name for item in available_filler]
|
||||
|
||||
|
||||
def remove_limited_amount_packs(packs):
|
||||
return [pack for pack in packs if Group.MAXIMUM_ONE not in pack.groups and Group.EXACTLY_TWO not in pack.groups]
|
||||
|
||||
|
||||
14
worlds/stardew_valley/options/worlds_group.py
Normal file
14
worlds/stardew_valley/options/worlds_group.py
Normal file
@@ -0,0 +1,14 @@
|
||||
from typing import Iterable
|
||||
|
||||
from .options import StardewValleyOptions
|
||||
|
||||
|
||||
def apply_most_restrictive_options(group_option: StardewValleyOptions, world_options: Iterable[StardewValleyOptions]) -> None:
|
||||
"""Merge the options of the worlds member of the group that can impact fillers generation into the option class of the group.
|
||||
"""
|
||||
|
||||
# If at least one world disabled ginger island, disabling it for the whole group
|
||||
group_option.exclude_ginger_island.value = max(o.exclude_ginger_island.value for o in world_options)
|
||||
|
||||
# If at least one world disabled traps, disabling them for the whole group
|
||||
group_option.trap_items.value = min(o.trap_items.value for o in world_options)
|
||||
@@ -2,7 +2,7 @@ from unittest import TestCase
|
||||
|
||||
from BaseClasses import MultiWorld
|
||||
from .option_assert import get_stardew_options
|
||||
from ... import options, ExcludeGingerIsland
|
||||
from ... import options
|
||||
|
||||
|
||||
def is_goal(multiworld: MultiWorld, goal: int) -> bool:
|
||||
@@ -36,7 +36,7 @@ def is_not_perfection(multiworld: MultiWorld) -> bool:
|
||||
class GoalAssertMixin(TestCase):
|
||||
|
||||
def assert_ginger_island_is_included(self, multiworld: MultiWorld):
|
||||
self.assertEqual(get_stardew_options(multiworld).exclude_ginger_island, ExcludeGingerIsland.option_false)
|
||||
self.assertEqual(get_stardew_options(multiworld).exclude_ginger_island, options.ExcludeGingerIsland.option_false)
|
||||
|
||||
def assert_walnut_hunter_world_is_valid(self, multiworld: MultiWorld):
|
||||
if is_not_walnut_hunter(multiworld):
|
||||
|
||||
@@ -2,7 +2,7 @@ from unittest import TestCase
|
||||
|
||||
from BaseClasses import MultiWorld
|
||||
from .world_assert import get_all_item_names, get_all_location_names
|
||||
from ... import StardewValleyWorld, options, item_table, Group, location_table, ExcludeGingerIsland
|
||||
from ... import StardewValleyWorld, options, item_table, Group, location_table
|
||||
from ...locations import LocationTags
|
||||
from ...strings.ap_names.transport_names import Transportation
|
||||
|
||||
@@ -49,7 +49,7 @@ class OptionAssertMixin(TestCase):
|
||||
|
||||
def assert_can_reach_island_if_should(self, multiworld: MultiWorld):
|
||||
stardew_options = get_stardew_options(multiworld)
|
||||
include_island = stardew_options.exclude_ginger_island.value == ExcludeGingerIsland.option_false
|
||||
include_island = stardew_options.exclude_ginger_island.value == options.ExcludeGingerIsland.option_false
|
||||
if include_island:
|
||||
self.assert_can_reach_island(multiworld)
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user