Stardew Valley: Refactor skill progression to use new feature system (#3662)
* create a first draft of the feature * use feature in items and locations * add content to more places * use feature in logic * replace option check by feature * remove unused code * remove weird white space * some import nitpicking * flip negative if
This commit is contained in:
		| @@ -16,7 +16,7 @@ from ..data.craftable_data import CraftingRecipe, all_crafting_recipes_by_name | ||||
| from ..data.recipe_source import CutsceneSource, ShopTradeSource, ArchipelagoSource, LogicSource, SpecialOrderSource, \ | ||||
|     FestivalShopSource, QuestSource, StarterSource, ShopSource, SkillSource, MasterySource, FriendshipSource, SkillCraftsanitySource | ||||
| from ..locations import locations_by_tag, LocationTags | ||||
| from ..options import Craftsanity, SpecialOrderLocations, ExcludeGingerIsland, SkillProgression | ||||
| from ..options import Craftsanity, SpecialOrderLocations, ExcludeGingerIsland | ||||
| from ..stardew_rule import StardewRule, True_, False_ | ||||
| from ..strings.region_names import Region | ||||
|  | ||||
| @@ -101,12 +101,13 @@ SkillLogicMixin, SpecialOrderLogicMixin, CraftingLogicMixin, QuestLogicMixin]]): | ||||
|         craftsanity_prefix = "Craft " | ||||
|         all_recipes_names = [] | ||||
|         exclude_island = self.options.exclude_ginger_island == ExcludeGingerIsland.option_true | ||||
|         exclude_masteries = self.options.skill_progression != SkillProgression.option_progressive_with_masteries | ||||
|         exclude_masteries = not self.content.features.skill_progression.are_masteries_shuffled | ||||
|         for location in locations_by_tag[LocationTags.CRAFTSANITY]: | ||||
|             if not location.name.startswith(craftsanity_prefix): | ||||
|                 continue | ||||
|             if exclude_island and LocationTags.GINGER_ISLAND in location.tags: | ||||
|                 continue | ||||
|             # FIXME Remove when recipes are in content packs | ||||
|             if exclude_masteries and LocationTags.REQUIRES_MASTERIES in location.tags: | ||||
|                 continue | ||||
|             if location.mod_name and location.mod_name not in self.options.mods: | ||||
|   | ||||
| @@ -7,7 +7,6 @@ from .has_logic import HasLogicMixin | ||||
| from .received_logic import ReceivedLogicMixin | ||||
| from .region_logic import RegionLogicMixin | ||||
| from .time_logic import TimeLogicMixin | ||||
| from ..options import Booksanity | ||||
| from ..stardew_rule import StardewRule, HasProgressionPercent | ||||
| from ..strings.book_names import Book | ||||
| from ..strings.craftable_names import Consumable | ||||
| @@ -39,7 +38,7 @@ class GrindLogic(BaseLogic[Union[GrindLogicMixin, HasLogicMixin, ReceivedLogicMi | ||||
|         opening_rule = self.logic.region.can_reach(Region.blacksmith) | ||||
|         mystery_box_rule = self.logic.has(Consumable.mystery_box) | ||||
|         book_of_mysteries_rule = self.logic.true_ \ | ||||
|             if self.options.booksanity == Booksanity.option_none \ | ||||
|             if not self.content.features.booksanity.is_enabled \ | ||||
|             else self.logic.book.has_book_power(Book.book_of_mysteries) | ||||
|         # Assuming one box per day, but halved because we don't know how many months have passed before Mr. Qi's Plane Ride. | ||||
|         time_rule = self.logic.time.has_lived_months(quantity // 14) | ||||
|   | ||||
| @@ -58,14 +58,19 @@ SkillLogicMixin, CookingLogicMixin]]): | ||||
|         rules = [] | ||||
|         weapon_rule = self.logic.mine.get_weapon_rule_for_floor_tier(tier) | ||||
|         rules.append(weapon_rule) | ||||
|  | ||||
|         if self.options.tool_progression & ToolProgression.option_progressive: | ||||
|             rules.append(self.logic.tool.has_tool(Tool.pickaxe, ToolMaterial.tiers[tier])) | ||||
|         if self.options.skill_progression >= options.SkillProgression.option_progressive: | ||||
|             skill_tier = min(10, max(0, tier * 2)) | ||||
|             rules.append(self.logic.skill.has_level(Skill.combat, skill_tier)) | ||||
|             rules.append(self.logic.skill.has_level(Skill.mining, skill_tier)) | ||||
|  | ||||
|         # No alternative for vanilla because we assume that you will grind the levels in the mines. | ||||
|         if self.content.features.skill_progression.is_progressive: | ||||
|             skill_level = min(10, max(0, tier * 2)) | ||||
|             rules.append(self.logic.skill.has_level(Skill.combat, skill_level)) | ||||
|             rules.append(self.logic.skill.has_level(Skill.mining, skill_level)) | ||||
|  | ||||
|         if tier >= 4: | ||||
|             rules.append(self.logic.cooking.can_cook()) | ||||
|  | ||||
|         return self.logic.and_(*rules) | ||||
|  | ||||
|     @cache_self1 | ||||
| @@ -82,10 +87,14 @@ SkillLogicMixin, CookingLogicMixin]]): | ||||
|         rules = [] | ||||
|         weapon_rule = self.logic.combat.has_great_weapon | ||||
|         rules.append(weapon_rule) | ||||
|  | ||||
|         if self.options.tool_progression & ToolProgression.option_progressive: | ||||
|             rules.append(self.logic.received("Progressive Pickaxe", min(4, max(0, tier + 2)))) | ||||
|         if self.options.skill_progression >= options.SkillProgression.option_progressive: | ||||
|             skill_tier = min(10, max(0, tier * 2 + 6)) | ||||
|             rules.extend({self.logic.skill.has_level(Skill.combat, skill_tier), | ||||
|                           self.logic.skill.has_level(Skill.mining, skill_tier)}) | ||||
|  | ||||
|         # No alternative for vanilla because we assume that you will grind the levels in the mines. | ||||
|         if self.content.features.skill_progression.is_progressive: | ||||
|             skill_level = min(10, max(0, tier * 2 + 6)) | ||||
|             rules.extend((self.logic.skill.has_level(Skill.combat, skill_level), | ||||
|                           self.logic.skill.has_level(Skill.mining, skill_level))) | ||||
|  | ||||
|         return self.logic.and_(*rules) | ||||
|   | ||||
| @@ -11,7 +11,6 @@ from .region_logic import RegionLogicMixin | ||||
| from .season_logic import SeasonLogicMixin | ||||
| from .time_logic import TimeLogicMixin | ||||
| from .tool_logic import ToolLogicMixin | ||||
| from .. import options | ||||
| from ..data.harvest import HarvestCropSource | ||||
| from ..mods.logic.magic_logic import MagicLogicMixin | ||||
| from ..mods.logic.mod_skills_levels import get_mod_skill_levels | ||||
| @@ -77,21 +76,21 @@ CombatLogicMixin, MagicLogicMixin, HarvestingLogicMixin]]): | ||||
|         if level == 0: | ||||
|             return true_ | ||||
|  | ||||
|         if self.options.skill_progression == options.SkillProgression.option_vanilla: | ||||
|             return self.logic.skill.can_earn_level(skill, level) | ||||
|         if self.content.features.skill_progression.is_progressive: | ||||
|             return self.logic.received(f"{skill} Level", level) | ||||
|  | ||||
|         return self.logic.received(f"{skill} Level", level) | ||||
|         return self.logic.skill.can_earn_level(skill, level) | ||||
|  | ||||
|     def has_previous_level(self, skill: str, level: int) -> StardewRule: | ||||
|         assert level > 0, f"There is no level before level 0." | ||||
|         if level == 1: | ||||
|             return true_ | ||||
|  | ||||
|         if self.options.skill_progression == options.SkillProgression.option_vanilla: | ||||
|             months = max(1, level - 1) | ||||
|             return self.logic.time.has_lived_months(months) | ||||
|         if self.content.features.skill_progression.is_progressive: | ||||
|             return self.logic.received(f"{skill} Level", level - 1) | ||||
|  | ||||
|         return self.logic.received(f"{skill} Level", level - 1) | ||||
|         months = max(1, level - 1) | ||||
|         return self.logic.time.has_lived_months(months) | ||||
|  | ||||
|     @cache_self1 | ||||
|     def has_farming_level(self, level: int) -> StardewRule: | ||||
| @@ -102,7 +101,7 @@ CombatLogicMixin, MagicLogicMixin, HarvestingLogicMixin]]): | ||||
|         if level <= 0: | ||||
|             return True_() | ||||
|  | ||||
|         if self.options.skill_progression >= options.SkillProgression.option_progressive: | ||||
|         if self.content.features.skill_progression.is_progressive: | ||||
|             skills_items = vanilla_skill_items | ||||
|             if allow_modded_skills: | ||||
|                 skills_items += get_mod_skill_levels(self.options.mods) | ||||
| @@ -148,7 +147,7 @@ CombatLogicMixin, MagicLogicMixin, HarvestingLogicMixin]]): | ||||
|  | ||||
|     @cached_property | ||||
|     def can_get_fishing_xp(self) -> StardewRule: | ||||
|         if self.options.skill_progression >= options.SkillProgression.option_progressive: | ||||
|         if self.content.features.skill_progression.is_progressive: | ||||
|             return self.logic.skill.can_fish() | self.logic.skill.can_crab_pot | ||||
|  | ||||
|         return self.logic.skill.can_fish() | ||||
| @@ -178,7 +177,9 @@ CombatLogicMixin, MagicLogicMixin, HarvestingLogicMixin]]): | ||||
|     @cached_property | ||||
|     def can_crab_pot(self) -> StardewRule: | ||||
|         crab_pot_rule = self.logic.has(Fishing.bait) | ||||
|         if self.options.skill_progression >= options.SkillProgression.option_progressive: | ||||
|  | ||||
|         # We can't use the same rule if skills are vanilla, because fishing levels are required to crab pot, which is required to get fishing levels... | ||||
|         if self.content.features.skill_progression.is_progressive: | ||||
|             crab_pot_rule = crab_pot_rule & self.logic.has(Machine.crab_pot) | ||||
|         else: | ||||
|             crab_pot_rule = crab_pot_rule & self.logic.skill.can_get_fishing_xp | ||||
| @@ -200,14 +201,14 @@ CombatLogicMixin, MagicLogicMixin, HarvestingLogicMixin]]): | ||||
|         return self.logic.skill.can_earn_level(skill, 11) & self.logic.region.can_reach(Region.mastery_cave) | ||||
|  | ||||
|     def has_mastery(self, skill: str) -> StardewRule: | ||||
|         if self.options.skill_progression == options.SkillProgression.option_progressive_with_masteries: | ||||
|         if self.content.features.skill_progression.are_masteries_shuffled: | ||||
|             return self.logic.received(f"{skill} Mastery") | ||||
|  | ||||
|         return self.logic.skill.can_earn_mastery(skill) | ||||
|  | ||||
|     @cached_property | ||||
|     def can_enter_mastery_cave(self) -> StardewRule: | ||||
|         if self.options.skill_progression == options.SkillProgression.option_progressive_with_masteries: | ||||
|         if self.content.features.skill_progression.are_masteries_shuffled: | ||||
|             return self.logic.received(Wallet.mastery_of_the_five_ways) | ||||
|  | ||||
|         return self.has_any_skills_maxed(included_modded_skills=False) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Jouramie
					Jouramie