Skip to content

Commit

Permalink
Merge branch 'main' into tloz-fix-determinism
Browse files Browse the repository at this point in the history
  • Loading branch information
t3hf1gm3nt authored Jul 23, 2024
2 parents 2e9de9c + ed4ad38 commit 084b8c1
Show file tree
Hide file tree
Showing 26 changed files with 390 additions and 275 deletions.
2 changes: 1 addition & 1 deletion kvui.py
Original file line number Diff line number Diff line change
Expand Up @@ -595,8 +595,8 @@ def command_button_action(self, button):
"!help for server commands.")

def connect_button_action(self, button):
self.ctx.username = None
if self.ctx.server:
self.ctx.username = None
async_start(self.ctx.disconnect())
else:
async_start(self.ctx.connect(self.server_connect_bar.text.replace("/connect ", "")))
Expand Down
2 changes: 1 addition & 1 deletion worlds/bomb_rush_cyberfunk/Locations.py
Original file line number Diff line number Diff line change
Expand Up @@ -762,7 +762,7 @@ class EventDict(TypedDict):
'game_id': "graf385"},
{'name': "Tagged 389 Graffiti Spots",
'stage': Stages.Misc,
'game_id': "graf379"},
'game_id': "graf389"},
]


Expand Down
10 changes: 9 additions & 1 deletion worlds/lingo/data/LL1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,15 @@
painting: True
The Colorful:
painting: True
Welcome Back Area:
room: Welcome Back Area
door: Shortcut to Starting Room
Second Room:
door: Main Door
Hidden Room:
door: Back Right Door
Rhyme Room (Looped Square):
door: Rhyme Room Entrance
panels:
HI:
id: Entry Room/Panel_hi_hi
Expand Down Expand Up @@ -3265,7 +3274,6 @@
door: Traveled Entrance
Color Hallways:
door: Color Hallways Entrance
warp: True
panels:
Achievement:
id: Countdown Panels/Panel_traveled_traveled
Expand Down
Binary file modified worlds/lingo/data/generated.dat
Binary file not shown.
2 changes: 1 addition & 1 deletion worlds/lingo/regions.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ def create_regions(world: "LingoWorld") -> None:
RoomAndDoor("Pilgrim Antechamber", "Sun Painting"), EntranceType.PAINTING, False, world)

if early_color_hallways:
connect_entrance(regions, regions["Starting Room"], regions["Outside The Undeterred"], "Early Color Hallways",
connect_entrance(regions, regions["Starting Room"], regions["Color Hallways"], "Early Color Hallways",
None, EntranceType.PAINTING, False, world)

if painting_shuffle:
Expand Down
32 changes: 28 additions & 4 deletions worlds/lingo/test/TestPilgrimage.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ def test_access(self):
"Outside The Undeterred - Green Painting"]

for door in doors:
print(door)
self.assertFalse(self.can_reach_location("Pilgrim Antechamber - PILGRIM"))
self.collect_by_name(door)

Expand All @@ -53,7 +52,6 @@ def test_access(self):
"Starting Room - Street Painting"]

for door in doors:
print(door)
self.assertFalse(self.can_reach_location("Pilgrim Antechamber - PILGRIM"))
self.collect_by_name(door)

Expand Down Expand Up @@ -81,13 +79,40 @@ def test_access(self):
"Orange Tower Fourth Floor - Hot Crusts Door"]

for door in doors:
print(door)
self.assertFalse(self.can_reach_location("Pilgrim Antechamber - PILGRIM"))
self.collect_by_name(door)

self.assertTrue(self.can_reach_location("Pilgrim Antechamber - PILGRIM"))


class TestPilgrimageRequireStartingRoom(LingoTestBase):
options = {
"enable_pilgrimage": "true",
"shuffle_colors": "false",
"shuffle_doors": "complex",
"pilgrimage_allows_roof_access": "false",
"pilgrimage_allows_paintings": "false",
"early_color_hallways": "false"
}

def test_access(self):
doors = ["Second Room - Exit Door", "Crossroads - Roof Access", "Hub Room - Crossroads Entrance",
"Outside The Undeterred - Green Painting", "Outside The Undeterred - Number Hunt",
"Starting Room - Street Painting", "Outside The Initiated - Shortcut to Hub Room",
"Directional Gallery - Shortcut to The Undeterred", "Orange Tower First Floor - Salt Pepper Door",
"Color Hunt - Shortcut to The Steady", "The Bearer - Entrance",
"Orange Tower Fifth Floor - Quadruple Intersection", "The Tenacious - Shortcut to Hub Room",
"Outside The Agreeable - Tenacious Entrance", "Crossroads - Tower Entrance",
"Orange Tower Fourth Floor - Hot Crusts Door", "Challenge Room - Welcome Door",
"Number Hunt - Challenge Entrance", "Welcome Back Area - Shortcut to Starting Room"]

