Skip to content

Commit 4dd49a3

Browse files
authored
Merge pull request ArchipelagoMW#9 from agilbert1412/StardewValley/5.x.x-mod-rewrite
Logic Mixins
2 parents 9a1107b + 64a7c26 commit 4dd49a3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1450
-2031
lines changed

worlds/stardew_valley/__init__.py

+8-9
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
from .items import item_table, create_items, ItemData, Group, items_by_group
1010
from .locations import location_table, create_locations, LocationData
1111
from .logic.bundle_logic import BundleLogic
12-
from .logic.cached_logic import function_total_times, function_call_numbers
1312
from .logic.logic import StardewLogic
1413
from .logic.time_logic import MAX_MONTHS
1514
from .options import StardewValleyOptions, SeasonRandomization, Goal, BundleRandomization, BundlePrice, NumberOfLuckBuffs, NumberOfMovementBuffs, \
@@ -230,35 +229,35 @@ def setup_victory(self):
230229
self.create_event_location(location_table[GoalName.greatest_walnut_hunter],
231230
self.logic.has_walnut(130),
232231
Event.victory)
233-
elif self.options.goal == options.Goal.option_protector_of_the_valley:
232+
elif self.options.goal == Goal.option_protector_of_the_valley:
234233
self.create_event_location(location_table[GoalName.protector_of_the_valley],
235234
self.logic.can_complete_all_monster_slaying_goals(),
236235
Event.victory)
237-
elif self.options.goal == options.Goal.option_full_shipment:
236+
elif self.options.goal == Goal.option_full_shipment:
238237
self.create_event_location(location_table[GoalName.full_shipment],
239238
self.logic.shipping.can_ship_everything(),
240239
Event.victory)
241-
elif self.options.goal == options.Goal.option_gourmet_chef:
240+
elif self.options.goal == Goal.option_gourmet_chef:
242241
self.create_event_location(location_table[GoalName.gourmet_chef],
243242
self.logic.cooking.can_cook_everything,
244243
Event.victory)
245-
elif self.options.goal == options.Goal.option_craft_master:
244+
elif self.options.goal == Goal.option_craft_master:
246245
self.create_event_location(location_table[GoalName.craft_master],
247246
self.logic.crafting.can_craft_everything,
248247
Event.victory)
249-
elif self.options.goal == options.Goal.option_legend:
248+
elif self.options.goal == Goal.option_legend:
250249
self.create_event_location(location_table[GoalName.legend],
251250
self.logic.money.can_have_earned_total(10_000_000),
252251
Event.victory)
253-
elif self.options.goal == options.Goal.option_mystery_of_the_stardrops:
252+
elif self.options.goal == Goal.option_mystery_of_the_stardrops:
254253
self.create_event_location(location_table[GoalName.mystery_of_the_stardrops],
255254
self.logic.has_all_stardrops(),
256255
Event.victory)
257-
elif self.options.goal == options.Goal.option_allsanity:
256+
elif self.options.goal == Goal.option_allsanity:
258257
self.create_event_location(location_table[GoalName.allsanity],
259258
CountPercent(self.player, 100),
260259
Event.victory)
261-
elif self.options.goal == options.Goal.option_perfection:
260+
elif self.options.goal == Goal.option_perfection:
262261
self.create_event_location(location_table[GoalName.perfection],
263262
CountPercent(self.player, 100),
264263
Event.victory)

worlds/stardew_valley/bundles.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
from random import Random
22
from typing import List, Dict, Union
33

4-
from .logic.logic import StardewLogic
54
from .data.bundle_data import *
5+
from .logic.logic import StardewLogic
66
from .options import BundleRandomization, BundlePrice
77

