Stardew Valley: Fix Art Of Crabbing Logic and Extract Festival Logic (#3625)
* here you go kaito kid * here you go kaito kid * move reward logic in its own method --------- Co-authored-by: Jouramie <jouramie@hotmail.com> Co-authored-by: Jérémie Bolduc <16137441+Jouramie@users.noreply.github.com>
This commit is contained in:
parent
69d3db21df
commit
204e940f47
|
@ -2,7 +2,7 @@ from ..game_content import ContentPack
|
||||||
from ...data import villagers_data, fish_data
|
from ...data import villagers_data, fish_data
|
||||||
from ...data.game_item import GenericSource, ItemTag, Tag, CustomRuleSource, CompoundSource
|
from ...data.game_item import GenericSource, ItemTag, Tag, CustomRuleSource, CompoundSource
|
||||||
from ...data.harvest import ForagingSource, SeasonalForagingSource, ArtifactSpotSource
|
from ...data.harvest import ForagingSource, SeasonalForagingSource, ArtifactSpotSource
|
||||||
from ...data.requirement import ToolRequirement, BookRequirement, SkillRequirement, SeasonRequirement
|
from ...data.requirement import ToolRequirement, BookRequirement, SkillRequirement
|
||||||
from ...data.shop import ShopSource, MysteryBoxSource, ArtifactTroveSource, PrizeMachineSource, FishingTreasureChestSource
|
from ...data.shop import ShopSource, MysteryBoxSource, ArtifactTroveSource, PrizeMachineSource, FishingTreasureChestSource
|
||||||
from ...strings.book_names import Book
|
from ...strings.book_names import Book
|
||||||
from ...strings.crop_names import Fruit
|
from ...strings.crop_names import Fruit
|
||||||
|
@ -250,10 +250,7 @@ pelican_town = ContentPack(
|
||||||
ShopSource(money_price=20000, shop_region=LogicRegion.bookseller_3),),
|
ShopSource(money_price=20000, shop_region=LogicRegion.bookseller_3),),
|
||||||
Book.the_art_o_crabbing: (
|
Book.the_art_o_crabbing: (
|
||||||
Tag(ItemTag.BOOK, ItemTag.BOOK_POWER),
|
Tag(ItemTag.BOOK, ItemTag.BOOK_POWER),
|
||||||
GenericSource(regions=(Region.beach,),
|
CustomRuleSource(create_rule=lambda logic: logic.festival.has_squidfest_day_1_iridium_reward()),
|
||||||
other_requirements=(ToolRequirement(Tool.fishing_rod, ToolMaterial.iridium),
|
|
||||||
SkillRequirement(Skill.fishing, 6),
|
|
||||||
SeasonRequirement(Season.winter))),
|
|
||||||
ShopSource(money_price=20000, shop_region=LogicRegion.bookseller_3),),
|
ShopSource(money_price=20000, shop_region=LogicRegion.bookseller_3),),
|
||||||
Book.treasure_appraisal_guide: (
|
Book.treasure_appraisal_guide: (
|
||||||
Tag(ItemTag.BOOK, ItemTag.BOOK_POWER),
|
Tag(ItemTag.BOOK, ItemTag.BOOK_POWER),
|
||||||
|
|
|
@ -474,7 +474,7 @@ id,name,classification,groups,mod_name
|
||||||
507,Resource Pack: 40 Calico Egg,useful,"FESTIVAL",
|
507,Resource Pack: 40 Calico Egg,useful,"FESTIVAL",
|
||||||
508,Resource Pack: 35 Calico Egg,useful,"FESTIVAL",
|
508,Resource Pack: 35 Calico Egg,useful,"FESTIVAL",
|
||||||
509,Resource Pack: 30 Calico Egg,useful,"FESTIVAL",
|
509,Resource Pack: 30 Calico Egg,useful,"FESTIVAL",
|
||||||
510,Book: The Art O' Crabbing,useful,"FESTIVAL",
|
510,Book: The Art O' Crabbing,progression,"FESTIVAL",
|
||||||
511,Mr Qi's Plane Ride,progression,,
|
511,Mr Qi's Plane Ride,progression,,
|
||||||
521,Power: Price Catalogue,useful,"BOOK_POWER",
|
521,Power: Price Catalogue,useful,"BOOK_POWER",
|
||||||
522,Power: Mapping Cave Systems,useful,"BOOK_POWER",
|
522,Power: Mapping Cave Systems,useful,"BOOK_POWER",
|
||||||
|
|
|
|
@ -0,0 +1,186 @@
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
|
from .action_logic import ActionLogicMixin
|
||||||
|
from .animal_logic import AnimalLogicMixin
|
||||||
|
from .artisan_logic import ArtisanLogicMixin
|
||||||
|
from .base_logic import BaseLogicMixin, BaseLogic
|
||||||
|
from .fishing_logic import FishingLogicMixin
|
||||||
|
from .gift_logic import GiftLogicMixin
|
||||||
|
from .has_logic import HasLogicMixin
|
||||||
|
from .money_logic import MoneyLogicMixin
|
||||||
|
from .monster_logic import MonsterLogicMixin
|
||||||
|
from .museum_logic import MuseumLogicMixin
|
||||||
|
from .received_logic import ReceivedLogicMixin
|
||||||
|
from .region_logic import RegionLogicMixin
|
||||||
|
from .relationship_logic import RelationshipLogicMixin
|
||||||
|
from .skill_logic import SkillLogicMixin
|
||||||
|
from .time_logic import TimeLogicMixin
|
||||||
|
from ..options import FestivalLocations
|
||||||
|
from ..stardew_rule import StardewRule
|
||||||
|
from ..strings.book_names import Book
|
||||||
|
from ..strings.craftable_names import Fishing
|
||||||
|
from ..strings.crop_names import Fruit, Vegetable
|
||||||
|
from ..strings.festival_check_names import FestivalCheck
|
||||||
|
from ..strings.fish_names import Fish
|
||||||
|
from ..strings.forageable_names import Forageable
|
||||||
|
from ..strings.generic_names import Generic
|
||||||
|
from ..strings.machine_names import Machine
|
||||||
|
from ..strings.monster_names import Monster
|
||||||
|
from ..strings.region_names import Region
|
||||||
|
|
||||||
|
|
||||||
|
class FestivalLogicMixin(BaseLogicMixin):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.festival = FestivalLogic(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class FestivalLogic(BaseLogic[Union[HasLogicMixin, ReceivedLogicMixin, FestivalLogicMixin, ArtisanLogicMixin, AnimalLogicMixin, MoneyLogicMixin, TimeLogicMixin,
|
||||||
|
SkillLogicMixin, RegionLogicMixin, ActionLogicMixin, MonsterLogicMixin, RelationshipLogicMixin, FishingLogicMixin, MuseumLogicMixin, GiftLogicMixin]]):
|
||||||
|
|
||||||
|
def initialize_rules(self):
|
||||||
|
self.registry.festival_rules.update({
|
||||||
|
FestivalCheck.egg_hunt: self.logic.festival.can_win_egg_hunt(),
|
||||||
|
FestivalCheck.strawberry_seeds: self.logic.money.can_spend(1000),
|
||||||
|
FestivalCheck.dance: self.logic.relationship.has_hearts_with_any_bachelor(4),
|
||||||
|
FestivalCheck.tub_o_flowers: self.logic.money.can_spend(2000),
|
||||||
|
FestivalCheck.rarecrow_5: self.logic.money.can_spend(2500),
|
||||||
|
FestivalCheck.luau_soup: self.logic.festival.can_succeed_luau_soup(),
|
||||||
|
FestivalCheck.moonlight_jellies: self.logic.true_,
|
||||||
|
FestivalCheck.moonlight_jellies_banner: self.logic.money.can_spend(800),
|
||||||
|
FestivalCheck.starport_decal: self.logic.money.can_spend(1000),
|
||||||
|
FestivalCheck.smashing_stone: self.logic.true_,
|
||||||
|
FestivalCheck.grange_display: self.logic.festival.can_succeed_grange_display(),
|
||||||
|
FestivalCheck.rarecrow_1: self.logic.true_, # only cost star tokens
|
||||||
|
FestivalCheck.fair_stardrop: self.logic.true_, # only cost star tokens
|
||||||
|
FestivalCheck.spirit_eve_maze: self.logic.true_,
|
||||||
|
FestivalCheck.jack_o_lantern: self.logic.money.can_spend(2000),
|
||||||
|
FestivalCheck.rarecrow_2: self.logic.money.can_spend(5000),
|
||||||
|
FestivalCheck.fishing_competition: self.logic.festival.can_win_fishing_competition(),
|
||||||
|
FestivalCheck.rarecrow_4: self.logic.money.can_spend(5000),
|
||||||
|
FestivalCheck.mermaid_pearl: self.logic.has(Forageable.secret_note),
|
||||||
|
FestivalCheck.cone_hat: self.logic.money.can_spend(2500),
|
||||||
|
FestivalCheck.iridium_fireplace: self.logic.money.can_spend(15000),
|
||||||
|
FestivalCheck.rarecrow_7: self.logic.money.can_spend(5000) & self.logic.museum.can_donate_museum_artifacts(20),
|
||||||
|
FestivalCheck.rarecrow_8: self.logic.money.can_spend(5000) & self.logic.museum.can_donate_museum_items(40),
|
||||||
|
FestivalCheck.lupini_red_eagle: self.logic.money.can_spend(1200),
|
||||||
|
FestivalCheck.lupini_portrait_mermaid: self.logic.money.can_spend(1200),
|
||||||
|
FestivalCheck.lupini_solar_kingdom: self.logic.money.can_spend(1200),
|
||||||
|
FestivalCheck.lupini_clouds: self.logic.time.has_year_two & self.logic.money.can_spend(1200),
|
||||||
|
FestivalCheck.lupini_1000_years: self.logic.time.has_year_two & self.logic.money.can_spend(1200),
|
||||||
|
FestivalCheck.lupini_three_trees: self.logic.time.has_year_two & self.logic.money.can_spend(1200),
|
||||||
|
FestivalCheck.lupini_the_serpent: self.logic.time.has_year_three & self.logic.money.can_spend(1200),
|
||||||
|
FestivalCheck.lupini_tropical_fish: self.logic.time.has_year_three & self.logic.money.can_spend(1200),
|
||||||
|
FestivalCheck.lupini_land_of_clay: self.logic.time.has_year_three & self.logic.money.can_spend(1200),
|
||||||
|
FestivalCheck.secret_santa: self.logic.gifts.has_any_universal_love,
|
||||||
|
FestivalCheck.legend_of_the_winter_star: self.logic.true_,
|
||||||
|
FestivalCheck.rarecrow_3: self.logic.true_,
|
||||||
|
FestivalCheck.all_rarecrows: self.logic.region.can_reach(Region.farm) & self.logic.festival.has_all_rarecrows(),
|
||||||
|
FestivalCheck.calico_race: self.logic.true_,
|
||||||
|
FestivalCheck.mummy_mask: self.logic.true_,
|
||||||
|
FestivalCheck.calico_statue: self.logic.true_,
|
||||||
|
FestivalCheck.emily_outfit_service: self.logic.true_,
|
||||||
|
FestivalCheck.earthy_mousse: self.logic.true_,
|
||||||
|
FestivalCheck.sweet_bean_cake: self.logic.true_,
|
||||||
|
FestivalCheck.skull_cave_casserole: self.logic.true_,
|
||||||
|
FestivalCheck.spicy_tacos: self.logic.true_,
|
||||||
|
FestivalCheck.mountain_chili: self.logic.true_,
|
||||||
|
FestivalCheck.crystal_cake: self.logic.true_,
|
||||||
|
FestivalCheck.cave_kebab: self.logic.true_,
|
||||||
|
FestivalCheck.hot_log: self.logic.true_,
|
||||||
|
FestivalCheck.sour_salad: self.logic.true_,
|
||||||
|
FestivalCheck.superfood_cake: self.logic.true_,
|
||||||
|
FestivalCheck.warrior_smoothie: self.logic.true_,
|
||||||
|
FestivalCheck.rumpled_fruit_skin: self.logic.true_,
|
||||||
|
FestivalCheck.calico_pizza: self.logic.true_,
|
||||||
|
FestivalCheck.stuffed_mushrooms: self.logic.true_,
|
||||||
|
FestivalCheck.elf_quesadilla: self.logic.true_,
|
||||||
|
FestivalCheck.nachos_of_the_desert: self.logic.true_,
|
||||||
|
FestivalCheck.cloppino: self.logic.true_,
|
||||||
|
FestivalCheck.rainforest_shrimp: self.logic.true_,
|
||||||
|
FestivalCheck.shrimp_donut: self.logic.true_,
|
||||||
|
FestivalCheck.smell_of_the_sea: self.logic.true_,
|
||||||
|
FestivalCheck.desert_gumbo: self.logic.true_,
|
||||||
|
FestivalCheck.free_cactis: self.logic.true_,
|
||||||
|
FestivalCheck.monster_hunt: self.logic.monster.can_kill(Monster.serpent),
|
||||||
|
FestivalCheck.deep_dive: self.logic.region.can_reach(Region.skull_cavern_50),
|
||||||
|
FestivalCheck.treasure_hunt: self.logic.region.can_reach(Region.skull_cavern_25),
|
||||||
|
FestivalCheck.touch_calico_statue: self.logic.region.can_reach(Region.skull_cavern_25),
|
||||||
|
FestivalCheck.real_calico_egg_hunter: self.logic.region.can_reach(Region.skull_cavern_100),
|
||||||
|
FestivalCheck.willy_challenge: self.logic.fishing.can_catch_fish(self.content.fishes[Fish.scorpion_carp]),
|
||||||
|
FestivalCheck.desert_scholar: self.logic.true_,
|
||||||
|
FestivalCheck.squidfest_day_1_copper: self.logic.fishing.can_catch_fish(self.content.fishes[Fish.squid]),
|
||||||
|
FestivalCheck.squidfest_day_1_iron: self.logic.fishing.can_catch_fish(self.content.fishes[Fish.squid]) & self.logic.has(Fishing.bait),
|
||||||
|
FestivalCheck.squidfest_day_1_gold: self.logic.fishing.can_catch_fish(self.content.fishes[Fish.squid]) & self.logic.has(Fishing.deluxe_bait),
|
||||||
|
FestivalCheck.squidfest_day_1_iridium: self.logic.festival.can_squidfest_day_1_iridium_reward(),
|
||||||
|
FestivalCheck.squidfest_day_2_copper: self.logic.fishing.can_catch_fish(self.content.fishes[Fish.squid]),
|
||||||
|
FestivalCheck.squidfest_day_2_iron: self.logic.fishing.can_catch_fish(self.content.fishes[Fish.squid]) & self.logic.has(Fishing.bait),
|
||||||
|
FestivalCheck.squidfest_day_2_gold: self.logic.fishing.can_catch_fish(self.content.fishes[Fish.squid]) & self.logic.has(Fishing.deluxe_bait),
|
||||||
|
FestivalCheck.squidfest_day_2_iridium: self.logic.fishing.can_catch_fish(self.content.fishes[Fish.squid]) &
|
||||||
|
self.logic.fishing.has_specific_bait(self.content.fishes[Fish.squid]),
|
||||||
|
})
|
||||||
|
for i in range(1, 11):
|
||||||
|
check_name = f"{FestivalCheck.trout_derby_reward_pattern}{i}"
|
||||||
|
self.registry.festival_rules[check_name] = self.logic.fishing.can_catch_fish(self.content.fishes[Fish.rainbow_trout])
|
||||||
|
|
||||||
|
def can_squidfest_day_1_iridium_reward(self) -> StardewRule:
|
||||||
|
return self.logic.fishing.can_catch_fish(self.content.fishes[Fish.squid]) & self.logic.fishing.has_specific_bait(self.content.fishes[Fish.squid])
|
||||||
|
|
||||||
|
def has_squidfest_day_1_iridium_reward(self) -> StardewRule:
|
||||||
|
if self.options.festival_locations == FestivalLocations.option_disabled:
|
||||||
|
return self.logic.festival.can_squidfest_day_1_iridium_reward()
|
||||||
|
else:
|
||||||
|
return self.logic.received(f"Book: {Book.the_art_o_crabbing}")
|
||||||
|
|
||||||
|
def can_win_egg_hunt(self) -> StardewRule:
|
||||||
|
return self.logic.true_
|
||||||
|
|
||||||
|
def can_succeed_luau_soup(self) -> StardewRule:
|
||||||
|
if self.options.festival_locations != FestivalLocations.option_hard:
|
||||||
|
return self.logic.true_
|
||||||
|
eligible_fish = (Fish.blobfish, Fish.crimsonfish, Fish.ice_pip, Fish.lava_eel, Fish.legend, Fish.angler, Fish.catfish, Fish.glacierfish,
|
||||||
|
Fish.mutant_carp, Fish.spookfish, Fish.stingray, Fish.sturgeon, Fish.super_cucumber)
|
||||||
|
fish_rule = self.logic.has_any(*(f for f in eligible_fish if f in self.content.fishes)) # To filter stingray
|
||||||
|
eligible_kegables = (Fruit.ancient_fruit, Fruit.apple, Fruit.banana, Forageable.coconut, Forageable.crystal_fruit, Fruit.mango, Fruit.melon,
|
||||||
|
Fruit.orange, Fruit.peach, Fruit.pineapple, Fruit.pomegranate, Fruit.rhubarb, Fruit.starfruit, Fruit.strawberry,
|
||||||
|
Forageable.cactus_fruit, Fruit.cherry, Fruit.cranberries, Fruit.grape, Forageable.spice_berry, Forageable.wild_plum,
|
||||||
|
Vegetable.hops, Vegetable.wheat)
|
||||||
|
keg_rules = [self.logic.artisan.can_keg(kegable) for kegable in eligible_kegables if kegable in self.content.game_items]
|
||||||
|
aged_rule = self.logic.has(Machine.cask) & self.logic.or_(*keg_rules)
|
||||||
|
# There are a few other valid items, but I don't feel like coding them all
|
||||||
|
return fish_rule | aged_rule
|
||||||
|
|
||||||
|
def can_succeed_grange_display(self) -> StardewRule:
|
||||||
|
if self.options.festival_locations != FestivalLocations.option_hard:
|
||||||
|
return self.logic.true_
|
||||||
|
|
||||||
|
animal_rule = self.logic.animal.has_animal(Generic.any)
|
||||||
|
artisan_rule = self.logic.artisan.can_keg(Generic.any) | self.logic.artisan.can_preserves_jar(Generic.any)
|
||||||
|
cooking_rule = self.logic.money.can_spend_at(Region.saloon, 220) # Salads at the bar are good enough
|
||||||
|
fish_rule = self.logic.skill.can_fish(difficulty=50)
|
||||||
|
forage_rule = self.logic.region.can_reach_any((Region.forest, Region.backwoods)) # Hazelnut always available since the grange display is in fall
|
||||||
|
mineral_rule = self.logic.action.can_open_geode(Generic.any) # More than half the minerals are good enough
|
||||||
|
good_fruits = (fruit
|
||||||
|
for fruit in
|
||||||
|
(Fruit.apple, Fruit.banana, Forageable.coconut, Forageable.crystal_fruit, Fruit.mango, Fruit.orange, Fruit.peach, Fruit.pomegranate,
|
||||||
|
Fruit.strawberry, Fruit.melon, Fruit.rhubarb, Fruit.pineapple, Fruit.ancient_fruit, Fruit.starfruit)
|
||||||
|
if fruit in self.content.game_items)
|
||||||
|
fruit_rule = self.logic.has_any(*good_fruits)
|
||||||
|
good_vegetables = (vegeteable
|
||||||
|
for vegeteable in
|
||||||
|
(Vegetable.amaranth, Vegetable.artichoke, Vegetable.beet, Vegetable.cauliflower, Forageable.fiddlehead_fern, Vegetable.kale,
|
||||||
|
Vegetable.radish, Vegetable.taro_root, Vegetable.yam, Vegetable.red_cabbage, Vegetable.pumpkin)
|
||||||
|
if vegeteable in self.content.game_items)
|
||||||
|
vegetable_rule = self.logic.has_any(*good_vegetables)
|
||||||
|
|
||||||
|
return animal_rule & artisan_rule & cooking_rule & fish_rule & \
|
||||||
|
forage_rule & fruit_rule & mineral_rule & vegetable_rule
|
||||||
|
|
||||||
|
def can_win_fishing_competition(self) -> StardewRule:
|
||||||
|
return self.logic.skill.can_fish(difficulty=60)
|
||||||
|
|
||||||
|
def has_all_rarecrows(self) -> StardewRule:
|
||||||
|
rules = []
|
||||||
|
for rarecrow_number in range(1, 9):
|
||||||
|
rules.append(self.logic.received(f"Rarecrow #{rarecrow_number}"))
|
||||||
|
return self.logic.and_(*rules)
|
|
@ -16,6 +16,7 @@ from .combat_logic import CombatLogicMixin
|
||||||
from .cooking_logic import CookingLogicMixin
|
from .cooking_logic import CookingLogicMixin
|
||||||
from .crafting_logic import CraftingLogicMixin
|
from .crafting_logic import CraftingLogicMixin
|
||||||
from .farming_logic import FarmingLogicMixin
|
from .farming_logic import FarmingLogicMixin
|
||||||
|
from .festival_logic import FestivalLogicMixin
|
||||||
from .fishing_logic import FishingLogicMixin
|
from .fishing_logic import FishingLogicMixin
|
||||||
from .gift_logic import GiftLogicMixin
|
from .gift_logic import GiftLogicMixin
|
||||||
from .grind_logic import GrindLogicMixin
|
from .grind_logic import GrindLogicMixin
|
||||||
|
@ -62,7 +63,6 @@ from ..strings.crop_names import Fruit, Vegetable
|
||||||
from ..strings.currency_names import Currency
|
from ..strings.currency_names import Currency
|
||||||
from ..strings.decoration_names import Decoration
|
from ..strings.decoration_names import Decoration
|
||||||
from ..strings.fertilizer_names import Fertilizer, SpeedGro, RetainingSoil
|
from ..strings.fertilizer_names import Fertilizer, SpeedGro, RetainingSoil
|
||||||
from ..strings.festival_check_names import FestivalCheck
|
|
||||||
from ..strings.fish_names import Fish, Trash, WaterItem, WaterChest
|
from ..strings.fish_names import Fish, Trash, WaterItem, WaterChest
|
||||||
from ..strings.flower_names import Flower
|
from ..strings.flower_names import Flower
|
||||||
from ..strings.food_names import Meal, Beverage
|
from ..strings.food_names import Meal, Beverage
|
||||||
|
@ -94,7 +94,7 @@ class StardewLogic(ReceivedLogicMixin, HasLogicMixin, RegionLogicMixin, Travelin
|
||||||
CombatLogicMixin, MagicLogicMixin, MonsterLogicMixin, ToolLogicMixin, PetLogicMixin, QualityLogicMixin,
|
CombatLogicMixin, MagicLogicMixin, MonsterLogicMixin, ToolLogicMixin, PetLogicMixin, QualityLogicMixin,
|
||||||
SkillLogicMixin, FarmingLogicMixin, BundleLogicMixin, FishingLogicMixin, MineLogicMixin, CookingLogicMixin, AbilityLogicMixin,
|
SkillLogicMixin, FarmingLogicMixin, BundleLogicMixin, FishingLogicMixin, MineLogicMixin, CookingLogicMixin, AbilityLogicMixin,
|
||||||
SpecialOrderLogicMixin, QuestLogicMixin, CraftingLogicMixin, ModLogicMixin, HarvestingLogicMixin, SourceLogicMixin,
|
SpecialOrderLogicMixin, QuestLogicMixin, CraftingLogicMixin, ModLogicMixin, HarvestingLogicMixin, SourceLogicMixin,
|
||||||
RequirementLogicMixin, BookLogicMixin, GrindLogicMixin, WalnutLogicMixin):
|
RequirementLogicMixin, BookLogicMixin, GrindLogicMixin, FestivalLogicMixin, WalnutLogicMixin):
|
||||||
player: int
|
player: int
|
||||||
options: StardewValleyOptions
|
options: StardewValleyOptions
|
||||||
content: StardewContent
|
content: StardewContent
|
||||||
|
@ -363,89 +363,7 @@ class StardewLogic(ReceivedLogicMixin, HasLogicMixin, RegionLogicMixin, Travelin
|
||||||
self.quest.initialize_rules()
|
self.quest.initialize_rules()
|
||||||
self.quest.update_rules(self.mod.quest.get_modded_quest_rules())
|
self.quest.update_rules(self.mod.quest.get_modded_quest_rules())
|
||||||
|
|
||||||
self.registry.festival_rules.update({
|
self.festival.initialize_rules()
|
||||||
FestivalCheck.egg_hunt: self.can_win_egg_hunt(),
|
|
||||||
FestivalCheck.strawberry_seeds: self.money.can_spend(1000),
|
|
||||||
FestivalCheck.dance: self.relationship.has_hearts_with_any_bachelor(4),
|
|
||||||
FestivalCheck.tub_o_flowers: self.money.can_spend(2000),
|
|
||||||
FestivalCheck.rarecrow_5: self.money.can_spend(2500),
|
|
||||||
FestivalCheck.luau_soup: self.can_succeed_luau_soup(),
|
|
||||||
FestivalCheck.moonlight_jellies: True_(),
|
|
||||||
FestivalCheck.moonlight_jellies_banner: self.money.can_spend(800),
|
|
||||||
FestivalCheck.starport_decal: self.money.can_spend(1000),
|
|
||||||
FestivalCheck.smashing_stone: True_(),
|
|
||||||
FestivalCheck.grange_display: self.can_succeed_grange_display(),
|
|
||||||
FestivalCheck.rarecrow_1: True_(), # only cost star tokens
|
|
||||||
FestivalCheck.fair_stardrop: True_(), # only cost star tokens
|
|
||||||
FestivalCheck.spirit_eve_maze: True_(),
|
|
||||||
FestivalCheck.jack_o_lantern: self.money.can_spend(2000),
|
|
||||||
FestivalCheck.rarecrow_2: self.money.can_spend(5000),
|
|
||||||
FestivalCheck.fishing_competition: self.can_win_fishing_competition(),
|
|
||||||
FestivalCheck.rarecrow_4: self.money.can_spend(5000),
|
|
||||||
FestivalCheck.mermaid_pearl: self.has(Forageable.secret_note),
|
|
||||||
FestivalCheck.cone_hat: self.money.can_spend(2500),
|
|
||||||
FestivalCheck.iridium_fireplace: self.money.can_spend(15000),
|
|
||||||
FestivalCheck.rarecrow_7: self.money.can_spend(5000) & self.museum.can_donate_museum_artifacts(20),
|
|
||||||
FestivalCheck.rarecrow_8: self.money.can_spend(5000) & self.museum.can_donate_museum_items(40),
|
|
||||||
FestivalCheck.lupini_red_eagle: self.money.can_spend(1200),
|
|
||||||
FestivalCheck.lupini_portrait_mermaid: self.money.can_spend(1200),
|
|
||||||
FestivalCheck.lupini_solar_kingdom: self.money.can_spend(1200),
|
|
||||||
FestivalCheck.lupini_clouds: self.time.has_year_two & self.money.can_spend(1200),
|
|
||||||
FestivalCheck.lupini_1000_years: self.time.has_year_two & self.money.can_spend(1200),
|
|
||||||
FestivalCheck.lupini_three_trees: self.time.has_year_two & self.money.can_spend(1200),
|
|
||||||
FestivalCheck.lupini_the_serpent: self.time.has_year_three & self.money.can_spend(1200),
|
|
||||||
FestivalCheck.lupini_tropical_fish: self.time.has_year_three & self.money.can_spend(1200),
|
|
||||||
FestivalCheck.lupini_land_of_clay: self.time.has_year_three & self.money.can_spend(1200),
|
|
||||||
FestivalCheck.secret_santa: self.gifts.has_any_universal_love,
|
|
||||||
FestivalCheck.legend_of_the_winter_star: True_(),
|
|
||||||
FestivalCheck.rarecrow_3: True_(),
|
|
||||||
FestivalCheck.all_rarecrows: self.region.can_reach(Region.farm) & self.has_all_rarecrows(),
|
|
||||||
FestivalCheck.calico_race: True_(),
|
|
||||||
FestivalCheck.mummy_mask: True_(),
|
|
||||||
FestivalCheck.calico_statue: True_(),
|
|
||||||
FestivalCheck.emily_outfit_service: True_(),
|
|
||||||
FestivalCheck.earthy_mousse: True_(),
|
|
||||||
FestivalCheck.sweet_bean_cake: True_(),
|
|
||||||
FestivalCheck.skull_cave_casserole: True_(),
|
|
||||||
FestivalCheck.spicy_tacos: True_(),
|
|
||||||
FestivalCheck.mountain_chili: True_(),
|
|
||||||
FestivalCheck.crystal_cake: True_(),
|
|
||||||
FestivalCheck.cave_kebab: True_(),
|
|
||||||
FestivalCheck.hot_log: True_(),
|
|
||||||
FestivalCheck.sour_salad: True_(),
|
|
||||||
FestivalCheck.superfood_cake: True_(),
|
|
||||||
FestivalCheck.warrior_smoothie: True_(),
|
|
||||||
FestivalCheck.rumpled_fruit_skin: True_(),
|
|
||||||
FestivalCheck.calico_pizza: True_(),
|
|
||||||
FestivalCheck.stuffed_mushrooms: True_(),
|
|
||||||
FestivalCheck.elf_quesadilla: True_(),
|
|
||||||
FestivalCheck.nachos_of_the_desert: True_(),
|
|
||||||
FestivalCheck.cloppino: True_(),
|
|
||||||
FestivalCheck.rainforest_shrimp: True_(),
|
|
||||||
FestivalCheck.shrimp_donut: True_(),
|
|
||||||
FestivalCheck.smell_of_the_sea: True_(),
|
|
||||||
FestivalCheck.desert_gumbo: True_(),
|
|
||||||
FestivalCheck.free_cactis: True_(),
|
|
||||||
FestivalCheck.monster_hunt: self.monster.can_kill(Monster.serpent),
|
|
||||||
FestivalCheck.deep_dive: self.region.can_reach(Region.skull_cavern_50),
|
|
||||||
FestivalCheck.treasure_hunt: self.region.can_reach(Region.skull_cavern_25),
|
|
||||||
FestivalCheck.touch_calico_statue: self.region.can_reach(Region.skull_cavern_25),
|
|
||||||
FestivalCheck.real_calico_egg_hunter: self.region.can_reach(Region.skull_cavern_100),
|
|
||||||
FestivalCheck.willy_challenge: self.fishing.can_catch_fish(content.fishes[Fish.scorpion_carp]),
|
|
||||||
FestivalCheck.desert_scholar: True_(),
|
|
||||||
FestivalCheck.squidfest_day_1_copper: self.fishing.can_catch_fish(content.fishes[Fish.squid]),
|
|
||||||
FestivalCheck.squidfest_day_1_iron: self.fishing.can_catch_fish(content.fishes[Fish.squid]) & self.has(Fishing.bait),
|
|
||||||
FestivalCheck.squidfest_day_1_gold: self.fishing.can_catch_fish(content.fishes[Fish.squid]) & self.has(Fishing.deluxe_bait),
|
|
||||||
FestivalCheck.squidfest_day_1_iridium: self.fishing.can_catch_fish(content.fishes[Fish.squid]) &
|
|
||||||
self.fishing.has_specific_bait(content.fishes[Fish.squid]),
|
|
||||||
FestivalCheck.squidfest_day_2_copper: self.fishing.can_catch_fish(content.fishes[Fish.squid]),
|
|
||||||
FestivalCheck.squidfest_day_2_iron: self.fishing.can_catch_fish(content.fishes[Fish.squid]) & self.has(Fishing.bait),
|
|
||||||
FestivalCheck.squidfest_day_2_gold: self.fishing.can_catch_fish(content.fishes[Fish.squid]) & self.has(Fishing.deluxe_bait),
|
|
||||||
FestivalCheck.squidfest_day_2_iridium: self.fishing.can_catch_fish(content.fishes[Fish.squid]) &
|
|
||||||
self.fishing.has_specific_bait(content.fishes[Fish.squid]),
|
|
||||||
})
|
|
||||||
for i in range(1, 11):
|
|
||||||
self.registry.festival_rules[f"{FestivalCheck.trout_derby_reward_pattern}{i}"] = self.fishing.can_catch_fish(content.fishes[Fish.rainbow_trout])
|
|
||||||
|
|
||||||
self.special_order.initialize_rules()
|
self.special_order.initialize_rules()
|
||||||
self.special_order.update_rules(self.mod.special_order.get_modded_special_orders_rules())
|
self.special_order.update_rules(self.mod.special_order.get_modded_special_orders_rules())
|
||||||
|
@ -486,53 +404,6 @@ class StardewLogic(ReceivedLogicMixin, HasLogicMixin, RegionLogicMixin, Travelin
|
||||||
]
|
]
|
||||||
return self.count(12, *rules_worth_a_point)
|
return self.count(12, *rules_worth_a_point)
|
||||||
|
|
||||||
def can_win_egg_hunt(self) -> StardewRule:
|
|
||||||
return True_()
|
|
||||||
|
|
||||||
def can_succeed_luau_soup(self) -> StardewRule:
|
|
||||||
if self.options.festival_locations != FestivalLocations.option_hard:
|
|
||||||
return True_()
|
|
||||||
eligible_fish = (Fish.blobfish, Fish.crimsonfish, Fish.ice_pip, Fish.lava_eel, Fish.legend, Fish.angler, Fish.catfish, Fish.glacierfish,
|
|
||||||
Fish.mutant_carp, Fish.spookfish, Fish.stingray, Fish.sturgeon, Fish.super_cucumber)
|
|
||||||
fish_rule = self.has_any(*(f for f in eligible_fish if f in self.content.fishes)) # To filter stingray
|
|
||||||
eligible_kegables = (Fruit.ancient_fruit, Fruit.apple, Fruit.banana, Forageable.coconut, Forageable.crystal_fruit, Fruit.mango, Fruit.melon,
|
|
||||||
Fruit.orange, Fruit.peach, Fruit.pineapple, Fruit.pomegranate, Fruit.rhubarb, Fruit.starfruit, Fruit.strawberry,
|
|
||||||
Forageable.cactus_fruit, Fruit.cherry, Fruit.cranberries, Fruit.grape, Forageable.spice_berry, Forageable.wild_plum,
|
|
||||||
Vegetable.hops, Vegetable.wheat)
|
|
||||||
keg_rules = [self.artisan.can_keg(kegable) for kegable in eligible_kegables if kegable in self.content.game_items]
|
|
||||||
aged_rule = self.has(Machine.cask) & self.logic.or_(*keg_rules)
|
|
||||||
# There are a few other valid items, but I don't feel like coding them all
|
|
||||||
return fish_rule | aged_rule
|
|
||||||
|
|
||||||
def can_succeed_grange_display(self) -> StardewRule:
|
|
||||||
if self.options.festival_locations != FestivalLocations.option_hard:
|
|
||||||
return True_()
|
|
||||||
|
|
||||||
animal_rule = self.animal.has_animal(Generic.any)
|
|
||||||
artisan_rule = self.artisan.can_keg(Generic.any) | self.artisan.can_preserves_jar(Generic.any)
|
|
||||||
cooking_rule = self.money.can_spend_at(Region.saloon, 220) # Salads at the bar are good enough
|
|
||||||
fish_rule = self.skill.can_fish(difficulty=50)
|
|
||||||
forage_rule = self.region.can_reach_any((Region.forest, Region.backwoods)) # Hazelnut always available since the grange display is in fall
|
|
||||||
mineral_rule = self.action.can_open_geode(Generic.any) # More than half the minerals are good enough
|
|
||||||
good_fruits = (fruit
|
|
||||||
for fruit in
|
|
||||||
(Fruit.apple, Fruit.banana, Forageable.coconut, Forageable.crystal_fruit, Fruit.mango, Fruit.orange, Fruit.peach, Fruit.pomegranate,
|
|
||||||
Fruit.strawberry, Fruit.melon, Fruit.rhubarb, Fruit.pineapple, Fruit.ancient_fruit, Fruit.starfruit)
|
|
||||||
if fruit in self.content.game_items)
|
|
||||||
fruit_rule = self.has_any(*good_fruits)
|
|
||||||
good_vegetables = (vegeteable
|
|
||||||
for vegeteable in
|
|
||||||
(Vegetable.amaranth, Vegetable.artichoke, Vegetable.beet, Vegetable.cauliflower, Forageable.fiddlehead_fern, Vegetable.kale,
|
|
||||||
Vegetable.radish, Vegetable.taro_root, Vegetable.yam, Vegetable.red_cabbage, Vegetable.pumpkin)
|
|
||||||
if vegeteable in self.content.game_items)
|
|
||||||
vegetable_rule = self.has_any(*good_vegetables)
|
|
||||||
|
|
||||||
return animal_rule & artisan_rule & cooking_rule & fish_rule & \
|
|
||||||
forage_rule & fruit_rule & mineral_rule & vegetable_rule
|
|
||||||
|
|
||||||
def can_win_fishing_competition(self) -> StardewRule:
|
|
||||||
return self.skill.can_fish(difficulty=60)
|
|
||||||
|
|
||||||
def has_island_trader(self) -> StardewRule:
|
def has_island_trader(self) -> StardewRule:
|
||||||
if self.options.exclude_ginger_island == ExcludeGingerIsland.option_true:
|
if self.options.exclude_ginger_island == ExcludeGingerIsland.option_true:
|
||||||
return False_()
|
return False_()
|
||||||
|
@ -571,12 +442,6 @@ class StardewLogic(ReceivedLogicMixin, HasLogicMixin, RegionLogicMixin, Travelin
|
||||||
|
|
||||||
return self.received("Stardrop", number_of_stardrops_to_receive) & self.logic.and_(*other_rules)
|
return self.received("Stardrop", number_of_stardrops_to_receive) & self.logic.and_(*other_rules)
|
||||||
|
|
||||||
def has_all_rarecrows(self) -> StardewRule:
|
|
||||||
rules = []
|
|
||||||
for rarecrow_number in range(1, 9):
|
|
||||||
rules.append(self.received(f"Rarecrow #{rarecrow_number}"))
|
|
||||||
return self.logic.and_(*rules)
|
|
||||||
|
|
||||||
def has_abandoned_jojamart(self) -> StardewRule:
|
def has_abandoned_jojamart(self) -> StardewRule:
|
||||||
return self.received(CommunityUpgrade.movie_theater, 1)
|
return self.received(CommunityUpgrade.movie_theater, 1)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue