Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stardew Valley: Remove some events for a slight performance increase #4085

15 changes: 0 additions & 15 deletions worlds/stardew_valley/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,25 +206,10 @@ def precollect_farm_type_items(self):
self.multiworld.push_precollected(self.create_starting_item("Progressive Coop"))

def setup_player_events(self):
self.setup_construction_events()
self.setup_quest_events()
self.setup_action_events()
self.setup_logic_events()

def setup_construction_events(self):
can_construct_buildings = LocationData(None, RegionName.carpenter, Event.can_construct_buildings)
self.create_event_location(can_construct_buildings, True_(), Event.can_construct_buildings)

def setup_quest_events(self):
start_dark_talisman_quest = LocationData(None, RegionName.railroad, Event.start_dark_talisman_quest)
self.create_event_location(start_dark_talisman_quest, self.logic.wallet.has_rusty_key(), Event.start_dark_talisman_quest)

def setup_action_events(self):
can_ship_event = LocationData(None, LogicRegion.shipping, Event.can_ship_items)
self.create_event_location(can_ship_event, true_, Event.can_ship_items)
can_shop_pierre_event = LocationData(None, RegionName.pierre_store, Event.can_shop_at_pierre)
self.create_event_location(can_shop_pierre_event, true_, Event.can_shop_at_pierre)

spring_farming = LocationData(None, LogicRegion.spring_farming, Event.spring_farming)
self.create_event_location(spring_farming, true_, Event.spring_farming)
summer_farming = LocationData(None, LogicRegion.summer_farming, Event.summer_farming)
Expand Down
11 changes: 8 additions & 3 deletions worlds/stardew_valley/logic/building_logic.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from functools import cached_property
from typing import Dict, Union

from Utils import cache_self1
Expand All @@ -8,12 +9,12 @@
from .region_logic import RegionLogicMixin
from ..options import BuildingProgression
from ..stardew_rule import StardewRule, True_, False_, Has
from ..strings.ap_names.event_names import Event
from ..strings.artisan_good_names import ArtisanGood
from ..strings.building_names import Building
from ..strings.fish_names import WaterItem
from ..strings.material_names import Material
from ..strings.metal_names import MetalBar
from ..strings.region_names import Region

has_group = "building"

Expand Down Expand Up @@ -60,7 +61,7 @@ def has_building(self, building: str) -> StardewRule:
return True_()
return self.logic.received(building)

carpenter_rule = self.logic.received(Event.can_construct_buildings)
carpenter_rule = self.logic.building.can_construct_buildings
if not self.options.building_progression & BuildingProgression.option_progressive:
return Has(building, self.registry.building_rules, has_group) & carpenter_rule

Expand All @@ -75,6 +76,10 @@ def has_building(self, building: str) -> StardewRule:
building = " ".join(["Progressive", *building.split(" ")[1:]])
return self.logic.received(building, count) & carpenter_rule

@cached_property
def can_construct_buildings(self) -> StardewRule:
return self.logic.region.can_reach(Region.carpenter)

@cache_self1
def has_house(self, upgrade_level: int) -> StardewRule:
if upgrade_level < 1:
Expand All @@ -83,7 +88,7 @@ def has_house(self, upgrade_level: int) -> StardewRule:
if upgrade_level > 3:
return False_()

carpenter_rule = self.logic.received(Event.can_construct_buildings)
carpenter_rule = self.logic.building.can_construct_buildings
if self.options.building_progression & BuildingProgression.option_progressive:
return carpenter_rule & self.logic.received(f"Progressive House", upgrade_level)

Expand Down
13 changes: 9 additions & 4 deletions worlds/stardew_valley/logic/money_logic.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import typing
from typing import Union

from Utils import cache_self1
Expand All @@ -11,10 +12,14 @@
from ..data.shop import ShopSource
from ..options import SpecialOrderLocations
from ..stardew_rule import StardewRule, True_, HasProgressionPercent, False_, true_
from ..strings.ap_names.event_names import Event
from ..strings.currency_names import Currency
from ..strings.region_names import Region, LogicRegion

if typing.TYPE_CHECKING:
Jouramie marked this conversation as resolved.
Show resolved Hide resolved
from .shipping_logic import ShippingLogicMixin

assert ShippingLogicMixin

qi_gem_rewards = ("100 Qi Gems", "50 Qi Gems", "40 Qi Gems", "35 Qi Gems", "25 Qi Gems",
"20 Qi Gems", "15 Qi Gems", "10 Qi Gems")

Expand All @@ -26,7 +31,7 @@ def __init__(self, *args, **kwargs):


class MoneyLogic(BaseLogic[Union[RegionLogicMixin, MoneyLogicMixin, TimeLogicMixin, RegionLogicMixin, ReceivedLogicMixin, HasLogicMixin, SeasonLogicMixin,
GrindLogicMixin]]):
GrindLogicMixin, 'ShippingLogicMixin']]):

@cache_self1
def can_have_earned_total(self, amount: int) -> StardewRule:
Expand All @@ -37,7 +42,7 @@ def can_have_earned_total(self, amount: int) -> StardewRule:
willy_rule = self.logic.region.can_reach_all((Region.fish_shop, LogicRegion.fishing))
clint_rule = self.logic.region.can_reach_all((Region.blacksmith, Region.mines_floor_5))
robin_rule = self.logic.region.can_reach_all((Region.carpenter, Region.secret_woods))
shipping_rule = self.logic.received(Event.can_ship_items)
shipping_rule = self.logic.shipping.can_use_shipping_bin

if amount < 2000:
selling_any_rule = pierre_rule | willy_rule | clint_rule | robin_rule | shipping_rule
Expand All @@ -50,7 +55,7 @@ def can_have_earned_total(self, amount: int) -> StardewRule:
if amount < 10000:
return shipping_rule

seed_rules = self.logic.received(Event.can_shop_at_pierre)
seed_rules = self.logic.region.can_reach(Region.pierre_store)
if amount < 40000:
return shipping_rule & seed_rules

Expand Down
5 changes: 2 additions & 3 deletions worlds/stardew_valley/logic/shipping_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from ..options import ExcludeGingerIsland, Shipsanity
from ..options import SpecialOrderLocations
from ..stardew_rule import StardewRule
from ..strings.ap_names.event_names import Event
from ..strings.building_names import Building


Expand All @@ -29,7 +28,7 @@ def can_use_shipping_bin(self) -> StardewRule:

@cache_self1
def can_ship(self, item: str) -> StardewRule:
return self.logic.received(Event.can_ship_items) & self.logic.has(item)
return self.logic.shipping.can_use_shipping_bin & self.logic.has(item)
Jouramie marked this conversation as resolved.
Show resolved Hide resolved

def can_ship_everything(self) -> StardewRule:
shipsanity_prefix = "Shipsanity: "
Expand All @@ -49,7 +48,7 @@ def can_ship_everything(self) -> StardewRule:

def can_ship_everything_in_slot(self, all_location_names_in_slot: List[str]) -> StardewRule:
if self.options.shipsanity == Shipsanity.option_none:
return self.can_ship_everything()
return self.logic.shipping.can_ship_everything()

rules = [self.logic.building.has_building(Building.shipping_bin)]