88
vanilla_bundles = {
@@ -188,7 +188,7 @@ def shuffle_bundles_completely(random: Random, logic: StardewLogic, bundles: Dic
188188
random.sample(quality_crops_items, 10)
189189
choices = random.sample(all_bundle_items_without_quality_and_money, total_required_item_number - 4)
190190

191-
items_sorted = sorted(choices, key=lambda x: logic.item_rules[x.item.name].get_difficulty())
191+
items_sorted = sorted(choices, key=lambda x: logic.registry.item_rules[x.item.name].get_difficulty())
192192

193193
keys = sorted(bundles.keys())
194194
random.shuffle(keys)
+27-47
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,50 @@
1-
from .cached_logic import profile_rule
2-
from .mine_logic import MineLogic
3-
from .received_logic import ReceivedLogic
4-
from .region_logic import RegionLogic
5-
from .skill_logic import SkillLogic
6-
from .tool_logic import ToolLogic
7-
from ..options import NumberOfMovementBuffs, NumberOfLuckBuffs
8-
from ..mods.logic.magic_logic import MagicLogic
9-
from ..mods.logic.skills_logic import ModSkillLogic
1+
from typing import Union
2+
3+
from .base_logic import BaseLogicMixin, BaseLogic
4+
from .mine_logic import MineLogicMixin
5+
from .received_logic import ReceivedLogicMixin
6+
from .region_logic import RegionLogicMixin
7+
from .skill_logic import SkillLogicMixin
8+
from .tool_logic import ToolLogicMixin
9+
from ..mods.logic.magic_logic import MagicLogicMixin
1010
from ..stardew_rule import StardewRule
1111
from ..strings.ap_names.buff_names import Buff
1212
from ..strings.region_names import Region
1313
from ..strings.skill_names import Skill, ModSkill
1414
from ..strings.tool_names import ToolMaterial, Tool
1515

1616

17-
class AbilityLogic:
18-
player: int
19-
movement_buff_option: NumberOfMovementBuffs
20-
luck_buff_option: NumberOfLuckBuffs
21-
received: ReceivedLogic
22-
region: RegionLogic
23-
tool: ToolLogic
24-
skill: SkillLogic
25-
mine: MineLogic
26-
magic: MagicLogic
27-
mod_skill: ModSkillLogic
17+
class AbilityLogicMixin(BaseLogicMixin):
18+
def __init__(self, *args, **kwargs):
19+
super().__init__(*args, **kwargs)
20+
self.ability = AbilityLogic(*args, **kwargs)
2821

29-
def __init__(self, player: int, movement_buff_option: NumberOfMovementBuffs, luck_buff_option: NumberOfLuckBuffs, received: ReceivedLogic, region: RegionLogic, tool: ToolLogic,
30-
skill: SkillLogic, mine: MineLogic):
31-
self.player = player
32-
self.movement_buff_option = movement_buff_option
33-
self.luck_buff_option = luck_buff_option
34-
self.received = received
35-
self.region = region
36-
self.tool = tool
37-
self.skill = skill
38-
self.mine = mine
39-
40-
def set_magic(self, magic: MagicLogic, mod_skill: ModSkillLogic):
41-
self.magic = magic
42-
self.mod_skill = mod_skill
4322

23+
class AbilityLogic(BaseLogic[Union[AbilityLogicMixin, RegionLogicMixin, ReceivedLogicMixin, ToolLogicMixin, SkillLogicMixin, MineLogicMixin, MagicLogicMixin]]):
4424
def can_mine_perfectly(self) -> StardewRule:
45-
return self.mine.can_progress_in_the_mines_from_floor(160)
25+
return self.logic.mine.can_progress_in_the_mines_from_floor(160)
4626

4727
def can_mine_perfectly_in_the_skull_cavern(self) -> StardewRule:
48-
return (self.can_mine_perfectly() &
49-
self.region.can_reach(Region.skull_cavern))
28+
return (self.logic.ability.can_mine_perfectly() &
29+
self.logic.region.can_reach(Region.skull_cavern))
5030

5131
def can_farm_perfectly(self) -> StardewRule:
52-
tool_rule = self.tool.has_tool(Tool.hoe, ToolMaterial.iridium) & self.tool.can_water(4)
53-
return tool_rule & self.skill.has_farming_level(10)
32+
tool_rule = self.logic.tool.has_tool(Tool.hoe, ToolMaterial.iridium) & self.logic.tool.can_water(4)
33+
return tool_rule & self.logic.skill.has_farming_level(10)
5434

5535
def can_fish_perfectly(self) -> StardewRule:
56-
skill_rule = self.skill.has_level(Skill.fishing, 10)
57-
return skill_rule & self.tool.has_fishing_rod(4)
36+
skill_rule = self.logic.skill.has_level(Skill.fishing, 10)
37+
return skill_rule & self.logic.tool.has_fishing_rod(4)
5838

5939
def can_chop_trees(self) -> StardewRule:
60-
return self.tool.has_tool(Tool.axe) & self.region.can_reach(Region.forest)
40+
return self.logic.tool.has_tool(Tool.axe) & self.logic.region.can_reach(Region.forest)
6141

6242
def can_chop_perfectly(self) -> StardewRule:
63-
magic_rule = (self.magic.can_use_clear_debris_instead_of_tool_level(3)) & self.mod_skill.has_mod_level(ModSkill.magic, 10)
64-
tool_rule = self.tool.has_tool(Tool.axe, ToolMaterial.iridium)
65-
foraging_rule = self.skill.has_level(Skill.foraging, 10)
66-
region_rule = self.region.can_reach(Region.forest)
43+
magic_rule = (self.logic.magic.can_use_clear_debris_instead_of_tool_level(3)) & self.logic.mod.skill.has_mod_level(ModSkill.magic, 10)
44+
tool_rule = self.logic.tool.has_tool(Tool.axe, ToolMaterial.iridium)
45+
foraging_rule = self.logic.skill.has_level(Skill.foraging, 10)
46+
region_rule = self.logic.region.can_reach(Region.forest)
6747
return region_rule & ((tool_rule & foraging_rule) | magic_rule)
6848

6949
def has_max_buffs(self) -> StardewRule:
70-
return self.received(Buff.movement, self.movement_buff_option.value) & self.received(Buff.luck, self.luck_buff_option.value)
50+
return self.logic.received(Buff.movement, self.options.movement_buff_number.value) & self.logic.received(Buff.luck, self.options.luck_buff_number.value)
+18-20
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,40 @@
1+
from typing import Union
2+
13
from Utils import cache_self1
2-
from .cached_logic import CachedLogic
3-
from .has_logic import HasLogic, CachedRules
4-
from .received_logic import ReceivedLogic
5-
from .region_logic import RegionLogic
4+
from .base_logic import BaseLogic, BaseLogicMixin
5+
from .has_logic import HasLogicMixin
6+
from .received_logic import ReceivedLogicMixin
7+
from .region_logic import RegionLogicMixin
68
from ..stardew_rule import StardewRule, True_, Or
79
from ..strings.generic_names import Generic
810
from ..strings.geode_names import Geode
911
from ..strings.region_names import Region
1012

1113

12-
class ActionLogic(CachedLogic):
13-
received: ReceivedLogic
14-
has: HasLogic
15-
region: RegionLogic
14+
class ActionLogicMixin(BaseLogicMixin):
15+
def __init__(self, *args, **kwargs):
16+
super().__init__(*args, **kwargs)
17+
self.action = ActionLogic(*args, **kwargs)
18+
1619

17-
def __init__(self, player: int, cached_rules: CachedRules, received: ReceivedLogic, has: HasLogic,
18-
region: RegionLogic):
19-
super().__init__(player, cached_rules)
20-
self.received = received
21-
self.has = has
22-
self.region = region
20+
class ActionLogic(BaseLogic[Union[ActionLogicMixin, RegionLogicMixin, ReceivedLogicMixin, HasLogicMixin]]):
2321

2422
def can_watch(self, channel: str = None):
2523
tv_rule = True_()
2624
if channel is None:
2725
return tv_rule
28-
return self.received(channel) & tv_rule
26+
return self.logic.received(channel) & tv_rule
2927

3028
def can_pan(self) -> StardewRule:
31-
return self.received("Glittering Boulder Removed") & self.region.can_reach(Region.mountain)
29+
return self.logic.received("Glittering Boulder Removed") & self.logic.region.can_reach(Region.mountain)
3230

3331
def can_pan_at(self, region: str) -> StardewRule:
34-
return self.region.can_reach(region) & self.can_pan()
32+
return self.logic.region.can_reach(region) & self.logic.action.can_pan()
3533

3634
@cache_self1
3735
def can_open_geode(self, geode: str) -> StardewRule:
38-
blacksmith_access = self.region.can_reach(Region.blacksmith)
36+
blacksmith_access = self.logic.region.can_reach(Region.blacksmith)
3937
geodes = [Geode.geode, Geode.frozen, Geode.magma, Geode.omni]
4038
if geode == Generic.any:
41-
return blacksmith_access & Or(*(self.has(geode_type) for geode_type in geodes))
42-
return blacksmith_access & self.has(geode)
39+
return blacksmith_access & Or(*(self.logic.has(geode_type) for geode_type in geodes))
40+
return blacksmith_access & self.logic.has(geode)
+18-20
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,34 @@
1-
from .received_logic import ReceivedLogic
2-
from .region_logic import RegionLogic
1+
from typing import Union
2+
3+
from .base_logic import BaseLogic, BaseLogicMixin
4+
from .received_logic import ReceivedLogicMixin
5+
from .region_logic import RegionLogicMixin
36
from .. import options
4-
from ..options import ArcadeMachineLocations
57
from ..stardew_rule import StardewRule, True_
68
from ..strings.region_names import Region
79

810

9-
class ArcadeLogic:
10-
player: int
11-
arcade_option: ArcadeMachineLocations
12-
received = ReceivedLogic
13-
region: RegionLogic
11+
class ArcadeLogicMixin(BaseLogicMixin):
12+
def __init__(self, *args, **kwargs):
13+
super().__init__(*args, **kwargs)
14+
self.arcade = ArcadeLogic(*args, **kwargs)
15+
1416

15-
def __init__(self, player: int, arcade_option: ArcadeMachineLocations, received: ReceivedLogic, region: RegionLogic):
16-
self.player = player
17-
self.arcade_option = arcade_option
18-
self.received = received
19-
self.region = region
17+
class ArcadeLogic(BaseLogic[Union[ArcadeLogicMixin, RegionLogicMixin, ReceivedLogicMixin]]):
2018

2119
def has_jotpk_power_level(self, power_level: int) -> StardewRule:
22-
if self.arcade_option != options.ArcadeMachineLocations.option_full_shuffling:
20+
if self.options.arcade_machine_locations != options.ArcadeMachineLocations.option_full_shuffling:
2321
return True_()
2422
jotpk_buffs = ("JotPK: Progressive Boots", "JotPK: Progressive Gun", "JotPK: Progressive Ammo", "JotPK: Extra Life", "JotPK: Increased Drop Rate")
25-
return self.received(jotpk_buffs, power_level)
23+
return self.logic.received(jotpk_buffs, power_level)
2624

2725
def has_junimo_kart_power_level(self, power_level: int) -> StardewRule:
28-
if self.arcade_option != options.ArcadeMachineLocations.option_full_shuffling:
26+
if self.options.arcade_machine_locations != options.ArcadeMachineLocations.option_full_shuffling:
2927
return True_()
30-
return self.received("Junimo Kart: Extra Life", power_level)
28+
return self.logic.received("Junimo Kart: Extra Life", power_level)
3129

3230
def has_junimo_kart_max_level(self) -> StardewRule:
33-
play_rule = self.region.can_reach(Region.junimo_kart_3)
34-
if self.arcade_option != options.ArcadeMachineLocations.option_full_shuffling:
31+
play_rule = self.logic.region.can_reach(Region.junimo_kart_3)
32+
if self.options.arcade_machine_locations != options.ArcadeMachineLocations.option_full_shuffling:
3533
return play_rule
36-
return self.has_junimo_kart_power_level(8)
34+
return self.logic.arcade.has_junimo_kart_power_level(8)
+22-24
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,53 @@
11
from typing import Union
22

3-
from .cached_logic import profile_rule
4-
from .has_logic import HasLogic
5-
from .time_logic import TimeLogic
3+
from .base_logic import BaseLogic, BaseLogicMixin
4+
from .has_logic import HasLogicMixin
5+
from .time_logic import TimeLogicMixin
66
from ..stardew_rule import StardewRule
77
from ..strings.crop_names import all_vegetables, all_fruits, Vegetable, Fruit
88
from ..strings.generic_names import Generic
99
from ..strings.machine_names import Machine
1010

1111

12-
class ArtisanLogic:
13-
player: int
14-
has: HasLogic
15-
time: TimeLogic
12+
class ArtisanLogicMixin(BaseLogicMixin):
13+
def __init__(self, *args, **kwargs):
14+
super().__init__(*args, **kwargs)
15+
self.artisan = ArtisanLogic(*args, **kwargs)
1616

17-
def __init__(self, player: int, has: HasLogic, time: TimeLogic):
18-
self.player = player
19-
self.has = has
20-
self.time = time
17+
18+
class ArtisanLogic(BaseLogic[Union[ArtisanLogicMixin, TimeLogicMixin, HasLogicMixin]]):
2119

2220
def has_jelly(self) -> StardewRule:
23-
return self.can_preserves_jar(Fruit.any)
21+
return self.logic.artisan.can_preserves_jar(Fruit.any)
2422

2523
def has_pickle(self) -> StardewRule:
26-
return self.can_preserves_jar(Vegetable.any)
24+
return self.logic.artisan.can_preserves_jar(Vegetable.any)
2725

2826
def can_preserves_jar(self, item: str) -> StardewRule:
29-
machine_rule = self.has(Machine.preserves_jar)
27+
machine_rule = self.logic.has(Machine.preserves_jar)
3028
if item == Generic.any:
3129
return machine_rule
3230
if item == Fruit.any:
33-
return machine_rule & self.has(all_fruits, 1)
31+
return machine_rule & self.logic.has(all_fruits, 1)
3432
if item == Vegetable.any:
35-
return machine_rule & self.has(all_vegetables, 1)
36-
return machine_rule & self.has(item)
33+
return machine_rule & self.logic.has(all_vegetables, 1)
34+
return machine_rule & self.logic.has(item)
3735

3836
def has_wine(self) -> StardewRule:
39-
return self.can_keg(Fruit.any)
37+
return self.logic.artisan.can_keg(Fruit.any)
4038

4139
def has_juice(self) -> StardewRule:
42-
return self.can_keg(Vegetable.any)
40+
return self.logic.artisan.can_keg(Vegetable.any)
4341

4442
def can_keg(self, item: str) -> StardewRule:
45-
machine_rule = self.has(Machine.keg)
43+
machine_rule = self.logic.has(Machine.keg)
4644
if item == Generic.any:
4745
return machine_rule
4846
if item == Fruit.any:
49-
return machine_rule & self.has(all_fruits, 1)
47+
return machine_rule & self.logic.has(all_fruits, 1)
5048
if item == Vegetable.any:
51-
return machine_rule & self.has(all_vegetables, 1)
52-
return machine_rule & self.has(item)
49+
return machine_rule & self.logic.has(all_vegetables, 1)
50+
return machine_rule & self.logic.has(item)
5351

5452
def can_mayonnaise(self, item: str) -> StardewRule:
55-
return self.has(Machine.mayonnaise_machine) & self.has(item)
53+
return self.logic.has(Machine.mayonnaise_machine) & self.logic.has(item)

0 commit comments

Comments
 (0)