TUNIC: Expanded hexagon quest options (#4076)
* More hex quest updates - Implement page ability shuffle for hex quest - Fix keys behind bosses if hex goal is less than 3 - Added check to fix conflicting hex quest options - Add option to slot data * Change option comparison * Change option checking and fix some stuff - also keep prayer first on low hex counts * Update option defaulting * Update option checking * Fix option assignment again * Show player name in option warning * Add new option to universal tracker stuff * Update __init__.py * Make helper method for getting total hexagons in itempool * Update options.py * Update option value passthrough * Change ability shuffle to default on * Check for hexagons option when writing spoiler
This commit is contained in:
		| @@ -11,7 +11,8 @@ from .er_scripts import create_er_regions | ||||
| from .grass import grass_location_table, grass_location_name_to_id, grass_location_name_groups, excluded_grass_locations | ||||
| from .er_data import portal_mapping, RegionInfo, tunic_er_regions | ||||
| from .options import (TunicOptions, EntranceRando, tunic_option_groups, tunic_option_presets, TunicPlandoConnections, | ||||
|                       LaurelsLocation, LogicRules, LaurelsZips, IceGrappling, LadderStorage) | ||||
|                       LaurelsLocation, LogicRules, LaurelsZips, IceGrappling, LadderStorage, check_options, | ||||
|                       get_hexagons_in_pool, HexagonQuestAbilityUnlockType) | ||||
| from .combat_logic import area_data, CombatState | ||||
| from worlds.AutoWorld import WebWorld, World | ||||
| from Options import PlandoConnection, OptionError | ||||
| @@ -109,6 +110,8 @@ class TunicWorld(World): | ||||
|     ut_can_gen_without_yaml = True  # class var that tells it to ignore the player yaml | ||||
|  | ||||
|     def generate_early(self) -> None: | ||||
|         check_options(self) | ||||
|  | ||||
|         if self.options.logic_rules >= LogicRules.option_no_major_glitches: | ||||
|             self.options.laurels_zips.value = LaurelsZips.option_true | ||||
|             self.options.ice_grappling.value = IceGrappling.option_medium | ||||
| @@ -144,6 +147,7 @@ class TunicWorld(World): | ||||
|                 self.options.lanternless.value = self.passthrough["lanternless"] | ||||
|                 self.options.maskless.value = self.passthrough["maskless"] | ||||
|                 self.options.hexagon_quest.value = self.passthrough["hexagon_quest"] | ||||
|                 self.options.hexagon_quest_ability_type.value = self.passthrough.get("hexagon_quest_ability_type", 0) | ||||
|                 self.options.entrance_rando.value = self.passthrough["entrance_rando"] | ||||
|                 self.options.shuffle_ladders.value = self.passthrough["shuffle_ladders"] | ||||
|                 self.options.grass_randomizer.value = self.passthrough.get("grass_randomizer", 0) | ||||
| @@ -261,6 +265,10 @@ class TunicWorld(World): | ||||
|  | ||||
|         items_to_create: Dict[str, int] = {item: data.quantity_in_item_pool for item, data in item_table.items()} | ||||
|  | ||||
|         # Calculate number of hexagons in item pool | ||||
|         if self.options.hexagon_quest: | ||||
|             items_to_create[gold_hexagon] = get_hexagons_in_pool(self) | ||||
|  | ||||
|         for money_fool in fool_tiers[self.options.fool_traps]: | ||||
|             items_to_create["Fool Trap"] += items_to_create[money_fool] | ||||
|             items_to_create[money_fool] = 0 | ||||
| @@ -291,11 +299,21 @@ class TunicWorld(World): | ||||
|             items_to_create["Grass"] -= len(excluded_grass_locations) | ||||
|  | ||||
|         if self.options.keys_behind_bosses: | ||||
|             for rgb_hexagon, location in hexagon_locations.items(): | ||||
|                 hex_item = self.create_item(gold_hexagon if self.options.hexagon_quest else rgb_hexagon) | ||||
|                 self.get_location(location).place_locked_item(hex_item) | ||||
|                 items_to_create[rgb_hexagon] = 0 | ||||
|             items_to_create[gold_hexagon] -= 3 | ||||
|             rgb_hexagons = list(hexagon_locations.keys()) | ||||
|             # shuffle these in case not all are placed in hex quest | ||||
|             self.random.shuffle(rgb_hexagons) | ||||
|             for rgb_hexagon in rgb_hexagons: | ||||
|                 location = hexagon_locations[rgb_hexagon] | ||||
|                 if self.options.hexagon_quest: | ||||
|                     if items_to_create[gold_hexagon] > 0: | ||||
|                         hex_item = self.create_item(gold_hexagon) | ||||
|                         items_to_create[gold_hexagon] -= 1 | ||||
|                         items_to_create[rgb_hexagon] = 0 | ||||
|                         self.get_location(location).place_locked_item(hex_item) | ||||
|                 else: | ||||
|                     hex_item = self.create_item(rgb_hexagon) | ||||
|                     self.get_location(location).place_locked_item(hex_item) | ||||
|                     items_to_create[rgb_hexagon] = 0 | ||||
|  | ||||
|         # Filler items in the item pool | ||||
|         available_filler: List[str] = [filler for filler in items_to_create if items_to_create[filler] > 0 and | ||||
| @@ -323,13 +341,11 @@ class TunicWorld(World): | ||||
|             remove_filler(ladder_count) | ||||
|  | ||||
|         if self.options.hexagon_quest: | ||||
|             # Calculate number of hexagons in item pool | ||||
|             hexagon_goal = self.options.hexagon_goal | ||||
|             extra_hexagons = self.options.extra_hexagon_percentage | ||||
|             items_to_create[gold_hexagon] += int((Decimal(100 + extra_hexagons) / 100 * hexagon_goal).to_integral_value(rounding=ROUND_HALF_UP)) | ||||
|  | ||||
|             # Replace pages and normal hexagons with filler | ||||
|             for replaced_item in list(filter(lambda item: "Pages" in item or item in hexagon_locations, items_to_create)): | ||||
|                 if replaced_item in item_name_groups["Abilities"] and self.options.ability_shuffling \ | ||||
|                         and self.options.hexagon_quest_ability_type == "pages": | ||||
|                     continue | ||||
|                 filler_name = self.get_filler_item_name() | ||||
|                 items_to_create[filler_name] += items_to_create[replaced_item] | ||||
|                 if items_to_create[filler_name] >= 1 and filler_name not in available_filler: | ||||
| @@ -441,7 +457,7 @@ class TunicWorld(World): | ||||
|     def create_regions(self) -> None: | ||||
|         self.tunic_portal_pairs = {} | ||||
|         self.er_portal_hints = {} | ||||
|         self.ability_unlocks = randomize_ability_unlocks(self.random, self.options) | ||||
|         self.ability_unlocks = randomize_ability_unlocks(self) | ||||
|  | ||||
|         # stuff for universal tracker support, can be ignored for standard gen | ||||
|         if self.using_ut: | ||||
| @@ -504,7 +520,8 @@ class TunicWorld(World): | ||||
|         return change | ||||
|  | ||||
|     def write_spoiler_header(self, spoiler_handle: TextIO): | ||||
|         if self.options.hexagon_quest and self.options.ability_shuffling: | ||||
|         if self.options.hexagon_quest and self.options.ability_shuffling\ | ||||
|                 and self.options.hexagon_quest_ability_type == HexagonQuestAbilityUnlockType.option_hexagons: | ||||
|             spoiler_handle.write("\nAbility Unlocks (Hexagon Quest):\n") | ||||
|             for ability in self.ability_unlocks: | ||||
|                 # Remove parentheses for better readability | ||||
| @@ -567,6 +584,7 @@ class TunicWorld(World): | ||||
|             "sword_progression": self.options.sword_progression.value, | ||||
|             "ability_shuffling": self.options.ability_shuffling.value, | ||||
|             "hexagon_quest": self.options.hexagon_quest.value, | ||||
|             "hexagon_quest_ability_type": self.options.hexagon_quest_ability_type.value, | ||||
|             "fool_traps": self.options.fool_traps.value, | ||||
|             "laurels_zips": self.options.laurels_zips.value, | ||||
|             "ice_grappling": self.options.ice_grappling.value, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Silent
					Silent