Stardew Valley: 5.x.x - The Allsanity Update (#2764)

Major Content update for Stardew Valley, including the following features

- Major performance improvements all across the Stardew Valley apworld, including a significant reduction in the test time
- Randomized Farm Type
- Bundles rework (Remixed Bundles and Missing Bundle!)
- New Settings:
  * Shipsanity - Shipping individual items
  * Monstersanity - Slaying monsters
  * Cooksanity - Cooking individual recipes
  * Chefsanity - Learning individual recipes
  * Craftsanity - Crafting individual items
- New Goals:
  * Protector of the Valley - Complete every monster slayer goal
  * Full Shipment - Ship every item
  * Craftmaster - Craft every item
  * Gourmet Chef - Cook every recipe
  * Legend - Earn 10 000 000g
  * Mystery of the Stardrops - Find every stardrop (Maguffin Hunt)
  * Allsanity - Complete every check in your slot
- Building Shuffle: Cheaper options
- Tool Shuffle: Cheaper options
- Money rework
- New traps
- New isolated checks and items, including the farm cave, the movie theater, etc
- Mod Support: SVE [Albrekka]
- Mod Support: Distant Lands [Albrekka]
- Mod Support: Hat Mouse Lacey [Albrekka]
- Mod Support: Boarding House [Albrekka]

Co-authored-by: Witchybun <elnendil@gmail.com>
Co-authored-by: Witchybun <96719127+Witchybun@users.noreply.github.com>
Co-authored-by: Jouramie <jouramie@hotmail.com>
Co-authored-by: Alchav <59858495+Alchav@users.noreply.github.com>
This commit is contained in:
agilbert1412
2024-03-15 15:05:14 +03:00
committed by GitHub
parent f7da833572
commit 52e65e208e
177 changed files with 17815 additions and 6863 deletions

View File

@@ -1,16 +0,0 @@
from typing import Union
from ...strings.artisan_good_names import ArtisanGood
from ...strings.building_names import ModBuilding
from ..mod_data import ModNames
from ...strings.metal_names import MetalBar
from ...strings.region_names import Region
def get_modded_building_rules(vanilla_logic, active_mods):
buildings = {}
if ModNames.tractor in active_mods:
buildings.update({
ModBuilding.tractor_garage: vanilla_logic.can_spend_money_at(Region.carpenter, 150000) & vanilla_logic.has(MetalBar.iron) &
vanilla_logic.has(MetalBar.iridium) & vanilla_logic.has(ArtisanGood.battery_pack)})
return buildings

View File

@@ -0,0 +1,28 @@
from typing import Dict, Union
from ..mod_data import ModNames
from ...logic.base_logic import BaseLogicMixin, BaseLogic
from ...logic.has_logic import HasLogicMixin
from ...logic.money_logic import MoneyLogicMixin
from ...stardew_rule import StardewRule
from ...strings.artisan_good_names import ArtisanGood
from ...strings.building_names import ModBuilding
from ...strings.metal_names import MetalBar
from ...strings.region_names import Region
class ModBuildingLogicMixin(BaseLogicMixin):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.building = ModBuildingLogic(*args, **kwargs)
class ModBuildingLogic(BaseLogic[Union[MoneyLogicMixin, HasLogicMixin]]):
def get_modded_building_rules(self) -> Dict[str, StardewRule]:
buildings = dict()
if ModNames.tractor in self.options.mods:
tractor_rule = (self.logic.money.can_spend_at(Region.carpenter, 150000) &
self.logic.has_all(MetalBar.iron, MetalBar.iridium, ArtisanGood.battery_pack))
buildings.update({ModBuilding.tractor_garage: tractor_rule})
return buildings

View File

@@ -1,35 +0,0 @@
from ...strings.craftable_names import Craftable
from ...strings.performance_names import Performance
from ...strings.skill_names import Skill
from ...strings.tool_names import Tool, ToolMaterial
from ...strings.ap_names.transport_names import ModTransportation
from ...stardew_rule import StardewRule, True_, And
from ... import options
def can_reach_woods_depth(vanilla_logic, depth: int) -> StardewRule:
tier = int(depth / 25) + 1
rules = []
if depth > 10:
rules.append(vanilla_logic.has(Craftable.bomb) | vanilla_logic.has_tool(Tool.axe, ToolMaterial.iridium))
if depth > 30:
rules.append(vanilla_logic.received(ModTransportation.woods_obelisk))
if depth > 50:
rules.append(vanilla_logic.can_do_combat_at_level(Performance.great) & vanilla_logic.can_cook() &
vanilla_logic.received(ModTransportation.woods_obelisk))
if vanilla_logic.options.skill_progression == options.SkillProgression.option_progressive:
combat_tier = min(10, max(0, tier + 5))
rules.append(vanilla_logic.has_skill_level(Skill.combat, combat_tier))
return And(rules)
def has_woods_rune_to_depth(vanilla_logic, floor: int) -> StardewRule:
if vanilla_logic.options.elevator_progression == options.ElevatorProgression.option_vanilla:
return True_()
return vanilla_logic.received("Progressive Woods Obelisk Sigils", count=int(floor / 10))
def can_chop_to_depth(vanilla_logic, floor: int) -> StardewRule:
previous_elevator = max(floor - 10, 0)
return (has_woods_rune_to_depth(vanilla_logic, previous_elevator) &
can_reach_woods_depth(vanilla_logic, previous_elevator))

View File

@@ -0,0 +1,73 @@
from typing import Union
from ... import options
from ...logic.base_logic import BaseLogicMixin, BaseLogic
from ...logic.combat_logic import CombatLogicMixin
from ...logic.cooking_logic import CookingLogicMixin
from ...logic.has_logic import HasLogicMixin
from ...logic.received_logic import ReceivedLogicMixin
from ...logic.skill_logic import SkillLogicMixin
from ...logic.tool_logic import ToolLogicMixin
from ...mods.mod_data import ModNames
from ...options import ElevatorProgression
from ...stardew_rule import StardewRule, True_, And, true_
from ...strings.ap_names.mods.mod_items import DeepWoodsItem, SkillLevel
from ...strings.ap_names.transport_names import ModTransportation
from ...strings.craftable_names import Bomb
from ...strings.food_names import Meal
from ...strings.performance_names import Performance
from ...strings.skill_names import Skill
from ...strings.tool_names import Tool, ToolMaterial
class DeepWoodsLogicMixin(BaseLogicMixin):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.deepwoods = DeepWoodsLogic(*args, **kwargs)
class DeepWoodsLogic(BaseLogic[Union[SkillLogicMixin, ReceivedLogicMixin, HasLogicMixin, CombatLogicMixin, ToolLogicMixin, SkillLogicMixin,
CookingLogicMixin]]):
def can_reach_woods_depth(self, depth: int) -> StardewRule:
# Assuming you can always do the 10 first floor
if depth <= 10:
return true_
rules = []
if depth > 10:
rules.append(self.logic.has(Bomb.bomb) | self.logic.tool.has_tool(Tool.axe, ToolMaterial.iridium))
if depth > 30:
rules.append(self.logic.received(ModTransportation.woods_obelisk))
if depth > 50:
rules.append(self.logic.combat.can_fight_at_level(Performance.great) & self.logic.cooking.can_cook() &
self.logic.received(ModTransportation.woods_obelisk))
tier = int(depth / 25) + 1
if self.options.skill_progression == options.SkillProgression.option_progressive:
combat_tier = min(10, max(0, tier + 5))
rules.append(self.logic.skill.has_level(Skill.combat, combat_tier))
return And(*rules)
def has_woods_rune_to_depth(self, floor: int) -> StardewRule:
if self.options.elevator_progression == ElevatorProgression.option_vanilla:
return True_()
return self.logic.received(DeepWoodsItem.obelisk_sigil, int(floor / 10))
def can_chop_to_depth(self, floor: int) -> StardewRule:
previous_elevator = max(floor - 10, 0)
return (self.has_woods_rune_to_depth(previous_elevator) &
self.can_reach_woods_depth(previous_elevator))
def can_pull_sword(self) -> StardewRule:
rules = [self.logic.received(DeepWoodsItem.pendant_depths) & self.logic.received(DeepWoodsItem.pendant_community) &
self.logic.received(DeepWoodsItem.pendant_elder),
self.logic.skill.has_total_level(40)]
if ModNames.luck_skill in self.options.mods:
rules.append(self.logic.received(SkillLevel.luck, 7))
else:
rules.append(
self.logic.has(Meal.magic_rock_candy)) # You need more luck than this, but it'll push the logic down a ways; you can get the rest there.
return And(*rules)

View File

@@ -0,0 +1,18 @@
from ...logic.base_logic import BaseLogicMixin, BaseLogic
from ...logic.received_logic import ReceivedLogicMixin
from ...mods.mod_data import ModNames
from ...options import ElevatorProgression
from ...stardew_rule import StardewRule, True_
class ModElevatorLogicMixin(BaseLogicMixin):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.elevator = ModElevatorLogic(*args, **kwargs)
class ModElevatorLogic(BaseLogic[ReceivedLogicMixin]):
def has_skull_cavern_elevator_to_floor(self, floor: int) -> StardewRule:
if self.options.elevator_progression != ElevatorProgression.option_vanilla and ModNames.skull_cavern_elevator in self.options.mods:
return self.logic.received("Progressive Skull Cavern Elevator", floor // 25)
return True_()

View File

@@ -0,0 +1,289 @@
from typing import Dict, Union
from ..mod_data import ModNames
from ... import options
from ...data.craftable_data import all_crafting_recipes_by_name
from ...logic.base_logic import BaseLogicMixin, BaseLogic
from ...logic.combat_logic import CombatLogicMixin
from ...logic.cooking_logic import CookingLogicMixin
from ...logic.crafting_logic import CraftingLogicMixin
from ...logic.crop_logic import CropLogicMixin
from ...logic.fishing_logic import FishingLogicMixin
from ...logic.has_logic import HasLogicMixin
from ...logic.money_logic import MoneyLogicMixin
from ...logic.museum_logic import MuseumLogicMixin
from ...logic.quest_logic import QuestLogicMixin
from ...logic.received_logic import ReceivedLogicMixin
from ...logic.region_logic import RegionLogicMixin
from ...logic.relationship_logic import RelationshipLogicMixin
from ...logic.season_logic import SeasonLogicMixin
from ...logic.skill_logic import SkillLogicMixin
from ...logic.time_logic import TimeLogicMixin
from ...logic.tool_logic import ToolLogicMixin
from ...options import Cropsanity
from ...stardew_rule import StardewRule, True_
from ...strings.artisan_good_names import ModArtisanGood
from ...strings.craftable_names import ModCraftable, ModEdible, ModMachine
from ...strings.crop_names import SVEVegetable, SVEFruit, DistantLandsCrop, Fruit
from ...strings.fish_names import WaterItem
from ...strings.flower_names import Flower
from ...strings.food_names import SVEMeal, SVEBeverage
from ...strings.forageable_names import SVEForage, DistantLandsForageable, Forageable
from ...strings.gift_names import SVEGift
from ...strings.ingredient_names import Ingredient
from ...strings.material_names import Material
from ...strings.metal_names import all_fossils, all_artifacts, Ore, ModFossil
from ...strings.monster_drop_names import ModLoot, Loot
from ...strings.performance_names import Performance
from ...strings.quest_names import ModQuest
from ...strings.region_names import Region, SVERegion, DeepWoodsRegion, BoardingHouseRegion
from ...strings.season_names import Season
from ...strings.seed_names import SVESeed, DistantLandsSeed
from ...strings.skill_names import Skill
from ...strings.tool_names import Tool, ToolMaterial
from ...strings.villager_names import ModNPC
display_types = [ModCraftable.wooden_display, ModCraftable.hardwood_display]
display_items = all_artifacts + all_fossils
class ModItemLogicMixin(BaseLogicMixin):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.item = ModItemLogic(*args, **kwargs)
class ModItemLogic(BaseLogic[Union[CombatLogicMixin, ReceivedLogicMixin, CropLogicMixin, CookingLogicMixin, FishingLogicMixin, HasLogicMixin, MoneyLogicMixin,
RegionLogicMixin, SeasonLogicMixin, RelationshipLogicMixin, MuseumLogicMixin, ToolLogicMixin, CraftingLogicMixin, SkillLogicMixin, TimeLogicMixin, QuestLogicMixin]]):
def get_modded_item_rules(self) -> Dict[str, StardewRule]:
items = dict()
if ModNames.sve in self.options.mods:
items.update(self.get_sve_item_rules())
if ModNames.archaeology in self.options.mods:
items.update(self.get_archaeology_item_rules())
if ModNames.distant_lands in self.options.mods:
items.update(self.get_distant_lands_item_rules())
if ModNames.boarding_house in self.options.mods:
items.update(self.get_boarding_house_item_rules())
return items
def modify_vanilla_item_rules_with_mod_additions(self, item_rule: Dict[str, StardewRule]):
if ModNames.sve in self.options.mods:
item_rule.update(self.get_modified_item_rules_for_sve(item_rule))
if ModNames.deepwoods in self.options.mods:
item_rule.update(self.get_modified_item_rules_for_deep_woods(item_rule))
return item_rule
def get_sve_item_rules(self):
return {SVEGift.aged_blue_moon_wine: self.logic.money.can_spend_at(SVERegion.sophias_house, 28000),
SVEGift.blue_moon_wine: self.logic.money.can_spend_at(SVERegion.sophias_house, 3000),
SVESeed.fungus_seed: self.logic.region.can_reach(SVERegion.highlands_cavern) & self.logic.combat.has_good_weapon,
ModLoot.green_mushroom: self.logic.region.can_reach(SVERegion.highlands_outside) &
self.logic.tool.has_tool(Tool.axe, ToolMaterial.iron) & self.logic.season.has_any_not_winter(),
SVEFruit.monster_fruit: self.logic.season.has(Season.summer) & self.logic.has(SVESeed.stalk_seed),
SVEVegetable.monster_mushroom: self.logic.season.has(Season.fall) & self.logic.has(SVESeed.fungus_seed),
SVEForage.ornate_treasure_chest: self.logic.region.can_reach(SVERegion.highlands_outside) & self.logic.combat.has_galaxy_weapon &
self.logic.tool.has_tool(Tool.axe, ToolMaterial.iron),
SVEFruit.slime_berry: self.logic.season.has(Season.spring) & self.logic.has(SVESeed.slime_seed),
SVESeed.slime_seed: self.logic.region.can_reach(SVERegion.highlands_outside) & self.logic.combat.has_good_weapon,
SVESeed.stalk_seed: self.logic.region.can_reach(SVERegion.highlands_outside) & self.logic.combat.has_good_weapon,
SVEForage.swirl_stone: self.logic.region.can_reach(SVERegion.crimson_badlands) & self.logic.combat.has_great_weapon,
SVEVegetable.void_root: self.logic.season.has(Season.winter) & self.logic.has(SVESeed.void_seed),
SVESeed.void_seed: self.logic.region.can_reach(SVERegion.highlands_cavern) & self.logic.combat.has_good_weapon,
SVEForage.void_soul: self.logic.region.can_reach(
SVERegion.crimson_badlands) & self.logic.combat.has_good_weapon & self.logic.cooking.can_cook(),
SVEForage.winter_star_rose: self.logic.region.can_reach(SVERegion.summit) & self.logic.season.has(Season.winter),
SVEForage.bearberrys: self.logic.region.can_reach(Region.secret_woods) & self.logic.season.has(Season.winter),
SVEForage.poison_mushroom: self.logic.region.can_reach(Region.secret_woods) & self.logic.season.has_any([Season.summer, Season.fall]),
SVEForage.red_baneberry: self.logic.region.can_reach(Region.secret_woods) & self.logic.season.has(Season.summer),
SVEForage.ferngill_primrose: self.logic.region.can_reach(SVERegion.summit) & self.logic.season.has(Season.spring),
SVEForage.goldenrod: self.logic.region.can_reach(SVERegion.summit) & (
self.logic.season.has(Season.summer) | self.logic.season.has(Season.fall)),
SVESeed.shrub_seed: self.logic.region.can_reach(Region.secret_woods) & self.logic.tool.has_tool(Tool.hoe, ToolMaterial.basic),
SVEFruit.salal_berry: self.logic.crop.can_plant_and_grow_item([Season.spring, Season.summer]) & self.logic.has(SVESeed.shrub_seed),
ModEdible.aegis_elixir: self.logic.money.can_spend_at(SVERegion.galmoran_outpost, 28000),
ModEdible.lightning_elixir: self.logic.money.can_spend_at(SVERegion.galmoran_outpost, 12000),
ModEdible.barbarian_elixir: self.logic.money.can_spend_at(SVERegion.galmoran_outpost, 22000),
ModEdible.gravity_elixir: self.logic.money.can_spend_at(SVERegion.galmoran_outpost, 4000),
SVESeed.ancient_ferns_seed: self.logic.region.can_reach(Region.secret_woods) & self.logic.tool.has_tool(Tool.hoe, ToolMaterial.basic),
SVEVegetable.ancient_fiber: self.logic.crop.can_plant_and_grow_item(Season.summer) & self.logic.has(SVESeed.ancient_ferns_seed),
SVEForage.big_conch: self.logic.region.can_reach_any((Region.beach, SVERegion.fable_reef)),
SVEForage.dewdrop_berry: self.logic.region.can_reach(SVERegion.enchanted_grove),
SVEForage.dried_sand_dollar: self.logic.region.can_reach(SVERegion.fable_reef) | (self.logic.region.can_reach(Region.beach) &
self.logic.season.has_any([Season.summer, Season.fall])),
SVEForage.golden_ocean_flower: self.logic.region.can_reach(SVERegion.fable_reef),
SVEMeal.grampleton_orange_chicken: self.logic.money.can_spend_at(Region.saloon, 650) & self.logic.relationship.has_hearts(ModNPC.sophia, 6),
ModEdible.hero_elixir: self.logic.money.can_spend_at(SVERegion.isaac_shop, 8000),
SVEForage.lucky_four_leaf_clover: self.logic.region.can_reach_any((Region.secret_woods, SVERegion.forest_west)) &
self.logic.season.has_any([Season.spring, Season.summer]),
SVEForage.mushroom_colony: self.logic.region.can_reach_any((Region.secret_woods, SVERegion.junimo_woods, SVERegion.forest_west)) &
self.logic.season.has(Season.fall),
SVEForage.rusty_blade: self.logic.region.can_reach(SVERegion.crimson_badlands) & self.logic.combat.has_great_weapon,
SVEForage.smelly_rafflesia: self.logic.region.can_reach(Region.secret_woods),
SVEBeverage.sports_drink: self.logic.money.can_spend_at(Region.hospital, 750),
"Stamina Capsule": self.logic.money.can_spend_at(Region.hospital, 4000),
SVEForage.thistle: self.logic.region.can_reach(SVERegion.summit),
SVEForage.void_pebble: self.logic.region.can_reach(SVERegion.crimson_badlands) & self.logic.combat.has_great_weapon,
ModLoot.void_shard: self.logic.region.can_reach(SVERegion.crimson_badlands) & self.logic.combat.has_galaxy_weapon &
self.logic.skill.has_level(Skill.combat, 10) & self.logic.region.can_reach(Region.saloon) & self.logic.time.has_year_three
}
# @formatter:on
def get_modified_item_rules_for_sve(self, items: Dict[str, StardewRule]):
return {
Loot.void_essence: items[Loot.void_essence] | self.logic.region.can_reach(SVERegion.highlands_cavern) | self.logic.region.can_reach(
SVERegion.crimson_badlands),
Loot.solar_essence: items[Loot.solar_essence] | self.logic.region.can_reach(SVERegion.crimson_badlands),
Flower.tulip: items[Flower.tulip] | self.logic.tool.can_forage(Season.spring, SVERegion.sprite_spring),
Flower.blue_jazz: items[Flower.blue_jazz] | self.logic.tool.can_forage(Season.spring, SVERegion.sprite_spring),
Flower.summer_spangle: items[Flower.summer_spangle] | self.logic.tool.can_forage(Season.summer, SVERegion.sprite_spring),
Flower.sunflower: items[Flower.sunflower] | self.logic.tool.can_forage((Season.summer, Season.fall), SVERegion.sprite_spring),
Flower.fairy_rose: items[Flower.fairy_rose] | self.logic.tool.can_forage(Season.fall, SVERegion.sprite_spring),
Fruit.ancient_fruit: items[Fruit.ancient_fruit] | (
self.logic.tool.can_forage((Season.spring, Season.summer, Season.fall), SVERegion.sprite_spring) &
self.logic.time.has_year_three) | self.logic.region.can_reach(SVERegion.sprite_spring_cave),
Fruit.sweet_gem_berry: items[Fruit.sweet_gem_berry] | (
self.logic.tool.can_forage((Season.spring, Season.summer, Season.fall), SVERegion.sprite_spring) &
self.logic.time.has_year_three),
WaterItem.coral: items[WaterItem.coral] | self.logic.region.can_reach(SVERegion.fable_reef),
Forageable.rainbow_shell: items[Forageable.rainbow_shell] | self.logic.region.can_reach(SVERegion.fable_reef),
WaterItem.sea_urchin: items[WaterItem.sea_urchin] | self.logic.region.can_reach(SVERegion.fable_reef),
Forageable.red_mushroom: items[Forageable.red_mushroom] | self.logic.tool.can_forage((Season.summer, Season.fall), SVERegion.forest_west) |
self.logic.region.can_reach(SVERegion.sprite_spring_cave),
Forageable.purple_mushroom: items[Forageable.purple_mushroom] | self.logic.tool.can_forage(Season.fall, SVERegion.forest_west) |
self.logic.region.can_reach(SVERegion.sprite_spring_cave),
Forageable.morel: items[Forageable.morel] | self.logic.tool.can_forage(Season.fall, SVERegion.forest_west),
Forageable.chanterelle: items[Forageable.chanterelle] | self.logic.tool.can_forage(Season.fall, SVERegion.forest_west) |
self.logic.region.can_reach(SVERegion.sprite_spring_cave),
Ore.copper: items[Ore.copper] | (self.logic.tool.can_use_tool_at(Tool.pickaxe, ToolMaterial.basic, SVERegion.highlands_cavern) &
self.logic.combat.can_fight_at_level(Performance.great)),
Ore.iron: items[Ore.iron] | (self.logic.tool.can_use_tool_at(Tool.pickaxe, ToolMaterial.basic, SVERegion.highlands_cavern) &
self.logic.combat.can_fight_at_level(Performance.great)),
Ore.iridium: items[Ore.iridium] | (self.logic.tool.can_use_tool_at(Tool.pickaxe, ToolMaterial.basic, SVERegion.crimson_badlands) &
self.logic.combat.can_fight_at_level(Performance.maximum)),
}
def get_modified_item_rules_for_deep_woods(self, items: Dict[str, StardewRule]):
options_to_update = {
Fruit.apple: items[Fruit.apple] | self.logic.region.can_reach(DeepWoodsRegion.floor_10), # Deep enough to have seen such a tree at least once
Fruit.apricot: items[Fruit.apricot] | self.logic.region.can_reach(DeepWoodsRegion.floor_10),
Fruit.cherry: items[Fruit.cherry] | self.logic.region.can_reach(DeepWoodsRegion.floor_10),
Fruit.orange: items[Fruit.orange] | self.logic.region.can_reach(DeepWoodsRegion.floor_10),
Fruit.peach: items[Fruit.peach] | self.logic.region.can_reach(DeepWoodsRegion.floor_10),
Fruit.pomegranate: items[Fruit.pomegranate] | self.logic.region.can_reach(DeepWoodsRegion.floor_10),
Fruit.mango: items[Fruit.mango] | self.logic.region.can_reach(DeepWoodsRegion.floor_10),
Flower.tulip: items[Flower.tulip] | self.logic.tool.can_forage(Season.not_winter, DeepWoodsRegion.floor_10),
Flower.blue_jazz: items[Flower.blue_jazz] | self.logic.region.can_reach(DeepWoodsRegion.floor_10),
Flower.summer_spangle: items[Flower.summer_spangle] | self.logic.tool.can_forage(Season.not_winter, DeepWoodsRegion.floor_10),
Flower.poppy: items[Flower.poppy] | self.logic.tool.can_forage(Season.not_winter, DeepWoodsRegion.floor_10),
Flower.fairy_rose: items[Flower.fairy_rose] | self.logic.region.can_reach(DeepWoodsRegion.floor_10),
Material.hardwood: items[Material.hardwood] | self.logic.tool.can_use_tool_at(Tool.axe, ToolMaterial.iron, DeepWoodsRegion.floor_10),
Ingredient.sugar: items[Ingredient.sugar] | self.logic.tool.can_use_tool_at(Tool.axe, ToolMaterial.gold, DeepWoodsRegion.floor_50),
# Gingerbread House
Ingredient.wheat_flour: items[Ingredient.wheat_flour] | self.logic.tool.can_use_tool_at(Tool.axe, ToolMaterial.gold, DeepWoodsRegion.floor_50),
# Gingerbread House
}
if self.options.tool_progression & options.ToolProgression.option_progressive:
options_to_update.update({
Ore.iridium: items[Ore.iridium] | self.logic.tool.can_use_tool_at(Tool.axe, ToolMaterial.iridium, DeepWoodsRegion.floor_50), # Iridium Tree
})
return options_to_update
def get_archaeology_item_rules(self):
archaeology_item_rules = {}
preservation_chamber_rule = self.logic.has(ModMachine.preservation_chamber)
hardwood_preservation_chamber_rule = self.logic.has(ModMachine.hardwood_preservation_chamber)
for item in display_items:
for display_type in display_types:
if item == "Trilobite":
location_name = f"{display_type}: Trilobite Fossil"
else:
location_name = f"{display_type}: {item}"
display_item_rule = self.logic.crafting.can_craft(all_crafting_recipes_by_name[display_type]) & self.logic.has(item)
if "Wooden" in display_type:
archaeology_item_rules[location_name] = display_item_rule & preservation_chamber_rule
else:
archaeology_item_rules[location_name] = display_item_rule & hardwood_preservation_chamber_rule
return archaeology_item_rules
def get_distant_lands_item_rules(self):
return {
DistantLandsForageable.swamp_herb: self.logic.region.can_reach(Region.witch_swamp),
DistantLandsForageable.brown_amanita: self.logic.region.can_reach(Region.witch_swamp),
DistantLandsSeed.vile_ancient_fruit: self.logic.quest.can_complete_quest(ModQuest.WitchOrder) | self.logic.quest.can_complete_quest(
ModQuest.CorruptedCropsTask),
DistantLandsSeed.void_mint: self.logic.quest.can_complete_quest(ModQuest.WitchOrder) | self.logic.quest.can_complete_quest(
ModQuest.CorruptedCropsTask),
DistantLandsCrop.void_mint: self.logic.season.has_any_not_winter() & self.logic.has(DistantLandsSeed.void_mint),
DistantLandsCrop.vile_ancient_fruit: self.logic.season.has_any_not_winter() & self.logic.has(DistantLandsSeed.vile_ancient_fruit),
}
def get_boarding_house_item_rules(self):
return {
# Mob Drops from lost valley enemies
ModArtisanGood.pterodactyl_egg: self.logic.region.can_reach_any((BoardingHouseRegion.lost_valley_ruins, BoardingHouseRegion.lost_valley_house_1,
BoardingHouseRegion.lost_valley_house_2,)) & self.logic.combat.can_fight_at_level(
Performance.good),
ModFossil.pterodactyl_claw: self.logic.region.can_reach_any((BoardingHouseRegion.lost_valley_ruins, BoardingHouseRegion.lost_valley_house_1,
BoardingHouseRegion.lost_valley_house_2,)) & self.logic.combat.can_fight_at_level(
Performance.good),
ModFossil.pterodactyl_ribs: self.logic.region.can_reach_any((BoardingHouseRegion.lost_valley_ruins, BoardingHouseRegion.lost_valley_house_1,
BoardingHouseRegion.lost_valley_house_2,)) & self.logic.combat.can_fight_at_level(
Performance.good),
ModFossil.pterodactyl_vertebra: self.logic.region.can_reach_any((BoardingHouseRegion.lost_valley_ruins, BoardingHouseRegion.lost_valley_house_1,
BoardingHouseRegion.lost_valley_house_2,)) & self.logic.combat.can_fight_at_level(
Performance.good),
ModFossil.pterodactyl_skull: self.logic.region.can_reach_any((BoardingHouseRegion.lost_valley_ruins, BoardingHouseRegion.lost_valley_house_1,
BoardingHouseRegion.lost_valley_house_2,)) & self.logic.combat.can_fight_at_level(
Performance.good),
ModFossil.pterodactyl_phalange: self.logic.region.can_reach_any((BoardingHouseRegion.lost_valley_ruins, BoardingHouseRegion.lost_valley_house_1,
BoardingHouseRegion.lost_valley_house_2,)) & self.logic.combat.can_fight_at_level(
Performance.good),
ModFossil.pterodactyl_l_wing_bone: self.logic.region.can_reach_any((BoardingHouseRegion.lost_valley_ruins, BoardingHouseRegion.lost_valley_house_1,
BoardingHouseRegion.lost_valley_house_2,)) & self.logic.combat.can_fight_at_level(
Performance.good),
ModFossil.pterodactyl_r_wing_bone: self.logic.region.can_reach_any((BoardingHouseRegion.lost_valley_ruins, BoardingHouseRegion.lost_valley_house_1,
BoardingHouseRegion.lost_valley_house_2,)) & self.logic.combat.can_fight_at_level(
Performance.good),
ModFossil.dinosaur_skull: self.logic.region.can_reach_any((BoardingHouseRegion.lost_valley_ruins, BoardingHouseRegion.lost_valley_house_1,
BoardingHouseRegion.lost_valley_house_2,)) & self.logic.combat.can_fight_at_level(
Performance.good),
ModFossil.dinosaur_tooth: self.logic.region.can_reach_any((BoardingHouseRegion.lost_valley_ruins, BoardingHouseRegion.lost_valley_house_1,
BoardingHouseRegion.lost_valley_house_2,)) & self.logic.combat.can_fight_at_level(
Performance.good),
ModFossil.dinosaur_femur: self.logic.region.can_reach_any((BoardingHouseRegion.lost_valley_ruins, BoardingHouseRegion.lost_valley_house_1,
BoardingHouseRegion.lost_valley_house_2,)) & self.logic.combat.can_fight_at_level(
Performance.good),
ModFossil.dinosaur_pelvis: self.logic.region.can_reach_any((BoardingHouseRegion.lost_valley_ruins, BoardingHouseRegion.lost_valley_house_1,
BoardingHouseRegion.lost_valley_house_2,)) & self.logic.combat.can_fight_at_level(
Performance.good),
ModFossil.dinosaur_ribs: self.logic.region.can_reach_any((BoardingHouseRegion.lost_valley_ruins, BoardingHouseRegion.lost_valley_house_1,
BoardingHouseRegion.lost_valley_house_2,)) & self.logic.combat.can_fight_at_level(
Performance.good),
ModFossil.dinosaur_vertebra: self.logic.region.can_reach_any((BoardingHouseRegion.lost_valley_ruins, BoardingHouseRegion.lost_valley_house_1,
BoardingHouseRegion.lost_valley_house_2,)) & self.logic.combat.can_fight_at_level(
Performance.good),
ModFossil.dinosaur_claw: self.logic.region.can_reach_any((BoardingHouseRegion.lost_valley_ruins, BoardingHouseRegion.lost_valley_house_1,
BoardingHouseRegion.lost_valley_house_2,)) & self.logic.combat.can_fight_at_level(
Performance.good),
ModFossil.neanderthal_skull: self.logic.region.can_reach_any((BoardingHouseRegion.lost_valley_ruins, BoardingHouseRegion.lost_valley_house_1,
BoardingHouseRegion.lost_valley_house_2,)) & self.logic.combat.can_fight_at_level(
Performance.great),
ModFossil.neanderthal_ribs: self.logic.region.can_reach_any((BoardingHouseRegion.lost_valley_ruins, BoardingHouseRegion.lost_valley_house_1,
BoardingHouseRegion.lost_valley_house_2,)) & self.logic.combat.can_fight_at_level(
Performance.great),
ModFossil.neanderthal_pelvis: self.logic.region.can_reach_any((BoardingHouseRegion.lost_valley_ruins, BoardingHouseRegion.lost_valley_house_1,
BoardingHouseRegion.lost_valley_house_2,)) & self.logic.combat.can_fight_at_level(
Performance.great),
ModFossil.neanderthal_limb_bones: self.logic.region.can_reach_any((BoardingHouseRegion.lost_valley_ruins, BoardingHouseRegion.lost_valley_house_1,
BoardingHouseRegion.lost_valley_house_2,)) & self.logic.combat.can_fight_at_level(
Performance.great),
}
def has_seed_unlocked(self, seed_name: str):
if self.options.cropsanity == Cropsanity.option_disabled:
return True_()
return self.logic.received(seed_name)

View File

@@ -1,80 +0,0 @@
from ...strings.region_names import MagicRegion
from ...mods.mod_data import ModNames
from ...strings.spells import MagicSpell
from ...strings.ap_names.skill_level_names import ModSkillLevel
from ...stardew_rule import Count, StardewRule, False_
from ... import options
def can_use_clear_debris_instead_of_tool_level(vanilla_logic, level: int) -> StardewRule:
if ModNames.magic not in vanilla_logic.options.mods:
return False_()
return vanilla_logic.received(MagicSpell.clear_debris) & can_use_altar(vanilla_logic) & vanilla_logic.received(ModSkillLevel.magic_level, level)
def can_use_altar(vanilla_logic) -> StardewRule:
if ModNames.magic not in vanilla_logic.options.mods:
return False_()
return vanilla_logic.can_reach_region(MagicRegion.altar)
def has_any_spell(vanilla_logic) -> StardewRule:
if ModNames.magic not in vanilla_logic.options.mods:
return False_()
return can_use_altar(vanilla_logic)
def has_attack_spell_count(vanilla_logic, count: int) -> StardewRule:
attack_spell_rule = [vanilla_logic.received(MagicSpell.fireball), vanilla_logic.received(
MagicSpell.frostbite), vanilla_logic.received(MagicSpell.shockwave), vanilla_logic.received(MagicSpell.spirit),
vanilla_logic.received(MagicSpell.meteor)
]
return Count(count, attack_spell_rule)
def has_support_spell_count(vanilla_logic, count: int) -> StardewRule:
support_spell_rule = [can_use_altar(vanilla_logic), vanilla_logic.received(ModSkillLevel.magic_level, 2),
vanilla_logic.received(MagicSpell.descend), vanilla_logic.received(MagicSpell.heal),
vanilla_logic.received(MagicSpell.tendrils)]
return Count(count, support_spell_rule)
def has_decent_spells(vanilla_logic) -> StardewRule:
if ModNames.magic not in vanilla_logic.options.mods:
return False_()
magic_resource_rule = can_use_altar(vanilla_logic) & vanilla_logic.received(ModSkillLevel.magic_level, 2)
magic_attack_options_rule = has_attack_spell_count(vanilla_logic, 1)
return magic_resource_rule & magic_attack_options_rule
def has_good_spells(vanilla_logic) -> StardewRule:
if ModNames.magic not in vanilla_logic.options.mods:
return False_()
magic_resource_rule = can_use_altar(vanilla_logic) & vanilla_logic.received(ModSkillLevel.magic_level, 4)
magic_attack_options_rule = has_attack_spell_count(vanilla_logic, 2)
magic_support_options_rule = has_support_spell_count(vanilla_logic, 1)
return magic_resource_rule & magic_attack_options_rule & magic_support_options_rule
def has_great_spells(vanilla_logic) -> StardewRule:
if ModNames.magic not in vanilla_logic.options.mods:
return False_()
magic_resource_rule = can_use_altar(vanilla_logic) & vanilla_logic.received(ModSkillLevel.magic_level, 6)
magic_attack_options_rule = has_attack_spell_count(vanilla_logic, 3)
magic_support_options_rule = has_support_spell_count(vanilla_logic, 1)
return magic_resource_rule & magic_attack_options_rule & magic_support_options_rule
def has_amazing_spells(vanilla_logic) -> StardewRule:
if ModNames.magic not in vanilla_logic.options.mods:
return False_()
magic_resource_rule = can_use_altar(vanilla_logic) & vanilla_logic.received(ModSkillLevel.magic_level, 8)
magic_attack_options_rule = has_attack_spell_count(vanilla_logic, 4)
magic_support_options_rule = has_support_spell_count(vanilla_logic, 2)
return magic_resource_rule & magic_attack_options_rule & magic_support_options_rule
def can_blink(vanilla_logic) -> StardewRule:
if ModNames.magic not in vanilla_logic.options.mods:
return False_()
return vanilla_logic.received(MagicSpell.blink) & can_use_altar(vanilla_logic)

View File

@@ -0,0 +1,82 @@
from typing import Union
from ...logic.base_logic import BaseLogicMixin, BaseLogic
from ...logic.has_logic import HasLogicMixin
from ...logic.received_logic import ReceivedLogicMixin
from ...logic.region_logic import RegionLogicMixin
from ...mods.mod_data import ModNames
from ...stardew_rule import StardewRule, False_
from ...strings.ap_names.skill_level_names import ModSkillLevel
from ...strings.region_names import MagicRegion
from ...strings.spells import MagicSpell
class MagicLogicMixin(BaseLogicMixin):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.magic = MagicLogic(*args, **kwargs)
# TODO add logic.mods.magic for altar
class MagicLogic(BaseLogic[Union[RegionLogicMixin, ReceivedLogicMixin, HasLogicMixin]]):
def can_use_clear_debris_instead_of_tool_level(self, level: int) -> StardewRule:
if ModNames.magic not in self.options.mods:
return False_()
return self.logic.received(MagicSpell.clear_debris) & self.can_use_altar() & self.logic.received(ModSkillLevel.magic_level, level)
def can_use_altar(self) -> StardewRule:
if ModNames.magic not in self.options.mods:
return False_()
return self.logic.region.can_reach(MagicRegion.altar)
def has_any_spell(self) -> StardewRule:
if ModNames.magic not in self.options.mods:
return False_()
return self.can_use_altar()
def has_attack_spell_count(self, count: int) -> StardewRule:
attack_spell_rule = [self.logic.received(MagicSpell.fireball), self.logic.received(MagicSpell.frostbite), self.logic.received(MagicSpell.shockwave),
self.logic.received(MagicSpell.spirit), self.logic.received(MagicSpell.meteor)]
return self.logic.count(count, *attack_spell_rule)
def has_support_spell_count(self, count: int) -> StardewRule:
support_spell_rule = [self.can_use_altar(), self.logic.received(ModSkillLevel.magic_level, 2),
self.logic.received(MagicSpell.descend), self.logic.received(MagicSpell.heal),
self.logic.received(MagicSpell.tendrils)]
return self.logic.count(count, *support_spell_rule)
def has_decent_spells(self) -> StardewRule:
if ModNames.magic not in self.options.mods:
return False_()
magic_resource_rule = self.can_use_altar() & self.logic.received(ModSkillLevel.magic_level, 2)
magic_attack_options_rule = self.has_attack_spell_count(1)
return magic_resource_rule & magic_attack_options_rule
def has_good_spells(self) -> StardewRule:
if ModNames.magic not in self.options.mods:
return False_()
magic_resource_rule = self.can_use_altar() & self.logic.received(ModSkillLevel.magic_level, 4)
magic_attack_options_rule = self.has_attack_spell_count(2)
magic_support_options_rule = self.has_support_spell_count(1)
return magic_resource_rule & magic_attack_options_rule & magic_support_options_rule
def has_great_spells(self) -> StardewRule:
if ModNames.magic not in self.options.mods:
return False_()
magic_resource_rule = self.can_use_altar() & self.logic.received(ModSkillLevel.magic_level, 6)
magic_attack_options_rule = self.has_attack_spell_count(3)
magic_support_options_rule = self.has_support_spell_count(1)
return magic_resource_rule & magic_attack_options_rule & magic_support_options_rule
def has_amazing_spells(self) -> StardewRule:
if ModNames.magic not in self.options.mods:
return False_()
magic_resource_rule = self.can_use_altar() & self.logic.received(ModSkillLevel.magic_level, 8)
magic_attack_options_rule = self.has_attack_spell_count(4)
magic_support_options_rule = self.has_support_spell_count(2)
return magic_resource_rule & magic_attack_options_rule & magic_support_options_rule
def can_blink(self) -> StardewRule:
if ModNames.magic not in self.options.mods:
return False_()
return self.logic.received(MagicSpell.blink) & self.can_use_altar()

View File

@@ -0,0 +1,21 @@
from .buildings_logic import ModBuildingLogicMixin
from .deepwoods_logic import DeepWoodsLogicMixin
from .elevator_logic import ModElevatorLogicMixin
from .item_logic import ModItemLogicMixin
from .magic_logic import MagicLogicMixin
from .quests_logic import ModQuestLogicMixin
from .skills_logic import ModSkillLogicMixin
from .special_orders_logic import ModSpecialOrderLogicMixin
from .sve_logic import SVELogicMixin
from ...logic.base_logic import BaseLogicMixin
class ModLogicMixin(BaseLogicMixin):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.mod = ModLogic(*args, **kwargs)
class ModLogic(ModElevatorLogicMixin, MagicLogicMixin, ModSkillLogicMixin, ModItemLogicMixin, ModQuestLogicMixin, ModBuildingLogicMixin,
ModSpecialOrderLogicMixin, DeepWoodsLogicMixin, SVELogicMixin):
pass

View File

@@ -0,0 +1,21 @@
from typing import Tuple
from ...mods.mod_data import ModNames
from ...options import Mods
def get_mod_skill_levels(mods: Mods) -> Tuple[str]:
skills_items = []
if ModNames.luck_skill in mods:
skills_items.append("Luck Level")
if ModNames.socializing_skill in mods:
skills_items.append("Socializing Level")
if ModNames.magic in mods:
skills_items.append("Magic Level")
if ModNames.archaeology in mods:
skills_items.append("Archaeology Level")
if ModNames.binning_skill in mods:
skills_items.append("Binning Level")
if ModNames.cooking_skill in mods:
skills_items.append("Cooking Level")
return tuple(skills_items)

View File

@@ -1,31 +0,0 @@
from typing import Union
from ...strings.quest_names import ModQuest
from ..mod_data import ModNames
from ...strings.food_names import Meal, Beverage
from ...strings.monster_drop_names import Loot
from ...strings.villager_names import ModNPC
from ...strings.season_names import Season
from ...strings.region_names import Region
def get_modded_quest_rules(vanilla_logic, active_mods):
quests = {}
if ModNames.juna in active_mods:
quests.update({
ModQuest.JunaCola: vanilla_logic.has_relationship(ModNPC.juna, 3) & vanilla_logic.has(Beverage.joja_cola),
ModQuest.JunaSpaghetti: vanilla_logic.has_relationship(ModNPC.juna, 6) & vanilla_logic.has(Meal.spaghetti)
})
if ModNames.ginger in active_mods:
quests.update({
ModQuest.MrGinger: vanilla_logic.has_relationship(ModNPC.mr_ginger, 6) & vanilla_logic.has(Loot.void_essence)
})
if ModNames.ayeisha in active_mods:
quests.update({
ModQuest.AyeishaEnvelope: (vanilla_logic.has_season(Season.spring) | vanilla_logic.has_season(Season.fall)) &
vanilla_logic.can_reach_region(Region.mountain),
ModQuest.AyeishaRing: vanilla_logic.has_season(Season.winter) & vanilla_logic.can_reach_region(Region.forest)
})
return quests

View File

@@ -0,0 +1,128 @@
from typing import Dict, Union
from ..mod_data import ModNames
from ...logic.base_logic import BaseLogic, BaseLogicMixin
from ...logic.has_logic import HasLogicMixin
from ...logic.quest_logic import QuestLogicMixin
from ...logic.monster_logic import MonsterLogicMixin
from ...logic.received_logic import ReceivedLogicMixin
from ...logic.region_logic import RegionLogicMixin
from ...logic.relationship_logic import RelationshipLogicMixin
from ...logic.season_logic import SeasonLogicMixin
from ...logic.time_logic import TimeLogicMixin
from ...stardew_rule import StardewRule
from ...strings.animal_product_names import AnimalProduct
from ...strings.artisan_good_names import ArtisanGood
from ...strings.crop_names import Fruit, SVEFruit, SVEVegetable, Vegetable
from ...strings.fertilizer_names import Fertilizer
from ...strings.food_names import Meal, Beverage
from ...strings.forageable_names import SVEForage
from ...strings.material_names import Material
from ...strings.metal_names import Ore, MetalBar
from ...strings.monster_drop_names import Loot
from ...strings.monster_names import Monster
from ...strings.quest_names import Quest, ModQuest
from ...strings.region_names import Region, SVERegion, BoardingHouseRegion
from ...strings.season_names import Season
from ...strings.villager_names import ModNPC, NPC
from ...strings.wallet_item_names import Wallet
class ModQuestLogicMixin(BaseLogicMixin):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.quest = ModQuestLogic(*args, **kwargs)
class ModQuestLogic(BaseLogic[Union[HasLogicMixin, QuestLogicMixin, ReceivedLogicMixin, RegionLogicMixin,
TimeLogicMixin, SeasonLogicMixin, RelationshipLogicMixin, MonsterLogicMixin]]):
def get_modded_quest_rules(self) -> Dict[str, StardewRule]:
quests = dict()
quests.update(self._get_juna_quest_rules())
quests.update(self._get_mr_ginger_quest_rules())
quests.update(self._get_ayeisha_quest_rules())
quests.update(self._get_sve_quest_rules())
quests.update(self._get_distant_lands_quest_rules())
quests.update(self._get_boarding_house_quest_rules())
quests.update((self._get_hat_mouse_quest_rules()))
return quests
def _get_juna_quest_rules(self):
if ModNames.juna not in self.options.mods:
return {}
return {
ModQuest.JunaCola: self.logic.relationship.has_hearts(ModNPC.juna, 3) & self.logic.has(Beverage.joja_cola),
ModQuest.JunaSpaghetti: self.logic.relationship.has_hearts(ModNPC.juna, 6) & self.logic.has(Meal.spaghetti)
}
def _get_mr_ginger_quest_rules(self):
if ModNames.ginger not in self.options.mods:
return {}
return {
ModQuest.MrGinger: self.logic.relationship.has_hearts(ModNPC.mr_ginger, 6) & self.logic.has(Loot.void_essence)
}
def _get_ayeisha_quest_rules(self):
if ModNames.ayeisha not in self.options.mods:
return {}
return {
ModQuest.AyeishaEnvelope: (self.logic.season.has(Season.spring) | self.logic.season.has(Season.fall)),
ModQuest.AyeishaRing: self.logic.season.has(Season.winter)
}
def _get_sve_quest_rules(self):
if ModNames.sve not in self.options.mods:
return {}
return {
ModQuest.RailroadBoulder: self.logic.received(Wallet.skull_key) & self.logic.has_all(*(Ore.iridium, Material.coal)) &
self.logic.region.can_reach(Region.blacksmith) & self.logic.region.can_reach(Region.railroad),
ModQuest.GrandpasShed: self.logic.has_all(*(Material.hardwood, MetalBar.iron, ArtisanGood.battery_pack, Material.stone)) &
self.logic.region.can_reach(SVERegion.grandpas_shed),
ModQuest.MarlonsBoat: self.logic.has_all(*(Loot.void_essence, Loot.solar_essence, Loot.slime, Loot.bat_wing, Loot.bug_meat)) &
self.logic.relationship.can_meet(ModNPC.lance) & self.logic.region.can_reach(SVERegion.guild_summit),
ModQuest.AuroraVineyard: self.logic.has(Fruit.starfruit) & self.logic.region.can_reach(SVERegion.aurora_vineyard),
ModQuest.MonsterCrops: self.logic.has_all(*(SVEVegetable.monster_mushroom, SVEFruit.slime_berry, SVEFruit.monster_fruit, SVEVegetable.void_root)),
ModQuest.VoidSoul: self.logic.has(SVEForage.void_soul) & self.logic.region.can_reach(Region.farm) &
self.logic.season.has_any_not_winter() & self.logic.region.can_reach(SVERegion.badlands_entrance) &
self.logic.relationship.has_hearts(NPC.krobus, 10) & self.logic.quest.can_complete_quest(ModQuest.MonsterCrops) &
self.logic.monster.can_kill_any((Monster.shadow_brute, Monster.shadow_shaman, Monster.shadow_sniper)),
}
def _get_distant_lands_quest_rules(self):
if ModNames.distant_lands not in self.options.mods:
return {}
return {
ModQuest.CorruptedCropsTask: self.logic.region.can_reach(Region.wizard_tower) & self.logic.has(Fertilizer.deluxe) &
self.logic.quest.can_complete_quest(Quest.magic_ink),
ModQuest.WitchOrder: self.logic.region.can_reach(Region.witch_swamp) & self.logic.has(Fertilizer.deluxe) &
self.logic.quest.can_complete_quest(Quest.magic_ink),
ModQuest.ANewPot: self.logic.region.can_reach(Region.saloon) &
self.logic.region.can_reach(Region.sam_house) & self.logic.region.can_reach(Region.pierre_store) &
self.logic.region.can_reach(Region.blacksmith) & self.logic.has(MetalBar.iron) & self.logic.relationship.has_hearts(ModNPC.goblin,
6),
ModQuest.FancyBlanketTask: self.logic.region.can_reach(Region.haley_house) & self.logic.has(AnimalProduct.wool) &
self.logic.has(ArtisanGood.cloth) & self.logic.relationship.has_hearts(ModNPC.goblin, 10) &
self.logic.relationship.has_hearts(NPC.emily, 8) & self.logic.season.has(Season.winter)
}
def _get_boarding_house_quest_rules(self):
if ModNames.boarding_house not in self.options.mods:
return {}
return {
ModQuest.PumpkinSoup: self.logic.region.can_reach(BoardingHouseRegion.boarding_house_first) & self.logic.has(Vegetable.pumpkin)
}
def _get_hat_mouse_quest_rules(self):
if ModNames.lacey not in self.options.mods:
return {}
return {
ModQuest.HatMouseHat: self.logic.relationship.has_hearts(ModNPC.lacey, 2) & self.logic.time.has_lived_months(4)
}

View File

@@ -1,94 +0,0 @@
from typing import List, Union
from . import magic
from ...strings.building_names import Building
from ...strings.geode_names import Geode
from ...strings.region_names import Region
from ...strings.skill_names import ModSkill
from ...strings.spells import MagicSpell
from ...strings.machine_names import Machine
from ...strings.tool_names import Tool, ToolMaterial
from ...mods.mod_data import ModNames
from ...data.villagers_data import all_villagers
from ...stardew_rule import Count, StardewRule, False_
from ... import options
def append_mod_skill_level(skills_items: List[str], active_mods):
if ModNames.luck_skill in active_mods:
skills_items.append("Luck Level")
if ModNames.socializing_skill in active_mods:
skills_items.append("Socializing Level")
if ModNames.magic in active_mods:
skills_items.append("Magic Level")
if ModNames.archaeology in active_mods:
skills_items.append("Archaeology Level")
if ModNames.binning_skill in active_mods:
skills_items.append("Binning Level")
if ModNames.cooking_skill in active_mods:
skills_items.append("Cooking Level")
def can_earn_mod_skill_level(logic, skill: str, level: int) -> StardewRule:
if ModNames.luck_skill in logic.options.mods and skill == ModSkill.luck:
return can_earn_luck_skill_level(logic, level)
if ModNames.magic in logic.options.mods and skill == ModSkill.magic:
return can_earn_magic_skill_level(logic, level)
if ModNames.socializing_skill in logic.options.mods and skill == ModSkill.socializing:
return can_earn_socializing_skill_level(logic, level)
if ModNames.archaeology in logic.options.mods and skill == ModSkill.archaeology:
return can_earn_archaeology_skill_level(logic, level)
if ModNames.cooking_skill in logic.options.mods and skill == ModSkill.cooking:
return can_earn_cooking_skill_level(logic, level)
if ModNames.binning_skill in logic.options.mods and skill == ModSkill.binning:
return can_earn_binning_skill_level(logic, level)
return False_()
def can_earn_luck_skill_level(vanilla_logic, level: int) -> StardewRule:
if level >= 6:
return vanilla_logic.can_fish_chests() | vanilla_logic.can_open_geode(Geode.magma)
else:
return vanilla_logic.can_fish_chests() | vanilla_logic.can_open_geode(Geode.geode)
def can_earn_magic_skill_level(vanilla_logic, level: int) -> StardewRule:
spell_count = [vanilla_logic.received(MagicSpell.clear_debris), vanilla_logic.received(MagicSpell.water),
vanilla_logic.received(MagicSpell.blink), vanilla_logic.received(MagicSpell.fireball),
vanilla_logic.received(MagicSpell.frostbite),
vanilla_logic.received(MagicSpell.descend), vanilla_logic.received(MagicSpell.tendrils),
vanilla_logic.received(MagicSpell.shockwave),
vanilla_logic.received(MagicSpell.meteor),
vanilla_logic.received(MagicSpell.spirit)]
return magic.can_use_altar(vanilla_logic) & Count(level, spell_count)
def can_earn_socializing_skill_level(vanilla_logic, level: int) -> StardewRule:
villager_count = []
for villager in all_villagers:
if villager.mod_name in vanilla_logic.options.mods or villager.mod_name is None:
villager_count.append(vanilla_logic.can_earn_relationship(villager.name, level))
return Count(level * 2, villager_count)
def can_earn_archaeology_skill_level(vanilla_logic, level: int) -> StardewRule:
if level >= 6:
return vanilla_logic.can_do_panning() | vanilla_logic.has_tool(Tool.hoe, ToolMaterial.gold)
else:
return vanilla_logic.can_do_panning() | vanilla_logic.has_tool(Tool.hoe, ToolMaterial.basic)
def can_earn_cooking_skill_level(vanilla_logic, level: int) -> StardewRule:
if level >= 6:
return vanilla_logic.can_cook() & vanilla_logic.can_fish() & vanilla_logic.can_reach_region(Region.saloon) & \
vanilla_logic.has_building(Building.coop) & vanilla_logic.has_building(Building.barn)
else:
return vanilla_logic.can_cook()
def can_earn_binning_skill_level(vanilla_logic, level: int) -> StardewRule:
if level >= 6:
return vanilla_logic.can_reach_region(Region.town) & vanilla_logic.has(Machine.recycling_machine) & \
(vanilla_logic.can_fish() | vanilla_logic.can_crab_pot())
else:
return vanilla_logic.can_reach_region(Region.town) | (vanilla_logic.has(Machine.recycling_machine) &
(vanilla_logic.can_fish() | vanilla_logic.can_crab_pot()))

View File

@@ -0,0 +1,110 @@
from typing import Union
from .magic_logic import MagicLogicMixin
from ...data.villagers_data import all_villagers
from ...logic.action_logic import ActionLogicMixin
from ...logic.base_logic import BaseLogicMixin, BaseLogic
from ...logic.building_logic import BuildingLogicMixin
from ...logic.cooking_logic import CookingLogicMixin
from ...logic.fishing_logic import FishingLogicMixin
from ...logic.has_logic import HasLogicMixin
from ...logic.received_logic import ReceivedLogicMixin
from ...logic.region_logic import RegionLogicMixin
from ...logic.relationship_logic import RelationshipLogicMixin
from ...logic.tool_logic import ToolLogicMixin
from ...mods.mod_data import ModNames
from ...options import SkillProgression
from ...stardew_rule import StardewRule, False_, True_
from ...strings.ap_names.mods.mod_items import SkillLevel
from ...strings.craftable_names import ModCraftable, ModMachine
from ...strings.building_names import Building
from ...strings.geode_names import Geode
from ...strings.machine_names import Machine
from ...strings.region_names import Region
from ...strings.skill_names import ModSkill
from ...strings.spells import MagicSpell
from ...strings.tool_names import Tool, ToolMaterial
class ModSkillLogicMixin(BaseLogicMixin):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.skill = ModSkillLogic(*args, **kwargs)
class ModSkillLogic(BaseLogic[Union[HasLogicMixin, ReceivedLogicMixin, RegionLogicMixin, ActionLogicMixin, RelationshipLogicMixin, BuildingLogicMixin,
ToolLogicMixin, FishingLogicMixin, CookingLogicMixin, MagicLogicMixin]]):
def has_mod_level(self, skill: str, level: int) -> StardewRule:
if level <= 0:
return True_()
if self.options.skill_progression == SkillProgression.option_progressive:
return self.logic.received(f"{skill} Level", level)
return self.can_earn_mod_skill_level(skill, level)
def can_earn_mod_skill_level(self, skill: str, level: int) -> StardewRule:
if ModNames.luck_skill in self.options.mods and skill == ModSkill.luck:
return self.can_earn_luck_skill_level(level)
if ModNames.magic in self.options.mods and skill == ModSkill.magic:
return self.can_earn_magic_skill_level(level)
if ModNames.socializing_skill in self.options.mods and skill == ModSkill.socializing:
return self.can_earn_socializing_skill_level(level)
if ModNames.archaeology in self.options.mods and skill == ModSkill.archaeology:
return self.can_earn_archaeology_skill_level(level)
if ModNames.cooking_skill in self.options.mods and skill == ModSkill.cooking:
return self.can_earn_cooking_skill_level(level)
if ModNames.binning_skill in self.options.mods and skill == ModSkill.binning:
return self.can_earn_binning_skill_level(level)
return False_()
def can_earn_luck_skill_level(self, level: int) -> StardewRule:
if level >= 6:
return self.logic.fishing.can_fish_chests() | self.logic.action.can_open_geode(Geode.magma)
if level >= 3:
return self.logic.fishing.can_fish_chests() | self.logic.action.can_open_geode(Geode.geode)
return True_() # You can literally wake up and or get them by opening starting chests.
def can_earn_magic_skill_level(self, level: int) -> StardewRule:
spell_count = [self.logic.received(MagicSpell.clear_debris), self.logic.received(MagicSpell.water),
self.logic.received(MagicSpell.blink), self.logic.received(MagicSpell.fireball),
self.logic.received(MagicSpell.frostbite),
self.logic.received(MagicSpell.descend), self.logic.received(MagicSpell.tendrils),
self.logic.received(MagicSpell.shockwave),
self.logic.received(MagicSpell.meteor),
self.logic.received(MagicSpell.spirit)]
return self.logic.count(level, *spell_count)
def can_earn_socializing_skill_level(self, level: int) -> StardewRule:
villager_count = []
for villager in all_villagers:
if villager.mod_name in self.options.mods or villager.mod_name is None:
villager_count.append(self.logic.relationship.can_earn_relationship(villager.name, level))
return self.logic.count(level * 2, *villager_count)
def can_earn_archaeology_skill_level(self, level: int) -> StardewRule:
shifter_rule = True_()
preservation_rule = True_()
if self.options.skill_progression == self.options.skill_progression.option_progressive:
shifter_rule = self.logic.has(ModCraftable.water_shifter)
preservation_rule = self.logic.has(ModMachine.hardwood_preservation_chamber)
if level >= 8:
return (self.logic.action.can_pan() & self.logic.tool.has_tool(Tool.hoe, ToolMaterial.gold)) & shifter_rule & preservation_rule
if level >= 5:
return (self.logic.action.can_pan() & self.logic.tool.has_tool(Tool.hoe, ToolMaterial.iron)) & shifter_rule
if level >= 3:
return self.logic.action.can_pan() | self.logic.tool.has_tool(Tool.hoe, ToolMaterial.copper)
return self.logic.action.can_pan() | self.logic.tool.has_tool(Tool.hoe, ToolMaterial.basic)
def can_earn_cooking_skill_level(self, level: int) -> StardewRule:
if level >= 6:
return self.logic.cooking.can_cook() & self.logic.region.can_reach(Region.saloon) & \
self.logic.building.has_building(Building.coop) & self.logic.building.has_building(Building.barn)
else:
return self.logic.cooking.can_cook()
def can_earn_binning_skill_level(self, level: int) -> StardewRule:
if level >= 6:
return self.logic.has(Machine.recycling_machine)
else:
return True_() # You can always earn levels 1-5 with trash cans

View File

@@ -1,10 +0,0 @@
from ...stardew_rule import Count, StardewRule, True_
from ...mods.mod_data import ModNames
from ... import options
def has_skull_cavern_elevator_to_floor(self, floor: int) -> StardewRule:
if self.options.elevator_progression != options.ElevatorProgression.option_vanilla and \
ModNames.skull_cavern_elevator in self.options.mods:
return self.received("Progressive Skull Cavern Elevator", floor // 25)
return True_()

View File

@@ -1,24 +0,0 @@
from typing import Union
from ...strings.craftable_names import Craftable
from ...strings.food_names import Meal
from ...strings.material_names import Material
from ...strings.monster_drop_names import Loot
from ...strings.region_names import Region
from ...strings.special_order_names import SpecialOrder, ModSpecialOrder
from ...strings.villager_names import ModNPC
from ..mod_data import ModNames
def get_modded_special_orders_rules(vanilla_logic, active_mods):
special_orders = {}
if ModNames.juna in active_mods:
special_orders.update({
ModSpecialOrder.junas_monster_mash: vanilla_logic.has_relationship(ModNPC.juna, 4) &
vanilla_logic.can_complete_special_order(SpecialOrder.a_curious_substance) &
vanilla_logic.has_rusty_key() &
vanilla_logic.can_reach_region(Region.forest) & vanilla_logic.has(Craftable.monster_musk) &
vanilla_logic.has("Energy Tonic") & vanilla_logic.has(Material.sap) & vanilla_logic.has(Loot.bug_meat) &
vanilla_logic.has(Craftable.oil_of_garlic) & vanilla_logic.has(Meal.strange_bun)
})
return special_orders

View File

@@ -0,0 +1,76 @@
from typing import Union
from ...data.craftable_data import all_crafting_recipes_by_name
from ..mod_data import ModNames
from ...logic.action_logic import ActionLogicMixin
from ...logic.artisan_logic import ArtisanLogicMixin
from ...logic.base_logic import BaseLogicMixin, BaseLogic
from ...logic.crafting_logic import CraftingLogicMixin
from ...logic.crop_logic import CropLogicMixin
from ...logic.has_logic import HasLogicMixin
from ...logic.received_logic import ReceivedLogicMixin
from ...logic.region_logic import RegionLogicMixin
from ...logic.relationship_logic import RelationshipLogicMixin
from ...logic.season_logic import SeasonLogicMixin
from ...logic.wallet_logic import WalletLogicMixin
from ...strings.ap_names.community_upgrade_names import CommunityUpgrade
from ...strings.artisan_good_names import ArtisanGood
from ...strings.craftable_names import Consumable, Edible, Bomb
from ...strings.crop_names import Fruit
from ...strings.fertilizer_names import Fertilizer
from ...strings.food_names import Meal
from ...strings.geode_names import Geode
from ...strings.material_names import Material
from ...strings.metal_names import MetalBar, Artifact
from ...strings.monster_drop_names import Loot
from ...strings.region_names import Region, SVERegion
from ...strings.special_order_names import SpecialOrder, ModSpecialOrder
from ...strings.villager_names import ModNPC
class ModSpecialOrderLogicMixin(BaseLogicMixin):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.special_order = ModSpecialOrderLogic(*args, **kwargs)
class ModSpecialOrderLogic(BaseLogic[Union[ActionLogicMixin, ArtisanLogicMixin, CraftingLogicMixin, CropLogicMixin, HasLogicMixin, RegionLogicMixin,
ReceivedLogicMixin, RelationshipLogicMixin, SeasonLogicMixin, WalletLogicMixin]]):
def get_modded_special_orders_rules(self):
special_orders = {}
if ModNames.juna in self.options.mods:
special_orders.update({
ModSpecialOrder.junas_monster_mash: self.logic.relationship.has_hearts(ModNPC.juna, 4) &
self.registry.special_order_rules[SpecialOrder.a_curious_substance] &
self.logic.wallet.has_rusty_key() &
self.logic.region.can_reach(Region.forest) & self.logic.has(Consumable.monster_musk) &
self.logic.has("Energy Tonic") & self.logic.has(Material.sap) & self.logic.has(Loot.bug_meat) &
self.logic.has(Edible.oil_of_garlic) & self.logic.has(Meal.strange_bun)
})
if ModNames.sve in self.options.mods:
special_orders.update({
ModSpecialOrder.andys_cellar: self.logic.has(Material.stone) & self.logic.has(Material.wood) & self.logic.has(Material.hardwood) &
self.logic.has(MetalBar.iron) & self.logic.received(CommunityUpgrade.movie_theater, 1) &
self.logic.region.can_reach(SVERegion.fairhaven_farm),
ModSpecialOrder.a_mysterious_venture: self.logic.has(Bomb.cherry_bomb) & self.logic.has(Bomb.bomb) & self.logic.has(Bomb.mega_bomb) &
self.logic.region.can_reach(Region.adventurer_guild),
ModSpecialOrder.an_elegant_reception: self.logic.artisan.can_keg(Fruit.starfruit) & self.logic.has(ArtisanGood.cheese) &
self.logic.has(ArtisanGood.goat_cheese) & self.logic.season.has_any_not_winter() &
self.logic.region.can_reach(SVERegion.jenkins_cellar),
ModSpecialOrder.fairy_garden: self.logic.has(Consumable.fairy_dust) &
self.logic.region.can_reach(Region.island_south) & (
self.logic.action.can_open_geode(Geode.frozen) | self.logic.action.can_open_geode(Geode.omni)) &
self.logic.region.can_reach(SVERegion.blue_moon_vineyard),
ModSpecialOrder.homemade_fertilizer: self.logic.crafting.can_craft(all_crafting_recipes_by_name[Fertilizer.quality]) &
self.logic.region.can_reach(SVERegion.susans_house) # quest requires you make the fertilizer
})
if ModNames.jasper in self.options.mods:
special_orders.update({
ModSpecialOrder.dwarf_scroll: self.logic.has_all(*(Artifact.dwarf_scroll_i, Artifact.dwarf_scroll_ii, Artifact.dwarf_scroll_iii,
Artifact.dwarf_scroll_iv,)),
ModSpecialOrder.geode_order: self.logic.has_all(*(Geode.geode, Geode.frozen, Geode.magma, Geode.omni,)) &
self.logic.relationship.has_hearts(ModNPC.jasper, 8)
})
return special_orders

View File

@@ -0,0 +1,55 @@
from typing import Union
from ..mod_regions import SVERegion
from ...logic.base_logic import BaseLogicMixin, BaseLogic
from ...logic.combat_logic import CombatLogicMixin
from ...logic.cooking_logic import CookingLogicMixin
from ...logic.has_logic import HasLogicMixin
from ...logic.money_logic import MoneyLogicMixin
from ...logic.quest_logic import QuestLogicMixin
from ...logic.received_logic import ReceivedLogicMixin
from ...logic.region_logic import RegionLogicMixin
from ...logic.relationship_logic import RelationshipLogicMixin
from ...logic.season_logic import SeasonLogicMixin
from ...logic.time_logic import TimeLogicMixin
from ...logic.tool_logic import ToolLogicMixin
from ...strings.ap_names.mods.mod_items import SVELocation, SVERunes, SVEQuestItem
from ...strings.quest_names import Quest
from ...strings.region_names import Region
from ...strings.tool_names import Tool, ToolMaterial
from ...strings.wallet_item_names import Wallet
from ...stardew_rule import Or
from ...strings.quest_names import ModQuest
class SVELogicMixin(BaseLogicMixin):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.sve = SVELogic(*args, **kwargs)
class SVELogic(BaseLogic[Union[HasLogicMixin, ReceivedLogicMixin, QuestLogicMixin, RegionLogicMixin, RelationshipLogicMixin, TimeLogicMixin, ToolLogicMixin,
CookingLogicMixin, MoneyLogicMixin, CombatLogicMixin, SeasonLogicMixin, QuestLogicMixin]]):
def initialize_rules(self):
self.registry.sve_location_rules.update({
SVELocation.tempered_galaxy_sword: self.logic.money.can_spend_at(SVERegion.alesia_shop, 350000),
SVELocation.tempered_galaxy_dagger: self.logic.money.can_spend_at(SVERegion.isaac_shop, 600000),
SVELocation.tempered_galaxy_hammer: self.logic.money.can_spend_at(SVERegion.isaac_shop, 400000),
})
def has_any_rune(self):
rune_list = SVERunes.nexus_items
return Or(*(self.logic.received(rune) for rune in rune_list))
def has_iridium_bomb(self):
if self.options.quest_locations < 0:
return self.logic.quest.can_complete_quest(ModQuest.RailroadBoulder)
return self.logic.received(SVEQuestItem.iridium_bomb)
def can_buy_bear_recipe(self):
access_rule = (self.logic.quest.can_complete_quest(Quest.strange_note) & self.logic.tool.has_tool(Tool.axe, ToolMaterial.basic) &
self.logic.tool.has_tool(Tool.pickaxe, ToolMaterial.basic))
forage_rule = self.logic.region.can_reach_any((Region.forest, Region.backwoods, Region.mountain))
knowledge_rule = self.logic.received(Wallet.bears_knowledge)
return access_rule & forage_rule & knowledge_rule

View File

@@ -21,6 +21,13 @@ class ModNames:
ayeisha = "Ayeisha - The Postal Worker (Custom NPC)"
riley = "Custom NPC - Riley"
skull_cavern_elevator = "Skull Cavern Elevator"
sve = "Stardew Valley Expanded"
alecto = "Alecto the Witch"
distant_lands = "Distant Lands - Witch Swamp Overhaul"
lacey = "Hat Mouse Lacey"
boarding_house = "Boarding House and Bus Stop Extension"
jasper_sve = jasper + "," + sve
all_mods = frozenset({ModNames.deepwoods, ModNames.tractor, ModNames.big_backpack,
@@ -28,4 +35,5 @@ all_mods = frozenset({ModNames.deepwoods, ModNames.tractor, ModNames.big_backpac
ModNames.cooking_skill, ModNames.binning_skill, ModNames.juna,
ModNames.jasper, ModNames.alec, ModNames.yoba, ModNames.eugene,
ModNames.wellwick, ModNames.ginger, ModNames.shiko, ModNames.delores,
ModNames.ayeisha, ModNames.riley, ModNames.skull_cavern_elevator})
ModNames.ayeisha, ModNames.riley, ModNames.skull_cavern_elevator, ModNames.sve, ModNames.alecto,
ModNames.distant_lands, ModNames.lacey, ModNames.boarding_house})

View File

@@ -0,0 +1,40 @@
from typing import Dict, Tuple
from .mod_data import ModNames
from ..strings.monster_names import Monster
from ..strings.region_names import SVERegion, DeepWoodsRegion, BoardingHouseRegion
sve_monsters_locations: Dict[str, Tuple[str, ...]] = {
Monster.shadow_brute_dangerous: (SVERegion.highlands_cavern,),
Monster.shadow_sniper: (SVERegion.highlands_cavern,),
Monster.shadow_shaman_dangerous: (SVERegion.highlands_cavern,),
Monster.mummy_dangerous: (SVERegion.crimson_badlands,),
Monster.royal_serpent: (SVERegion.crimson_badlands,),
Monster.skeleton_dangerous: (SVERegion.crimson_badlands,),
Monster.skeleton_mage: (SVERegion.crimson_badlands,),
Monster.dust_sprite_dangerous: (SVERegion.highlands_outside,),
}
deepwoods_monsters_locations: Dict[str, Tuple[str, ...]] = {
Monster.shadow_brute: (DeepWoodsRegion.floor_10,),
Monster.cave_fly: (DeepWoodsRegion.floor_10,),
Monster.green_slime: (DeepWoodsRegion.floor_10,),
}
boardinghouse_monsters_locations: Dict[str, Tuple[str, ...]] = {
Monster.shadow_brute: (BoardingHouseRegion.lost_valley_ruins, BoardingHouseRegion.lost_valley_house_1, BoardingHouseRegion.lost_valley_house_2,),
Monster.pepper_rex: (BoardingHouseRegion.lost_valley_ruins, BoardingHouseRegion.lost_valley_house_1, BoardingHouseRegion.lost_valley_house_2,),
Monster.iridium_bat: (BoardingHouseRegion.lost_valley_ruins, BoardingHouseRegion.lost_valley_house_2,),
Monster.grub: (BoardingHouseRegion.abandoned_mines_1a, BoardingHouseRegion.abandoned_mines_1b, BoardingHouseRegion.abandoned_mines_2a,
BoardingHouseRegion.abandoned_mines_2b,),
Monster.bug: (BoardingHouseRegion.abandoned_mines_1a, BoardingHouseRegion.abandoned_mines_1b,),
Monster.bat: (BoardingHouseRegion.abandoned_mines_2a, BoardingHouseRegion.abandoned_mines_2b,),
Monster.cave_fly: (BoardingHouseRegion.abandoned_mines_3, BoardingHouseRegion.abandoned_mines_4, BoardingHouseRegion.abandoned_mines_5,),
Monster.frost_bat: (BoardingHouseRegion.abandoned_mines_3, BoardingHouseRegion.abandoned_mines_4, BoardingHouseRegion.abandoned_mines_5,),
}
modded_monsters_locations: Dict[str, Dict[str, Tuple[str, ...]]] = {
ModNames.sve: sve_monsters_locations,
ModNames.deepwoods: deepwoods_monsters_locations,
ModNames.boarding_house: boardinghouse_monsters_locations
}

View File

@@ -1,8 +1,10 @@
from ..strings.entrance_names import DeepWoodsEntrance, EugeneEntrance, \
JasperEntrance, AlecEntrance, YobaEntrance, JunaEntrance, MagicEntrance, AyeishaEntrance, RileyEntrance
from ..strings.region_names import Region, DeepWoodsRegion, EugeneRegion, JasperRegion, \
AlecRegion, YobaRegion, JunaRegion, MagicRegion, AyeishaRegion, RileyRegion
from ..region_classes import RegionData, ConnectionData, RandomizationFlag, ModRegionData
from typing import Dict, List
from ..strings.entrance_names import Entrance, DeepWoodsEntrance, EugeneEntrance, LaceyEntrance, BoardingHouseEntrance, \
JasperEntrance, AlecEntrance, YobaEntrance, JunaEntrance, MagicEntrance, AyeishaEntrance, RileyEntrance, SVEEntrance, AlectoEntrance
from ..strings.region_names import Region, DeepWoodsRegion, EugeneRegion, JasperRegion, BoardingHouseRegion, \
AlecRegion, YobaRegion, JunaRegion, MagicRegion, AyeishaRegion, RileyRegion, SVERegion, AlectoRegion, LaceyRegion
from ..region_classes import RegionData, ConnectionData, ModificationFlag, RandomizationFlag, ModRegionData
from .mod_data import ModNames
deep_woods_regions = [
@@ -131,6 +133,232 @@ riley_entrances = [
flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA)
]
stardew_valley_expanded_regions = [
RegionData(Region.backwoods, [SVEEntrance.backwoods_to_grove]),
RegionData(SVERegion.enchanted_grove, [SVEEntrance.grove_to_outpost_warp, SVEEntrance.grove_to_wizard_warp,
SVEEntrance.grove_to_farm_warp, SVEEntrance.grove_to_guild_warp, SVEEntrance.grove_to_junimo_warp,
SVEEntrance.grove_to_spring_warp, SVEEntrance.grove_to_aurora_warp]),
RegionData(SVERegion.grove_farm_warp, [SVEEntrance.farm_warp_to_farm]),
RegionData(SVERegion.grove_aurora_warp, [SVEEntrance.aurora_warp_to_aurora]),
RegionData(SVERegion.grove_guild_warp, [SVEEntrance.guild_warp_to_guild]),
RegionData(SVERegion.grove_junimo_warp, [SVEEntrance.junimo_warp_to_junimo]),
RegionData(SVERegion.grove_spring_warp, [SVEEntrance.spring_warp_to_spring]),
RegionData(SVERegion.grove_outpost_warp, [SVEEntrance.outpost_warp_to_outpost]),
RegionData(SVERegion.grove_wizard_warp, [SVEEntrance.wizard_warp_to_wizard]),
RegionData(SVERegion.galmoran_outpost, [SVEEntrance.outpost_to_badlands_entrance, SVEEntrance.use_alesia_shop,
SVEEntrance.use_isaac_shop]),
RegionData(SVERegion.badlands_entrance, [SVEEntrance.badlands_entrance_to_badlands]),
RegionData(SVERegion.crimson_badlands, [SVEEntrance.badlands_to_cave]),
RegionData(SVERegion.badlands_cave),
RegionData(Region.bus_stop, [SVEEntrance.bus_stop_to_shed]),
RegionData(SVERegion.grandpas_shed, [SVEEntrance.grandpa_shed_to_interior, SVEEntrance.grandpa_shed_to_town]),
RegionData(SVERegion.grandpas_shed_interior, [SVEEntrance.grandpa_interior_to_upstairs]),
RegionData(SVERegion.grandpas_shed_upstairs),
RegionData(Region.forest,
[SVEEntrance.forest_to_fairhaven, SVEEntrance.forest_to_west, SVEEntrance.forest_to_lost_woods,
SVEEntrance.forest_to_bmv, SVEEntrance.forest_to_marnie_shed]),
RegionData(SVERegion.marnies_shed),
RegionData(SVERegion.fairhaven_farm),
RegionData(Region.town, [SVEEntrance.town_to_bmv, SVEEntrance.town_to_jenkins,
SVEEntrance.town_to_bridge, SVEEntrance.town_to_plot]),
RegionData(SVERegion.blue_moon_vineyard, [SVEEntrance.bmv_to_sophia, SVEEntrance.bmv_to_beach]),
RegionData(SVERegion.sophias_house),
RegionData(SVERegion.jenkins_residence, [SVEEntrance.jenkins_to_cellar]),
RegionData(SVERegion.jenkins_cellar),
RegionData(SVERegion.unclaimed_plot, [SVEEntrance.plot_to_bridge]),
RegionData(SVERegion.shearwater),
RegionData(Region.museum, [SVEEntrance.museum_to_gunther_bedroom]),
RegionData(SVERegion.gunther_bedroom),
RegionData(Region.fish_shop, [SVEEntrance.fish_shop_to_willy_bedroom]),
RegionData(SVERegion.willy_bedroom),
RegionData(Region.mountain, [SVEEntrance.mountain_to_guild_summit]),
RegionData(SVERegion.guild_summit, [SVEEntrance.guild_to_interior, SVEEntrance.guild_to_mines,
SVEEntrance.summit_to_highlands]),
RegionData(Region.railroad, [SVEEntrance.to_susan_house, SVEEntrance.enter_summit, SVEEntrance.railroad_to_grampleton_station]),
RegionData(SVERegion.grampleton_station, [SVEEntrance.grampleton_station_to_grampleton_suburbs]),
RegionData(SVERegion.grampleton_suburbs, [SVEEntrance.grampleton_suburbs_to_scarlett_house]),
RegionData(SVERegion.scarlett_house),
RegionData(Region.wizard_basement, [SVEEntrance.wizard_to_fable_reef]),
RegionData(SVERegion.fable_reef, [SVEEntrance.fable_reef_to_guild]),
RegionData(SVERegion.first_slash_guild, [SVEEntrance.first_slash_guild_to_hallway]),
RegionData(SVERegion.first_slash_hallway, [SVEEntrance.first_slash_hallway_to_room]),
RegionData(SVERegion.first_slash_spare_room),
RegionData(SVERegion.highlands_outside, [SVEEntrance.highlands_to_lance, SVEEntrance.highlands_to_cave]),
RegionData(SVERegion.highlands_cavern, [SVEEntrance.to_dwarf_prison]),
RegionData(SVERegion.dwarf_prison),
RegionData(SVERegion.lances_house, [SVEEntrance.lance_to_ladder]),
RegionData(SVERegion.lances_ladder, [SVEEntrance.lance_ladder_to_highlands]),
RegionData(SVERegion.forest_west, [SVEEntrance.forest_west_to_spring, SVEEntrance.west_to_aurora,
SVEEntrance.use_bear_shop]),
RegionData(SVERegion.aurora_vineyard, [SVEEntrance.to_aurora_basement]),
RegionData(SVERegion.aurora_vineyard_basement),
RegionData(Region.secret_woods, [SVEEntrance.secret_woods_to_west]),
RegionData(SVERegion.bear_shop),
RegionData(SVERegion.sprite_spring, [SVEEntrance.sprite_spring_to_cave]),
RegionData(SVERegion.sprite_spring_cave),
RegionData(SVERegion.lost_woods, [SVEEntrance.lost_woods_to_junimo_woods]),
RegionData(SVERegion.junimo_woods, [SVEEntrance.use_purple_junimo]),
RegionData(SVERegion.purple_junimo_shop),
RegionData(SVERegion.alesia_shop),
RegionData(SVERegion.isaac_shop),
RegionData(SVERegion.summit),
RegionData(SVERegion.susans_house),
RegionData(Region.mountain, [Entrance.mountain_to_adventurer_guild, Entrance.mountain_to_the_mines], ModificationFlag.MODIFIED)
]
mandatory_sve_connections = [
ConnectionData(SVEEntrance.town_to_jenkins, SVERegion.jenkins_residence, flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA),
ConnectionData(SVEEntrance.jenkins_to_cellar, SVERegion.jenkins_cellar, flag=RandomizationFlag.BUILDINGS),
ConnectionData(SVEEntrance.forest_to_bmv, SVERegion.blue_moon_vineyard),
ConnectionData(SVEEntrance.bmv_to_beach, Region.beach),
ConnectionData(SVEEntrance.town_to_plot, SVERegion.unclaimed_plot),
ConnectionData(SVEEntrance.town_to_bmv, SVERegion.blue_moon_vineyard),
ConnectionData(SVEEntrance.town_to_bridge, SVERegion.shearwater),
ConnectionData(SVEEntrance.plot_to_bridge, SVERegion.shearwater),
ConnectionData(SVEEntrance.bus_stop_to_shed, SVERegion.grandpas_shed),
ConnectionData(SVEEntrance.grandpa_shed_to_interior, SVERegion.grandpas_shed_interior, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA),
ConnectionData(SVEEntrance.grandpa_interior_to_upstairs, SVERegion.grandpas_shed_upstairs, flag=RandomizationFlag.BUILDINGS),
ConnectionData(SVEEntrance.grandpa_shed_to_town, Region.town),
ConnectionData(SVEEntrance.bmv_to_sophia, SVERegion.sophias_house, flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA),
ConnectionData(SVEEntrance.summit_to_highlands, SVERegion.highlands_outside, flag=RandomizationFlag.GINGER_ISLAND),
ConnectionData(SVEEntrance.guild_to_interior, Region.adventurer_guild, flag=RandomizationFlag.BUILDINGS),
ConnectionData(SVEEntrance.backwoods_to_grove, SVERegion.enchanted_grove, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA),
ConnectionData(SVEEntrance.grove_to_outpost_warp, SVERegion.grove_outpost_warp),
ConnectionData(SVEEntrance.outpost_warp_to_outpost, SVERegion.galmoran_outpost, flag=RandomizationFlag.BUILDINGS),
ConnectionData(SVEEntrance.grove_to_wizard_warp, SVERegion.grove_wizard_warp),
ConnectionData(SVEEntrance.wizard_warp_to_wizard, Region.wizard_basement, flag=RandomizationFlag.BUILDINGS),
ConnectionData(SVEEntrance.grove_to_aurora_warp, SVERegion.grove_aurora_warp),
ConnectionData(SVEEntrance.aurora_warp_to_aurora, SVERegion.aurora_vineyard_basement, flag=RandomizationFlag.BUILDINGS),
ConnectionData(SVEEntrance.grove_to_farm_warp, SVERegion.grove_farm_warp),
ConnectionData(SVEEntrance.to_aurora_basement, SVERegion.aurora_vineyard_basement, flag=RandomizationFlag.BUILDINGS),
ConnectionData(SVEEntrance.farm_warp_to_farm, Region.farm),
ConnectionData(SVEEntrance.grove_to_guild_warp, SVERegion.grove_guild_warp),
ConnectionData(SVEEntrance.guild_warp_to_guild, Region.adventurer_guild, flag=RandomizationFlag.BUILDINGS),
ConnectionData(SVEEntrance.grove_to_junimo_warp, SVERegion.grove_junimo_warp),
ConnectionData(SVEEntrance.junimo_warp_to_junimo, SVERegion.junimo_woods, flag=RandomizationFlag.BUILDINGS),
ConnectionData(SVEEntrance.use_purple_junimo, SVERegion.purple_junimo_shop),
ConnectionData(SVEEntrance.grove_to_spring_warp, SVERegion.grove_spring_warp),
ConnectionData(SVEEntrance.spring_warp_to_spring, SVERegion.sprite_spring, flag=RandomizationFlag.BUILDINGS),
ConnectionData(SVEEntrance.wizard_to_fable_reef, SVERegion.fable_reef, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND),
ConnectionData(SVEEntrance.fable_reef_to_guild, SVERegion.first_slash_guild, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND),
ConnectionData(SVEEntrance.outpost_to_badlands_entrance, SVERegion.badlands_entrance, flag=RandomizationFlag.BUILDINGS),
ConnectionData(SVEEntrance.badlands_entrance_to_badlands, SVERegion.crimson_badlands, flag=RandomizationFlag.BUILDINGS),
ConnectionData(SVEEntrance.badlands_to_cave, SVERegion.badlands_cave, flag=RandomizationFlag.BUILDINGS),
ConnectionData(SVEEntrance.guild_to_mines, Region.mines, flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA),
ConnectionData(SVEEntrance.mountain_to_guild_summit, SVERegion.guild_summit),
ConnectionData(SVEEntrance.forest_to_west, SVERegion.forest_west),
ConnectionData(SVEEntrance.secret_woods_to_west, SVERegion.forest_west),
ConnectionData(SVEEntrance.west_to_aurora, SVERegion.aurora_vineyard, flag=RandomizationFlag.NON_PROGRESSION),
ConnectionData(SVEEntrance.forest_to_lost_woods, SVERegion.lost_woods),
ConnectionData(SVEEntrance.lost_woods_to_junimo_woods, SVERegion.junimo_woods),
ConnectionData(SVEEntrance.forest_to_marnie_shed, SVERegion.marnies_shed, flag=RandomizationFlag.NON_PROGRESSION),
ConnectionData(SVEEntrance.forest_west_to_spring, SVERegion.sprite_spring, flag=RandomizationFlag.BUILDINGS),
ConnectionData(SVEEntrance.to_susan_house, SVERegion.susans_house, flag=RandomizationFlag.BUILDINGS),
ConnectionData(SVEEntrance.enter_summit, SVERegion.summit, flag=RandomizationFlag.BUILDINGS),
ConnectionData(SVEEntrance.forest_to_fairhaven, SVERegion.fairhaven_farm, flag=RandomizationFlag.NON_PROGRESSION),
ConnectionData(SVEEntrance.highlands_to_lance, SVERegion.lances_house, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND),
ConnectionData(SVEEntrance.lance_to_ladder, SVERegion.lances_ladder, flag=RandomizationFlag.GINGER_ISLAND),
ConnectionData(SVEEntrance.lance_ladder_to_highlands, SVERegion.highlands_outside, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND),
ConnectionData(SVEEntrance.highlands_to_cave, SVERegion.highlands_cavern, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND),
ConnectionData(SVEEntrance.use_bear_shop, SVERegion.bear_shop),
ConnectionData(SVEEntrance.use_purple_junimo, SVERegion.purple_junimo_shop),
ConnectionData(SVEEntrance.use_alesia_shop, SVERegion.alesia_shop),
ConnectionData(SVEEntrance.use_isaac_shop, SVERegion.isaac_shop),
ConnectionData(SVEEntrance.to_dwarf_prison, SVERegion.dwarf_prison, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND),
ConnectionData(SVEEntrance.railroad_to_grampleton_station, SVERegion.grampleton_station),
ConnectionData(SVEEntrance.grampleton_station_to_grampleton_suburbs, SVERegion.grampleton_suburbs),
ConnectionData(SVEEntrance.grampleton_suburbs_to_scarlett_house, SVERegion.scarlett_house, flag=RandomizationFlag.BUILDINGS),
ConnectionData(SVEEntrance.first_slash_guild_to_hallway, SVERegion.first_slash_hallway, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND),
ConnectionData(SVEEntrance.first_slash_hallway_to_room, SVERegion.first_slash_spare_room, flag=RandomizationFlag.BUILDINGS | RandomizationFlag.GINGER_ISLAND),
ConnectionData(SVEEntrance.sprite_spring_to_cave, SVERegion.sprite_spring_cave, flag=RandomizationFlag.BUILDINGS),
ConnectionData(SVEEntrance.fish_shop_to_willy_bedroom, SVERegion.willy_bedroom, flag=RandomizationFlag.BUILDINGS),
ConnectionData(SVEEntrance.museum_to_gunther_bedroom, SVERegion.gunther_bedroom, flag=RandomizationFlag.BUILDINGS),
]
alecto_regions = [
RegionData(Region.witch_hut, [AlectoEntrance.witch_hut_to_witch_attic]),
RegionData(AlectoRegion.witch_attic)
]
alecto_entrances = [
ConnectionData(AlectoEntrance.witch_hut_to_witch_attic, AlectoRegion.witch_attic, flag=RandomizationFlag.BUILDINGS)
]
lacey_regions = [
RegionData(Region.forest, [LaceyEntrance.forest_to_hat_house]),
RegionData(LaceyRegion.hat_house)
]
lacey_entrances = [
ConnectionData(LaceyEntrance.forest_to_hat_house, LaceyRegion.hat_house, flag=RandomizationFlag.BUILDINGS)
]
boarding_house_regions = [
RegionData(Region.bus_stop, [BoardingHouseEntrance.bus_stop_to_boarding_house_plateau]),
RegionData(BoardingHouseRegion.boarding_house_plateau, [BoardingHouseEntrance.boarding_house_plateau_to_boarding_house_first,
BoardingHouseEntrance.boarding_house_plateau_to_buffalo_ranch,
BoardingHouseEntrance.boarding_house_plateau_to_abandoned_mines_entrance]),
RegionData(BoardingHouseRegion.boarding_house_first, [BoardingHouseEntrance.boarding_house_first_to_boarding_house_second]),
RegionData(BoardingHouseRegion.boarding_house_second),
RegionData(BoardingHouseRegion.buffalo_ranch),
RegionData(BoardingHouseRegion.abandoned_mines_entrance, [BoardingHouseEntrance.abandoned_mines_entrance_to_abandoned_mines_1a,
BoardingHouseEntrance.abandoned_mines_entrance_to_the_lost_valley]),
RegionData(BoardingHouseRegion.abandoned_mines_1a, [BoardingHouseEntrance.abandoned_mines_1a_to_abandoned_mines_1b]),
RegionData(BoardingHouseRegion.abandoned_mines_1b, [BoardingHouseEntrance.abandoned_mines_1b_to_abandoned_mines_2a]),
RegionData(BoardingHouseRegion.abandoned_mines_2a, [BoardingHouseEntrance.abandoned_mines_2a_to_abandoned_mines_2b]),
RegionData(BoardingHouseRegion.abandoned_mines_2b, [BoardingHouseEntrance.abandoned_mines_2b_to_abandoned_mines_3]),
RegionData(BoardingHouseRegion.abandoned_mines_3, [BoardingHouseEntrance.abandoned_mines_3_to_abandoned_mines_4]),
RegionData(BoardingHouseRegion.abandoned_mines_4, [BoardingHouseEntrance.abandoned_mines_4_to_abandoned_mines_5]),
RegionData(BoardingHouseRegion.abandoned_mines_5, [BoardingHouseEntrance.abandoned_mines_5_to_the_lost_valley]),
RegionData(BoardingHouseRegion.the_lost_valley, [BoardingHouseEntrance.the_lost_valley_to_gregory_tent,
BoardingHouseEntrance.lost_valley_to_lost_valley_minecart,
BoardingHouseEntrance.the_lost_valley_to_lost_valley_ruins]),
RegionData(BoardingHouseRegion.gregory_tent),
RegionData(BoardingHouseRegion.lost_valley_ruins, [BoardingHouseEntrance.lost_valley_ruins_to_lost_valley_house_1,
BoardingHouseEntrance.lost_valley_ruins_to_lost_valley_house_2]),
RegionData(BoardingHouseRegion.lost_valley_minecart),
RegionData(BoardingHouseRegion.lost_valley_house_1),
RegionData(BoardingHouseRegion.lost_valley_house_2)
]
boarding_house_entrances = [
ConnectionData(BoardingHouseEntrance.bus_stop_to_boarding_house_plateau, BoardingHouseRegion.boarding_house_plateau),
ConnectionData(BoardingHouseEntrance.boarding_house_plateau_to_boarding_house_first, BoardingHouseRegion.boarding_house_first,
flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA),
ConnectionData(BoardingHouseEntrance.boarding_house_first_to_boarding_house_second, BoardingHouseRegion.boarding_house_second,
flag=RandomizationFlag.BUILDINGS),
ConnectionData(BoardingHouseEntrance.boarding_house_plateau_to_buffalo_ranch, BoardingHouseRegion.buffalo_ranch,
flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA),
ConnectionData(BoardingHouseEntrance.boarding_house_plateau_to_abandoned_mines_entrance, BoardingHouseRegion.abandoned_mines_entrance,
flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA),
ConnectionData(BoardingHouseEntrance.abandoned_mines_entrance_to_the_lost_valley, BoardingHouseRegion.lost_valley_minecart, flag=RandomizationFlag.BUILDINGS),
ConnectionData(BoardingHouseEntrance.abandoned_mines_entrance_to_abandoned_mines_1a, BoardingHouseRegion.abandoned_mines_1a,
flag=RandomizationFlag.BUILDINGS),
ConnectionData(BoardingHouseEntrance.abandoned_mines_1a_to_abandoned_mines_1b, BoardingHouseRegion.abandoned_mines_1b, flag=RandomizationFlag.BUILDINGS),
ConnectionData(BoardingHouseEntrance.abandoned_mines_1b_to_abandoned_mines_2a, BoardingHouseRegion.abandoned_mines_2a, flag=RandomizationFlag.BUILDINGS),
ConnectionData(BoardingHouseEntrance.abandoned_mines_2a_to_abandoned_mines_2b, BoardingHouseRegion.abandoned_mines_2b, flag=RandomizationFlag.BUILDINGS),
ConnectionData(BoardingHouseEntrance.abandoned_mines_2b_to_abandoned_mines_3, BoardingHouseRegion.abandoned_mines_3, flag=RandomizationFlag.BUILDINGS),
ConnectionData(BoardingHouseEntrance.abandoned_mines_3_to_abandoned_mines_4, BoardingHouseRegion.abandoned_mines_4, flag=RandomizationFlag.BUILDINGS),
ConnectionData(BoardingHouseEntrance.abandoned_mines_4_to_abandoned_mines_5, BoardingHouseRegion.abandoned_mines_5, flag=RandomizationFlag.BUILDINGS),
ConnectionData(BoardingHouseEntrance.abandoned_mines_5_to_the_lost_valley, BoardingHouseRegion.the_lost_valley, flag=RandomizationFlag.BUILDINGS),
ConnectionData(BoardingHouseEntrance.the_lost_valley_to_gregory_tent, BoardingHouseRegion.gregory_tent, flag=RandomizationFlag.BUILDINGS),
ConnectionData(BoardingHouseEntrance.lost_valley_to_lost_valley_minecart, BoardingHouseRegion.lost_valley_minecart),
ConnectionData(BoardingHouseEntrance.the_lost_valley_to_lost_valley_ruins, BoardingHouseRegion.lost_valley_ruins, flag=RandomizationFlag.BUILDINGS),
ConnectionData(BoardingHouseEntrance.lost_valley_ruins_to_lost_valley_house_1, BoardingHouseRegion.lost_valley_house_1, flag=RandomizationFlag.BUILDINGS),
ConnectionData(BoardingHouseEntrance.lost_valley_ruins_to_lost_valley_house_2, BoardingHouseRegion.lost_valley_house_2, flag=RandomizationFlag.BUILDINGS)
]
vanilla_connections_to_remove_by_mod: Dict[str, List[ConnectionData]] = {
ModNames.sve: [ConnectionData(Entrance.mountain_to_the_mines, Region.mines,
flag=RandomizationFlag.NON_PROGRESSION | RandomizationFlag.LEAD_TO_OPEN_AREA),
ConnectionData(Entrance.mountain_to_adventurer_guild, Region.adventurer_guild,
flag=RandomizationFlag.BUILDINGS | RandomizationFlag.LEAD_TO_OPEN_AREA),
]
}
ModDataList = {
ModNames.deepwoods: ModRegionData(ModNames.deepwoods, deep_woods_regions, deep_woods_entrances),
ModNames.eugene: ModRegionData(ModNames.eugene, eugene_regions, eugene_entrances),
@@ -141,4 +369,8 @@ ModDataList = {
ModNames.magic: ModRegionData(ModNames.magic, magic_regions, magic_entrances),
ModNames.ayeisha: ModRegionData(ModNames.ayeisha, ayeisha_regions, ayeisha_entrances),
ModNames.riley: ModRegionData(ModNames.riley, riley_regions, riley_entrances),
ModNames.sve: ModRegionData(ModNames.sve, stardew_valley_expanded_regions, mandatory_sve_connections),
ModNames.alecto: ModRegionData(ModNames.alecto, alecto_regions, alecto_entrances),
ModNames.lacey: ModRegionData(ModNames.lacey, lacey_regions, lacey_entrances),
ModNames.boarding_house: ModRegionData(ModNames.boarding_house, boarding_house_regions, boarding_house_entrances),
}