for door in doors:
self.assertFalse(self.can_reach_location("Pilgrim Antechamber - PILGRIM"))
self.collect_by_name(door)

self.assertTrue(self.can_reach_location("Pilgrim Antechamber - PILGRIM"))


class TestPilgrimageYesRoofNoPaintings(LingoTestBase):
options = {
"enable_pilgrimage": "true",
Expand All @@ -107,7 +132,6 @@ def test_access(self):
"Orange Tower Fifth Floor - Quadruple Intersection"]

for door in doors:
print(door)
self.assertFalse(self.can_reach_location("Pilgrim Antechamber - PILGRIM"))
self.collect_by_name(door)

Expand Down
2 changes: 1 addition & 1 deletion worlds/shorthike/Locations.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ class LocationInfo(TypedDict):
{"name": "Boat Rental",
"id": base_id + 55,
"inGameId": "DadDeer[0]",
"needsShovel": False, "purchase": True,
"needsShovel": False, "purchase": 100,
"minGoldenFeathers": 0, "minGoldenFeathersEasy": 0, "minGoldenFeathersBucket": 0},
{"name": "Boat Challenge Reward",
"id": base_id + 56,
Expand Down
2 changes: 1 addition & 1 deletion worlds/stardew_valley/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ def setup_victory(self):
Event.victory)
elif self.options.goal == Goal.option_greatest_walnut_hunter:
self.create_event_location(location_table[GoalName.greatest_walnut_hunter],
self.logic.has_walnut(130),
self.logic.walnut.has_walnut(130),
Event.victory)
elif self.options.goal == Goal.option_protector_of_the_valley:
self.create_event_location(location_table[GoalName.protector_of_the_valley],
Expand Down
6 changes: 5 additions & 1 deletion worlds/stardew_valley/content/vanilla/ginger_island.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
from ...data import villagers_data, fish_data
from ...data.game_item import ItemTag, Tag
from ...data.harvest import ForagingSource, HarvestFruitTreeSource, HarvestCropSource
from ...data.requirement import WalnutRequirement
from ...data.shop import ShopSource
from ...strings.book_names import Book
from ...strings.crop_names import Fruit, Vegetable
from ...strings.fish_names import Fish
from ...strings.forageable_names import Forageable, Mushroom
from ...strings.fruit_tree_names import Sapling
from ...strings.metal_names import Fossil, Mineral
from ...strings.region_names import Region
from ...strings.region_names import Region, LogicRegion
from ...strings.season_names import Season
from ...strings.seed_names import Seed

Expand Down Expand Up @@ -62,6 +63,9 @@ def harvest_source_hook(self, content: StardewContent):
Tag(ItemTag.BOOK, ItemTag.BOOK_POWER),
ShopSource(items_price=((10, Mineral.diamond),), shop_region=Region.volcano_dwarf_shop),
),
Book.queen_of_sauce_cookbook: (
Tag(ItemTag.BOOK, ItemTag.BOOK_SKILL),
ShopSource(money_price=50000, shop_region=LogicRegion.bookseller_2, other_requirements=(WalnutRequirement(100),)),), # Worst book ever

},
fishes=(
Expand Down
3 changes: 0 additions & 3 deletions worlds/stardew_valley/content/vanilla/pelican_town.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,9 +290,6 @@
Book.woodcutters_weekly: (
Tag(ItemTag.BOOK, ItemTag.BOOK_SKILL),
ShopSource(money_price=5000, shop_region=LogicRegion.bookseller_1),),
Book.queen_of_sauce_cookbook: (
Tag(ItemTag.BOOK, ItemTag.BOOK_SKILL),
ShopSource(money_price=50000, shop_region=LogicRegion.bookseller_2),), # Worst book ever
},
fishes=(
fish_data.albacore,
Expand Down
6 changes: 3 additions & 3 deletions worlds/stardew_valley/data/locations.csv
Original file line number Diff line number Diff line change
Expand Up @@ -2221,7 +2221,7 @@ id,region,name,tags,mod_name
3817,Shipping,Shipsanity: Raisins,"SHIPSANITY,SHIPSANITY_FULL_SHIPMENT",
3818,Shipping,Shipsanity: Dried Fruit,"SHIPSANITY,SHIPSANITY_FULL_SHIPMENT",
3819,Shipping,Shipsanity: Dried Mushrooms,"SHIPSANITY,SHIPSANITY_FULL_SHIPMENT",
3820,Shipping,Shipsanity: Stardrop Tea,"SHIPSANITY,SHIPSANITY_FULL_SHIPMENT",
3820,Shipping,Shipsanity: Stardrop Tea,"SHIPSANITY",
3821,Shipping,Shipsanity: Prize Ticket,"SHIPSANITY",
3822,Shipping,Shipsanity: Treasure Totem,"SHIPSANITY,REQUIRES_MASTERIES",
3823,Shipping,Shipsanity: Challenge Bait,"SHIPSANITY,REQUIRES_MASTERIES",
Expand Down Expand Up @@ -2252,7 +2252,7 @@ id,region,name,tags,mod_name
3848,Shipping,Shipsanity: Way Of The Wind pt. 1,"SHIPSANITY",
3849,Shipping,Shipsanity: Mapping Cave Systems,"SHIPSANITY",
3850,Shipping,Shipsanity: Price Catalogue,"SHIPSANITY",
3851,Shipping,Shipsanity: Queen Of Sauce Cookbook,"SHIPSANITY",
3851,Shipping,Shipsanity: Queen Of Sauce Cookbook,"SHIPSANITY,GINGER_ISLAND",
3852,Shipping,Shipsanity: The Diamond Hunter,"SHIPSANITY,GINGER_ISLAND",
3853,Shipping,Shipsanity: Book of Mysteries,"SHIPSANITY",
3854,Shipping,Shipsanity: Animal Catalogue,"SHIPSANITY",
Expand Down Expand Up @@ -2292,7 +2292,7 @@ id,region,name,tags,mod_name
4032,Farm,Read Book Of Stars,"BOOKSANITY,BOOKSANITY_SKILL",
4033,Farm,Read Combat Quarterly,"BOOKSANITY,BOOKSANITY_SKILL",
4034,Farm,Read Mining Monthly,"BOOKSANITY,BOOKSANITY_SKILL",
4035,Farm,Read Queen Of Sauce Cookbook,"BOOKSANITY,BOOKSANITY_SKILL",
4035,Farm,Read Queen Of Sauce Cookbook,"BOOKSANITY,BOOKSANITY_SKILL,GINGER_ISLAND",
4036,Farm,Read Stardew Valley Almanac,"BOOKSANITY,BOOKSANITY_SKILL",
4037,Farm,Read Woodcutter's Weekly,"BOOKSANITY,BOOKSANITY_SKILL",
4051,Museum,Read Tips on Farming,"BOOKSANITY,BOOKSANITY_LOST",
Expand Down
5 changes: 5 additions & 0 deletions worlds/stardew_valley/data/requirement.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,8 @@ class SeasonRequirement(Requirement):
@dataclass(frozen=True)
class YearRequirement(Requirement):
year: int


@dataclass(frozen=True)
class WalnutRequirement(Requirement):
amount: int
6 changes: 3 additions & 3 deletions worlds/stardew_valley/logic/bundle_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ def __init__(self, *args, **kwargs):
self.bundle = BundleLogic(*args, **kwargs)


class BundleLogic(BaseLogic[Union[ReceivedLogicMixin, HasLogicMixin, TimeLogicMixin, RegionLogicMixin, MoneyLogicMixin, QualityLogicMixin, FishingLogicMixin, SkillLogicMixin,
QuestLogicMixin]]):
class BundleLogic(BaseLogic[Union[ReceivedLogicMixin, HasLogicMixin, TimeLogicMixin, RegionLogicMixin, MoneyLogicMixin, QualityLogicMixin, FishingLogicMixin,
SkillLogicMixin, QuestLogicMixin]]):
# Should be cached
def can_complete_bundle(self, bundle: Bundle) -> StardewRule:
item_rules = []
Expand All @@ -45,7 +45,7 @@ def can_complete_bundle(self, bundle: Bundle) -> StardewRule:
qualities.append(bundle_item.quality)
quality_rules = self.get_quality_rules(qualities)
item_rules = self.logic.has_n(*item_rules, count=bundle.number_required)
time_rule = True_() if time_to_grind <= 0 else self.logic.time.has_lived_months(time_to_grind)
time_rule = self.logic.time.has_lived_months(time_to_grind)
return can_speak_junimo & item_rules & quality_rules & time_rule

def get_quality_rules(self, qualities: List[str]) -> StardewRule:
Expand Down
116 changes: 4 additions & 112 deletions worlds/stardew_valley/logic/logic.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from __future__ import annotations

import logging
from functools import cached_property
from typing import Collection, Callable

from .ability_logic import AbilityLogicMixin
Expand Down Expand Up @@ -43,23 +42,22 @@
from .tool_logic import ToolLogicMixin
from .traveling_merchant_logic import TravelingMerchantLogicMixin
from .wallet_logic import WalletLogicMixin
from .walnut_logic import WalnutLogicMixin
from ..content.game_content import StardewContent
from ..data.craftable_data import all_crafting_recipes
from ..data.museum_data import all_museum_items
from ..data.recipe_data import all_cooking_recipes
from ..mods.logic.magic_logic import MagicLogicMixin
from ..mods.logic.mod_logic import ModLogicMixin
from ..mods.mod_data import ModNames
from ..options import SpecialOrderLocations, ExcludeGingerIsland, FestivalLocations, StardewValleyOptions, Walnutsanity
from ..options import ExcludeGingerIsland, FestivalLocations, StardewValleyOptions
from ..stardew_rule import False_, True_, StardewRule
from ..strings.animal_names import Animal
from ..strings.animal_product_names import AnimalProduct
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.artisan_good_names import ArtisanGood
from ..strings.building_names import Building
from ..strings.craftable_names import Consumable, Furniture, Ring, Fishing, Lighting, WildSeeds
from ..strings.craftable_names import Consumable, Ring, Fishing, Lighting, WildSeeds
from ..strings.crop_names import Fruit, Vegetable
from ..strings.currency_names import Currency
from ..strings.decoration_names import Decoration
Expand Down Expand Up @@ -96,7 +94,7 @@ class StardewLogic(ReceivedLogicMixin, HasLogicMixin, RegionLogicMixin, Travelin
CombatLogicMixin, MagicLogicMixin, MonsterLogicMixin, ToolLogicMixin, PetLogicMixin, QualityLogicMixin,
SkillLogicMixin, FarmingLogicMixin, BundleLogicMixin, FishingLogicMixin, MineLogicMixin, CookingLogicMixin, AbilityLogicMixin,
SpecialOrderLogicMixin, QuestLogicMixin, CraftingLogicMixin, ModLogicMixin, HarvestingLogicMixin, SourceLogicMixin,
RequirementLogicMixin, BookLogicMixin, GrindLogicMixin):
RequirementLogicMixin, BookLogicMixin, GrindLogicMixin, WalnutLogicMixin):
player: int
options: StardewValleyOptions
content: StardewContent
Expand Down Expand Up @@ -461,32 +459,6 @@ def setup_events(self, register_event: Callable[[str, str, StardewRule], None])
def can_smelt(self, item: str) -> StardewRule:
return self.has(Machine.furnace) & self.has(item)