Expand Down
7 changes: 3 additions & 4 deletions worlds/stardew_valley/logic/special_order_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
from ..content.vanilla.qi_board import qi_board_content_pack
from ..stardew_rule import StardewRule, Has, false_
from ..strings.animal_product_names import AnimalProduct
from ..strings.ap_names.event_names import Event
from ..strings.ap_names.transport_names import Transportation
from ..strings.artisan_good_names import ArtisanGood
from ..strings.crop_names import Vegetable, Fruit
Expand Down Expand Up @@ -61,7 +60,7 @@ def initialize_rules(self):
SpecialOrder.gifts_for_george: self.logic.season.has(Season.spring) & self.logic.has(Forageable.leek),
SpecialOrder.fragments_of_the_past: self.logic.monster.can_kill(Monster.skeleton),
SpecialOrder.gus_famous_omelet: self.logic.has(AnimalProduct.any_egg),
SpecialOrder.crop_order: self.logic.ability.can_farm_perfectly() & self.logic.received(Event.can_ship_items),
SpecialOrder.crop_order: self.logic.ability.can_farm_perfectly() & self.logic.shipping.can_use_shipping_bin,
SpecialOrder.community_cleanup: self.logic.skill.can_crab_pot,
SpecialOrder.the_strong_stuff: self.logic.has(ArtisanGood.specific_juice(Vegetable.potato)),
SpecialOrder.pierres_prime_produce: self.logic.ability.can_farm_perfectly(),
Expand Down Expand Up @@ -94,12 +93,12 @@ def initialize_rules(self):
self.update_rules({
SpecialOrder.qis_crop: self.logic.ability.can_farm_perfectly() & self.logic.region.can_reach(Region.greenhouse) &
self.logic.region.can_reach(Region.island_west) & self.logic.skill.has_total_level(50) &
self.logic.has(Machine.seed_maker) & self.logic.received(Event.can_ship_items),
self.logic.has(Machine.seed_maker) & self.logic.shipping.can_use_shipping_bin,
SpecialOrder.lets_play_a_game: self.logic.arcade.has_junimo_kart_max_level(),
SpecialOrder.four_precious_stones: self.logic.time.has_lived_max_months & self.logic.has("Prismatic Shard") &
self.logic.ability.can_mine_perfectly_in_the_skull_cavern(),
SpecialOrder.qis_hungry_challenge: self.logic.ability.can_mine_perfectly_in_the_skull_cavern(),
SpecialOrder.qis_cuisine: self.logic.cooking.can_cook() & self.logic.received(Event.can_ship_items) &
SpecialOrder.qis_cuisine: self.logic.cooking.can_cook() & self.logic.shipping.can_use_shipping_bin &
(self.logic.money.can_spend_at(Region.saloon, 205000) | self.logic.money.can_spend_at(Region.pierre_store, 170000)),
SpecialOrder.qis_kindness: self.logic.relationship.can_give_loved_gifts_to_everyone(),
SpecialOrder.extended_family: self.logic.ability.can_fish_perfectly() & self.logic.has(Fish.angler) & self.logic.has(Fish.glacierfish) &
Expand Down
40 changes: 16 additions & 24 deletions worlds/stardew_valley/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
from .stardew_rule.rule_explain import explain
from .strings.ap_names.ap_option_names import OptionName
from .strings.ap_names.community_upgrade_names import CommunityUpgrade
from .strings.ap_names.event_names import Event
from .strings.ap_names.mods.mod_items import SVEQuestItem, SVERunes
from .strings.ap_names.transport_names import Transportation
from .strings.artisan_good_names import ArtisanGood
Expand Down Expand Up @@ -251,7 +250,8 @@ def set_entrance_rules(logic: StardewLogic, multiworld, player, world_options: S
set_entrance_rule(multiworld, player, Entrance.enter_witch_warp_cave, logic.quest.has_dark_talisman() | (logic.mod.magic.can_blink()))
set_entrance_rule(multiworld, player, Entrance.enter_witch_hut, (logic.has(ArtisanGood.void_mayonnaise) | logic.mod.magic.can_blink()))
set_entrance_rule(multiworld, player, Entrance.enter_mutant_bug_lair,
(logic.received(Event.start_dark_talisman_quest) & logic.relationship.can_meet(NPC.krobus)) | logic.mod.magic.can_blink())
(logic.wallet.has_rusty_key() & logic.region.can_reach(Region.railroad) & logic.relationship.can_meet(
NPC.krobus)) | logic.mod.magic.can_blink())
set_entrance_rule(multiworld, player, Entrance.enter_casino, logic.quest.has_club_card())

set_bedroom_entrance_rules(logic, multiworld, player, world_options)
Expand Down Expand Up @@ -307,17 +307,15 @@ def set_mines_floor_entrance_rules(logic, multiworld, player):
rule = logic.mine.has_mine_elevator_to_floor(floor - 10)
if floor == 5 or floor == 45 or floor == 85:
rule = rule & logic.mine.can_progress_in_the_mines_from_floor(floor)
entrance = multiworld.get_entrance(dig_to_mines_floor(floor), player)
MultiWorldRules.set_rule(entrance, rule)
set_entrance_rule(multiworld, player, dig_to_mines_floor(floor), rule)


def set_skull_cavern_floor_entrance_rules(logic, multiworld, player):
for floor in range(25, 200 + 25, 25):
rule = logic.mod.elevator.has_skull_cavern_elevator_to_floor(floor - 25)
if floor == 25 or floor == 75 or floor == 125:
rule = rule & logic.mine.can_progress_in_the_skull_cavern_from_floor(floor)
entrance = multiworld.get_entrance(dig_to_skull_floor(floor), player)
MultiWorldRules.set_rule(entrance, rule)
set_entrance_rule(multiworld, player, dig_to_skull_floor(floor), rule)


def set_blacksmith_entrance_rules(logic, multiworld, player):
Expand Down Expand Up @@ -346,9 +344,8 @@ def set_skill_entrance_rules(logic, multiworld, player, world_options: StardewVa


def set_blacksmith_upgrade_rule(logic, multiworld, player, entrance_name: str, item_name: str, tool_material: str):
material_entrance = multiworld.get_entrance(entrance_name, player)
upgrade_rule = logic.has(item_name) & logic.money.can_spend(tool_upgrade_prices[tool_material])
MultiWorldRules.set_rule(material_entrance, upgrade_rule)
set_entrance_rule(multiworld, player, entrance_name, upgrade_rule)


def set_festival_entrance_rules(logic, multiworld, player):
Expand Down Expand Up @@ -880,25 +877,19 @@ def set_traveling_merchant_day_rules(logic: StardewLogic, multiworld: MultiWorld


def set_arcade_machine_rules(logic: StardewLogic, multiworld: MultiWorld, player: int, world_options: StardewValleyOptions):
MultiWorldRules.add_rule(multiworld.get_entrance(Entrance.play_junimo_kart, player),
logic.received(Wallet.skull_key))
play_junimo_kart_rule = logic.received(Wallet.skull_key)

if world_options.arcade_machine_locations != ArcadeMachineLocations.option_full_shuffling:
set_entrance_rule(multiworld, player, Entrance.play_junimo_kart, play_junimo_kart_rule)
return

MultiWorldRules.add_rule(multiworld.get_entrance(Entrance.play_junimo_kart, player),
logic.has("Junimo Kart Small Buff"))
MultiWorldRules.add_rule(multiworld.get_entrance(Entrance.reach_junimo_kart_2, player),
logic.has("Junimo Kart Medium Buff"))
MultiWorldRules.add_rule(multiworld.get_entrance(Entrance.reach_junimo_kart_3, player),
logic.has("Junimo Kart Big Buff"))
MultiWorldRules.add_rule(multiworld.get_entrance(Entrance.reach_junimo_kart_4, player),
logic.has("Junimo Kart Max Buff"))
MultiWorldRules.add_rule(multiworld.get_entrance(Entrance.play_journey_of_the_prairie_king, player),
logic.has("JotPK Small Buff"))
MultiWorldRules.add_rule(multiworld.get_entrance(Entrance.reach_jotpk_world_2, player),
logic.has("JotPK Medium Buff"))
MultiWorldRules.add_rule(multiworld.get_entrance(Entrance.reach_jotpk_world_3, player),
logic.has("JotPK Big Buff"))
set_entrance_rule(multiworld, player, Entrance.play_junimo_kart, play_junimo_kart_rule & logic.has("Junimo Kart Small Buff"))
set_entrance_rule(multiworld, player, Entrance.reach_junimo_kart_2, logic.has("Junimo Kart Medium Buff"))
set_entrance_rule(multiworld, player, Entrance.reach_junimo_kart_3, logic.has("Junimo Kart Big Buff"))
set_entrance_rule(multiworld, player, Entrance.reach_junimo_kart_4, logic.has("Junimo Kart Max Buff"))
set_entrance_rule(multiworld, player, Entrance.play_journey_of_the_prairie_king, logic.has("JotPK Small Buff"))
set_entrance_rule(multiworld, player, Entrance.reach_jotpk_world_2, logic.has("JotPK Medium Buff"))
set_entrance_rule(multiworld, player, Entrance.reach_jotpk_world_3, logic.has("JotPK Big Buff"))
MultiWorldRules.add_rule(multiworld.get_location("Journey of the Prairie King Victory", player),
logic.has("JotPK Max Buff"))

Expand Down Expand Up @@ -1049,6 +1040,7 @@ def set_entrance_rule(multiworld, player, entrance: str, rule: StardewRule):
potentially_required_regions = look_for_indirect_connection(rule)
if potentially_required_regions:
for region in potentially_required_regions:
logger.debug(f"Registering indirect condition for {region} -> {entrance}")
github-advanced-security[bot] marked this conversation as resolved.
Dismissed
Show resolved Hide resolved
multiworld.register_indirect_condition(multiworld.get_region(region, player), multiworld.get_entrance(entrance, player))

MultiWorldRules.set_rule(multiworld.get_entrance(entrance, player), rule)
Expand Down
20 changes: 10 additions & 10 deletions worlds/stardew_valley/stardew_rule/rule_explain.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@
from functools import cached_property, singledispatch
from typing import Iterable, Set, Tuple, List, Optional

from BaseClasses import CollectionState
from BaseClasses import CollectionState, Location, Entrance
from worlds.generic.Rules import CollectionRule
from . import StardewRule, AggregatingStardewRule, Count, Has, TotalReceived, Received, Reach, true_


@dataclass
class RuleExplanation:
rule: StardewRule
state: CollectionState
state: CollectionState = field(repr=False, hash=False)
expected: bool
sub_rules: Iterable[StardewRule] = field(default_factory=list)
explored_rules_key: Set[Tuple[str, str]] = field(default_factory=set)
explored_rules_key: Set[Tuple[str, str]] = field(default_factory=set, repr=False, hash=False)
current_rule_explored: bool = False

def __post_init__(self):
Expand All @@ -38,13 +38,6 @@ def __str__(self, depth=0):
if i.result is not self.expected else i.summary(depth + 1)
for i in sorted(self.explained_sub_rules, key=lambda x: x.result))

def __repr__(self, depth=0):
if not self.sub_rules:
return self.summary(depth)

return self.summary(depth) + "\n" + "\n".join(i.__repr__(depth + 1)
for i in sorted(self.explained_sub_rules, key=lambda x: x.result))

@cached_property
def result(self) -> bool:
try:
Expand Down Expand Up @@ -134,6 +127,10 @@ def _(rule: Reach, state: CollectionState, expected: bool, explored_spots: Set[T
access_rules = [Reach(spot.parent_region.name, "Region", rule.player)]
else:
access_rules = [spot.access_rule, Reach(spot.parent_region.name, "Region", rule.player)]
elif spot.access_rule == Location.access_rule:
# Sometime locations just don't have an access rule and all the relevant logic is in the parent region.
access_rules = [Reach(spot.parent_region.name, "Region", rule.player)]


elif rule.resolution_hint == 'Entrance':
spot = state.multiworld.get_entrance(rule.spot, rule.player)
Expand All @@ -143,6 +140,9 @@ def _(rule: Reach, state: CollectionState, expected: bool, explored_spots: Set[T
access_rules = [Reach(spot.parent_region.name, "Region", rule.player)]
else:
access_rules = [spot.access_rule, Reach(spot.parent_region.name, "Region", rule.player)]
elif spot.access_rule == Entrance.access_rule:
# Sometime entrances just don't have an access rule and all the relevant logic is in the parent region.
access_rules = [Reach(spot.parent_region.name, "Region", rule.player)]

else:
spot = state.multiworld.get_region(rule.spot, rule.player)
Expand Down
4 changes: 0 additions & 4 deletions worlds/stardew_valley/strings/ap_names/event_names.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@ def event(name: str):

class Event:
victory = event("Victory")
can_construct_buildings = event("Can Construct Buildings")
start_dark_talisman_quest = event("Start Dark Talisman Quest")
can_ship_items = event("Can Ship Items")
can_shop_at_pierre = event("Can Shop At Pierre's")
spring_farming = event("Spring Farming")
summer_farming = event("Summer Farming")
fall_farming = event("Fall Farming")
Expand Down
Loading
Loading