@cached_property
def can_start_field_office(self) -> StardewRule:
field_office = self.region.can_reach(Region.field_office)
professor_snail = self.received("Open Professor Snail Cave")
return field_office & professor_snail

def can_complete_large_animal_collection(self) -> StardewRule:
fossils = self.has_all(Fossil.fossilized_leg, Fossil.fossilized_ribs, Fossil.fossilized_skull, Fossil.fossilized_spine, Fossil.fossilized_tail)
return self.can_start_field_office & fossils

def can_complete_snake_collection(self) -> StardewRule:
fossils = self.has_all(Fossil.snake_skull, Fossil.snake_vertebrae)
return self.can_start_field_office & fossils

def can_complete_frog_collection(self) -> StardewRule:
fossils = self.has_all(Fossil.mummified_frog)
return self.can_start_field_office & fossils

def can_complete_bat_collection(self) -> StardewRule:
fossils = self.has_all(Fossil.mummified_bat)
return self.can_start_field_office & fossils

def can_complete_field_office(self) -> StardewRule:
return self.can_complete_large_animal_collection() & self.can_complete_snake_collection() & \
self.can_complete_frog_collection() & self.can_complete_bat_collection()

def can_finish_grandpa_evaluation(self) -> StardewRule:
# https://stardewvalleywiki.com/Grandpa
rules_worth_a_point = [
Expand Down Expand Up @@ -566,86 +538,6 @@ def has_island_trader(self) -> StardewRule:
return False_()
return self.region.can_reach(Region.island_trader)

def has_walnut(self, number: int) -> StardewRule:
if self.options.exclude_ginger_island == ExcludeGingerIsland.option_true:
return False_()
if number <= 0:
return True_()

if self.options.walnutsanity == Walnutsanity.preset_none:
return self.can_get_walnuts(number)
if self.options.walnutsanity == Walnutsanity.preset_all:
return self.has_received_walnuts(number)
puzzle_walnuts = 61
bush_walnuts = 25
dig_walnuts = 18
repeatable_walnuts = 33
total_walnuts = puzzle_walnuts + bush_walnuts + dig_walnuts + repeatable_walnuts
walnuts_to_receive = 0
walnuts_to_collect = number
if OptionName.walnutsanity_puzzles in self.options.walnutsanity:
puzzle_walnut_rate = puzzle_walnuts / total_walnuts
puzzle_walnuts_required = round(puzzle_walnut_rate * number)
walnuts_to_receive += puzzle_walnuts_required
walnuts_to_collect -= puzzle_walnuts_required
if OptionName.walnutsanity_bushes in self.options.walnutsanity:
bush_walnuts_rate = bush_walnuts / total_walnuts
bush_walnuts_required = round(bush_walnuts_rate * number)
walnuts_to_receive += bush_walnuts_required
walnuts_to_collect -= bush_walnuts_required
if OptionName.walnutsanity_dig_spots in self.options.walnutsanity:
dig_walnuts_rate = dig_walnuts / total_walnuts
dig_walnuts_required = round(dig_walnuts_rate * number)
walnuts_to_receive += dig_walnuts_required
walnuts_to_collect -= dig_walnuts_required
if OptionName.walnutsanity_repeatables in self.options.walnutsanity:
repeatable_walnuts_rate = repeatable_walnuts / total_walnuts
repeatable_walnuts_required = round(repeatable_walnuts_rate * number)
walnuts_to_receive += repeatable_walnuts_required
walnuts_to_collect -= repeatable_walnuts_required
return self.has_received_walnuts(walnuts_to_receive) & self.can_get_walnuts(walnuts_to_collect)

def has_received_walnuts(self, number: int) -> StardewRule:
return self.received(Event.received_walnuts, number)

def can_get_walnuts(self, number: int) -> StardewRule:
# https://stardewcommunitywiki.com/Golden_Walnut#Walnut_Locations
reach_south = self.region.can_reach(Region.island_south)
reach_north = self.region.can_reach(Region.island_north)
reach_west = self.region.can_reach(Region.island_west)
reach_hut = self.region.can_reach(Region.leo_hut)
reach_southeast = self.region.can_reach(Region.island_south_east)
reach_field_office = self.region.can_reach(Region.field_office)
reach_pirate_cove = self.region.can_reach(Region.pirate_cove)
reach_outside_areas = self.logic.and_(reach_south, reach_north, reach_west, reach_hut)
reach_volcano_regions = [self.region.can_reach(Region.volcano),
self.region.can_reach(Region.volcano_secret_beach),
self.region.can_reach(Region.volcano_floor_5),
self.region.can_reach(Region.volcano_floor_10)]
reach_volcano = self.logic.or_(*reach_volcano_regions)
reach_all_volcano = self.logic.and_(*reach_volcano_regions)
reach_walnut_regions = [reach_south, reach_north, reach_west, reach_volcano, reach_field_office]
reach_caves = self.logic.and_(self.region.can_reach(Region.qi_walnut_room), self.region.can_reach(Region.dig_site),
self.region.can_reach(Region.gourmand_frog_cave),
self.region.can_reach(Region.colored_crystals_cave),
self.region.can_reach(Region.shipwreck), self.combat.has_slingshot)
reach_entire_island = self.logic.and_(reach_outside_areas, reach_all_volcano,
reach_caves, reach_southeast, reach_field_office, reach_pirate_cove)
if number <= 5:
return self.logic.or_(reach_south, reach_north, reach_west, reach_volcano)
if number <= 10:
return self.count(2, *reach_walnut_regions)
if number <= 15:
return self.count(3, *reach_walnut_regions)
if number <= 20:
return self.logic.and_(*reach_walnut_regions)
if number <= 50:
return reach_entire_island
gems = (Mineral.amethyst, Mineral.aquamarine, Mineral.emerald, Mineral.ruby, Mineral.topaz)
return reach_entire_island & self.has(Fruit.banana) & self.has_all(*gems) & self.ability.can_mine_perfectly() & \
self.ability.can_fish_perfectly() & self.has(Furniture.flute_block) & self.has(Seed.melon) & self.has(Seed.wheat) & self.has(Seed.garlic) & \
self.can_complete_field_office()

def has_all_stardrops(self) -> StardewRule:
other_rules = []
number_of_stardrops_to_receive = 0
Expand Down
Loading

0 comments on commit 084b8c1

Please sign in to comment.