2025-05-07 10:59:16 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								from dataclasses import fields
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-24 16:55:49 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								from typing import Dict, List, Any, Tuple, TypedDict, ClassVar, Union, Set, TextIO
							 | 
						
					
						
							
								
									
										
										
										
											2024-04-13 18:20:52 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								from logging import warning
							 | 
						
					
						
							
								
									
										
										
										
											2024-12-15 16:40:36 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								from BaseClasses import Region, Location, Item, Tutorial, ItemClassification, MultiWorld, CollectionState
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								from .items import (item_name_to_id, item_table, item_name_groups, fool_tiers, filler_items, slot_data_item_names,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    combat_items)
							 | 
						
					
						
							
								
									
										
										
										
											2025-04-21 17:41:20 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								from .locations import location_table, location_name_groups, standard_location_name_to_id, hexagon_locations
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								from .rules import set_location_rules, set_region_rules, randomize_ability_unlocks, gold_hexagon
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								from .er_rules import set_er_location_rules
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								from .regions import tunic_regions
							 | 
						
					
						
							
								
									
										
											 
										 
										
											
												TUNIC: Entrance rando Direction Pairs + Decoupled (#3761)
* Fix merge conflict
* Fix formatting, fix rule for heir access after merge
* Writing combat logic helpers
* More helpers!
* More logic!
* Rename has_stick to has_melee, some fixes per Medic's review
* Clamp max power from sword upgrades
* Wrote the rest of the helpers
* Remove unused import
* Apply item classifications
* Create the combat logic option
* Item classification varies based on option
* Add the shop sword logic stuff in
* Add the rules for the boss-only option
* Fix tiny issues
* Some early Overworld combat logic
* Fill out swamp combat logic
* Add note
* Bump up Boss Scav and Heir
* More revisions to combat logic
* Some changes, currently broken
* New system for power, kinda jank probably
* Revisions to new system, needs more balancing
* Cap attack upgrades
* Uncap mp power since it's directly related to damage output
* Voidlings
* Put together a table showing the vanilla-expected stats for each area
* Added some info on potion counts
* Made new helper functions
* Make has_required_stats
* Make has_combat_reqs
* Update er_rules for new combat reqs
* Fix all the broken things ever
* Remove outdated todo
* Make temp option for testing logic
* More flexible choices for combat items
* Hard require sword for bosses
* Temporarily default combat logic to on
* Finish writing overworld combat logic
* East Forest combat logic done
* Remove a few easy ones
* Finish beneath the well
* Dark Tomb combat logic
* West Garden combat logic
* make unit tests checkmark again
* Weird west garden dagger house edge case
* Try block for that weird west garden edge case
* Add quarry combat logic
* Update to filter out unreachable regions outside of ER
* Fortress Grave Path logic, and a couple fixes to the west garden logic
* Fortress east shortcut logic, and rewriting the try except blocks to use finally
* Refactor to use a new function cause wow there was a lot of repeated code
* Add combat logic to the other two sets of fortress fuses
* Add combat rules to beneath the vault
* Fix missing cathedral -> elevator connection
* Combat logic for cathedral to elevator
* Add cathedral main region, rename cathedral -> cathedral entry
* Setup cathedral combat logic
* Adjust locations' regions for ER
* Add laurels zip logic to the chest in the spike room in cathedral
* Add combat logic to frog's domain
* Move frog's domain locations to regions for combat logic
* Add new frog's domain regions for combat logic
* Update region name for frog's domain
* Fix typo
* Add more regions for lower zig
* Move around lower zig regions for combat logic
* Lower Zig combat logic
* Upper zig combat logic
* Fix typo
* Fix typos
* Fix missing world.
* Update combat logic description
* Add todo
* Add todo
* Don't make zig skip if er or fixed shop is off
* Make it so zig skip is only made with fewer shops and er
* Temporarily default combat logic on
* Update test to explicitly disable combat logic
* Update test_access.py
* Slight wording changes
* Fix bugs, refactor quarry regions so you can access chests in lower quarry with ice grapples
* Run through checks you can do with magic dagger
* Run through checks you can do with magic dagger
* Add rule for entering town portal of having equipment to deal with enemies
* Add rule for atoll near the 6 crabs surrounding a poor defenseless baby slorm
* Update the rule for the chest near the 6 crabs surrounding a slorm to also possibly require laurels
* Revamp combat logic function to work properly without melee
* Add laurels rules to combat logic chests
* Modify beneath the vault bridge rule to need a lantern if combat logic is on
* Put in money logic
* Dagger or combat for swamp big skeleton chest
* Remove the 100 moneys from logic
* Modify lower zig ls drop region destinations
* Remove completed todo
* Reword combat logic option description, remove test option
* Add combat logic to slot data
* Merge Silent's missing slot data bugfix PR #3628
* Remove test combat option
* Update combat logic description
* Fix secret gathering place issue
* Fix secret gathering place issue
* Fix lower zig ls rule
* Fix accidentally removed librarian rule
* Remove redundant rule
* Update gauntlet rule to hard-require a sword
* Add test for a problematic connection
* Adjust combat logic to deal with weird edge cases so it doesn't take stuff out of logic that was previously in logic
* Fix create_item classification
* Update some comments
* Update per exempt's suggestion
* Add combat logic to the well boss fight, reorder the combat logic stuff a little to better section them off
* Add EntranceLayout option
* Add back LogicRules as an invisible option, to not break old yamls
* Fix a bug with seed group, continue changing fixed shop to entrance layout
* Fix missed fixed shop -> entrance layout spot
* Fix bug in seed groups with fixed shop on and off
* Add entrance layout to the UT regen stuff
* Put direction. in, will add them later
* Remove unused elevation from portal class
* Got like half of them in
* Finish adding all of the directions
* Add combat rule for zig front to back
* Update per Medic's suggestion
* Update ladder storage without items option description
* Mess with state with collect and remove to save like 2 seconds (never again)
* Save even more time, still never going to do this again on anything else
* Add option check for collect and remove
* Add directions to shop portals
* Update direction in Portal with default
* Move Direction above Portal
* Add decoupled option, mess with plando connection stuff
* Merge, implement verify plando directions
* Condense the stuff in change and remove to less lines (thanks medic)
* Remove unused thing
* Swap to using logicmixin instead of prog_items (thanks Vi)
* Fix consistency in stat counters
* Add back something that was needed
* Fix mistake when adding back
* Making the fix better (thanks medic)
* Make it actually return false if it gets to the backup lists and fails them
* Fix stuff after merge
* Add outlet regions, create new regions as needed for them
* Put together part of decoupled and direction pairs
* make direction pairs work
* Make decoupled work
* Make fixed shop work again
* Fix a few minor bugs
* Fix a few minor bugs
* Fix plando
* god i love programming
* Reorder portal list
* Update portal sorter for variable shops
* Add missing parameter
* Some cleanup of prints and functions
* Fix typo
* it's aliiiiiive
* Make seed groups not sync decoupled
* Add test with full-shop plando
* Fix bug with vanilla portals
* Handle plando connections and direction pair errors
* Update plando checking for decoupled
* Fix typo
* Fix exception text to be shorter
* Add some more comments
* Add todo note
* Remove unused safety thing
* Remove extra plando connections definition in options
* Make seed groups in decoupled with overlapping but not fully overlapped plando connections interact nicely without messing with what the entrances look like in the spoiler log
* Fix weird edge case that is technically user error
* Add note to fixed shop
* Fix parsing shop names in UT
* Remove debug print
* Actually make UT work
* multiworld. to world.
* Fix typo from merge
* Make it so the shops show up in the entrance hints
* Fix bug in ladder storage rules
* Remove blank line
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
#	worlds/tunic/rules.py
#	worlds/tunic/test/test_access.py
* Fix issues after merge
* Update plando connections stuff in docs
* Fix library mistake
* has_stick -> has_melee
* has_stick -> has_melee
* Add a failsafe for direction pairing
* Fix playthrough crash bug
* Remove init from logicmixin
* Updates per code review (thanks hesto)
* has_stick to has_melee in newer update
* has_stick to has_melee in newer update
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/combat_logic.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
* Cleanup more stuff after merge
* Revert "Cleanup more stuff after merge"
This reverts commit a6ee9a93da8f2fcc4413de6df6927b246017889d.
* Revert "# Conflicts:"
This reverts commit c74ccd74a45b6ad6b9abe6e339d115a0c98baf30.
* Cleanup more stuff after merge
* Swap to .get for decoupled so it works with older games probably maybe
* Fix after merge
* Fix typo
* Fix UT support with fixed shop option
* Backport plando connections fix
* Fix issue with fixed shop + decoupled
* Make the error not duplicate the while loop condition
* Fix rule for quarry back to monastery
* Fix more stuff after merge
* Make it not output anything if you set plando connections but not ER
* Add obvious note to plando connections description
* Fix after merge
* add comment to commented out connection
---------
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
											
										 
										
											2025-05-06 12:33:21 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								from .er_scripts import create_er_regions, verify_plando_directions
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-15 18:17:07 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								from .grass import grass_location_table, grass_location_name_to_id, grass_location_name_groups, excluded_grass_locations
							 | 
						
					
						
							
								
									
										
										
										
											2024-09-08 08:42:59 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								from .er_data import portal_mapping, RegionInfo, tunic_er_regions
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								from .options import (TunicOptions, EntranceRando, tunic_option_groups, tunic_option_presets, TunicPlandoConnections,
							 | 
						
					
						
							
								
									
										
										
										
											2025-03-07 19:43:02 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                      LaurelsLocation, LogicRules, LaurelsZips, IceGrappling, LadderStorage, check_options,
							 | 
						
					
						
							
								
									
										
											 
										 
										
											
												TUNIC: Entrance rando Direction Pairs + Decoupled (#3761)
* Fix merge conflict
* Fix formatting, fix rule for heir access after merge
* Writing combat logic helpers
* More helpers!
* More logic!
* Rename has_stick to has_melee, some fixes per Medic's review
* Clamp max power from sword upgrades
* Wrote the rest of the helpers
* Remove unused import
* Apply item classifications
* Create the combat logic option
* Item classification varies based on option
* Add the shop sword logic stuff in
* Add the rules for the boss-only option
* Fix tiny issues
* Some early Overworld combat logic
* Fill out swamp combat logic
* Add note
* Bump up Boss Scav and Heir
* More revisions to combat logic
* Some changes, currently broken
* New system for power, kinda jank probably
* Revisions to new system, needs more balancing
* Cap attack upgrades
* Uncap mp power since it's directly related to damage output
* Voidlings
* Put together a table showing the vanilla-expected stats for each area
* Added some info on potion counts
* Made new helper functions
* Make has_required_stats
* Make has_combat_reqs
* Update er_rules for new combat reqs
* Fix all the broken things ever
* Remove outdated todo
* Make temp option for testing logic
* More flexible choices for combat items
* Hard require sword for bosses
* Temporarily default combat logic to on
* Finish writing overworld combat logic
* East Forest combat logic done
* Remove a few easy ones
* Finish beneath the well
* Dark Tomb combat logic
* West Garden combat logic
* make unit tests checkmark again
* Weird west garden dagger house edge case
* Try block for that weird west garden edge case
* Add quarry combat logic
* Update to filter out unreachable regions outside of ER
* Fortress Grave Path logic, and a couple fixes to the west garden logic
* Fortress east shortcut logic, and rewriting the try except blocks to use finally
* Refactor to use a new function cause wow there was a lot of repeated code
* Add combat logic to the other two sets of fortress fuses
* Add combat rules to beneath the vault
* Fix missing cathedral -> elevator connection
* Combat logic for cathedral to elevator
* Add cathedral main region, rename cathedral -> cathedral entry
* Setup cathedral combat logic
* Adjust locations' regions for ER
* Add laurels zip logic to the chest in the spike room in cathedral
* Add combat logic to frog's domain
* Move frog's domain locations to regions for combat logic
* Add new frog's domain regions for combat logic
* Update region name for frog's domain
* Fix typo
* Add more regions for lower zig
* Move around lower zig regions for combat logic
* Lower Zig combat logic
* Upper zig combat logic
* Fix typo
* Fix typos
* Fix missing world.
* Update combat logic description
* Add todo
* Add todo
* Don't make zig skip if er or fixed shop is off
* Make it so zig skip is only made with fewer shops and er
* Temporarily default combat logic on
* Update test to explicitly disable combat logic
* Update test_access.py
* Slight wording changes
* Fix bugs, refactor quarry regions so you can access chests in lower quarry with ice grapples
* Run through checks you can do with magic dagger
* Run through checks you can do with magic dagger
* Add rule for entering town portal of having equipment to deal with enemies
* Add rule for atoll near the 6 crabs surrounding a poor defenseless baby slorm
* Update the rule for the chest near the 6 crabs surrounding a slorm to also possibly require laurels
* Revamp combat logic function to work properly without melee
* Add laurels rules to combat logic chests
* Modify beneath the vault bridge rule to need a lantern if combat logic is on
* Put in money logic
* Dagger or combat for swamp big skeleton chest
* Remove the 100 moneys from logic
* Modify lower zig ls drop region destinations
* Remove completed todo
* Reword combat logic option description, remove test option
* Add combat logic to slot data
* Merge Silent's missing slot data bugfix PR #3628
* Remove test combat option
* Update combat logic description
* Fix secret gathering place issue
* Fix secret gathering place issue
* Fix lower zig ls rule
* Fix accidentally removed librarian rule
* Remove redundant rule
* Update gauntlet rule to hard-require a sword
* Add test for a problematic connection
* Adjust combat logic to deal with weird edge cases so it doesn't take stuff out of logic that was previously in logic
* Fix create_item classification
* Update some comments
* Update per exempt's suggestion
* Add combat logic to the well boss fight, reorder the combat logic stuff a little to better section them off
* Add EntranceLayout option
* Add back LogicRules as an invisible option, to not break old yamls
* Fix a bug with seed group, continue changing fixed shop to entrance layout
* Fix missed fixed shop -> entrance layout spot
* Fix bug in seed groups with fixed shop on and off
* Add entrance layout to the UT regen stuff
* Put direction. in, will add them later
* Remove unused elevation from portal class
* Got like half of them in
* Finish adding all of the directions
* Add combat rule for zig front to back
* Update per Medic's suggestion
* Update ladder storage without items option description
* Mess with state with collect and remove to save like 2 seconds (never again)
* Save even more time, still never going to do this again on anything else
* Add option check for collect and remove
* Add directions to shop portals
* Update direction in Portal with default
* Move Direction above Portal
* Add decoupled option, mess with plando connection stuff
* Merge, implement verify plando directions
* Condense the stuff in change and remove to less lines (thanks medic)
* Remove unused thing
* Swap to using logicmixin instead of prog_items (thanks Vi)
* Fix consistency in stat counters
* Add back something that was needed
* Fix mistake when adding back
* Making the fix better (thanks medic)
* Make it actually return false if it gets to the backup lists and fails them
* Fix stuff after merge
* Add outlet regions, create new regions as needed for them
* Put together part of decoupled and direction pairs
* make direction pairs work
* Make decoupled work
* Make fixed shop work again
* Fix a few minor bugs
* Fix a few minor bugs
* Fix plando
* god i love programming
* Reorder portal list
* Update portal sorter for variable shops
* Add missing parameter
* Some cleanup of prints and functions
* Fix typo
* it's aliiiiiive
* Make seed groups not sync decoupled
* Add test with full-shop plando
* Fix bug with vanilla portals
* Handle plando connections and direction pair errors
* Update plando checking for decoupled
* Fix typo
* Fix exception text to be shorter
* Add some more comments
* Add todo note
* Remove unused safety thing
* Remove extra plando connections definition in options
* Make seed groups in decoupled with overlapping but not fully overlapped plando connections interact nicely without messing with what the entrances look like in the spoiler log
* Fix weird edge case that is technically user error
* Add note to fixed shop
* Fix parsing shop names in UT
* Remove debug print
* Actually make UT work
* multiworld. to world.
* Fix typo from merge
* Make it so the shops show up in the entrance hints
* Fix bug in ladder storage rules
* Remove blank line
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
#	worlds/tunic/rules.py
#	worlds/tunic/test/test_access.py
* Fix issues after merge
* Update plando connections stuff in docs
* Fix library mistake
* has_stick -> has_melee
* has_stick -> has_melee
* Add a failsafe for direction pairing
* Fix playthrough crash bug
* Remove init from logicmixin
* Updates per code review (thanks hesto)
* has_stick to has_melee in newer update
* has_stick to has_melee in newer update
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/combat_logic.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
* Cleanup more stuff after merge
* Revert "Cleanup more stuff after merge"
This reverts commit a6ee9a93da8f2fcc4413de6df6927b246017889d.
* Revert "# Conflicts:"
This reverts commit c74ccd74a45b6ad6b9abe6e339d115a0c98baf30.
* Cleanup more stuff after merge
* Swap to .get for decoupled so it works with older games probably maybe
* Fix after merge
* Fix typo
* Fix UT support with fixed shop option
* Backport plando connections fix
* Fix issue with fixed shop + decoupled
* Make the error not duplicate the while loop condition
* Fix rule for quarry back to monastery
* Fix more stuff after merge
* Make it not output anything if you set plando connections but not ER
* Add obvious note to plando connections description
* Fix after merge
* add comment to commented out connection
---------
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
											
										 
										
											2025-05-06 12:33:21 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                      get_hexagons_in_pool, HexagonQuestAbilityUnlockType, EntranceLayout)
							 | 
						
					
						
							
								
									
										
										
										
											2025-03-08 11:25:47 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								from .breakables import breakable_location_name_to_id, breakable_location_groups, breakable_location_table
							 | 
						
					
						
							
								
									
										
										
										
											2024-12-15 16:40:36 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								from .combat_logic import area_data, CombatState
							 | 
						
					
						
							
								
									
										
										
										
											2025-05-22 09:24:50 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								from . import ut_stuff
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								from worlds.AutoWorld import WebWorld, World
							 | 
						
					
						
							
								
									
										
										
										
											2025-05-07 10:59:16 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								from Options import PlandoConnection, OptionError, PerGameCommonOptions, Removed, Range
							 | 
						
					
						
							
								
									
										
										
										
											2025-05-22 09:24:50 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								from settings import Group, Bool, FilePath
							 | 
						
					
						
							
								
									
										
										
										
											2024-07-23 03:04:24 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								class TunicSettings(Group):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    class DisableLocalSpoiler(Bool):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        """Disallows the TUNIC client from creating a local spoiler log."""
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-15 18:17:07 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    class LimitGrassRando(Bool):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        """Limits the impact of Grass Randomizer on the multiworld by disallowing local_fill percentages below 95."""
							 | 
						
					
						
							
								
									
										
										
										
											2025-05-22 09:24:50 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    class UTPoptrackerPath(FilePath):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        """Path to the user's TUNIC Poptracker Pack."""
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        description = "TUNIC Poptracker Pack zip file"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        required = False
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-15 18:17:07 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-07-23 03:04:24 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    disable_local_spoiler: Union[DisableLocalSpoiler, bool] = False
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-15 18:17:07 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    limit_grass_rando: Union[LimitGrassRando, bool] = True
							 | 
						
					
						
							
								
									
										
										
										
											2025-05-22 09:24:50 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    ut_poptracker_path: Union[UTPoptrackerPath, str] = UTPoptrackerPath()
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								class TunicWeb(WebWorld):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    tutorials = [
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        Tutorial(
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            tutorial_name="Multiworld Setup Guide",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            description="A guide to setting up the TUNIC Randomizer for Archipelago multiworld games.",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            language="English",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            file_name="setup_en.md",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            link="setup/en",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            authors=["SilentDestroyer"]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        )
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    ]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    theme = "grassFlowers"
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-17 19:56:34 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    game = "TUNIC"
							 | 
						
					
						
							
								
									
										
										
										
											2024-05-21 18:12:52 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    option_groups = tunic_option_groups
							 | 
						
					
						
							
								
									
										
										
										
											2024-05-22 20:12:59 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    options_presets = tunic_option_presets
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								class TunicItem(Item):
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-17 19:56:34 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    game: str = "TUNIC"
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								class TunicLocation(Location):
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-17 19:56:34 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    game: str = "TUNIC"
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-05-03 01:21:27 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								class SeedGroup(TypedDict):
							 | 
						
					
						
							
								
									
										
										
										
											2024-09-08 08:42:59 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    laurels_zips: bool  # laurels_zips value
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    ice_grappling: int  # ice_grappling value
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    ladder_storage: int  # ls value
							 | 
						
					
						
							
								
									
										
										
										
											2024-05-03 01:21:27 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    laurels_at_10_fairies: bool  # laurels location value
							 | 
						
					
						
							
								
									
										
											 
										 
										
											
												TUNIC: Entrance rando Direction Pairs + Decoupled (#3761)
* Fix merge conflict
* Fix formatting, fix rule for heir access after merge
* Writing combat logic helpers
* More helpers!
* More logic!
* Rename has_stick to has_melee, some fixes per Medic's review
* Clamp max power from sword upgrades
* Wrote the rest of the helpers
* Remove unused import
* Apply item classifications
* Create the combat logic option
* Item classification varies based on option
* Add the shop sword logic stuff in
* Add the rules for the boss-only option
* Fix tiny issues
* Some early Overworld combat logic
* Fill out swamp combat logic
* Add note
* Bump up Boss Scav and Heir
* More revisions to combat logic
* Some changes, currently broken
* New system for power, kinda jank probably
* Revisions to new system, needs more balancing
* Cap attack upgrades
* Uncap mp power since it's directly related to damage output
* Voidlings
* Put together a table showing the vanilla-expected stats for each area
* Added some info on potion counts
* Made new helper functions
* Make has_required_stats
* Make has_combat_reqs
* Update er_rules for new combat reqs
* Fix all the broken things ever
* Remove outdated todo
* Make temp option for testing logic
* More flexible choices for combat items
* Hard require sword for bosses
* Temporarily default combat logic to on
* Finish writing overworld combat logic
* East Forest combat logic done
* Remove a few easy ones
* Finish beneath the well
* Dark Tomb combat logic
* West Garden combat logic
* make unit tests checkmark again
* Weird west garden dagger house edge case
* Try block for that weird west garden edge case
* Add quarry combat logic
* Update to filter out unreachable regions outside of ER
* Fortress Grave Path logic, and a couple fixes to the west garden logic
* Fortress east shortcut logic, and rewriting the try except blocks to use finally
* Refactor to use a new function cause wow there was a lot of repeated code
* Add combat logic to the other two sets of fortress fuses
* Add combat rules to beneath the vault
* Fix missing cathedral -> elevator connection
* Combat logic for cathedral to elevator
* Add cathedral main region, rename cathedral -> cathedral entry
* Setup cathedral combat logic
* Adjust locations' regions for ER
* Add laurels zip logic to the chest in the spike room in cathedral
* Add combat logic to frog's domain
* Move frog's domain locations to regions for combat logic
* Add new frog's domain regions for combat logic
* Update region name for frog's domain
* Fix typo
* Add more regions for lower zig
* Move around lower zig regions for combat logic
* Lower Zig combat logic
* Upper zig combat logic
* Fix typo
* Fix typos
* Fix missing world.
* Update combat logic description
* Add todo
* Add todo
* Don't make zig skip if er or fixed shop is off
* Make it so zig skip is only made with fewer shops and er
* Temporarily default combat logic on
* Update test to explicitly disable combat logic
* Update test_access.py
* Slight wording changes
* Fix bugs, refactor quarry regions so you can access chests in lower quarry with ice grapples
* Run through checks you can do with magic dagger
* Run through checks you can do with magic dagger
* Add rule for entering town portal of having equipment to deal with enemies
* Add rule for atoll near the 6 crabs surrounding a poor defenseless baby slorm
* Update the rule for the chest near the 6 crabs surrounding a slorm to also possibly require laurels
* Revamp combat logic function to work properly without melee
* Add laurels rules to combat logic chests
* Modify beneath the vault bridge rule to need a lantern if combat logic is on
* Put in money logic
* Dagger or combat for swamp big skeleton chest
* Remove the 100 moneys from logic
* Modify lower zig ls drop region destinations
* Remove completed todo
* Reword combat logic option description, remove test option
* Add combat logic to slot data
* Merge Silent's missing slot data bugfix PR #3628
* Remove test combat option
* Update combat logic description
* Fix secret gathering place issue
* Fix secret gathering place issue
* Fix lower zig ls rule
* Fix accidentally removed librarian rule
* Remove redundant rule
* Update gauntlet rule to hard-require a sword
* Add test for a problematic connection
* Adjust combat logic to deal with weird edge cases so it doesn't take stuff out of logic that was previously in logic
* Fix create_item classification
* Update some comments
* Update per exempt's suggestion
* Add combat logic to the well boss fight, reorder the combat logic stuff a little to better section them off
* Add EntranceLayout option
* Add back LogicRules as an invisible option, to not break old yamls
* Fix a bug with seed group, continue changing fixed shop to entrance layout
* Fix missed fixed shop -> entrance layout spot
* Fix bug in seed groups with fixed shop on and off
* Add entrance layout to the UT regen stuff
* Put direction. in, will add them later
* Remove unused elevation from portal class
* Got like half of them in
* Finish adding all of the directions
* Add combat rule for zig front to back
* Update per Medic's suggestion
* Update ladder storage without items option description
* Mess with state with collect and remove to save like 2 seconds (never again)
* Save even more time, still never going to do this again on anything else
* Add option check for collect and remove
* Add directions to shop portals
* Update direction in Portal with default
* Move Direction above Portal
* Add decoupled option, mess with plando connection stuff
* Merge, implement verify plando directions
* Condense the stuff in change and remove to less lines (thanks medic)
* Remove unused thing
* Swap to using logicmixin instead of prog_items (thanks Vi)
* Fix consistency in stat counters
* Add back something that was needed
* Fix mistake when adding back
* Making the fix better (thanks medic)
* Make it actually return false if it gets to the backup lists and fails them
* Fix stuff after merge
* Add outlet regions, create new regions as needed for them
* Put together part of decoupled and direction pairs
* make direction pairs work
* Make decoupled work
* Make fixed shop work again
* Fix a few minor bugs
* Fix a few minor bugs
* Fix plando
* god i love programming
* Reorder portal list
* Update portal sorter for variable shops
* Add missing parameter
* Some cleanup of prints and functions
* Fix typo
* it's aliiiiiive
* Make seed groups not sync decoupled
* Add test with full-shop plando
* Fix bug with vanilla portals
* Handle plando connections and direction pair errors
* Update plando checking for decoupled
* Fix typo
* Fix exception text to be shorter
* Add some more comments
* Add todo note
* Remove unused safety thing
* Remove extra plando connections definition in options
* Make seed groups in decoupled with overlapping but not fully overlapped plando connections interact nicely without messing with what the entrances look like in the spoiler log
* Fix weird edge case that is technically user error
* Add note to fixed shop
* Fix parsing shop names in UT
* Remove debug print
* Actually make UT work
* multiworld. to world.
* Fix typo from merge
* Make it so the shops show up in the entrance hints
* Fix bug in ladder storage rules
* Remove blank line
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
#	worlds/tunic/rules.py
#	worlds/tunic/test/test_access.py
* Fix issues after merge
* Update plando connections stuff in docs
* Fix library mistake
* has_stick -> has_melee
* has_stick -> has_melee
* Add a failsafe for direction pairing
* Fix playthrough crash bug
* Remove init from logicmixin
* Updates per code review (thanks hesto)
* has_stick to has_melee in newer update
* has_stick to has_melee in newer update
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/combat_logic.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
* Cleanup more stuff after merge
* Revert "Cleanup more stuff after merge"
This reverts commit a6ee9a93da8f2fcc4413de6df6927b246017889d.
* Revert "# Conflicts:"
This reverts commit c74ccd74a45b6ad6b9abe6e339d115a0c98baf30.
* Cleanup more stuff after merge
* Swap to .get for decoupled so it works with older games probably maybe
* Fix after merge
* Fix typo
* Fix UT support with fixed shop option
* Backport plando connections fix
* Fix issue with fixed shop + decoupled
* Make the error not duplicate the while loop condition
* Fix rule for quarry back to monastery
* Fix more stuff after merge
* Make it not output anything if you set plando connections but not ER
* Add obvious note to plando connections description
* Fix after merge
* add comment to commented out connection
---------
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
											
										 
										
											2025-05-06 12:33:21 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    entrance_layout: int  # entrance layout value
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    has_decoupled_enabled: bool  # for checking that players don't have conflicting options
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    plando: List[PlandoConnection]  # consolidated plando connections for the seed group
							 | 
						
					
						
							
								
									
										
										
										
											2024-05-03 01:21:27 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								class TunicWorld(World):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    """
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    Explore a land filled with lost legends, ancient powers, and ferocious monsters in TUNIC, an isometric action game
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    about a small fox on a big adventure. Stranded on a mysterious beach, armed with only your own curiosity, you will
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    confront colossal beasts, collect strange and powerful items, and unravel long-lost secrets. Be brave, tiny fox!
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    """
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-17 19:56:34 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    game = "TUNIC"
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    web = TunicWeb()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    options: TunicOptions
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    options_dataclass = TunicOptions
							 | 
						
					
						
							
								
									
										
										
										
											2024-07-23 03:04:24 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    settings: ClassVar[TunicSettings]
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    item_name_groups = item_name_groups
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    location_name_groups = location_name_groups
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-20 11:44:39 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    for group_name, members in grass_location_name_groups.items():
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        location_name_groups.setdefault(group_name, set()).update(members)
							 | 
						
					
						
							
								
									
										
										
										
											2025-03-08 11:25:47 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    for group_name, members in breakable_location_groups.items():
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        location_name_groups.setdefault(group_name, set()).update(members)
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    item_name_to_id = item_name_to_id
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-15 18:17:07 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    location_name_to_id = standard_location_name_to_id.copy()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    location_name_to_id.update(grass_location_name_to_id)
							 | 
						
					
						
							
								
									
										
										
										
											2025-03-08 11:25:47 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    location_name_to_id.update(breakable_location_name_to_id)
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-15 18:17:07 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    player_location_table: Dict[str, int]
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    ability_unlocks: Dict[str, int]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    slot_data_items: List[TunicItem]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    tunic_portal_pairs: Dict[str, str]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    er_portal_hints: Dict[int, str]
							 | 
						
					
						
							
								
									
										
										
										
											2024-05-03 01:21:27 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    seed_groups: Dict[str, SeedGroup] = {}
							 | 
						
					
						
							
								
									
										
											 
										 
										
											
												TUNIC: Entrance rando Direction Pairs + Decoupled (#3761)
* Fix merge conflict
* Fix formatting, fix rule for heir access after merge
* Writing combat logic helpers
* More helpers!
* More logic!
* Rename has_stick to has_melee, some fixes per Medic's review
* Clamp max power from sword upgrades
* Wrote the rest of the helpers
* Remove unused import
* Apply item classifications
* Create the combat logic option
* Item classification varies based on option
* Add the shop sword logic stuff in
* Add the rules for the boss-only option
* Fix tiny issues
* Some early Overworld combat logic
* Fill out swamp combat logic
* Add note
* Bump up Boss Scav and Heir
* More revisions to combat logic
* Some changes, currently broken
* New system for power, kinda jank probably
* Revisions to new system, needs more balancing
* Cap attack upgrades
* Uncap mp power since it's directly related to damage output
* Voidlings
* Put together a table showing the vanilla-expected stats for each area
* Added some info on potion counts
* Made new helper functions
* Make has_required_stats
* Make has_combat_reqs
* Update er_rules for new combat reqs
* Fix all the broken things ever
* Remove outdated todo
* Make temp option for testing logic
* More flexible choices for combat items
* Hard require sword for bosses
* Temporarily default combat logic to on
* Finish writing overworld combat logic
* East Forest combat logic done
* Remove a few easy ones
* Finish beneath the well
* Dark Tomb combat logic
* West Garden combat logic
* make unit tests checkmark again
* Weird west garden dagger house edge case
* Try block for that weird west garden edge case
* Add quarry combat logic
* Update to filter out unreachable regions outside of ER
* Fortress Grave Path logic, and a couple fixes to the west garden logic
* Fortress east shortcut logic, and rewriting the try except blocks to use finally
* Refactor to use a new function cause wow there was a lot of repeated code
* Add combat logic to the other two sets of fortress fuses
* Add combat rules to beneath the vault
* Fix missing cathedral -> elevator connection
* Combat logic for cathedral to elevator
* Add cathedral main region, rename cathedral -> cathedral entry
* Setup cathedral combat logic
* Adjust locations' regions for ER
* Add laurels zip logic to the chest in the spike room in cathedral
* Add combat logic to frog's domain
* Move frog's domain locations to regions for combat logic
* Add new frog's domain regions for combat logic
* Update region name for frog's domain
* Fix typo
* Add more regions for lower zig
* Move around lower zig regions for combat logic
* Lower Zig combat logic
* Upper zig combat logic
* Fix typo
* Fix typos
* Fix missing world.
* Update combat logic description
* Add todo
* Add todo
* Don't make zig skip if er or fixed shop is off
* Make it so zig skip is only made with fewer shops and er
* Temporarily default combat logic on
* Update test to explicitly disable combat logic
* Update test_access.py
* Slight wording changes
* Fix bugs, refactor quarry regions so you can access chests in lower quarry with ice grapples
* Run through checks you can do with magic dagger
* Run through checks you can do with magic dagger
* Add rule for entering town portal of having equipment to deal with enemies
* Add rule for atoll near the 6 crabs surrounding a poor defenseless baby slorm
* Update the rule for the chest near the 6 crabs surrounding a slorm to also possibly require laurels
* Revamp combat logic function to work properly without melee
* Add laurels rules to combat logic chests
* Modify beneath the vault bridge rule to need a lantern if combat logic is on
* Put in money logic
* Dagger or combat for swamp big skeleton chest
* Remove the 100 moneys from logic
* Modify lower zig ls drop region destinations
* Remove completed todo
* Reword combat logic option description, remove test option
* Add combat logic to slot data
* Merge Silent's missing slot data bugfix PR #3628
* Remove test combat option
* Update combat logic description
* Fix secret gathering place issue
* Fix secret gathering place issue
* Fix lower zig ls rule
* Fix accidentally removed librarian rule
* Remove redundant rule
* Update gauntlet rule to hard-require a sword
* Add test for a problematic connection
* Adjust combat logic to deal with weird edge cases so it doesn't take stuff out of logic that was previously in logic
* Fix create_item classification
* Update some comments
* Update per exempt's suggestion
* Add combat logic to the well boss fight, reorder the combat logic stuff a little to better section them off
* Add EntranceLayout option
* Add back LogicRules as an invisible option, to not break old yamls
* Fix a bug with seed group, continue changing fixed shop to entrance layout
* Fix missed fixed shop -> entrance layout spot
* Fix bug in seed groups with fixed shop on and off
* Add entrance layout to the UT regen stuff
* Put direction. in, will add them later
* Remove unused elevation from portal class
* Got like half of them in
* Finish adding all of the directions
* Add combat rule for zig front to back
* Update per Medic's suggestion
* Update ladder storage without items option description
* Mess with state with collect and remove to save like 2 seconds (never again)
* Save even more time, still never going to do this again on anything else
* Add option check for collect and remove
* Add directions to shop portals
* Update direction in Portal with default
* Move Direction above Portal
* Add decoupled option, mess with plando connection stuff
* Merge, implement verify plando directions
* Condense the stuff in change and remove to less lines (thanks medic)
* Remove unused thing
* Swap to using logicmixin instead of prog_items (thanks Vi)
* Fix consistency in stat counters
* Add back something that was needed
* Fix mistake when adding back
* Making the fix better (thanks medic)
* Make it actually return false if it gets to the backup lists and fails them
* Fix stuff after merge
* Add outlet regions, create new regions as needed for them
* Put together part of decoupled and direction pairs
* make direction pairs work
* Make decoupled work
* Make fixed shop work again
* Fix a few minor bugs
* Fix a few minor bugs
* Fix plando
* god i love programming
* Reorder portal list
* Update portal sorter for variable shops
* Add missing parameter
* Some cleanup of prints and functions
* Fix typo
* it's aliiiiiive
* Make seed groups not sync decoupled
* Add test with full-shop plando
* Fix bug with vanilla portals
* Handle plando connections and direction pair errors
* Update plando checking for decoupled
* Fix typo
* Fix exception text to be shorter
* Add some more comments
* Add todo note
* Remove unused safety thing
* Remove extra plando connections definition in options
* Make seed groups in decoupled with overlapping but not fully overlapped plando connections interact nicely without messing with what the entrances look like in the spoiler log
* Fix weird edge case that is technically user error
* Add note to fixed shop
* Fix parsing shop names in UT
* Remove debug print
* Actually make UT work
* multiworld. to world.
* Fix typo from merge
* Make it so the shops show up in the entrance hints
* Fix bug in ladder storage rules
* Remove blank line
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
#	worlds/tunic/rules.py
#	worlds/tunic/test/test_access.py
* Fix issues after merge
* Update plando connections stuff in docs
* Fix library mistake
* has_stick -> has_melee
* has_stick -> has_melee
* Add a failsafe for direction pairing
* Fix playthrough crash bug
* Remove init from logicmixin
* Updates per code review (thanks hesto)
* has_stick to has_melee in newer update
* has_stick to has_melee in newer update
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/combat_logic.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
* Cleanup more stuff after merge
* Revert "Cleanup more stuff after merge"
This reverts commit a6ee9a93da8f2fcc4413de6df6927b246017889d.
* Revert "# Conflicts:"
This reverts commit c74ccd74a45b6ad6b9abe6e339d115a0c98baf30.
* Cleanup more stuff after merge
* Swap to .get for decoupled so it works with older games probably maybe
* Fix after merge
* Fix typo
* Fix UT support with fixed shop option
* Backport plando connections fix
* Fix issue with fixed shop + decoupled
* Make the error not duplicate the while loop condition
* Fix rule for quarry back to monastery
* Fix more stuff after merge
* Make it not output anything if you set plando connections but not ER
* Add obvious note to plando connections description
* Fix after merge
* add comment to commented out connection
---------
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
											
										 
										
											2025-05-06 12:33:21 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    used_shop_numbers: Set[int]
							 | 
						
					
						
							
								
									
										
										
										
											2024-09-08 08:42:59 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    er_regions: Dict[str, RegionInfo]  # absolutely needed so outlet regions work
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-15 18:17:07 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    # for the local_fill option
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    fill_items: List[TunicItem]
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-16 21:13:37 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    fill_locations: List[Location]
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-15 18:17:07 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    amount_to_local_fill: int
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-11-22 19:42:44 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    # so we only loop the multiworld locations once
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    # if these are locations instead of their info, it gives a memory leak error
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    item_link_locations: Dict[int, Dict[str, List[Tuple[int, str]]]] = {}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    player_item_link_locations: Dict[str, List[Location]]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-10 15:49:13 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    using_ut: bool  # so we can check if we're using UT only once
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    passthrough: Dict[str, Any]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    ut_can_gen_without_yaml = True  # class var that tells it to ignore the player yaml
							 | 
						
					
						
							
								
									
										
										
										
											2025-05-22 09:24:50 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    tracker_world: ClassVar = ut_stuff.tracker_world
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-10 15:49:13 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    def generate_early(self) -> None:
							 | 
						
					
						
							
								
									
										
										
										
											2025-03-08 09:56:29 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        try:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            int(self.settings.disable_local_spoiler)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        except AttributeError:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            raise Exception("You have a TUNIC APWorld in your lib/worlds folder and custom_worlds folder.\n"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            "This would cause an error at the end of generation.\n"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            "Please remove one of them, most likely the one in lib/worlds.")
							 | 
						
					
						
							
								
									
										
										
										
											2025-05-07 10:59:16 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if self.options.all_random:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            for option_name in (attr.name for attr in fields(TunicOptions)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                if attr not in fields(PerGameCommonOptions)):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                option = getattr(self.options, option_name)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if option_name == "all_random":
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    continue
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if isinstance(option, Removed):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    continue
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if option.supports_weighting:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    if isinstance(option, Range):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        option.value = self.random.randint(option.range_start, option.range_end)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    else:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        option.value = self.random.choice(list(option.name_lookup))
							 | 
						
					
						
							
								
									
										
										
										
											2025-03-08 09:56:29 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2025-03-07 19:43:02 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        check_options(self)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-09-08 08:42:59 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.er_regions = tunic_er_regions.copy()
							 | 
						
					
						
							
								
									
										
											 
										 
										
											
												TUNIC: Entrance rando Direction Pairs + Decoupled (#3761)
* Fix merge conflict
* Fix formatting, fix rule for heir access after merge
* Writing combat logic helpers
* More helpers!
* More logic!
* Rename has_stick to has_melee, some fixes per Medic's review
* Clamp max power from sword upgrades
* Wrote the rest of the helpers
* Remove unused import
* Apply item classifications
* Create the combat logic option
* Item classification varies based on option
* Add the shop sword logic stuff in
* Add the rules for the boss-only option
* Fix tiny issues
* Some early Overworld combat logic
* Fill out swamp combat logic
* Add note
* Bump up Boss Scav and Heir
* More revisions to combat logic
* Some changes, currently broken
* New system for power, kinda jank probably
* Revisions to new system, needs more balancing
* Cap attack upgrades
* Uncap mp power since it's directly related to damage output
* Voidlings
* Put together a table showing the vanilla-expected stats for each area
* Added some info on potion counts
* Made new helper functions
* Make has_required_stats
* Make has_combat_reqs
* Update er_rules for new combat reqs
* Fix all the broken things ever
* Remove outdated todo
* Make temp option for testing logic
* More flexible choices for combat items
* Hard require sword for bosses
* Temporarily default combat logic to on
* Finish writing overworld combat logic
* East Forest combat logic done
* Remove a few easy ones
* Finish beneath the well
* Dark Tomb combat logic
* West Garden combat logic
* make unit tests checkmark again
* Weird west garden dagger house edge case
* Try block for that weird west garden edge case
* Add quarry combat logic
* Update to filter out unreachable regions outside of ER
* Fortress Grave Path logic, and a couple fixes to the west garden logic
* Fortress east shortcut logic, and rewriting the try except blocks to use finally
* Refactor to use a new function cause wow there was a lot of repeated code
* Add combat logic to the other two sets of fortress fuses
* Add combat rules to beneath the vault
* Fix missing cathedral -> elevator connection
* Combat logic for cathedral to elevator
* Add cathedral main region, rename cathedral -> cathedral entry
* Setup cathedral combat logic
* Adjust locations' regions for ER
* Add laurels zip logic to the chest in the spike room in cathedral
* Add combat logic to frog's domain
* Move frog's domain locations to regions for combat logic
* Add new frog's domain regions for combat logic
* Update region name for frog's domain
* Fix typo
* Add more regions for lower zig
* Move around lower zig regions for combat logic
* Lower Zig combat logic
* Upper zig combat logic
* Fix typo
* Fix typos
* Fix missing world.
* Update combat logic description
* Add todo
* Add todo
* Don't make zig skip if er or fixed shop is off
* Make it so zig skip is only made with fewer shops and er
* Temporarily default combat logic on
* Update test to explicitly disable combat logic
* Update test_access.py
* Slight wording changes
* Fix bugs, refactor quarry regions so you can access chests in lower quarry with ice grapples
* Run through checks you can do with magic dagger
* Run through checks you can do with magic dagger
* Add rule for entering town portal of having equipment to deal with enemies
* Add rule for atoll near the 6 crabs surrounding a poor defenseless baby slorm
* Update the rule for the chest near the 6 crabs surrounding a slorm to also possibly require laurels
* Revamp combat logic function to work properly without melee
* Add laurels rules to combat logic chests
* Modify beneath the vault bridge rule to need a lantern if combat logic is on
* Put in money logic
* Dagger or combat for swamp big skeleton chest
* Remove the 100 moneys from logic
* Modify lower zig ls drop region destinations
* Remove completed todo
* Reword combat logic option description, remove test option
* Add combat logic to slot data
* Merge Silent's missing slot data bugfix PR #3628
* Remove test combat option
* Update combat logic description
* Fix secret gathering place issue
* Fix secret gathering place issue
* Fix lower zig ls rule
* Fix accidentally removed librarian rule
* Remove redundant rule
* Update gauntlet rule to hard-require a sword
* Add test for a problematic connection
* Adjust combat logic to deal with weird edge cases so it doesn't take stuff out of logic that was previously in logic
* Fix create_item classification
* Update some comments
* Update per exempt's suggestion
* Add combat logic to the well boss fight, reorder the combat logic stuff a little to better section them off
* Add EntranceLayout option
* Add back LogicRules as an invisible option, to not break old yamls
* Fix a bug with seed group, continue changing fixed shop to entrance layout
* Fix missed fixed shop -> entrance layout spot
* Fix bug in seed groups with fixed shop on and off
* Add entrance layout to the UT regen stuff
* Put direction. in, will add them later
* Remove unused elevation from portal class
* Got like half of them in
* Finish adding all of the directions
* Add combat rule for zig front to back
* Update per Medic's suggestion
* Update ladder storage without items option description
* Mess with state with collect and remove to save like 2 seconds (never again)
* Save even more time, still never going to do this again on anything else
* Add option check for collect and remove
* Add directions to shop portals
* Update direction in Portal with default
* Move Direction above Portal
* Add decoupled option, mess with plando connection stuff
* Merge, implement verify plando directions
* Condense the stuff in change and remove to less lines (thanks medic)
* Remove unused thing
* Swap to using logicmixin instead of prog_items (thanks Vi)
* Fix consistency in stat counters
* Add back something that was needed
* Fix mistake when adding back
* Making the fix better (thanks medic)
* Make it actually return false if it gets to the backup lists and fails them
* Fix stuff after merge
* Add outlet regions, create new regions as needed for them
* Put together part of decoupled and direction pairs
* make direction pairs work
* Make decoupled work
* Make fixed shop work again
* Fix a few minor bugs
* Fix a few minor bugs
* Fix plando
* god i love programming
* Reorder portal list
* Update portal sorter for variable shops
* Add missing parameter
* Some cleanup of prints and functions
* Fix typo
* it's aliiiiiive
* Make seed groups not sync decoupled
* Add test with full-shop plando
* Fix bug with vanilla portals
* Handle plando connections and direction pair errors
* Update plando checking for decoupled
* Fix typo
* Fix exception text to be shorter
* Add some more comments
* Add todo note
* Remove unused safety thing
* Remove extra plando connections definition in options
* Make seed groups in decoupled with overlapping but not fully overlapped plando connections interact nicely without messing with what the entrances look like in the spoiler log
* Fix weird edge case that is technically user error
* Add note to fixed shop
* Fix parsing shop names in UT
* Remove debug print
* Actually make UT work
* multiworld. to world.
* Fix typo from merge
* Make it so the shops show up in the entrance hints
* Fix bug in ladder storage rules
* Remove blank line
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
#	worlds/tunic/rules.py
#	worlds/tunic/test/test_access.py
* Fix issues after merge
* Update plando connections stuff in docs
* Fix library mistake
* has_stick -> has_melee
* has_stick -> has_melee
* Add a failsafe for direction pairing
* Fix playthrough crash bug
* Remove init from logicmixin
* Updates per code review (thanks hesto)
* has_stick to has_melee in newer update
* has_stick to has_melee in newer update
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/combat_logic.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
* Cleanup more stuff after merge
* Revert "Cleanup more stuff after merge"
This reverts commit a6ee9a93da8f2fcc4413de6df6927b246017889d.
* Revert "# Conflicts:"
This reverts commit c74ccd74a45b6ad6b9abe6e339d115a0c98baf30.
* Cleanup more stuff after merge
* Swap to .get for decoupled so it works with older games probably maybe
* Fix after merge
* Fix typo
* Fix UT support with fixed shop option
* Backport plando connections fix
* Fix issue with fixed shop + decoupled
* Make the error not duplicate the while loop condition
* Fix rule for quarry back to monastery
* Fix more stuff after merge
* Make it not output anything if you set plando connections but not ER
* Add obvious note to plando connections description
* Fix after merge
* add comment to commented out connection
---------
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
											
										 
										
											2025-05-06 12:33:21 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if self.options.plando_connections and not self.options.entrance_rando:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            self.options.plando_connections.value = ()
							 | 
						
					
						
							
								
									
										
										
										
											2024-06-01 06:34:41 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if self.options.plando_connections:
							 | 
						
					
						
							
								
									
										
											 
										 
										
											
												TUNIC: Entrance rando Direction Pairs + Decoupled (#3761)
* Fix merge conflict
* Fix formatting, fix rule for heir access after merge
* Writing combat logic helpers
* More helpers!
* More logic!
* Rename has_stick to has_melee, some fixes per Medic's review
* Clamp max power from sword upgrades
* Wrote the rest of the helpers
* Remove unused import
* Apply item classifications
* Create the combat logic option
* Item classification varies based on option
* Add the shop sword logic stuff in
* Add the rules for the boss-only option
* Fix tiny issues
* Some early Overworld combat logic
* Fill out swamp combat logic
* Add note
* Bump up Boss Scav and Heir
* More revisions to combat logic
* Some changes, currently broken
* New system for power, kinda jank probably
* Revisions to new system, needs more balancing
* Cap attack upgrades
* Uncap mp power since it's directly related to damage output
* Voidlings
* Put together a table showing the vanilla-expected stats for each area
* Added some info on potion counts
* Made new helper functions
* Make has_required_stats
* Make has_combat_reqs
* Update er_rules for new combat reqs
* Fix all the broken things ever
* Remove outdated todo
* Make temp option for testing logic
* More flexible choices for combat items
* Hard require sword for bosses
* Temporarily default combat logic to on
* Finish writing overworld combat logic
* East Forest combat logic done
* Remove a few easy ones
* Finish beneath the well
* Dark Tomb combat logic
* West Garden combat logic
* make unit tests checkmark again
* Weird west garden dagger house edge case
* Try block for that weird west garden edge case
* Add quarry combat logic
* Update to filter out unreachable regions outside of ER
* Fortress Grave Path logic, and a couple fixes to the west garden logic
* Fortress east shortcut logic, and rewriting the try except blocks to use finally
* Refactor to use a new function cause wow there was a lot of repeated code
* Add combat logic to the other two sets of fortress fuses
* Add combat rules to beneath the vault
* Fix missing cathedral -> elevator connection
* Combat logic for cathedral to elevator
* Add cathedral main region, rename cathedral -> cathedral entry
* Setup cathedral combat logic
* Adjust locations' regions for ER
* Add laurels zip logic to the chest in the spike room in cathedral
* Add combat logic to frog's domain
* Move frog's domain locations to regions for combat logic
* Add new frog's domain regions for combat logic
* Update region name for frog's domain
* Fix typo
* Add more regions for lower zig
* Move around lower zig regions for combat logic
* Lower Zig combat logic
* Upper zig combat logic
* Fix typo
* Fix typos
* Fix missing world.
* Update combat logic description
* Add todo
* Add todo
* Don't make zig skip if er or fixed shop is off
* Make it so zig skip is only made with fewer shops and er
* Temporarily default combat logic on
* Update test to explicitly disable combat logic
* Update test_access.py
* Slight wording changes
* Fix bugs, refactor quarry regions so you can access chests in lower quarry with ice grapples
* Run through checks you can do with magic dagger
* Run through checks you can do with magic dagger
* Add rule for entering town portal of having equipment to deal with enemies
* Add rule for atoll near the 6 crabs surrounding a poor defenseless baby slorm
* Update the rule for the chest near the 6 crabs surrounding a slorm to also possibly require laurels
* Revamp combat logic function to work properly without melee
* Add laurels rules to combat logic chests
* Modify beneath the vault bridge rule to need a lantern if combat logic is on
* Put in money logic
* Dagger or combat for swamp big skeleton chest
* Remove the 100 moneys from logic
* Modify lower zig ls drop region destinations
* Remove completed todo
* Reword combat logic option description, remove test option
* Add combat logic to slot data
* Merge Silent's missing slot data bugfix PR #3628
* Remove test combat option
* Update combat logic description
* Fix secret gathering place issue
* Fix secret gathering place issue
* Fix lower zig ls rule
* Fix accidentally removed librarian rule
* Remove redundant rule
* Update gauntlet rule to hard-require a sword
* Add test for a problematic connection
* Adjust combat logic to deal with weird edge cases so it doesn't take stuff out of logic that was previously in logic
* Fix create_item classification
* Update some comments
* Update per exempt's suggestion
* Add combat logic to the well boss fight, reorder the combat logic stuff a little to better section them off
* Add EntranceLayout option
* Add back LogicRules as an invisible option, to not break old yamls
* Fix a bug with seed group, continue changing fixed shop to entrance layout
* Fix missed fixed shop -> entrance layout spot
* Fix bug in seed groups with fixed shop on and off
* Add entrance layout to the UT regen stuff
* Put direction. in, will add them later
* Remove unused elevation from portal class
* Got like half of them in
* Finish adding all of the directions
* Add combat rule for zig front to back
* Update per Medic's suggestion
* Update ladder storage without items option description
* Mess with state with collect and remove to save like 2 seconds (never again)
* Save even more time, still never going to do this again on anything else
* Add option check for collect and remove
* Add directions to shop portals
* Update direction in Portal with default
* Move Direction above Portal
* Add decoupled option, mess with plando connection stuff
* Merge, implement verify plando directions
* Condense the stuff in change and remove to less lines (thanks medic)
* Remove unused thing
* Swap to using logicmixin instead of prog_items (thanks Vi)
* Fix consistency in stat counters
* Add back something that was needed
* Fix mistake when adding back
* Making the fix better (thanks medic)
* Make it actually return false if it gets to the backup lists and fails them
* Fix stuff after merge
* Add outlet regions, create new regions as needed for them
* Put together part of decoupled and direction pairs
* make direction pairs work
* Make decoupled work
* Make fixed shop work again
* Fix a few minor bugs
* Fix a few minor bugs
* Fix plando
* god i love programming
* Reorder portal list
* Update portal sorter for variable shops
* Add missing parameter
* Some cleanup of prints and functions
* Fix typo
* it's aliiiiiive
* Make seed groups not sync decoupled
* Add test with full-shop plando
* Fix bug with vanilla portals
* Handle plando connections and direction pair errors
* Update plando checking for decoupled
* Fix typo
* Fix exception text to be shorter
* Add some more comments
* Add todo note
* Remove unused safety thing
* Remove extra plando connections definition in options
* Make seed groups in decoupled with overlapping but not fully overlapped plando connections interact nicely without messing with what the entrances look like in the spoiler log
* Fix weird edge case that is technically user error
* Add note to fixed shop
* Fix parsing shop names in UT
* Remove debug print
* Actually make UT work
* multiworld. to world.
* Fix typo from merge
* Make it so the shops show up in the entrance hints
* Fix bug in ladder storage rules
* Remove blank line
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
#	worlds/tunic/rules.py
#	worlds/tunic/test/test_access.py
* Fix issues after merge
* Update plando connections stuff in docs
* Fix library mistake
* has_stick -> has_melee
* has_stick -> has_melee
* Add a failsafe for direction pairing
* Fix playthrough crash bug
* Remove init from logicmixin
* Updates per code review (thanks hesto)
* has_stick to has_melee in newer update
* has_stick to has_melee in newer update
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/combat_logic.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
* Cleanup more stuff after merge
* Revert "Cleanup more stuff after merge"
This reverts commit a6ee9a93da8f2fcc4413de6df6927b246017889d.
* Revert "# Conflicts:"
This reverts commit c74ccd74a45b6ad6b9abe6e339d115a0c98baf30.
* Cleanup more stuff after merge
* Swap to .get for decoupled so it works with older games probably maybe
* Fix after merge
* Fix typo
* Fix UT support with fixed shop option
* Backport plando connections fix
* Fix issue with fixed shop + decoupled
* Make the error not duplicate the while loop condition
* Fix rule for quarry back to monastery
* Fix more stuff after merge
* Make it not output anything if you set plando connections but not ER
* Add obvious note to plando connections description
* Fix after merge
* add comment to commented out connection
---------
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
											
										 
										
											2025-05-06 12:33:21 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            def replace_connection(old_cxn: PlandoConnection, new_cxn: PlandoConnection, index: int) -> None:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                self.options.plando_connections.value.remove(old_cxn)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                self.options.plando_connections.value.insert(index, new_cxn)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-06-01 06:34:41 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            for index, cxn in enumerate(self.options.plando_connections):
							 | 
						
					
						
							
								
									
										
											 
										 
										
											
												TUNIC: Entrance rando Direction Pairs + Decoupled (#3761)
* Fix merge conflict
* Fix formatting, fix rule for heir access after merge
* Writing combat logic helpers
* More helpers!
* More logic!
* Rename has_stick to has_melee, some fixes per Medic's review
* Clamp max power from sword upgrades
* Wrote the rest of the helpers
* Remove unused import
* Apply item classifications
* Create the combat logic option
* Item classification varies based on option
* Add the shop sword logic stuff in
* Add the rules for the boss-only option
* Fix tiny issues
* Some early Overworld combat logic
* Fill out swamp combat logic
* Add note
* Bump up Boss Scav and Heir
* More revisions to combat logic
* Some changes, currently broken
* New system for power, kinda jank probably
* Revisions to new system, needs more balancing
* Cap attack upgrades
* Uncap mp power since it's directly related to damage output
* Voidlings
* Put together a table showing the vanilla-expected stats for each area
* Added some info on potion counts
* Made new helper functions
* Make has_required_stats
* Make has_combat_reqs
* Update er_rules for new combat reqs
* Fix all the broken things ever
* Remove outdated todo
* Make temp option for testing logic
* More flexible choices for combat items
* Hard require sword for bosses
* Temporarily default combat logic to on
* Finish writing overworld combat logic
* East Forest combat logic done
* Remove a few easy ones
* Finish beneath the well
* Dark Tomb combat logic
* West Garden combat logic
* make unit tests checkmark again
* Weird west garden dagger house edge case
* Try block for that weird west garden edge case
* Add quarry combat logic
* Update to filter out unreachable regions outside of ER
* Fortress Grave Path logic, and a couple fixes to the west garden logic
* Fortress east shortcut logic, and rewriting the try except blocks to use finally
* Refactor to use a new function cause wow there was a lot of repeated code
* Add combat logic to the other two sets of fortress fuses
* Add combat rules to beneath the vault
* Fix missing cathedral -> elevator connection
* Combat logic for cathedral to elevator
* Add cathedral main region, rename cathedral -> cathedral entry
* Setup cathedral combat logic
* Adjust locations' regions for ER
* Add laurels zip logic to the chest in the spike room in cathedral
* Add combat logic to frog's domain
* Move frog's domain locations to regions for combat logic
* Add new frog's domain regions for combat logic
* Update region name for frog's domain
* Fix typo
* Add more regions for lower zig
* Move around lower zig regions for combat logic
* Lower Zig combat logic
* Upper zig combat logic
* Fix typo
* Fix typos
* Fix missing world.
* Update combat logic description
* Add todo
* Add todo
* Don't make zig skip if er or fixed shop is off
* Make it so zig skip is only made with fewer shops and er
* Temporarily default combat logic on
* Update test to explicitly disable combat logic
* Update test_access.py
* Slight wording changes
* Fix bugs, refactor quarry regions so you can access chests in lower quarry with ice grapples
* Run through checks you can do with magic dagger
* Run through checks you can do with magic dagger
* Add rule for entering town portal of having equipment to deal with enemies
* Add rule for atoll near the 6 crabs surrounding a poor defenseless baby slorm
* Update the rule for the chest near the 6 crabs surrounding a slorm to also possibly require laurels
* Revamp combat logic function to work properly without melee
* Add laurels rules to combat logic chests
* Modify beneath the vault bridge rule to need a lantern if combat logic is on
* Put in money logic
* Dagger or combat for swamp big skeleton chest
* Remove the 100 moneys from logic
* Modify lower zig ls drop region destinations
* Remove completed todo
* Reword combat logic option description, remove test option
* Add combat logic to slot data
* Merge Silent's missing slot data bugfix PR #3628
* Remove test combat option
* Update combat logic description
* Fix secret gathering place issue
* Fix secret gathering place issue
* Fix lower zig ls rule
* Fix accidentally removed librarian rule
* Remove redundant rule
* Update gauntlet rule to hard-require a sword
* Add test for a problematic connection
* Adjust combat logic to deal with weird edge cases so it doesn't take stuff out of logic that was previously in logic
* Fix create_item classification
* Update some comments
* Update per exempt's suggestion
* Add combat logic to the well boss fight, reorder the combat logic stuff a little to better section them off
* Add EntranceLayout option
* Add back LogicRules as an invisible option, to not break old yamls
* Fix a bug with seed group, continue changing fixed shop to entrance layout
* Fix missed fixed shop -> entrance layout spot
* Fix bug in seed groups with fixed shop on and off
* Add entrance layout to the UT regen stuff
* Put direction. in, will add them later
* Remove unused elevation from portal class
* Got like half of them in
* Finish adding all of the directions
* Add combat rule for zig front to back
* Update per Medic's suggestion
* Update ladder storage without items option description
* Mess with state with collect and remove to save like 2 seconds (never again)
* Save even more time, still never going to do this again on anything else
* Add option check for collect and remove
* Add directions to shop portals
* Update direction in Portal with default
* Move Direction above Portal
* Add decoupled option, mess with plando connection stuff
* Merge, implement verify plando directions
* Condense the stuff in change and remove to less lines (thanks medic)
* Remove unused thing
* Swap to using logicmixin instead of prog_items (thanks Vi)
* Fix consistency in stat counters
* Add back something that was needed
* Fix mistake when adding back
* Making the fix better (thanks medic)
* Make it actually return false if it gets to the backup lists and fails them
* Fix stuff after merge
* Add outlet regions, create new regions as needed for them
* Put together part of decoupled and direction pairs
* make direction pairs work
* Make decoupled work
* Make fixed shop work again
* Fix a few minor bugs
* Fix a few minor bugs
* Fix plando
* god i love programming
* Reorder portal list
* Update portal sorter for variable shops
* Add missing parameter
* Some cleanup of prints and functions
* Fix typo
* it's aliiiiiive
* Make seed groups not sync decoupled
* Add test with full-shop plando
* Fix bug with vanilla portals
* Handle plando connections and direction pair errors
* Update plando checking for decoupled
* Fix typo
* Fix exception text to be shorter
* Add some more comments
* Add todo note
* Remove unused safety thing
* Remove extra plando connections definition in options
* Make seed groups in decoupled with overlapping but not fully overlapped plando connections interact nicely without messing with what the entrances look like in the spoiler log
* Fix weird edge case that is technically user error
* Add note to fixed shop
* Fix parsing shop names in UT
* Remove debug print
* Actually make UT work
* multiworld. to world.
* Fix typo from merge
* Make it so the shops show up in the entrance hints
* Fix bug in ladder storage rules
* Remove blank line
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
#	worlds/tunic/rules.py
#	worlds/tunic/test/test_access.py
* Fix issues after merge
* Update plando connections stuff in docs
* Fix library mistake
* has_stick -> has_melee
* has_stick -> has_melee
* Add a failsafe for direction pairing
* Fix playthrough crash bug
* Remove init from logicmixin
* Updates per code review (thanks hesto)
* has_stick to has_melee in newer update
* has_stick to has_melee in newer update
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/combat_logic.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
* Cleanup more stuff after merge
* Revert "Cleanup more stuff after merge"
This reverts commit a6ee9a93da8f2fcc4413de6df6927b246017889d.
* Revert "# Conflicts:"
This reverts commit c74ccd74a45b6ad6b9abe6e339d115a0c98baf30.
* Cleanup more stuff after merge
* Swap to .get for decoupled so it works with older games probably maybe
* Fix after merge
* Fix typo
* Fix UT support with fixed shop option
* Backport plando connections fix
* Fix issue with fixed shop + decoupled
* Make the error not duplicate the while loop condition
* Fix rule for quarry back to monastery
* Fix more stuff after merge
* Make it not output anything if you set plando connections but not ER
* Add obvious note to plando connections description
* Fix after merge
* add comment to commented out connection
---------
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
											
										 
										
											2025-05-06 12:33:21 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                replacement = None
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if self.options.decoupled:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    # flip any that are pointing to exit to point to entrance so that I don't have to deal with it
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    if cxn.direction == "exit":
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        replacement = PlandoConnection(cxn.exit, cxn.entrance, "entrance", cxn.percentage)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    # if decoupled is on and you plando'd an entrance to itself but left the direction as both
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    if cxn.direction == "both" and cxn.entrance == cxn.exit:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        replacement = PlandoConnection(cxn.entrance, cxn.exit, "entrance")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                # if decoupled is off, just convert these to both
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                elif cxn.direction != "both":
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    replacement = PlandoConnection(cxn.entrance, cxn.exit, "both", cxn.percentage)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if replacement:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    replace_connection(cxn, replacement, index)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if (self.options.entrance_layout == EntranceLayout.option_direction_pairs
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        and not verify_plando_directions(cxn)):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    raise OptionError(f"TUNIC: Player {self.player_name} has invalid plando connections. "
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                      f"They have Direction Pairs enabled and the connection "
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                      f"{cxn.entrance} --> {cxn.exit} does not abide by this option.")
							 | 
						
					
						
							
								
									
										
										
										
											2024-05-03 01:21:27 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2025-05-22 09:24:50 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        ut_stuff.setup_options_from_slot_data(self)
							 | 
						
					
						
							
								
									
										
										
										
											2024-02-15 23:03:51 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-15 18:17:07 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.player_location_table = standard_location_name_to_id.copy()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if self.options.local_fill == -1:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if self.options.grass_randomizer:
							 | 
						
					
						
							
								
									
										
										
										
											2025-03-08 11:25:47 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                if self.options.breakable_shuffle:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    self.options.local_fill.value = 96
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                else:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    self.options.local_fill.value = 95
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            elif self.options.breakable_shuffle:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                self.options.local_fill.value = 40
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-15 18:17:07 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            else:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                self.options.local_fill.value = 0
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if self.options.grass_randomizer:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if self.settings.limit_grass_rando and self.options.local_fill < 95 and self.multiworld.players > 1:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                raise OptionError(f"TUNIC: Player {self.player_name} has their Local Fill option set too low. "
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                  f"They must either bring it above 95% or the host needs to disable limit_grass_rando "
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                  f"in their host.yaml settings")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            self.player_location_table.update(grass_location_name_to_id)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2025-03-08 11:25:47 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if self.options.breakable_shuffle:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if self.options.entrance_rando:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                self.player_location_table.update(breakable_location_name_to_id)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            else:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                self.player_location_table.update({name: num for name, num in breakable_location_name_to_id.items()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                                   if not name.startswith("Purgatory")})
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-05-03 01:21:27 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    @classmethod
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    def stage_generate_early(cls, multiworld: MultiWorld) -> None:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        tunic_worlds: Tuple[TunicWorld] = multiworld.get_game_worlds("TUNIC")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        for tunic in tunic_worlds:
							 | 
						
					
						
							
								
									
										
										
										
											2024-12-15 16:40:36 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            # setting up state combat logic stuff, see has_combat_reqs for its use
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            # and this is magic so pycharm doesn't like it, unfortunately
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if tunic.options.combat_logic:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                multiworld.state.tunic_need_to_reset_combat_from_collect[tunic.player] = False
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                multiworld.state.tunic_need_to_reset_combat_from_remove[tunic.player] = False
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                multiworld.state.tunic_area_combat_state[tunic.player] = {}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                for area_name in area_data.keys():
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    multiworld.state.tunic_area_combat_state[tunic.player][area_name] = CombatState.unchecked
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-05-03 01:21:27 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            # if it's one of the options, then it isn't a custom seed group
							 | 
						
					
						
							
								
									
										
										
										
											2024-06-03 04:44:37 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            if tunic.options.entrance_rando.value in EntranceRando.options.values():
							 | 
						
					
						
							
								
									
										
										
										
											2024-05-03 01:21:27 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                continue
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            group = tunic.options.entrance_rando.value
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            # if this is the first world in the group, set the rules equal to its rules
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if group not in cls.seed_groups:
							 | 
						
					
						
							
								
									
										
										
										
											2024-09-08 08:42:59 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                cls.seed_groups[group] = \
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    SeedGroup(laurels_zips=bool(tunic.options.laurels_zips),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                              ice_grappling=tunic.options.ice_grappling.value,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                              ladder_storage=tunic.options.ladder_storage.value,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                              laurels_at_10_fairies=tunic.options.laurels_location == LaurelsLocation.option_10_fairies,
							 | 
						
					
						
							
								
									
										
											 
										 
										
											
												TUNIC: Entrance rando Direction Pairs + Decoupled (#3761)
* Fix merge conflict
* Fix formatting, fix rule for heir access after merge
* Writing combat logic helpers
* More helpers!
* More logic!
* Rename has_stick to has_melee, some fixes per Medic's review
* Clamp max power from sword upgrades
* Wrote the rest of the helpers
* Remove unused import
* Apply item classifications
* Create the combat logic option
* Item classification varies based on option
* Add the shop sword logic stuff in
* Add the rules for the boss-only option
* Fix tiny issues
* Some early Overworld combat logic
* Fill out swamp combat logic
* Add note
* Bump up Boss Scav and Heir
* More revisions to combat logic
* Some changes, currently broken
* New system for power, kinda jank probably
* Revisions to new system, needs more balancing
* Cap attack upgrades
* Uncap mp power since it's directly related to damage output
* Voidlings
* Put together a table showing the vanilla-expected stats for each area
* Added some info on potion counts
* Made new helper functions
* Make has_required_stats
* Make has_combat_reqs
* Update er_rules for new combat reqs
* Fix all the broken things ever
* Remove outdated todo
* Make temp option for testing logic
* More flexible choices for combat items
* Hard require sword for bosses
* Temporarily default combat logic to on
* Finish writing overworld combat logic
* East Forest combat logic done
* Remove a few easy ones
* Finish beneath the well
* Dark Tomb combat logic
* West Garden combat logic
* make unit tests checkmark again
* Weird west garden dagger house edge case
* Try block for that weird west garden edge case
* Add quarry combat logic
* Update to filter out unreachable regions outside of ER
* Fortress Grave Path logic, and a couple fixes to the west garden logic
* Fortress east shortcut logic, and rewriting the try except blocks to use finally
* Refactor to use a new function cause wow there was a lot of repeated code
* Add combat logic to the other two sets of fortress fuses
* Add combat rules to beneath the vault
* Fix missing cathedral -> elevator connection
* Combat logic for cathedral to elevator
* Add cathedral main region, rename cathedral -> cathedral entry
* Setup cathedral combat logic
* Adjust locations' regions for ER
* Add laurels zip logic to the chest in the spike room in cathedral
* Add combat logic to frog's domain
* Move frog's domain locations to regions for combat logic
* Add new frog's domain regions for combat logic
* Update region name for frog's domain
* Fix typo
* Add more regions for lower zig
* Move around lower zig regions for combat logic
* Lower Zig combat logic
* Upper zig combat logic
* Fix typo
* Fix typos
* Fix missing world.
* Update combat logic description
* Add todo
* Add todo
* Don't make zig skip if er or fixed shop is off
* Make it so zig skip is only made with fewer shops and er
* Temporarily default combat logic on
* Update test to explicitly disable combat logic
* Update test_access.py
* Slight wording changes
* Fix bugs, refactor quarry regions so you can access chests in lower quarry with ice grapples
* Run through checks you can do with magic dagger
* Run through checks you can do with magic dagger
* Add rule for entering town portal of having equipment to deal with enemies
* Add rule for atoll near the 6 crabs surrounding a poor defenseless baby slorm
* Update the rule for the chest near the 6 crabs surrounding a slorm to also possibly require laurels
* Revamp combat logic function to work properly without melee
* Add laurels rules to combat logic chests
* Modify beneath the vault bridge rule to need a lantern if combat logic is on
* Put in money logic
* Dagger or combat for swamp big skeleton chest
* Remove the 100 moneys from logic
* Modify lower zig ls drop region destinations
* Remove completed todo
* Reword combat logic option description, remove test option
* Add combat logic to slot data
* Merge Silent's missing slot data bugfix PR #3628
* Remove test combat option
* Update combat logic description
* Fix secret gathering place issue
* Fix secret gathering place issue
* Fix lower zig ls rule
* Fix accidentally removed librarian rule
* Remove redundant rule
* Update gauntlet rule to hard-require a sword
* Add test for a problematic connection
* Adjust combat logic to deal with weird edge cases so it doesn't take stuff out of logic that was previously in logic
* Fix create_item classification
* Update some comments
* Update per exempt's suggestion
* Add combat logic to the well boss fight, reorder the combat logic stuff a little to better section them off
* Add EntranceLayout option
* Add back LogicRules as an invisible option, to not break old yamls
* Fix a bug with seed group, continue changing fixed shop to entrance layout
* Fix missed fixed shop -> entrance layout spot
* Fix bug in seed groups with fixed shop on and off
* Add entrance layout to the UT regen stuff
* Put direction. in, will add them later
* Remove unused elevation from portal class
* Got like half of them in
* Finish adding all of the directions
* Add combat rule for zig front to back
* Update per Medic's suggestion
* Update ladder storage without items option description
* Mess with state with collect and remove to save like 2 seconds (never again)
* Save even more time, still never going to do this again on anything else
* Add option check for collect and remove
* Add directions to shop portals
* Update direction in Portal with default
* Move Direction above Portal
* Add decoupled option, mess with plando connection stuff
* Merge, implement verify plando directions
* Condense the stuff in change and remove to less lines (thanks medic)
* Remove unused thing
* Swap to using logicmixin instead of prog_items (thanks Vi)
* Fix consistency in stat counters
* Add back something that was needed
* Fix mistake when adding back
* Making the fix better (thanks medic)
* Make it actually return false if it gets to the backup lists and fails them
* Fix stuff after merge
* Add outlet regions, create new regions as needed for them
* Put together part of decoupled and direction pairs
* make direction pairs work
* Make decoupled work
* Make fixed shop work again
* Fix a few minor bugs
* Fix a few minor bugs
* Fix plando
* god i love programming
* Reorder portal list
* Update portal sorter for variable shops
* Add missing parameter
* Some cleanup of prints and functions
* Fix typo
* it's aliiiiiive
* Make seed groups not sync decoupled
* Add test with full-shop plando
* Fix bug with vanilla portals
* Handle plando connections and direction pair errors
* Update plando checking for decoupled
* Fix typo
* Fix exception text to be shorter
* Add some more comments
* Add todo note
* Remove unused safety thing
* Remove extra plando connections definition in options
* Make seed groups in decoupled with overlapping but not fully overlapped plando connections interact nicely without messing with what the entrances look like in the spoiler log
* Fix weird edge case that is technically user error
* Add note to fixed shop
* Fix parsing shop names in UT
* Remove debug print
* Actually make UT work
* multiworld. to world.
* Fix typo from merge
* Make it so the shops show up in the entrance hints
* Fix bug in ladder storage rules
* Remove blank line
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
#	worlds/tunic/rules.py
#	worlds/tunic/test/test_access.py
* Fix issues after merge
* Update plando connections stuff in docs
* Fix library mistake
* has_stick -> has_melee
* has_stick -> has_melee
* Add a failsafe for direction pairing
* Fix playthrough crash bug
* Remove init from logicmixin
* Updates per code review (thanks hesto)
* has_stick to has_melee in newer update
* has_stick to has_melee in newer update
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/combat_logic.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
* Cleanup more stuff after merge
* Revert "Cleanup more stuff after merge"
This reverts commit a6ee9a93da8f2fcc4413de6df6927b246017889d.
* Revert "# Conflicts:"
This reverts commit c74ccd74a45b6ad6b9abe6e339d115a0c98baf30.
* Cleanup more stuff after merge
* Swap to .get for decoupled so it works with older games probably maybe
* Fix after merge
* Fix typo
* Fix UT support with fixed shop option
* Backport plando connections fix
* Fix issue with fixed shop + decoupled
* Make the error not duplicate the while loop condition
* Fix rule for quarry back to monastery
* Fix more stuff after merge
* Make it not output anything if you set plando connections but not ER
* Add obvious note to plando connections description
* Fix after merge
* add comment to commented out connection
---------
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
											
										 
										
											2025-05-06 12:33:21 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                              entrance_layout=tunic.options.entrance_layout.value,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                              has_decoupled_enabled=bool(tunic.options.decoupled),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                              plando=tunic.options.plando_connections.value.copy())
							 | 
						
					
						
							
								
									
										
										
										
											2024-05-03 01:21:27 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                continue
							 | 
						
					
						
							
								
									
										
											 
										 
										
											
												TUNIC: Entrance rando Direction Pairs + Decoupled (#3761)
* Fix merge conflict
* Fix formatting, fix rule for heir access after merge
* Writing combat logic helpers
* More helpers!
* More logic!
* Rename has_stick to has_melee, some fixes per Medic's review
* Clamp max power from sword upgrades
* Wrote the rest of the helpers
* Remove unused import
* Apply item classifications
* Create the combat logic option
* Item classification varies based on option
* Add the shop sword logic stuff in
* Add the rules for the boss-only option
* Fix tiny issues
* Some early Overworld combat logic
* Fill out swamp combat logic
* Add note
* Bump up Boss Scav and Heir
* More revisions to combat logic
* Some changes, currently broken
* New system for power, kinda jank probably
* Revisions to new system, needs more balancing
* Cap attack upgrades
* Uncap mp power since it's directly related to damage output
* Voidlings
* Put together a table showing the vanilla-expected stats for each area
* Added some info on potion counts
* Made new helper functions
* Make has_required_stats
* Make has_combat_reqs
* Update er_rules for new combat reqs
* Fix all the broken things ever
* Remove outdated todo
* Make temp option for testing logic
* More flexible choices for combat items
* Hard require sword for bosses
* Temporarily default combat logic to on
* Finish writing overworld combat logic
* East Forest combat logic done
* Remove a few easy ones
* Finish beneath the well
* Dark Tomb combat logic
* West Garden combat logic
* make unit tests checkmark again
* Weird west garden dagger house edge case
* Try block for that weird west garden edge case
* Add quarry combat logic
* Update to filter out unreachable regions outside of ER
* Fortress Grave Path logic, and a couple fixes to the west garden logic
* Fortress east shortcut logic, and rewriting the try except blocks to use finally
* Refactor to use a new function cause wow there was a lot of repeated code
* Add combat logic to the other two sets of fortress fuses
* Add combat rules to beneath the vault
* Fix missing cathedral -> elevator connection
* Combat logic for cathedral to elevator
* Add cathedral main region, rename cathedral -> cathedral entry
* Setup cathedral combat logic
* Adjust locations' regions for ER
* Add laurels zip logic to the chest in the spike room in cathedral
* Add combat logic to frog's domain
* Move frog's domain locations to regions for combat logic
* Add new frog's domain regions for combat logic
* Update region name for frog's domain
* Fix typo
* Add more regions for lower zig
* Move around lower zig regions for combat logic
* Lower Zig combat logic
* Upper zig combat logic
* Fix typo
* Fix typos
* Fix missing world.
* Update combat logic description
* Add todo
* Add todo
* Don't make zig skip if er or fixed shop is off
* Make it so zig skip is only made with fewer shops and er
* Temporarily default combat logic on
* Update test to explicitly disable combat logic
* Update test_access.py
* Slight wording changes
* Fix bugs, refactor quarry regions so you can access chests in lower quarry with ice grapples
* Run through checks you can do with magic dagger
* Run through checks you can do with magic dagger
* Add rule for entering town portal of having equipment to deal with enemies
* Add rule for atoll near the 6 crabs surrounding a poor defenseless baby slorm
* Update the rule for the chest near the 6 crabs surrounding a slorm to also possibly require laurels
* Revamp combat logic function to work properly without melee
* Add laurels rules to combat logic chests
* Modify beneath the vault bridge rule to need a lantern if combat logic is on
* Put in money logic
* Dagger or combat for swamp big skeleton chest
* Remove the 100 moneys from logic
* Modify lower zig ls drop region destinations
* Remove completed todo
* Reword combat logic option description, remove test option
* Add combat logic to slot data
* Merge Silent's missing slot data bugfix PR #3628
* Remove test combat option
* Update combat logic description
* Fix secret gathering place issue
* Fix secret gathering place issue
* Fix lower zig ls rule
* Fix accidentally removed librarian rule
* Remove redundant rule
* Update gauntlet rule to hard-require a sword
* Add test for a problematic connection
* Adjust combat logic to deal with weird edge cases so it doesn't take stuff out of logic that was previously in logic
* Fix create_item classification
* Update some comments
* Update per exempt's suggestion
* Add combat logic to the well boss fight, reorder the combat logic stuff a little to better section them off
* Add EntranceLayout option
* Add back LogicRules as an invisible option, to not break old yamls
* Fix a bug with seed group, continue changing fixed shop to entrance layout
* Fix missed fixed shop -> entrance layout spot
* Fix bug in seed groups with fixed shop on and off
* Add entrance layout to the UT regen stuff
* Put direction. in, will add them later
* Remove unused elevation from portal class
* Got like half of them in
* Finish adding all of the directions
* Add combat rule for zig front to back
* Update per Medic's suggestion
* Update ladder storage without items option description
* Mess with state with collect and remove to save like 2 seconds (never again)
* Save even more time, still never going to do this again on anything else
* Add option check for collect and remove
* Add directions to shop portals
* Update direction in Portal with default
* Move Direction above Portal
* Add decoupled option, mess with plando connection stuff
* Merge, implement verify plando directions
* Condense the stuff in change and remove to less lines (thanks medic)
* Remove unused thing
* Swap to using logicmixin instead of prog_items (thanks Vi)
* Fix consistency in stat counters
* Add back something that was needed
* Fix mistake when adding back
* Making the fix better (thanks medic)
* Make it actually return false if it gets to the backup lists and fails them
* Fix stuff after merge
* Add outlet regions, create new regions as needed for them
* Put together part of decoupled and direction pairs
* make direction pairs work
* Make decoupled work
* Make fixed shop work again
* Fix a few minor bugs
* Fix a few minor bugs
* Fix plando
* god i love programming
* Reorder portal list
* Update portal sorter for variable shops
* Add missing parameter
* Some cleanup of prints and functions
* Fix typo
* it's aliiiiiive
* Make seed groups not sync decoupled
* Add test with full-shop plando
* Fix bug with vanilla portals
* Handle plando connections and direction pair errors
* Update plando checking for decoupled
* Fix typo
* Fix exception text to be shorter
* Add some more comments
* Add todo note
* Remove unused safety thing
* Remove extra plando connections definition in options
* Make seed groups in decoupled with overlapping but not fully overlapped plando connections interact nicely without messing with what the entrances look like in the spoiler log
* Fix weird edge case that is technically user error
* Add note to fixed shop
* Fix parsing shop names in UT
* Remove debug print
* Actually make UT work
* multiworld. to world.
* Fix typo from merge
* Make it so the shops show up in the entrance hints
* Fix bug in ladder storage rules
* Remove blank line
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
#	worlds/tunic/rules.py
#	worlds/tunic/test/test_access.py
* Fix issues after merge
* Update plando connections stuff in docs
* Fix library mistake
* has_stick -> has_melee
* has_stick -> has_melee
* Add a failsafe for direction pairing
* Fix playthrough crash bug
* Remove init from logicmixin
* Updates per code review (thanks hesto)
* has_stick to has_melee in newer update
* has_stick to has_melee in newer update
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/combat_logic.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
* Cleanup more stuff after merge
* Revert "Cleanup more stuff after merge"
This reverts commit a6ee9a93da8f2fcc4413de6df6927b246017889d.
* Revert "# Conflicts:"
This reverts commit c74ccd74a45b6ad6b9abe6e339d115a0c98baf30.
* Cleanup more stuff after merge
* Swap to .get for decoupled so it works with older games probably maybe
* Fix after merge
* Fix typo
* Fix UT support with fixed shop option
* Backport plando connections fix
* Fix issue with fixed shop + decoupled
* Make the error not duplicate the while loop condition
* Fix rule for quarry back to monastery
* Fix more stuff after merge
* Make it not output anything if you set plando connections but not ER
* Add obvious note to plando connections description
* Fix after merge
* add comment to commented out connection
---------
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
											
										 
										
											2025-05-06 12:33:21 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            # I feel that syncing this one is worse than erroring out
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if bool(tunic.options.decoupled) != cls.seed_groups[group]["has_decoupled_enabled"]:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                raise OptionError(f"TUNIC: All players in the seed group {group} must "
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                  f"have Decoupled either enabled or disabled.")
							 | 
						
					
						
							
								
									
										
										
										
											2024-09-08 08:42:59 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            # off is more restrictive
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if not tunic.options.laurels_zips:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                cls.seed_groups[group]["laurels_zips"] = False
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            # lower value is more restrictive
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if tunic.options.ice_grappling < cls.seed_groups[group]["ice_grappling"]:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                cls.seed_groups[group]["ice_grappling"] = tunic.options.ice_grappling.value
							 | 
						
					
						
							
								
									
										
										
										
											2024-05-03 01:21:27 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            # lower value is more restrictive
							 | 
						
					
						
							
								
									
										
										
										
											2024-09-08 08:42:59 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            if tunic.options.ladder_storage.value < cls.seed_groups[group]["ladder_storage"]:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                cls.seed_groups[group]["ladder_storage"] = tunic.options.ladder_storage.value
							 | 
						
					
						
							
								
									
										
										
										
											2024-05-03 01:21:27 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            # laurels at 10 fairies changes logic for secret gathering place placement
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if tunic.options.laurels_location == 3:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                cls.seed_groups[group]["laurels_at_10_fairies"] = True
							 | 
						
					
						
							
								
									
										
											 
										 
										
											
												TUNIC: Entrance rando Direction Pairs + Decoupled (#3761)
* Fix merge conflict
* Fix formatting, fix rule for heir access after merge
* Writing combat logic helpers
* More helpers!
* More logic!
* Rename has_stick to has_melee, some fixes per Medic's review
* Clamp max power from sword upgrades
* Wrote the rest of the helpers
* Remove unused import
* Apply item classifications
* Create the combat logic option
* Item classification varies based on option
* Add the shop sword logic stuff in
* Add the rules for the boss-only option
* Fix tiny issues
* Some early Overworld combat logic
* Fill out swamp combat logic
* Add note
* Bump up Boss Scav and Heir
* More revisions to combat logic
* Some changes, currently broken
* New system for power, kinda jank probably
* Revisions to new system, needs more balancing
* Cap attack upgrades
* Uncap mp power since it's directly related to damage output
* Voidlings
* Put together a table showing the vanilla-expected stats for each area
* Added some info on potion counts
* Made new helper functions
* Make has_required_stats
* Make has_combat_reqs
* Update er_rules for new combat reqs
* Fix all the broken things ever
* Remove outdated todo
* Make temp option for testing logic
* More flexible choices for combat items
* Hard require sword for bosses
* Temporarily default combat logic to on
* Finish writing overworld combat logic
* East Forest combat logic done
* Remove a few easy ones
* Finish beneath the well
* Dark Tomb combat logic
* West Garden combat logic
* make unit tests checkmark again
* Weird west garden dagger house edge case
* Try block for that weird west garden edge case
* Add quarry combat logic
* Update to filter out unreachable regions outside of ER
* Fortress Grave Path logic, and a couple fixes to the west garden logic
* Fortress east shortcut logic, and rewriting the try except blocks to use finally
* Refactor to use a new function cause wow there was a lot of repeated code
* Add combat logic to the other two sets of fortress fuses
* Add combat rules to beneath the vault
* Fix missing cathedral -> elevator connection
* Combat logic for cathedral to elevator
* Add cathedral main region, rename cathedral -> cathedral entry
* Setup cathedral combat logic
* Adjust locations' regions for ER
* Add laurels zip logic to the chest in the spike room in cathedral
* Add combat logic to frog's domain
* Move frog's domain locations to regions for combat logic
* Add new frog's domain regions for combat logic
* Update region name for frog's domain
* Fix typo
* Add more regions for lower zig
* Move around lower zig regions for combat logic
* Lower Zig combat logic
* Upper zig combat logic
* Fix typo
* Fix typos
* Fix missing world.
* Update combat logic description
* Add todo
* Add todo
* Don't make zig skip if er or fixed shop is off
* Make it so zig skip is only made with fewer shops and er
* Temporarily default combat logic on
* Update test to explicitly disable combat logic
* Update test_access.py
* Slight wording changes
* Fix bugs, refactor quarry regions so you can access chests in lower quarry with ice grapples
* Run through checks you can do with magic dagger
* Run through checks you can do with magic dagger
* Add rule for entering town portal of having equipment to deal with enemies
* Add rule for atoll near the 6 crabs surrounding a poor defenseless baby slorm
* Update the rule for the chest near the 6 crabs surrounding a slorm to also possibly require laurels
* Revamp combat logic function to work properly without melee
* Add laurels rules to combat logic chests
* Modify beneath the vault bridge rule to need a lantern if combat logic is on
* Put in money logic
* Dagger or combat for swamp big skeleton chest
* Remove the 100 moneys from logic
* Modify lower zig ls drop region destinations
* Remove completed todo
* Reword combat logic option description, remove test option
* Add combat logic to slot data
* Merge Silent's missing slot data bugfix PR #3628
* Remove test combat option
* Update combat logic description
* Fix secret gathering place issue
* Fix secret gathering place issue
* Fix lower zig ls rule
* Fix accidentally removed librarian rule
* Remove redundant rule
* Update gauntlet rule to hard-require a sword
* Add test for a problematic connection
* Adjust combat logic to deal with weird edge cases so it doesn't take stuff out of logic that was previously in logic
* Fix create_item classification
* Update some comments
* Update per exempt's suggestion
* Add combat logic to the well boss fight, reorder the combat logic stuff a little to better section them off
* Add EntranceLayout option
* Add back LogicRules as an invisible option, to not break old yamls
* Fix a bug with seed group, continue changing fixed shop to entrance layout
* Fix missed fixed shop -> entrance layout spot
* Fix bug in seed groups with fixed shop on and off
* Add entrance layout to the UT regen stuff
* Put direction. in, will add them later
* Remove unused elevation from portal class
* Got like half of them in
* Finish adding all of the directions
* Add combat rule for zig front to back
* Update per Medic's suggestion
* Update ladder storage without items option description
* Mess with state with collect and remove to save like 2 seconds (never again)
* Save even more time, still never going to do this again on anything else
* Add option check for collect and remove
* Add directions to shop portals
* Update direction in Portal with default
* Move Direction above Portal
* Add decoupled option, mess with plando connection stuff
* Merge, implement verify plando directions
* Condense the stuff in change and remove to less lines (thanks medic)
* Remove unused thing
* Swap to using logicmixin instead of prog_items (thanks Vi)
* Fix consistency in stat counters
* Add back something that was needed
* Fix mistake when adding back
* Making the fix better (thanks medic)
* Make it actually return false if it gets to the backup lists and fails them
* Fix stuff after merge
* Add outlet regions, create new regions as needed for them
* Put together part of decoupled and direction pairs
* make direction pairs work
* Make decoupled work
* Make fixed shop work again
* Fix a few minor bugs
* Fix a few minor bugs
* Fix plando
* god i love programming
* Reorder portal list
* Update portal sorter for variable shops
* Add missing parameter
* Some cleanup of prints and functions
* Fix typo
* it's aliiiiiive
* Make seed groups not sync decoupled
* Add test with full-shop plando
* Fix bug with vanilla portals
* Handle plando connections and direction pair errors
* Update plando checking for decoupled
* Fix typo
* Fix exception text to be shorter
* Add some more comments
* Add todo note
* Remove unused safety thing
* Remove extra plando connections definition in options
* Make seed groups in decoupled with overlapping but not fully overlapped plando connections interact nicely without messing with what the entrances look like in the spoiler log
* Fix weird edge case that is technically user error
* Add note to fixed shop
* Fix parsing shop names in UT
* Remove debug print
* Actually make UT work
* multiworld. to world.
* Fix typo from merge
* Make it so the shops show up in the entrance hints
* Fix bug in ladder storage rules
* Remove blank line
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
#	worlds/tunic/rules.py
#	worlds/tunic/test/test_access.py
* Fix issues after merge
* Update plando connections stuff in docs
* Fix library mistake
* has_stick -> has_melee
* has_stick -> has_melee
* Add a failsafe for direction pairing
* Fix playthrough crash bug
* Remove init from logicmixin
* Updates per code review (thanks hesto)
* has_stick to has_melee in newer update
* has_stick to has_melee in newer update
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/combat_logic.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
* Cleanup more stuff after merge
* Revert "Cleanup more stuff after merge"
This reverts commit a6ee9a93da8f2fcc4413de6df6927b246017889d.
* Revert "# Conflicts:"
This reverts commit c74ccd74a45b6ad6b9abe6e339d115a0c98baf30.
* Cleanup more stuff after merge
* Swap to .get for decoupled so it works with older games probably maybe
* Fix after merge
* Fix typo
* Fix UT support with fixed shop option
* Backport plando connections fix
* Fix issue with fixed shop + decoupled
* Make the error not duplicate the while loop condition
* Fix rule for quarry back to monastery
* Fix more stuff after merge
* Make it not output anything if you set plando connections but not ER
* Add obvious note to plando connections description
* Fix after merge
* add comment to commented out connection
---------
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
											
										 
										
											2025-05-06 12:33:21 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            # fixed shop and direction pairs override standard, but conflict with each other
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if tunic.options.entrance_layout:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if cls.seed_groups[group]["entrance_layout"] == EntranceLayout.option_standard:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    cls.seed_groups[group]["entrance_layout"] = tunic.options.entrance_layout.value
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                elif cls.seed_groups[group]["entrance_layout"] != tunic.options.entrance_layout.value:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    raise OptionError(f"TUNIC: Conflict between seed group {group}'s Entrance Layout options. "
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                      f"Seed group cannot have both Fixed Shop and Direction Pairs enabled.")
							 | 
						
					
						
							
								
									
										
										
										
											2024-07-27 17:17:59 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            if tunic.options.plando_connections:
							 | 
						
					
						
							
								
									
										
										
										
											2024-05-03 01:21:27 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                # loop through the connections in the player's yaml
							 | 
						
					
						
							
								
									
										
											 
										 
										
											
												TUNIC: Entrance rando Direction Pairs + Decoupled (#3761)
* Fix merge conflict
* Fix formatting, fix rule for heir access after merge
* Writing combat logic helpers
* More helpers!
* More logic!
* Rename has_stick to has_melee, some fixes per Medic's review
* Clamp max power from sword upgrades
* Wrote the rest of the helpers
* Remove unused import
* Apply item classifications
* Create the combat logic option
* Item classification varies based on option
* Add the shop sword logic stuff in
* Add the rules for the boss-only option
* Fix tiny issues
* Some early Overworld combat logic
* Fill out swamp combat logic
* Add note
* Bump up Boss Scav and Heir
* More revisions to combat logic
* Some changes, currently broken
* New system for power, kinda jank probably
* Revisions to new system, needs more balancing
* Cap attack upgrades
* Uncap mp power since it's directly related to damage output
* Voidlings
* Put together a table showing the vanilla-expected stats for each area
* Added some info on potion counts
* Made new helper functions
* Make has_required_stats
* Make has_combat_reqs
* Update er_rules for new combat reqs
* Fix all the broken things ever
* Remove outdated todo
* Make temp option for testing logic
* More flexible choices for combat items
* Hard require sword for bosses
* Temporarily default combat logic to on
* Finish writing overworld combat logic
* East Forest combat logic done
* Remove a few easy ones
* Finish beneath the well
* Dark Tomb combat logic
* West Garden combat logic
* make unit tests checkmark again
* Weird west garden dagger house edge case
* Try block for that weird west garden edge case
* Add quarry combat logic
* Update to filter out unreachable regions outside of ER
* Fortress Grave Path logic, and a couple fixes to the west garden logic
* Fortress east shortcut logic, and rewriting the try except blocks to use finally
* Refactor to use a new function cause wow there was a lot of repeated code
* Add combat logic to the other two sets of fortress fuses
* Add combat rules to beneath the vault
* Fix missing cathedral -> elevator connection
* Combat logic for cathedral to elevator
* Add cathedral main region, rename cathedral -> cathedral entry
* Setup cathedral combat logic
* Adjust locations' regions for ER
* Add laurels zip logic to the chest in the spike room in cathedral
* Add combat logic to frog's domain
* Move frog's domain locations to regions for combat logic
* Add new frog's domain regions for combat logic
* Update region name for frog's domain
* Fix typo
* Add more regions for lower zig
* Move around lower zig regions for combat logic
* Lower Zig combat logic
* Upper zig combat logic
* Fix typo
* Fix typos
* Fix missing world.
* Update combat logic description
* Add todo
* Add todo
* Don't make zig skip if er or fixed shop is off
* Make it so zig skip is only made with fewer shops and er
* Temporarily default combat logic on
* Update test to explicitly disable combat logic
* Update test_access.py
* Slight wording changes
* Fix bugs, refactor quarry regions so you can access chests in lower quarry with ice grapples
* Run through checks you can do with magic dagger
* Run through checks you can do with magic dagger
* Add rule for entering town portal of having equipment to deal with enemies
* Add rule for atoll near the 6 crabs surrounding a poor defenseless baby slorm
* Update the rule for the chest near the 6 crabs surrounding a slorm to also possibly require laurels
* Revamp combat logic function to work properly without melee
* Add laurels rules to combat logic chests
* Modify beneath the vault bridge rule to need a lantern if combat logic is on
* Put in money logic
* Dagger or combat for swamp big skeleton chest
* Remove the 100 moneys from logic
* Modify lower zig ls drop region destinations
* Remove completed todo
* Reword combat logic option description, remove test option
* Add combat logic to slot data
* Merge Silent's missing slot data bugfix PR #3628
* Remove test combat option
* Update combat logic description
* Fix secret gathering place issue
* Fix secret gathering place issue
* Fix lower zig ls rule
* Fix accidentally removed librarian rule
* Remove redundant rule
* Update gauntlet rule to hard-require a sword
* Add test for a problematic connection
* Adjust combat logic to deal with weird edge cases so it doesn't take stuff out of logic that was previously in logic
* Fix create_item classification
* Update some comments
* Update per exempt's suggestion
* Add combat logic to the well boss fight, reorder the combat logic stuff a little to better section them off
* Add EntranceLayout option
* Add back LogicRules as an invisible option, to not break old yamls
* Fix a bug with seed group, continue changing fixed shop to entrance layout
* Fix missed fixed shop -> entrance layout spot
* Fix bug in seed groups with fixed shop on and off
* Add entrance layout to the UT regen stuff
* Put direction. in, will add them later
* Remove unused elevation from portal class
* Got like half of them in
* Finish adding all of the directions
* Add combat rule for zig front to back
* Update per Medic's suggestion
* Update ladder storage without items option description
* Mess with state with collect and remove to save like 2 seconds (never again)
* Save even more time, still never going to do this again on anything else
* Add option check for collect and remove
* Add directions to shop portals
* Update direction in Portal with default
* Move Direction above Portal
* Add decoupled option, mess with plando connection stuff
* Merge, implement verify plando directions
* Condense the stuff in change and remove to less lines (thanks medic)
* Remove unused thing
* Swap to using logicmixin instead of prog_items (thanks Vi)
* Fix consistency in stat counters
* Add back something that was needed
* Fix mistake when adding back
* Making the fix better (thanks medic)
* Make it actually return false if it gets to the backup lists and fails them
* Fix stuff after merge
* Add outlet regions, create new regions as needed for them
* Put together part of decoupled and direction pairs
* make direction pairs work
* Make decoupled work
* Make fixed shop work again
* Fix a few minor bugs
* Fix a few minor bugs
* Fix plando
* god i love programming
* Reorder portal list
* Update portal sorter for variable shops
* Add missing parameter
* Some cleanup of prints and functions
* Fix typo
* it's aliiiiiive
* Make seed groups not sync decoupled
* Add test with full-shop plando
* Fix bug with vanilla portals
* Handle plando connections and direction pair errors
* Update plando checking for decoupled
* Fix typo
* Fix exception text to be shorter
* Add some more comments
* Add todo note
* Remove unused safety thing
* Remove extra plando connections definition in options
* Make seed groups in decoupled with overlapping but not fully overlapped plando connections interact nicely without messing with what the entrances look like in the spoiler log
* Fix weird edge case that is technically user error
* Add note to fixed shop
* Fix parsing shop names in UT
* Remove debug print
* Actually make UT work
* multiworld. to world.
* Fix typo from merge
* Make it so the shops show up in the entrance hints
* Fix bug in ladder storage rules
* Remove blank line
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
#	worlds/tunic/rules.py
#	worlds/tunic/test/test_access.py
* Fix issues after merge
* Update plando connections stuff in docs
* Fix library mistake
* has_stick -> has_melee
* has_stick -> has_melee
* Add a failsafe for direction pairing
* Fix playthrough crash bug
* Remove init from logicmixin
* Updates per code review (thanks hesto)
* has_stick to has_melee in newer update
* has_stick to has_melee in newer update
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/combat_logic.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
* Cleanup more stuff after merge
* Revert "Cleanup more stuff after merge"
This reverts commit a6ee9a93da8f2fcc4413de6df6927b246017889d.
* Revert "# Conflicts:"
This reverts commit c74ccd74a45b6ad6b9abe6e339d115a0c98baf30.
* Cleanup more stuff after merge
* Swap to .get for decoupled so it works with older games probably maybe
* Fix after merge
* Fix typo
* Fix UT support with fixed shop option
* Backport plando connections fix
* Fix issue with fixed shop + decoupled
* Make the error not duplicate the while loop condition
* Fix rule for quarry back to monastery
* Fix more stuff after merge
* Make it not output anything if you set plando connections but not ER
* Add obvious note to plando connections description
* Fix after merge
* add comment to commented out connection
---------
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
											
										 
										
											2025-05-06 12:33:21 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                for index, player_cxn in enumerate(tunic.options.plando_connections):
							 | 
						
					
						
							
								
									
										
										
										
											2024-05-03 01:21:27 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    new_cxn = True
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    for group_cxn in cls.seed_groups[group]["plando"]:
							 | 
						
					
						
							
								
									
										
											 
										 
										
											
												TUNIC: Entrance rando Direction Pairs + Decoupled (#3761)
* Fix merge conflict
* Fix formatting, fix rule for heir access after merge
* Writing combat logic helpers
* More helpers!
* More logic!
* Rename has_stick to has_melee, some fixes per Medic's review
* Clamp max power from sword upgrades
* Wrote the rest of the helpers
* Remove unused import
* Apply item classifications
* Create the combat logic option
* Item classification varies based on option
* Add the shop sword logic stuff in
* Add the rules for the boss-only option
* Fix tiny issues
* Some early Overworld combat logic
* Fill out swamp combat logic
* Add note
* Bump up Boss Scav and Heir
* More revisions to combat logic
* Some changes, currently broken
* New system for power, kinda jank probably
* Revisions to new system, needs more balancing
* Cap attack upgrades
* Uncap mp power since it's directly related to damage output
* Voidlings
* Put together a table showing the vanilla-expected stats for each area
* Added some info on potion counts
* Made new helper functions
* Make has_required_stats
* Make has_combat_reqs
* Update er_rules for new combat reqs
* Fix all the broken things ever
* Remove outdated todo
* Make temp option for testing logic
* More flexible choices for combat items
* Hard require sword for bosses
* Temporarily default combat logic to on
* Finish writing overworld combat logic
* East Forest combat logic done
* Remove a few easy ones
* Finish beneath the well
* Dark Tomb combat logic
* West Garden combat logic
* make unit tests checkmark again
* Weird west garden dagger house edge case
* Try block for that weird west garden edge case
* Add quarry combat logic
* Update to filter out unreachable regions outside of ER
* Fortress Grave Path logic, and a couple fixes to the west garden logic
* Fortress east shortcut logic, and rewriting the try except blocks to use finally
* Refactor to use a new function cause wow there was a lot of repeated code
* Add combat logic to the other two sets of fortress fuses
* Add combat rules to beneath the vault
* Fix missing cathedral -> elevator connection
* Combat logic for cathedral to elevator
* Add cathedral main region, rename cathedral -> cathedral entry
* Setup cathedral combat logic
* Adjust locations' regions for ER
* Add laurels zip logic to the chest in the spike room in cathedral
* Add combat logic to frog's domain
* Move frog's domain locations to regions for combat logic
* Add new frog's domain regions for combat logic
* Update region name for frog's domain
* Fix typo
* Add more regions for lower zig
* Move around lower zig regions for combat logic
* Lower Zig combat logic
* Upper zig combat logic
* Fix typo
* Fix typos
* Fix missing world.
* Update combat logic description
* Add todo
* Add todo
* Don't make zig skip if er or fixed shop is off
* Make it so zig skip is only made with fewer shops and er
* Temporarily default combat logic on
* Update test to explicitly disable combat logic
* Update test_access.py
* Slight wording changes
* Fix bugs, refactor quarry regions so you can access chests in lower quarry with ice grapples
* Run through checks you can do with magic dagger
* Run through checks you can do with magic dagger
* Add rule for entering town portal of having equipment to deal with enemies
* Add rule for atoll near the 6 crabs surrounding a poor defenseless baby slorm
* Update the rule for the chest near the 6 crabs surrounding a slorm to also possibly require laurels
* Revamp combat logic function to work properly without melee
* Add laurels rules to combat logic chests
* Modify beneath the vault bridge rule to need a lantern if combat logic is on
* Put in money logic
* Dagger or combat for swamp big skeleton chest
* Remove the 100 moneys from logic
* Modify lower zig ls drop region destinations
* Remove completed todo
* Reword combat logic option description, remove test option
* Add combat logic to slot data
* Merge Silent's missing slot data bugfix PR #3628
* Remove test combat option
* Update combat logic description
* Fix secret gathering place issue
* Fix secret gathering place issue
* Fix lower zig ls rule
* Fix accidentally removed librarian rule
* Remove redundant rule
* Update gauntlet rule to hard-require a sword
* Add test for a problematic connection
* Adjust combat logic to deal with weird edge cases so it doesn't take stuff out of logic that was previously in logic
* Fix create_item classification
* Update some comments
* Update per exempt's suggestion
* Add combat logic to the well boss fight, reorder the combat logic stuff a little to better section them off
* Add EntranceLayout option
* Add back LogicRules as an invisible option, to not break old yamls
* Fix a bug with seed group, continue changing fixed shop to entrance layout
* Fix missed fixed shop -> entrance layout spot
* Fix bug in seed groups with fixed shop on and off
* Add entrance layout to the UT regen stuff
* Put direction. in, will add them later
* Remove unused elevation from portal class
* Got like half of them in
* Finish adding all of the directions
* Add combat rule for zig front to back
* Update per Medic's suggestion
* Update ladder storage without items option description
* Mess with state with collect and remove to save like 2 seconds (never again)
* Save even more time, still never going to do this again on anything else
* Add option check for collect and remove
* Add directions to shop portals
* Update direction in Portal with default
* Move Direction above Portal
* Add decoupled option, mess with plando connection stuff
* Merge, implement verify plando directions
* Condense the stuff in change and remove to less lines (thanks medic)
* Remove unused thing
* Swap to using logicmixin instead of prog_items (thanks Vi)
* Fix consistency in stat counters
* Add back something that was needed
* Fix mistake when adding back
* Making the fix better (thanks medic)
* Make it actually return false if it gets to the backup lists and fails them
* Fix stuff after merge
* Add outlet regions, create new regions as needed for them
* Put together part of decoupled and direction pairs
* make direction pairs work
* Make decoupled work
* Make fixed shop work again
* Fix a few minor bugs
* Fix a few minor bugs
* Fix plando
* god i love programming
* Reorder portal list
* Update portal sorter for variable shops
* Add missing parameter
* Some cleanup of prints and functions
* Fix typo
* it's aliiiiiive
* Make seed groups not sync decoupled
* Add test with full-shop plando
* Fix bug with vanilla portals
* Handle plando connections and direction pair errors
* Update plando checking for decoupled
* Fix typo
* Fix exception text to be shorter
* Add some more comments
* Add todo note
* Remove unused safety thing
* Remove extra plando connections definition in options
* Make seed groups in decoupled with overlapping but not fully overlapped plando connections interact nicely without messing with what the entrances look like in the spoiler log
* Fix weird edge case that is technically user error
* Add note to fixed shop
* Fix parsing shop names in UT
* Remove debug print
* Actually make UT work
* multiworld. to world.
* Fix typo from merge
* Make it so the shops show up in the entrance hints
* Fix bug in ladder storage rules
* Remove blank line
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
#	worlds/tunic/rules.py
#	worlds/tunic/test/test_access.py
* Fix issues after merge
* Update plando connections stuff in docs
* Fix library mistake
* has_stick -> has_melee
* has_stick -> has_melee
* Add a failsafe for direction pairing
* Fix playthrough crash bug
* Remove init from logicmixin
* Updates per code review (thanks hesto)
* has_stick to has_melee in newer update
* has_stick to has_melee in newer update
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/combat_logic.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
* Cleanup more stuff after merge
* Revert "Cleanup more stuff after merge"
This reverts commit a6ee9a93da8f2fcc4413de6df6927b246017889d.
* Revert "# Conflicts:"
This reverts commit c74ccd74a45b6ad6b9abe6e339d115a0c98baf30.
* Cleanup more stuff after merge
* Swap to .get for decoupled so it works with older games probably maybe
* Fix after merge
* Fix typo
* Fix UT support with fixed shop option
* Backport plando connections fix
* Fix issue with fixed shop + decoupled
* Make the error not duplicate the while loop condition
* Fix rule for quarry back to monastery
* Fix more stuff after merge
* Make it not output anything if you set plando connections but not ER
* Add obvious note to plando connections description
* Fix after merge
* add comment to commented out connection
---------
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
											
										 
										
											2025-05-06 12:33:21 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                        # verify that it abides by direction pairs if enabled
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        if (cls.seed_groups[group]["entrance_layout"] == EntranceLayout.option_direction_pairs
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                and not verify_plando_directions(player_cxn)):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            player_dir = "<->" if player_cxn.direction == "both" else "-->"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            raise Exception(f"TUNIC: Conflict between Entrance Layout option and Plando Connection: "
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                            f"{player_cxn.entrance} {player_dir} {player_cxn.exit}")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        # check if this pair is the same as a pair in the group already
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        if ((player_cxn.entrance == group_cxn.entrance and player_cxn.exit == group_cxn.exit)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            or (player_cxn.entrance == group_cxn.exit and player_cxn.exit == group_cxn.entrance
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                and "both" in [player_cxn.direction, group_cxn.direction])):
							 | 
						
					
						
							
								
									
										
										
										
											2024-05-03 01:21:27 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                            new_cxn = False
							 | 
						
					
						
							
								
									
										
											 
										 
										
											
												TUNIC: Entrance rando Direction Pairs + Decoupled (#3761)
* Fix merge conflict
* Fix formatting, fix rule for heir access after merge
* Writing combat logic helpers
* More helpers!
* More logic!
* Rename has_stick to has_melee, some fixes per Medic's review
* Clamp max power from sword upgrades
* Wrote the rest of the helpers
* Remove unused import
* Apply item classifications
* Create the combat logic option
* Item classification varies based on option
* Add the shop sword logic stuff in
* Add the rules for the boss-only option
* Fix tiny issues
* Some early Overworld combat logic
* Fill out swamp combat logic
* Add note
* Bump up Boss Scav and Heir
* More revisions to combat logic
* Some changes, currently broken
* New system for power, kinda jank probably
* Revisions to new system, needs more balancing
* Cap attack upgrades
* Uncap mp power since it's directly related to damage output
* Voidlings
* Put together a table showing the vanilla-expected stats for each area
* Added some info on potion counts
* Made new helper functions
* Make has_required_stats
* Make has_combat_reqs
* Update er_rules for new combat reqs
* Fix all the broken things ever
* Remove outdated todo
* Make temp option for testing logic
* More flexible choices for combat items
* Hard require sword for bosses
* Temporarily default combat logic to on
* Finish writing overworld combat logic
* East Forest combat logic done
* Remove a few easy ones
* Finish beneath the well
* Dark Tomb combat logic
* West Garden combat logic
* make unit tests checkmark again
* Weird west garden dagger house edge case
* Try block for that weird west garden edge case
* Add quarry combat logic
* Update to filter out unreachable regions outside of ER
* Fortress Grave Path logic, and a couple fixes to the west garden logic
* Fortress east shortcut logic, and rewriting the try except blocks to use finally
* Refactor to use a new function cause wow there was a lot of repeated code
* Add combat logic to the other two sets of fortress fuses
* Add combat rules to beneath the vault
* Fix missing cathedral -> elevator connection
* Combat logic for cathedral to elevator
* Add cathedral main region, rename cathedral -> cathedral entry
* Setup cathedral combat logic
* Adjust locations' regions for ER
* Add laurels zip logic to the chest in the spike room in cathedral
* Add combat logic to frog's domain
* Move frog's domain locations to regions for combat logic
* Add new frog's domain regions for combat logic
* Update region name for frog's domain
* Fix typo
* Add more regions for lower zig
* Move around lower zig regions for combat logic
* Lower Zig combat logic
* Upper zig combat logic
* Fix typo
* Fix typos
* Fix missing world.
* Update combat logic description
* Add todo
* Add todo
* Don't make zig skip if er or fixed shop is off
* Make it so zig skip is only made with fewer shops and er
* Temporarily default combat logic on
* Update test to explicitly disable combat logic
* Update test_access.py
* Slight wording changes
* Fix bugs, refactor quarry regions so you can access chests in lower quarry with ice grapples
* Run through checks you can do with magic dagger
* Run through checks you can do with magic dagger
* Add rule for entering town portal of having equipment to deal with enemies
* Add rule for atoll near the 6 crabs surrounding a poor defenseless baby slorm
* Update the rule for the chest near the 6 crabs surrounding a slorm to also possibly require laurels
* Revamp combat logic function to work properly without melee
* Add laurels rules to combat logic chests
* Modify beneath the vault bridge rule to need a lantern if combat logic is on
* Put in money logic
* Dagger or combat for swamp big skeleton chest
* Remove the 100 moneys from logic
* Modify lower zig ls drop region destinations
* Remove completed todo
* Reword combat logic option description, remove test option
* Add combat logic to slot data
* Merge Silent's missing slot data bugfix PR #3628
* Remove test combat option
* Update combat logic description
* Fix secret gathering place issue
* Fix secret gathering place issue
* Fix lower zig ls rule
* Fix accidentally removed librarian rule
* Remove redundant rule
* Update gauntlet rule to hard-require a sword
* Add test for a problematic connection
* Adjust combat logic to deal with weird edge cases so it doesn't take stuff out of logic that was previously in logic
* Fix create_item classification
* Update some comments
* Update per exempt's suggestion
* Add combat logic to the well boss fight, reorder the combat logic stuff a little to better section them off
* Add EntranceLayout option
* Add back LogicRules as an invisible option, to not break old yamls
* Fix a bug with seed group, continue changing fixed shop to entrance layout
* Fix missed fixed shop -> entrance layout spot
* Fix bug in seed groups with fixed shop on and off
* Add entrance layout to the UT regen stuff
* Put direction. in, will add them later
* Remove unused elevation from portal class
* Got like half of them in
* Finish adding all of the directions
* Add combat rule for zig front to back
* Update per Medic's suggestion
* Update ladder storage without items option description
* Mess with state with collect and remove to save like 2 seconds (never again)
* Save even more time, still never going to do this again on anything else
* Add option check for collect and remove
* Add directions to shop portals
* Update direction in Portal with default
* Move Direction above Portal
* Add decoupled option, mess with plando connection stuff
* Merge, implement verify plando directions
* Condense the stuff in change and remove to less lines (thanks medic)
* Remove unused thing
* Swap to using logicmixin instead of prog_items (thanks Vi)
* Fix consistency in stat counters
* Add back something that was needed
* Fix mistake when adding back
* Making the fix better (thanks medic)
* Make it actually return false if it gets to the backup lists and fails them
* Fix stuff after merge
* Add outlet regions, create new regions as needed for them
* Put together part of decoupled and direction pairs
* make direction pairs work
* Make decoupled work
* Make fixed shop work again
* Fix a few minor bugs
* Fix a few minor bugs
* Fix plando
* god i love programming
* Reorder portal list
* Update portal sorter for variable shops
* Add missing parameter
* Some cleanup of prints and functions
* Fix typo
* it's aliiiiiive
* Make seed groups not sync decoupled
* Add test with full-shop plando
* Fix bug with vanilla portals
* Handle plando connections and direction pair errors
* Update plando checking for decoupled
* Fix typo
* Fix exception text to be shorter
* Add some more comments
* Add todo note
* Remove unused safety thing
* Remove extra plando connections definition in options
* Make seed groups in decoupled with overlapping but not fully overlapped plando connections interact nicely without messing with what the entrances look like in the spoiler log
* Fix weird edge case that is technically user error
* Add note to fixed shop
* Fix parsing shop names in UT
* Remove debug print
* Actually make UT work
* multiworld. to world.
* Fix typo from merge
* Make it so the shops show up in the entrance hints
* Fix bug in ladder storage rules
* Remove blank line
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
#	worlds/tunic/rules.py
#	worlds/tunic/test/test_access.py
* Fix issues after merge
* Update plando connections stuff in docs
* Fix library mistake
* has_stick -> has_melee
* has_stick -> has_melee
* Add a failsafe for direction pairing
* Fix playthrough crash bug
* Remove init from logicmixin
* Updates per code review (thanks hesto)
* has_stick to has_melee in newer update
* has_stick to has_melee in newer update
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/combat_logic.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
* Cleanup more stuff after merge
* Revert "Cleanup more stuff after merge"
This reverts commit a6ee9a93da8f2fcc4413de6df6927b246017889d.
* Revert "# Conflicts:"
This reverts commit c74ccd74a45b6ad6b9abe6e339d115a0c98baf30.
* Cleanup more stuff after merge
* Swap to .get for decoupled so it works with older games probably maybe
* Fix after merge
* Fix typo
* Fix UT support with fixed shop option
* Backport plando connections fix
* Fix issue with fixed shop + decoupled
* Make the error not duplicate the while loop condition
* Fix rule for quarry back to monastery
* Fix more stuff after merge
* Make it not output anything if you set plando connections but not ER
* Add obvious note to plando connections description
* Fix after merge
* add comment to commented out connection
---------
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
											
										 
										
											2025-05-06 12:33:21 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                            # if the group's was one-way and the player's was two-way, we replace the group's now
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            if player_cxn.direction == "both" and group_cxn.direction == "entrance":
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                cls.seed_groups[group]["plando"].remove(group_cxn)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                cls.seed_groups[group]["plando"].insert(index, player_cxn)
							 | 
						
					
						
							
								
									
										
										
										
											2024-05-03 01:21:27 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                            break
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        is_mismatched = (
							 | 
						
					
						
							
								
									
										
											 
										 
										
											
												TUNIC: Entrance rando Direction Pairs + Decoupled (#3761)
* Fix merge conflict
* Fix formatting, fix rule for heir access after merge
* Writing combat logic helpers
* More helpers!
* More logic!
* Rename has_stick to has_melee, some fixes per Medic's review
* Clamp max power from sword upgrades
* Wrote the rest of the helpers
* Remove unused import
* Apply item classifications
* Create the combat logic option
* Item classification varies based on option
* Add the shop sword logic stuff in
* Add the rules for the boss-only option
* Fix tiny issues
* Some early Overworld combat logic
* Fill out swamp combat logic
* Add note
* Bump up Boss Scav and Heir
* More revisions to combat logic
* Some changes, currently broken
* New system for power, kinda jank probably
* Revisions to new system, needs more balancing
* Cap attack upgrades
* Uncap mp power since it's directly related to damage output
* Voidlings
* Put together a table showing the vanilla-expected stats for each area
* Added some info on potion counts
* Made new helper functions
* Make has_required_stats
* Make has_combat_reqs
* Update er_rules for new combat reqs
* Fix all the broken things ever
* Remove outdated todo
* Make temp option for testing logic
* More flexible choices for combat items
* Hard require sword for bosses
* Temporarily default combat logic to on
* Finish writing overworld combat logic
* East Forest combat logic done
* Remove a few easy ones
* Finish beneath the well
* Dark Tomb combat logic
* West Garden combat logic
* make unit tests checkmark again
* Weird west garden dagger house edge case
* Try block for that weird west garden edge case
* Add quarry combat logic
* Update to filter out unreachable regions outside of ER
* Fortress Grave Path logic, and a couple fixes to the west garden logic
* Fortress east shortcut logic, and rewriting the try except blocks to use finally
* Refactor to use a new function cause wow there was a lot of repeated code
* Add combat logic to the other two sets of fortress fuses
* Add combat rules to beneath the vault
* Fix missing cathedral -> elevator connection
* Combat logic for cathedral to elevator
* Add cathedral main region, rename cathedral -> cathedral entry
* Setup cathedral combat logic
* Adjust locations' regions for ER
* Add laurels zip logic to the chest in the spike room in cathedral
* Add combat logic to frog's domain
* Move frog's domain locations to regions for combat logic
* Add new frog's domain regions for combat logic
* Update region name for frog's domain
* Fix typo
* Add more regions for lower zig
* Move around lower zig regions for combat logic
* Lower Zig combat logic
* Upper zig combat logic
* Fix typo
* Fix typos
* Fix missing world.
* Update combat logic description
* Add todo
* Add todo
* Don't make zig skip if er or fixed shop is off
* Make it so zig skip is only made with fewer shops and er
* Temporarily default combat logic on
* Update test to explicitly disable combat logic
* Update test_access.py
* Slight wording changes
* Fix bugs, refactor quarry regions so you can access chests in lower quarry with ice grapples
* Run through checks you can do with magic dagger
* Run through checks you can do with magic dagger
* Add rule for entering town portal of having equipment to deal with enemies
* Add rule for atoll near the 6 crabs surrounding a poor defenseless baby slorm
* Update the rule for the chest near the 6 crabs surrounding a slorm to also possibly require laurels
* Revamp combat logic function to work properly without melee
* Add laurels rules to combat logic chests
* Modify beneath the vault bridge rule to need a lantern if combat logic is on
* Put in money logic
* Dagger or combat for swamp big skeleton chest
* Remove the 100 moneys from logic
* Modify lower zig ls drop region destinations
* Remove completed todo
* Reword combat logic option description, remove test option
* Add combat logic to slot data
* Merge Silent's missing slot data bugfix PR #3628
* Remove test combat option
* Update combat logic description
* Fix secret gathering place issue
* Fix secret gathering place issue
* Fix lower zig ls rule
* Fix accidentally removed librarian rule
* Remove redundant rule
* Update gauntlet rule to hard-require a sword
* Add test for a problematic connection
* Adjust combat logic to deal with weird edge cases so it doesn't take stuff out of logic that was previously in logic
* Fix create_item classification
* Update some comments
* Update per exempt's suggestion
* Add combat logic to the well boss fight, reorder the combat logic stuff a little to better section them off
* Add EntranceLayout option
* Add back LogicRules as an invisible option, to not break old yamls
* Fix a bug with seed group, continue changing fixed shop to entrance layout
* Fix missed fixed shop -> entrance layout spot
* Fix bug in seed groups with fixed shop on and off
* Add entrance layout to the UT regen stuff
* Put direction. in, will add them later
* Remove unused elevation from portal class
* Got like half of them in
* Finish adding all of the directions
* Add combat rule for zig front to back
* Update per Medic's suggestion
* Update ladder storage without items option description
* Mess with state with collect and remove to save like 2 seconds (never again)
* Save even more time, still never going to do this again on anything else
* Add option check for collect and remove
* Add directions to shop portals
* Update direction in Portal with default
* Move Direction above Portal
* Add decoupled option, mess with plando connection stuff
* Merge, implement verify plando directions
* Condense the stuff in change and remove to less lines (thanks medic)
* Remove unused thing
* Swap to using logicmixin instead of prog_items (thanks Vi)
* Fix consistency in stat counters
* Add back something that was needed
* Fix mistake when adding back
* Making the fix better (thanks medic)
* Make it actually return false if it gets to the backup lists and fails them
* Fix stuff after merge
* Add outlet regions, create new regions as needed for them
* Put together part of decoupled and direction pairs
* make direction pairs work
* Make decoupled work
* Make fixed shop work again
* Fix a few minor bugs
* Fix a few minor bugs
* Fix plando
* god i love programming
* Reorder portal list
* Update portal sorter for variable shops
* Add missing parameter
* Some cleanup of prints and functions
* Fix typo
* it's aliiiiiive
* Make seed groups not sync decoupled
* Add test with full-shop plando
* Fix bug with vanilla portals
* Handle plando connections and direction pair errors
* Update plando checking for decoupled
* Fix typo
* Fix exception text to be shorter
* Add some more comments
* Add todo note
* Remove unused safety thing
* Remove extra plando connections definition in options
* Make seed groups in decoupled with overlapping but not fully overlapped plando connections interact nicely without messing with what the entrances look like in the spoiler log
* Fix weird edge case that is technically user error
* Add note to fixed shop
* Fix parsing shop names in UT
* Remove debug print
* Actually make UT work
* multiworld. to world.
* Fix typo from merge
* Make it so the shops show up in the entrance hints
* Fix bug in ladder storage rules
* Remove blank line
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
#	worlds/tunic/rules.py
#	worlds/tunic/test/test_access.py
* Fix issues after merge
* Update plando connections stuff in docs
* Fix library mistake
* has_stick -> has_melee
* has_stick -> has_melee
* Add a failsafe for direction pairing
* Fix playthrough crash bug
* Remove init from logicmixin
* Updates per code review (thanks hesto)
* has_stick to has_melee in newer update
* has_stick to has_melee in newer update
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/combat_logic.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
* Cleanup more stuff after merge
* Revert "Cleanup more stuff after merge"
This reverts commit a6ee9a93da8f2fcc4413de6df6927b246017889d.
* Revert "# Conflicts:"
This reverts commit c74ccd74a45b6ad6b9abe6e339d115a0c98baf30.
* Cleanup more stuff after merge
* Swap to .get for decoupled so it works with older games probably maybe
* Fix after merge
* Fix typo
* Fix UT support with fixed shop option
* Backport plando connections fix
* Fix issue with fixed shop + decoupled
* Make the error not duplicate the while loop condition
* Fix rule for quarry back to monastery
* Fix more stuff after merge
* Make it not output anything if you set plando connections but not ER
* Add obvious note to plando connections description
* Fix after merge
* add comment to commented out connection
---------
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
											
										 
										
											2025-05-06 12:33:21 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                            player_cxn.entrance == group_cxn.entrance and player_cxn.exit != group_cxn.exit
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            or player_cxn.exit == group_cxn.exit and player_cxn.entrance != group_cxn.entrance
							 | 
						
					
						
							
								
									
										
										
										
											2024-05-03 01:21:27 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                        )
							 | 
						
					
						
							
								
									
										
											 
										 
										
											
												TUNIC: Entrance rando Direction Pairs + Decoupled (#3761)
* Fix merge conflict
* Fix formatting, fix rule for heir access after merge
* Writing combat logic helpers
* More helpers!
* More logic!
* Rename has_stick to has_melee, some fixes per Medic's review
* Clamp max power from sword upgrades
* Wrote the rest of the helpers
* Remove unused import
* Apply item classifications
* Create the combat logic option
* Item classification varies based on option
* Add the shop sword logic stuff in
* Add the rules for the boss-only option
* Fix tiny issues
* Some early Overworld combat logic
* Fill out swamp combat logic
* Add note
* Bump up Boss Scav and Heir
* More revisions to combat logic
* Some changes, currently broken
* New system for power, kinda jank probably
* Revisions to new system, needs more balancing
* Cap attack upgrades
* Uncap mp power since it's directly related to damage output
* Voidlings
* Put together a table showing the vanilla-expected stats for each area
* Added some info on potion counts
* Made new helper functions
* Make has_required_stats
* Make has_combat_reqs
* Update er_rules for new combat reqs
* Fix all the broken things ever
* Remove outdated todo
* Make temp option for testing logic
* More flexible choices for combat items
* Hard require sword for bosses
* Temporarily default combat logic to on
* Finish writing overworld combat logic
* East Forest combat logic done
* Remove a few easy ones
* Finish beneath the well
* Dark Tomb combat logic
* West Garden combat logic
* make unit tests checkmark again
* Weird west garden dagger house edge case
* Try block for that weird west garden edge case
* Add quarry combat logic
* Update to filter out unreachable regions outside of ER
* Fortress Grave Path logic, and a couple fixes to the west garden logic
* Fortress east shortcut logic, and rewriting the try except blocks to use finally
* Refactor to use a new function cause wow there was a lot of repeated code
* Add combat logic to the other two sets of fortress fuses
* Add combat rules to beneath the vault
* Fix missing cathedral -> elevator connection
* Combat logic for cathedral to elevator
* Add cathedral main region, rename cathedral -> cathedral entry
* Setup cathedral combat logic
* Adjust locations' regions for ER
* Add laurels zip logic to the chest in the spike room in cathedral
* Add combat logic to frog's domain
* Move frog's domain locations to regions for combat logic
* Add new frog's domain regions for combat logic
* Update region name for frog's domain
* Fix typo
* Add more regions for lower zig
* Move around lower zig regions for combat logic
* Lower Zig combat logic
* Upper zig combat logic
* Fix typo
* Fix typos
* Fix missing world.
* Update combat logic description
* Add todo
* Add todo
* Don't make zig skip if er or fixed shop is off
* Make it so zig skip is only made with fewer shops and er
* Temporarily default combat logic on
* Update test to explicitly disable combat logic
* Update test_access.py
* Slight wording changes
* Fix bugs, refactor quarry regions so you can access chests in lower quarry with ice grapples
* Run through checks you can do with magic dagger
* Run through checks you can do with magic dagger
* Add rule for entering town portal of having equipment to deal with enemies
* Add rule for atoll near the 6 crabs surrounding a poor defenseless baby slorm
* Update the rule for the chest near the 6 crabs surrounding a slorm to also possibly require laurels
* Revamp combat logic function to work properly without melee
* Add laurels rules to combat logic chests
* Modify beneath the vault bridge rule to need a lantern if combat logic is on
* Put in money logic
* Dagger or combat for swamp big skeleton chest
* Remove the 100 moneys from logic
* Modify lower zig ls drop region destinations
* Remove completed todo
* Reword combat logic option description, remove test option
* Add combat logic to slot data
* Merge Silent's missing slot data bugfix PR #3628
* Remove test combat option
* Update combat logic description
* Fix secret gathering place issue
* Fix secret gathering place issue
* Fix lower zig ls rule
* Fix accidentally removed librarian rule
* Remove redundant rule
* Update gauntlet rule to hard-require a sword
* Add test for a problematic connection
* Adjust combat logic to deal with weird edge cases so it doesn't take stuff out of logic that was previously in logic
* Fix create_item classification
* Update some comments
* Update per exempt's suggestion
* Add combat logic to the well boss fight, reorder the combat logic stuff a little to better section them off
* Add EntranceLayout option
* Add back LogicRules as an invisible option, to not break old yamls
* Fix a bug with seed group, continue changing fixed shop to entrance layout
* Fix missed fixed shop -> entrance layout spot
* Fix bug in seed groups with fixed shop on and off
* Add entrance layout to the UT regen stuff
* Put direction. in, will add them later
* Remove unused elevation from portal class
* Got like half of them in
* Finish adding all of the directions
* Add combat rule for zig front to back
* Update per Medic's suggestion
* Update ladder storage without items option description
* Mess with state with collect and remove to save like 2 seconds (never again)
* Save even more time, still never going to do this again on anything else
* Add option check for collect and remove
* Add directions to shop portals
* Update direction in Portal with default
* Move Direction above Portal
* Add decoupled option, mess with plando connection stuff
* Merge, implement verify plando directions
* Condense the stuff in change and remove to less lines (thanks medic)
* Remove unused thing
* Swap to using logicmixin instead of prog_items (thanks Vi)
* Fix consistency in stat counters
* Add back something that was needed
* Fix mistake when adding back
* Making the fix better (thanks medic)
* Make it actually return false if it gets to the backup lists and fails them
* Fix stuff after merge
* Add outlet regions, create new regions as needed for them
* Put together part of decoupled and direction pairs
* make direction pairs work
* Make decoupled work
* Make fixed shop work again
* Fix a few minor bugs
* Fix a few minor bugs
* Fix plando
* god i love programming
* Reorder portal list
* Update portal sorter for variable shops
* Add missing parameter
* Some cleanup of prints and functions
* Fix typo
* it's aliiiiiive
* Make seed groups not sync decoupled
* Add test with full-shop plando
* Fix bug with vanilla portals
* Handle plando connections and direction pair errors
* Update plando checking for decoupled
* Fix typo
* Fix exception text to be shorter
* Add some more comments
* Add todo note
* Remove unused safety thing
* Remove extra plando connections definition in options
* Make seed groups in decoupled with overlapping but not fully overlapped plando connections interact nicely without messing with what the entrances look like in the spoiler log
* Fix weird edge case that is technically user error
* Add note to fixed shop
* Fix parsing shop names in UT
* Remove debug print
* Actually make UT work
* multiworld. to world.
* Fix typo from merge
* Make it so the shops show up in the entrance hints
* Fix bug in ladder storage rules
* Remove blank line
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
#	worlds/tunic/rules.py
#	worlds/tunic/test/test_access.py
* Fix issues after merge
* Update plando connections stuff in docs
* Fix library mistake
* has_stick -> has_melee
* has_stick -> has_melee
* Add a failsafe for direction pairing
* Fix playthrough crash bug
* Remove init from logicmixin
* Updates per code review (thanks hesto)
* has_stick to has_melee in newer update
* has_stick to has_melee in newer update
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/combat_logic.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
* Cleanup more stuff after merge
* Revert "Cleanup more stuff after merge"
This reverts commit a6ee9a93da8f2fcc4413de6df6927b246017889d.
* Revert "# Conflicts:"
This reverts commit c74ccd74a45b6ad6b9abe6e339d115a0c98baf30.
* Cleanup more stuff after merge
* Swap to .get for decoupled so it works with older games probably maybe
* Fix after merge
* Fix typo
* Fix UT support with fixed shop option
* Backport plando connections fix
* Fix issue with fixed shop + decoupled
* Make the error not duplicate the while loop condition
* Fix rule for quarry back to monastery
* Fix more stuff after merge
* Make it not output anything if you set plando connections but not ER
* Add obvious note to plando connections description
* Fix after merge
* add comment to commented out connection
---------
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
											
										 
										
											2025-05-06 12:33:21 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                        if not tunic.options.decoupled:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            is_mismatched = is_mismatched or (
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                player_cxn.entrance == group_cxn.exit and player_cxn.exit != group_cxn.entrance
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                or player_cxn.exit == group_cxn.entrance and player_cxn.entrance != group_cxn.exit
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            )
							 | 
						
					
						
							
								
									
										
										
										
											2024-05-03 01:21:27 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                        if is_mismatched:
							 | 
						
					
						
							
								
									
										
											 
										 
										
											
												TUNIC: Entrance rando Direction Pairs + Decoupled (#3761)
* Fix merge conflict
* Fix formatting, fix rule for heir access after merge
* Writing combat logic helpers
* More helpers!
* More logic!
* Rename has_stick to has_melee, some fixes per Medic's review
* Clamp max power from sword upgrades
* Wrote the rest of the helpers
* Remove unused import
* Apply item classifications
* Create the combat logic option
* Item classification varies based on option
* Add the shop sword logic stuff in
* Add the rules for the boss-only option
* Fix tiny issues
* Some early Overworld combat logic
* Fill out swamp combat logic
* Add note
* Bump up Boss Scav and Heir
* More revisions to combat logic
* Some changes, currently broken
* New system for power, kinda jank probably
* Revisions to new system, needs more balancing
* Cap attack upgrades
* Uncap mp power since it's directly related to damage output
* Voidlings
* Put together a table showing the vanilla-expected stats for each area
* Added some info on potion counts
* Made new helper functions
* Make has_required_stats
* Make has_combat_reqs
* Update er_rules for new combat reqs
* Fix all the broken things ever
* Remove outdated todo
* Make temp option for testing logic
* More flexible choices for combat items
* Hard require sword for bosses
* Temporarily default combat logic to on
* Finish writing overworld combat logic
* East Forest combat logic done
* Remove a few easy ones
* Finish beneath the well
* Dark Tomb combat logic
* West Garden combat logic
* make unit tests checkmark again
* Weird west garden dagger house edge case
* Try block for that weird west garden edge case
* Add quarry combat logic
* Update to filter out unreachable regions outside of ER
* Fortress Grave Path logic, and a couple fixes to the west garden logic
* Fortress east shortcut logic, and rewriting the try except blocks to use finally
* Refactor to use a new function cause wow there was a lot of repeated code
* Add combat logic to the other two sets of fortress fuses
* Add combat rules to beneath the vault
* Fix missing cathedral -> elevator connection
* Combat logic for cathedral to elevator
* Add cathedral main region, rename cathedral -> cathedral entry
* Setup cathedral combat logic
* Adjust locations' regions for ER
* Add laurels zip logic to the chest in the spike room in cathedral
* Add combat logic to frog's domain
* Move frog's domain locations to regions for combat logic
* Add new frog's domain regions for combat logic
* Update region name for frog's domain
* Fix typo
* Add more regions for lower zig
* Move around lower zig regions for combat logic
* Lower Zig combat logic
* Upper zig combat logic
* Fix typo
* Fix typos
* Fix missing world.
* Update combat logic description
* Add todo
* Add todo
* Don't make zig skip if er or fixed shop is off
* Make it so zig skip is only made with fewer shops and er
* Temporarily default combat logic on
* Update test to explicitly disable combat logic
* Update test_access.py
* Slight wording changes
* Fix bugs, refactor quarry regions so you can access chests in lower quarry with ice grapples
* Run through checks you can do with magic dagger
* Run through checks you can do with magic dagger
* Add rule for entering town portal of having equipment to deal with enemies
* Add rule for atoll near the 6 crabs surrounding a poor defenseless baby slorm
* Update the rule for the chest near the 6 crabs surrounding a slorm to also possibly require laurels
* Revamp combat logic function to work properly without melee
* Add laurels rules to combat logic chests
* Modify beneath the vault bridge rule to need a lantern if combat logic is on
* Put in money logic
* Dagger or combat for swamp big skeleton chest
* Remove the 100 moneys from logic
* Modify lower zig ls drop region destinations
* Remove completed todo
* Reword combat logic option description, remove test option
* Add combat logic to slot data
* Merge Silent's missing slot data bugfix PR #3628
* Remove test combat option
* Update combat logic description
* Fix secret gathering place issue
* Fix secret gathering place issue
* Fix lower zig ls rule
* Fix accidentally removed librarian rule
* Remove redundant rule
* Update gauntlet rule to hard-require a sword
* Add test for a problematic connection
* Adjust combat logic to deal with weird edge cases so it doesn't take stuff out of logic that was previously in logic
* Fix create_item classification
* Update some comments
* Update per exempt's suggestion
* Add combat logic to the well boss fight, reorder the combat logic stuff a little to better section them off
* Add EntranceLayout option
* Add back LogicRules as an invisible option, to not break old yamls
* Fix a bug with seed group, continue changing fixed shop to entrance layout
* Fix missed fixed shop -> entrance layout spot
* Fix bug in seed groups with fixed shop on and off
* Add entrance layout to the UT regen stuff
* Put direction. in, will add them later
* Remove unused elevation from portal class
* Got like half of them in
* Finish adding all of the directions
* Add combat rule for zig front to back
* Update per Medic's suggestion
* Update ladder storage without items option description
* Mess with state with collect and remove to save like 2 seconds (never again)
* Save even more time, still never going to do this again on anything else
* Add option check for collect and remove
* Add directions to shop portals
* Update direction in Portal with default
* Move Direction above Portal
* Add decoupled option, mess with plando connection stuff
* Merge, implement verify plando directions
* Condense the stuff in change and remove to less lines (thanks medic)
* Remove unused thing
* Swap to using logicmixin instead of prog_items (thanks Vi)
* Fix consistency in stat counters
* Add back something that was needed
* Fix mistake when adding back
* Making the fix better (thanks medic)
* Make it actually return false if it gets to the backup lists and fails them
* Fix stuff after merge
* Add outlet regions, create new regions as needed for them
* Put together part of decoupled and direction pairs
* make direction pairs work
* Make decoupled work
* Make fixed shop work again
* Fix a few minor bugs
* Fix a few minor bugs
* Fix plando
* god i love programming
* Reorder portal list
* Update portal sorter for variable shops
* Add missing parameter
* Some cleanup of prints and functions
* Fix typo
* it's aliiiiiive
* Make seed groups not sync decoupled
* Add test with full-shop plando
* Fix bug with vanilla portals
* Handle plando connections and direction pair errors
* Update plando checking for decoupled
* Fix typo
* Fix exception text to be shorter
* Add some more comments
* Add todo note
* Remove unused safety thing
* Remove extra plando connections definition in options
* Make seed groups in decoupled with overlapping but not fully overlapped plando connections interact nicely without messing with what the entrances look like in the spoiler log
* Fix weird edge case that is technically user error
* Add note to fixed shop
* Fix parsing shop names in UT
* Remove debug print
* Actually make UT work
* multiworld. to world.
* Fix typo from merge
* Make it so the shops show up in the entrance hints
* Fix bug in ladder storage rules
* Remove blank line
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
#	worlds/tunic/rules.py
#	worlds/tunic/test/test_access.py
* Fix issues after merge
* Update plando connections stuff in docs
* Fix library mistake
* has_stick -> has_melee
* has_stick -> has_melee
* Add a failsafe for direction pairing
* Fix playthrough crash bug
* Remove init from logicmixin
* Updates per code review (thanks hesto)
* has_stick to has_melee in newer update
* has_stick to has_melee in newer update
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/combat_logic.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
* Cleanup more stuff after merge
* Revert "Cleanup more stuff after merge"
This reverts commit a6ee9a93da8f2fcc4413de6df6927b246017889d.
* Revert "# Conflicts:"
This reverts commit c74ccd74a45b6ad6b9abe6e339d115a0c98baf30.
* Cleanup more stuff after merge
* Swap to .get for decoupled so it works with older games probably maybe
* Fix after merge
* Fix typo
* Fix UT support with fixed shop option
* Backport plando connections fix
* Fix issue with fixed shop + decoupled
* Make the error not duplicate the while loop condition
* Fix rule for quarry back to monastery
* Fix more stuff after merge
* Make it not output anything if you set plando connections but not ER
* Add obvious note to plando connections description
* Fix after merge
* add comment to commented out connection
---------
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
											
										 
										
											2025-05-06 12:33:21 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                            group_dir = "<->" if group_cxn.direction == "both" else "-->"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            player_dir = "<->" if player_cxn.direction == "both" else "-->"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            raise OptionError(f"TUNIC: Conflict between seed group {group}'s plando "
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                              f"connection {group_cxn.entrance} {group_dir} {group_cxn.exit} and "
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                              f"{tunic.player_name}'s plando connection "
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                              f"{player_cxn.entrance} {player_dir} {player_cxn.exit}")
							 | 
						
					
						
							
								
									
										
										
										
											2024-05-03 01:21:27 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    if new_cxn:
							 | 
						
					
						
							
								
									
										
											 
										 
										
											
												TUNIC: Entrance rando Direction Pairs + Decoupled (#3761)
* Fix merge conflict
* Fix formatting, fix rule for heir access after merge
* Writing combat logic helpers
* More helpers!
* More logic!
* Rename has_stick to has_melee, some fixes per Medic's review
* Clamp max power from sword upgrades
* Wrote the rest of the helpers
* Remove unused import
* Apply item classifications
* Create the combat logic option
* Item classification varies based on option
* Add the shop sword logic stuff in
* Add the rules for the boss-only option
* Fix tiny issues
* Some early Overworld combat logic
* Fill out swamp combat logic
* Add note
* Bump up Boss Scav and Heir
* More revisions to combat logic
* Some changes, currently broken
* New system for power, kinda jank probably
* Revisions to new system, needs more balancing
* Cap attack upgrades
* Uncap mp power since it's directly related to damage output
* Voidlings
* Put together a table showing the vanilla-expected stats for each area
* Added some info on potion counts
* Made new helper functions
* Make has_required_stats
* Make has_combat_reqs
* Update er_rules for new combat reqs
* Fix all the broken things ever
* Remove outdated todo
* Make temp option for testing logic
* More flexible choices for combat items
* Hard require sword for bosses
* Temporarily default combat logic to on
* Finish writing overworld combat logic
* East Forest combat logic done
* Remove a few easy ones
* Finish beneath the well
* Dark Tomb combat logic
* West Garden combat logic
* make unit tests checkmark again
* Weird west garden dagger house edge case
* Try block for that weird west garden edge case
* Add quarry combat logic
* Update to filter out unreachable regions outside of ER
* Fortress Grave Path logic, and a couple fixes to the west garden logic
* Fortress east shortcut logic, and rewriting the try except blocks to use finally
* Refactor to use a new function cause wow there was a lot of repeated code
* Add combat logic to the other two sets of fortress fuses
* Add combat rules to beneath the vault
* Fix missing cathedral -> elevator connection
* Combat logic for cathedral to elevator
* Add cathedral main region, rename cathedral -> cathedral entry
* Setup cathedral combat logic
* Adjust locations' regions for ER
* Add laurels zip logic to the chest in the spike room in cathedral
* Add combat logic to frog's domain
* Move frog's domain locations to regions for combat logic
* Add new frog's domain regions for combat logic
* Update region name for frog's domain
* Fix typo
* Add more regions for lower zig
* Move around lower zig regions for combat logic
* Lower Zig combat logic
* Upper zig combat logic
* Fix typo
* Fix typos
* Fix missing world.
* Update combat logic description
* Add todo
* Add todo
* Don't make zig skip if er or fixed shop is off
* Make it so zig skip is only made with fewer shops and er
* Temporarily default combat logic on
* Update test to explicitly disable combat logic
* Update test_access.py
* Slight wording changes
* Fix bugs, refactor quarry regions so you can access chests in lower quarry with ice grapples
* Run through checks you can do with magic dagger
* Run through checks you can do with magic dagger
* Add rule for entering town portal of having equipment to deal with enemies
* Add rule for atoll near the 6 crabs surrounding a poor defenseless baby slorm
* Update the rule for the chest near the 6 crabs surrounding a slorm to also possibly require laurels
* Revamp combat logic function to work properly without melee
* Add laurels rules to combat logic chests
* Modify beneath the vault bridge rule to need a lantern if combat logic is on
* Put in money logic
* Dagger or combat for swamp big skeleton chest
* Remove the 100 moneys from logic
* Modify lower zig ls drop region destinations
* Remove completed todo
* Reword combat logic option description, remove test option
* Add combat logic to slot data
* Merge Silent's missing slot data bugfix PR #3628
* Remove test combat option
* Update combat logic description
* Fix secret gathering place issue
* Fix secret gathering place issue
* Fix lower zig ls rule
* Fix accidentally removed librarian rule
* Remove redundant rule
* Update gauntlet rule to hard-require a sword
* Add test for a problematic connection
* Adjust combat logic to deal with weird edge cases so it doesn't take stuff out of logic that was previously in logic
* Fix create_item classification
* Update some comments
* Update per exempt's suggestion
* Add combat logic to the well boss fight, reorder the combat logic stuff a little to better section them off
* Add EntranceLayout option
* Add back LogicRules as an invisible option, to not break old yamls
* Fix a bug with seed group, continue changing fixed shop to entrance layout
* Fix missed fixed shop -> entrance layout spot
* Fix bug in seed groups with fixed shop on and off
* Add entrance layout to the UT regen stuff
* Put direction. in, will add them later
* Remove unused elevation from portal class
* Got like half of them in
* Finish adding all of the directions
* Add combat rule for zig front to back
* Update per Medic's suggestion
* Update ladder storage without items option description
* Mess with state with collect and remove to save like 2 seconds (never again)
* Save even more time, still never going to do this again on anything else
* Add option check for collect and remove
* Add directions to shop portals
* Update direction in Portal with default
* Move Direction above Portal
* Add decoupled option, mess with plando connection stuff
* Merge, implement verify plando directions
* Condense the stuff in change and remove to less lines (thanks medic)
* Remove unused thing
* Swap to using logicmixin instead of prog_items (thanks Vi)
* Fix consistency in stat counters
* Add back something that was needed
* Fix mistake when adding back
* Making the fix better (thanks medic)
* Make it actually return false if it gets to the backup lists and fails them
* Fix stuff after merge
* Add outlet regions, create new regions as needed for them
* Put together part of decoupled and direction pairs
* make direction pairs work
* Make decoupled work
* Make fixed shop work again
* Fix a few minor bugs
* Fix a few minor bugs
* Fix plando
* god i love programming
* Reorder portal list
* Update portal sorter for variable shops
* Add missing parameter
* Some cleanup of prints and functions
* Fix typo
* it's aliiiiiive
* Make seed groups not sync decoupled
* Add test with full-shop plando
* Fix bug with vanilla portals
* Handle plando connections and direction pair errors
* Update plando checking for decoupled
* Fix typo
* Fix exception text to be shorter
* Add some more comments
* Add todo note
* Remove unused safety thing
* Remove extra plando connections definition in options
* Make seed groups in decoupled with overlapping but not fully overlapped plando connections interact nicely without messing with what the entrances look like in the spoiler log
* Fix weird edge case that is technically user error
* Add note to fixed shop
* Fix parsing shop names in UT
* Remove debug print
* Actually make UT work
* multiworld. to world.
* Fix typo from merge
* Make it so the shops show up in the entrance hints
* Fix bug in ladder storage rules
* Remove blank line
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
#	worlds/tunic/rules.py
#	worlds/tunic/test/test_access.py
* Fix issues after merge
* Update plando connections stuff in docs
* Fix library mistake
* has_stick -> has_melee
* has_stick -> has_melee
* Add a failsafe for direction pairing
* Fix playthrough crash bug
* Remove init from logicmixin
* Updates per code review (thanks hesto)
* has_stick to has_melee in newer update
* has_stick to has_melee in newer update
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/combat_logic.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
* Cleanup more stuff after merge
* Revert "Cleanup more stuff after merge"
This reverts commit a6ee9a93da8f2fcc4413de6df6927b246017889d.
* Revert "# Conflicts:"
This reverts commit c74ccd74a45b6ad6b9abe6e339d115a0c98baf30.
* Cleanup more stuff after merge
* Swap to .get for decoupled so it works with older games probably maybe
* Fix after merge
* Fix typo
* Fix UT support with fixed shop option
* Backport plando connections fix
* Fix issue with fixed shop + decoupled
* Make the error not duplicate the while loop condition
* Fix rule for quarry back to monastery
* Fix more stuff after merge
* Make it not output anything if you set plando connections but not ER
* Add obvious note to plando connections description
* Fix after merge
* add comment to commented out connection
---------
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
											
										 
										
											2025-05-06 12:33:21 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                        cls.seed_groups[group]["plando"].append(player_cxn)
							 | 
						
					
						
							
								
									
										
										
										
											2024-05-03 01:21:27 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-07-24 08:37:18 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def create_item(self, name: str, classification: ItemClassification = None) -> TunicItem:
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        item_data = item_table[name]
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-24 17:10:58 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # evaluate alternate classifications based on options
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        # it'll choose whichever classification isn't None first in this if else tree
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        itemclass: ItemClassification = (classification
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                         or (item_data.combat_ic if self.options.combat_logic else None)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                         or (ItemClassification.progression | ItemClassification.useful
							 | 
						
					
						
							
								
									
										
										
										
											2025-03-08 11:25:47 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                                             if name == "Glass Cannon"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                             and (self.options.grass_randomizer or self.options.breakable_shuffle)
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-24 17:10:58 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                                             and not self.options.start_with_sword else None)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                         or (ItemClassification.progression | ItemClassification.useful
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                             if name == "Shield" and self.options.ladder_storage
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                             and not self.options.ladder_storage_without_items else None)
							 | 
						
					
						
							
								
									
										
										
										
											2024-12-15 16:40:36 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                                         or item_data.classification)
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-24 17:10:58 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        return TunicItem(name, itemclass, self.item_name_to_id[name], self.player)
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    def create_items(self) -> None:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        tunic_items: List[TunicItem] = []
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.slot_data_items = []
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        items_to_create: Dict[str, int] = {item: data.quantity_in_item_pool for item, data in item_table.items()}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2025-03-07 19:43:02 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # Calculate number of hexagons in item pool
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if self.options.hexagon_quest:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            items_to_create[gold_hexagon] = get_hexagons_in_pool(self)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        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
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2025-03-08 11:25:47 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # creating these after the fool traps are made mostly so we don't have to mess with it
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if self.options.breakable_shuffle:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            for loc_data in breakable_location_table.values():
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if not self.options.entrance_rando and loc_data.er_region == "Purgatory":
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    continue
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                items_to_create[f"Money x{self.random.randint(1, 5)}"] += 1
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-02-23 13:41:59 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if self.options.start_with_sword:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            self.multiworld.push_precollected(self.create_item("Sword"))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-06-29 19:17:00 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if self.options.sword_progression:
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            items_to_create["Stick"] = 0
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            items_to_create["Sword"] = 0
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        else:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            items_to_create["Sword Upgrade"] = 0
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if self.options.laurels_location:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            laurels = self.create_item("Hero's Laurels")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if self.options.laurels_location == "6_coins":
							 | 
						
					
						
							
								
									
										
										
										
											2024-08-13 20:35:08 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                self.get_location("Coins in the Well - 6 Coins").place_locked_item(laurels)
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            elif self.options.laurels_location == "10_coins":
							 | 
						
					
						
							
								
									
										
										
										
											2024-08-13 20:35:08 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                self.get_location("Coins in the Well - 10 Coins").place_locked_item(laurels)
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            elif self.options.laurels_location == "10_fairies":
							 | 
						
					
						
							
								
									
										
										
										
											2024-08-13 20:35:08 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                self.get_location("Secret Gathering Place - 10 Fairy Reward").place_locked_item(laurels)
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            items_to_create["Hero's Laurels"] = 0
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-15 18:17:07 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if self.options.grass_randomizer:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            items_to_create["Grass"] = len(grass_location_table)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            for grass_location in excluded_grass_locations:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                self.get_location(grass_location).place_locked_item(self.create_item("Grass"))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            items_to_create["Grass"] -= len(excluded_grass_locations)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-06-29 19:17:00 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if self.options.keys_behind_bosses:
							 | 
						
					
						
							
								
									
										
										
										
											2025-03-07 19:43:02 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            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
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-03-21 11:50:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # Filler items in the item pool
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        available_filler: List[str] = [filler for filler in items_to_create if items_to_create[filler] > 0 and
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                       item_table[filler].classification == ItemClassification.filler]
							 | 
						
					
						
							
								
									
										
										
										
											2024-04-13 18:20:52 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-03-21 11:50:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # Remove filler to make room for other items
							 | 
						
					
						
							
								
									
										
										
										
											2024-04-13 20:06:06 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        def remove_filler(amount: int) -> None:
							 | 
						
					
						
							
								
									
										
										
										
											2024-07-05 16:50:12 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            for _ in range(amount):
							 | 
						
					
						
							
								
									
										
										
										
											2024-03-21 11:50:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                if not available_filler:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    fill = "Fool Trap"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                else:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    fill = self.random.choice(available_filler)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if items_to_create[fill] == 0:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    raise Exception("No filler items left to accommodate options selected. Turn down fool trap amount.")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                items_to_create[fill] -= 1
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if items_to_create[fill] == 0:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    available_filler.remove(fill)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if self.options.shuffle_ladders:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            ladder_count = 0
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            for item_name, item_data in item_table.items():
							 | 
						
					
						
							
								
									
										
										
										
											2024-05-02 04:02:59 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                if item_data.item_group == "Ladders":
							 | 
						
					
						
							
								
									
										
										
										
											2024-03-21 11:50:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    items_to_create[item_name] = 1
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    ladder_count += 1
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            remove_filler(ladder_count)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-06-29 19:17:00 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if self.options.hexagon_quest:
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            # 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)):
							 | 
						
					
						
							
								
									
										
										
										
											2025-03-07 19:43:02 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                if replaced_item in item_name_groups["Abilities"] and self.options.ability_shuffling \
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        and self.options.hexagon_quest_ability_type == "pages":
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    continue
							 | 
						
					
						
							
								
									
										
										
										
											2024-03-21 11:50:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                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:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    available_filler.append(filler_name)
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                items_to_create[replaced_item] = 0
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-03-21 11:50:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            remove_filler(items_to_create[gold_hexagon])
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-20 10:04:39 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            if not self.options.combat_logic:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                # Sort for deterministic order
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                for hero_relic in sorted(item_name_groups["Hero Relics"]):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    tunic_items.append(self.create_item(hero_relic, ItemClassification.useful))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    items_to_create[hero_relic] = 0
							 | 
						
					
						
							
								
									
										
										
										
											2024-06-29 19:17:00 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if not self.options.ability_shuffling:
							 | 
						
					
						
							
								
									
										
										
										
											2024-12-31 04:57:09 +00:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            # Sort for deterministic order
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            for page in sorted(item_name_groups["Abilities"]):
							 | 
						
					
						
							
								
									
										
										
										
											2024-06-29 19:17:00 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                if items_to_create[page] > 0:
							 | 
						
					
						
							
								
									
										
										
										
											2024-07-24 08:37:18 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    tunic_items.append(self.create_item(page, ItemClassification.useful))
							 | 
						
					
						
							
								
									
										
										
										
											2024-06-29 19:17:00 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    items_to_create[page] = 0
							 | 
						
					
						
							
								
									
										
										
										
											2024-10-22 20:30:31 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # if ice grapple logic is on, probably really want icebolt
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        elif self.options.ice_grappling:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            page = "Pages 52-53 (Icebolt)"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if items_to_create[page] > 0:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                tunic_items.append(self.create_item(page, ItemClassification.progression | ItemClassification.useful))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                items_to_create[page] = 0
							 | 
						
					
						
							
								
									
										
										
										
											2024-06-29 19:17:00 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if self.options.maskless:
							 | 
						
					
						
							
								
									
										
										
										
											2024-07-24 08:37:18 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            tunic_items.append(self.create_item("Scavenger Mask", ItemClassification.useful))
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            items_to_create["Scavenger Mask"] = 0
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if self.options.lanternless:
							 | 
						
					
						
							
								
									
										
										
										
											2024-07-24 08:37:18 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            tunic_items.append(self.create_item("Lantern", ItemClassification.useful))
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            items_to_create["Lantern"] = 0
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        for item, quantity in items_to_create.items():
							 | 
						
					
						
							
								
									
										
										
										
											2024-07-05 16:50:12 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            for _ in range(quantity):
							 | 
						
					
						
							
								
									
										
										
										
											2024-07-24 08:37:18 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                tunic_items.append(self.create_item(item))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        for tunic_item in tunic_items:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if tunic_item.name in slot_data_item_names:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                self.slot_data_items.append(tunic_item)
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-15 18:17:07 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # pull out the filler so that we can place it manually during pre_fill
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.fill_items = []
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if self.options.local_fill > 0 and self.multiworld.players > 1:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            # skip items marked local or non-local, let fill deal with them in its own way
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            # discard grass from non_local if it's meant to be limited
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if self.settings.limit_grass_rando:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                self.options.non_local_items.value.discard("Grass")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            all_filler: List[TunicItem] = []
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            non_filler: List[TunicItem] = []
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            for tunic_item in tunic_items:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if (tunic_item.excludable
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        and tunic_item.name not in self.options.local_items
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        and tunic_item.name not in self.options.non_local_items):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    all_filler.append(tunic_item)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                else:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    non_filler.append(tunic_item)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            self.amount_to_local_fill = int(self.options.local_fill.value * len(all_filler) / 100)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            self.fill_items += all_filler[:self.amount_to_local_fill]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            del all_filler[:self.amount_to_local_fill]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            tunic_items = all_filler + non_filler
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.multiworld.itempool += tunic_items
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-15 18:17:07 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def pre_fill(self) -> None:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if self.options.local_fill > 0 and self.multiworld.players > 1:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            # we need to reserve a couple locations so that we don't fill up every sphere 1 location
							 | 
						
					
						
							
								
									
										
										
										
											2025-04-21 17:41:20 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            sphere_one_locs = self.multiworld.get_reachable_locations(CollectionState(self.multiworld), self.player)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            reserved_locations: Set[Location] = set(self.random.sample(sphere_one_locs, 2))
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-15 18:17:07 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            viable_locations = [loc for loc in self.multiworld.get_unfilled_locations(self.player)
							 | 
						
					
						
							
								
									
										
										
										
											2025-04-21 17:41:20 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                                if loc not in reserved_locations
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-15 18:17:07 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                                and loc.name not in self.options.priority_locations.value]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if len(viable_locations) < self.amount_to_local_fill:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                raise OptionError(f"TUNIC: Not enough locations for local_fill option for {self.player_name}. "
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                  f"This is likely due to excess plando or priority locations.")
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-16 21:13:37 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            self.random.shuffle(viable_locations)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            self.fill_locations = viable_locations[:self.amount_to_local_fill]
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-15 18:17:07 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    @classmethod
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    def stage_pre_fill(cls, multiworld: MultiWorld) -> None:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        tunic_fill_worlds: List[TunicWorld] = [world for world in multiworld.get_game_worlds("TUNIC")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                               if world.options.local_fill.value > 0]
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-20 09:53:30 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if tunic_fill_worlds and multiworld.players > 1:
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-15 18:17:07 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            grass_fill: List[TunicItem] = []
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            non_grass_fill: List[TunicItem] = []
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            grass_fill_locations: List[Location] = []
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            non_grass_fill_locations: List[Location] = []
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            for world in tunic_fill_worlds:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if world.options.grass_randomizer:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    grass_fill.extend(world.fill_items)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    grass_fill_locations.extend(world.fill_locations)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                else:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    non_grass_fill.extend(world.fill_items)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    non_grass_fill_locations.extend(world.fill_locations)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            multiworld.random.shuffle(grass_fill)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            multiworld.random.shuffle(non_grass_fill)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            multiworld.random.shuffle(grass_fill_locations)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            multiworld.random.shuffle(non_grass_fill_locations)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            for filler_item in grass_fill:
							 | 
						
					
						
							
								
									
										
										
										
											2025-04-30 15:57:46 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                grass_fill_locations.pop().place_locked_item(filler_item)
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-15 18:17:07 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            for filler_item in non_grass_fill:
							 | 
						
					
						
							
								
									
										
										
										
											2025-04-30 15:57:46 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                non_grass_fill_locations.pop().place_locked_item(filler_item)
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-15 18:17:07 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    def create_regions(self) -> None:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.tunic_portal_pairs = {}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.er_portal_hints = {}
							 | 
						
					
						
							
								
									
										
										
										
											2025-03-07 19:43:02 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        self.ability_unlocks = randomize_ability_unlocks(self)
							 | 
						
					
						
							
								
									
										
										
										
											2024-04-13 18:20:52 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-02-15 23:03:51 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # stuff for universal tracker support, can be ignored for standard gen
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-10 15:49:13 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if self.using_ut:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            self.ability_unlocks["Pages 24-25 (Prayer)"] = self.passthrough["Hexagon Quest Prayer"]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            self.ability_unlocks["Pages 42-43 (Holy Cross)"] = self.passthrough["Hexagon Quest Holy Cross"]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            self.ability_unlocks["Pages 52-53 (Icebolt)"] = self.passthrough["Hexagon Quest Icebolt"]
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2025-03-08 11:25:47 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # Most non-standard options use ER regions
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-15 18:17:07 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if (self.options.entrance_rando or self.options.shuffle_ladders or self.options.combat_logic
							 | 
						
					
						
							
								
									
										
										
										
											2025-03-08 11:25:47 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                or self.options.grass_randomizer or self.options.breakable_shuffle):
							 | 
						
					
						
							
								
									
										
										
										
											2024-03-21 11:50:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            portal_pairs = create_er_regions(self)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if self.options.entrance_rando:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                # these get interpreted by the game to tell it which entrances to connect
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                for portal1, portal2 in portal_pairs.items():
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    self.tunic_portal_pairs[portal1.scene_destination()] = portal2.scene_destination()
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        else:
							 | 
						
					
						
							
								
									
										
										
										
											2024-12-15 16:40:36 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            # uses the original rules, easier to navigate and reference
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            for region_name in tunic_regions:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                region = Region(region_name, self.player, self.multiworld)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                self.multiworld.regions.append(region)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            for region_name, exits in tunic_regions.items():
							 | 
						
					
						
							
								
									
										
										
										
											2024-08-13 20:35:08 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                region = self.get_region(region_name)
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                region.add_exits(exits)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-15 18:17:07 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            for location_name, location_id in self.player_location_table.items():
							 | 
						
					
						
							
								
									
										
										
										
											2024-08-13 20:35:08 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                region = self.get_region(location_table[location_name].region)
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                location = TunicLocation(self.player, location_name, location_id, region)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                region.locations.append(location)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-08-13 20:35:08 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            victory_region = self.get_region("Spirit Arena")
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            victory_location = TunicLocation(self.player, "The Heir", None, victory_region)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            victory_location.place_locked_item(TunicItem("Victory", ItemClassification.progression, None, self.player))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            self.multiworld.completion_condition[self.player] = lambda state: state.has("Victory", self.player)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            victory_region.locations.append(victory_location)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    def set_rules(self) -> None:
							 | 
						
					
						
							
								
									
										
										
										
											2025-03-08 11:25:47 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # same reason as in create_regions
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-15 18:17:07 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if (self.options.entrance_rando or self.options.shuffle_ladders or self.options.combat_logic
							 | 
						
					
						
							
								
									
										
										
										
											2025-03-08 11:25:47 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                or self.options.grass_randomizer or self.options.breakable_shuffle):
							 | 
						
					
						
							
								
									
										
										
										
											2024-07-05 16:50:12 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            set_er_location_rules(self)
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        else:
							 | 
						
					
						
							
								
									
										
										
										
											2024-07-05 16:50:12 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            set_region_rules(self)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            set_location_rules(self)
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    def get_filler_item_name(self) -> str:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return self.random.choice(filler_items)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-12-15 16:40:36 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    # cache whether you can get through combat logic areas
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    def collect(self, state: CollectionState, item: Item) -> bool:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        change = super().collect(state, item)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if change and self.options.combat_logic and item.name in combat_items:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            state.tunic_need_to_reset_combat_from_collect[self.player] = True
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return change
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    def remove(self, state: CollectionState, item: Item) -> bool:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        change = super().remove(state, item)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if change and self.options.combat_logic and item.name in combat_items:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            state.tunic_need_to_reset_combat_from_remove[self.player] = True
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return change
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-24 16:55:49 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def write_spoiler_header(self, spoiler_handle: TextIO):
							 | 
						
					
						
							
								
									
										
										
										
											2025-03-07 19:43:02 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if self.options.hexagon_quest and self.options.ability_shuffling\
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                and self.options.hexagon_quest_ability_type == HexagonQuestAbilityUnlockType.option_hexagons:
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-24 16:55:49 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            spoiler_handle.write("\nAbility Unlocks (Hexagon Quest):\n")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            for ability in self.ability_unlocks:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                # Remove parentheses for better readability
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                spoiler_handle.write(f'{ability[ability.find("(")+1:ability.find(")")]}: {self.ability_unlocks[ability]} Gold Questagons\n')
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-04-13 20:06:06 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def extend_hint_information(self, hint_data: Dict[int, Dict[int, str]]) -> None:
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if self.options.entrance_rando:
							 | 
						
					
						
							
								
									
										
										
										
											2024-03-21 11:50:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            hint_data.update({self.player: {}})
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            # all state seems to have efficient paths
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            all_state = self.multiworld.get_all_state(True)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            all_state.update_reachable_regions(self.player)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            paths = all_state.path
							 | 
						
					
						
							
								
									
										
											 
										 
										
											
												TUNIC: Entrance rando Direction Pairs + Decoupled (#3761)
* Fix merge conflict
* Fix formatting, fix rule for heir access after merge
* Writing combat logic helpers
* More helpers!
* More logic!
* Rename has_stick to has_melee, some fixes per Medic's review
* Clamp max power from sword upgrades
* Wrote the rest of the helpers
* Remove unused import
* Apply item classifications
* Create the combat logic option
* Item classification varies based on option
* Add the shop sword logic stuff in
* Add the rules for the boss-only option
* Fix tiny issues
* Some early Overworld combat logic
* Fill out swamp combat logic
* Add note
* Bump up Boss Scav and Heir
* More revisions to combat logic
* Some changes, currently broken
* New system for power, kinda jank probably
* Revisions to new system, needs more balancing
* Cap attack upgrades
* Uncap mp power since it's directly related to damage output
* Voidlings
* Put together a table showing the vanilla-expected stats for each area
* Added some info on potion counts
* Made new helper functions
* Make has_required_stats
* Make has_combat_reqs
* Update er_rules for new combat reqs
* Fix all the broken things ever
* Remove outdated todo
* Make temp option for testing logic
* More flexible choices for combat items
* Hard require sword for bosses
* Temporarily default combat logic to on
* Finish writing overworld combat logic
* East Forest combat logic done
* Remove a few easy ones
* Finish beneath the well
* Dark Tomb combat logic
* West Garden combat logic
* make unit tests checkmark again
* Weird west garden dagger house edge case
* Try block for that weird west garden edge case
* Add quarry combat logic
* Update to filter out unreachable regions outside of ER
* Fortress Grave Path logic, and a couple fixes to the west garden logic
* Fortress east shortcut logic, and rewriting the try except blocks to use finally
* Refactor to use a new function cause wow there was a lot of repeated code
* Add combat logic to the other two sets of fortress fuses
* Add combat rules to beneath the vault
* Fix missing cathedral -> elevator connection
* Combat logic for cathedral to elevator
* Add cathedral main region, rename cathedral -> cathedral entry
* Setup cathedral combat logic
* Adjust locations' regions for ER
* Add laurels zip logic to the chest in the spike room in cathedral
* Add combat logic to frog's domain
* Move frog's domain locations to regions for combat logic
* Add new frog's domain regions for combat logic
* Update region name for frog's domain
* Fix typo
* Add more regions for lower zig
* Move around lower zig regions for combat logic
* Lower Zig combat logic
* Upper zig combat logic
* Fix typo
* Fix typos
* Fix missing world.
* Update combat logic description
* Add todo
* Add todo
* Don't make zig skip if er or fixed shop is off
* Make it so zig skip is only made with fewer shops and er
* Temporarily default combat logic on
* Update test to explicitly disable combat logic
* Update test_access.py
* Slight wording changes
* Fix bugs, refactor quarry regions so you can access chests in lower quarry with ice grapples
* Run through checks you can do with magic dagger
* Run through checks you can do with magic dagger
* Add rule for entering town portal of having equipment to deal with enemies
* Add rule for atoll near the 6 crabs surrounding a poor defenseless baby slorm
* Update the rule for the chest near the 6 crabs surrounding a slorm to also possibly require laurels
* Revamp combat logic function to work properly without melee
* Add laurels rules to combat logic chests
* Modify beneath the vault bridge rule to need a lantern if combat logic is on
* Put in money logic
* Dagger or combat for swamp big skeleton chest
* Remove the 100 moneys from logic
* Modify lower zig ls drop region destinations
* Remove completed todo
* Reword combat logic option description, remove test option
* Add combat logic to slot data
* Merge Silent's missing slot data bugfix PR #3628
* Remove test combat option
* Update combat logic description
* Fix secret gathering place issue
* Fix secret gathering place issue
* Fix lower zig ls rule
* Fix accidentally removed librarian rule
* Remove redundant rule
* Update gauntlet rule to hard-require a sword
* Add test for a problematic connection
* Adjust combat logic to deal with weird edge cases so it doesn't take stuff out of logic that was previously in logic
* Fix create_item classification
* Update some comments
* Update per exempt's suggestion
* Add combat logic to the well boss fight, reorder the combat logic stuff a little to better section them off
* Add EntranceLayout option
* Add back LogicRules as an invisible option, to not break old yamls
* Fix a bug with seed group, continue changing fixed shop to entrance layout
* Fix missed fixed shop -> entrance layout spot
* Fix bug in seed groups with fixed shop on and off
* Add entrance layout to the UT regen stuff
* Put direction. in, will add them later
* Remove unused elevation from portal class
* Got like half of them in
* Finish adding all of the directions
* Add combat rule for zig front to back
* Update per Medic's suggestion
* Update ladder storage without items option description
* Mess with state with collect and remove to save like 2 seconds (never again)
* Save even more time, still never going to do this again on anything else
* Add option check for collect and remove
* Add directions to shop portals
* Update direction in Portal with default
* Move Direction above Portal
* Add decoupled option, mess with plando connection stuff
* Merge, implement verify plando directions
* Condense the stuff in change and remove to less lines (thanks medic)
* Remove unused thing
* Swap to using logicmixin instead of prog_items (thanks Vi)
* Fix consistency in stat counters
* Add back something that was needed
* Fix mistake when adding back
* Making the fix better (thanks medic)
* Make it actually return false if it gets to the backup lists and fails them
* Fix stuff after merge
* Add outlet regions, create new regions as needed for them
* Put together part of decoupled and direction pairs
* make direction pairs work
* Make decoupled work
* Make fixed shop work again
* Fix a few minor bugs
* Fix a few minor bugs
* Fix plando
* god i love programming
* Reorder portal list
* Update portal sorter for variable shops
* Add missing parameter
* Some cleanup of prints and functions
* Fix typo
* it's aliiiiiive
* Make seed groups not sync decoupled
* Add test with full-shop plando
* Fix bug with vanilla portals
* Handle plando connections and direction pair errors
* Update plando checking for decoupled
* Fix typo
* Fix exception text to be shorter
* Add some more comments
* Add todo note
* Remove unused safety thing
* Remove extra plando connections definition in options
* Make seed groups in decoupled with overlapping but not fully overlapped plando connections interact nicely without messing with what the entrances look like in the spoiler log
* Fix weird edge case that is technically user error
* Add note to fixed shop
* Fix parsing shop names in UT
* Remove debug print
* Actually make UT work
* multiworld. to world.
* Fix typo from merge
* Make it so the shops show up in the entrance hints
* Fix bug in ladder storage rules
* Remove blank line
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
#	worlds/tunic/rules.py
#	worlds/tunic/test/test_access.py
* Fix issues after merge
* Update plando connections stuff in docs
* Fix library mistake
* has_stick -> has_melee
* has_stick -> has_melee
* Add a failsafe for direction pairing
* Fix playthrough crash bug
* Remove init from logicmixin
* Updates per code review (thanks hesto)
* has_stick to has_melee in newer update
* has_stick to has_melee in newer update
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/combat_logic.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
* Cleanup more stuff after merge
* Revert "Cleanup more stuff after merge"
This reverts commit a6ee9a93da8f2fcc4413de6df6927b246017889d.
* Revert "# Conflicts:"
This reverts commit c74ccd74a45b6ad6b9abe6e339d115a0c98baf30.
* Cleanup more stuff after merge
* Swap to .get for decoupled so it works with older games probably maybe
* Fix after merge
* Fix typo
* Fix UT support with fixed shop option
* Backport plando connections fix
* Fix issue with fixed shop + decoupled
* Make the error not duplicate the while loop condition
* Fix rule for quarry back to monastery
* Fix more stuff after merge
* Make it not output anything if you set plando connections but not ER
* Add obvious note to plando connections description
* Fix after merge
* add comment to commented out connection
---------
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
											
										 
										
											2025-05-06 12:33:21 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            portal_names = {portal.name for portal in portal_mapping}.union({f"Shop Portal {i + 1}" for i in range(500)})
							 | 
						
					
						
							
								
									
										
										
										
											2024-03-21 11:50:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            for location in self.multiworld.get_locations(self.player):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                # skipping event locations
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if not location.address:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    continue
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                path_to_loc = []
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                previous_name = "placeholder"
							 | 
						
					
						
							
								
									
										
										
										
											2024-04-13 18:20:52 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                try:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    name, connection = paths[location.parent_region]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                except KeyError:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    # logic bug, proceed with warning since it takes a long time to update AP
							 | 
						
					
						
							
								
									
										
										
										
											2024-08-13 20:35:08 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    warning(f"{location.name} is not logically accessible for {self.player_name}. "
							 | 
						
					
						
							
								
									
										
										
										
											2024-08-29 03:42:46 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                            "Creating entrance hint Inaccessible. Please report this to the TUNIC rando devs. "
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            "If you are using Plando Items (excluding early locations), then this is likely the cause.")
							 | 
						
					
						
							
								
									
										
										
										
											2024-04-13 18:20:52 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                    hint_text = "Inaccessible"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                else:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    while connection != ("Menu", None):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        name, connection = connection
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        # for LS entrances, we just want to give the portal name
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        if "(LS)" in name:
							 | 
						
					
						
							
								
									
										
										
										
											2024-05-02 04:02:59 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                            name = name.split(" (LS) ", 1)[0]
							 | 
						
					
						
							
								
									
										
										
										
											2024-04-13 18:20:52 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                        # was getting some cases like Library Grave -> Library Grave -> other place
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        if name in portal_names and name != previous_name:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            previous_name = name
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            path_to_loc.append(name)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    hint_text = " -> ".join(reversed(path_to_loc))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-03-21 11:50:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                if hint_text:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    hint_data[self.player][location.address] = hint_text
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-11-22 19:42:44 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def get_real_location(self, location: Location) -> Tuple[str, int]:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        # if it's not in a group, it's not in an item link
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if location.player not in self.multiworld.groups or not location.item:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            return location.name, location.player
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        try:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            loc = self.player_item_link_locations[location.item.name].pop()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            return loc.name, loc.player
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        except IndexError:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            warning(f"TUNIC: Failed to parse item location for in-game hints for {self.player_name}. "
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    f"Using a potentially incorrect location name instead.")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            return location.name, location.player
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    def fill_slot_data(self) -> Dict[str, Any]:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        slot_data: Dict[str, Any] = {
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            "seed": self.random.randint(0, 2147483647),
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            "start_with_sword": self.options.start_with_sword.value,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            "keys_behind_bosses": self.options.keys_behind_bosses.value,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            "sword_progression": self.options.sword_progression.value,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            "ability_shuffling": self.options.ability_shuffling.value,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            "hexagon_quest": self.options.hexagon_quest.value,
							 | 
						
					
						
							
								
									
										
										
										
											2025-03-07 19:43:02 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            "hexagon_quest_ability_type": self.options.hexagon_quest_ability_type.value,
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            "fool_traps": self.options.fool_traps.value,
							 | 
						
					
						
							
								
									
										
										
										
											2024-09-08 08:42:59 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            "laurels_zips": self.options.laurels_zips.value,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            "ice_grappling": self.options.ice_grappling.value,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            "ladder_storage": self.options.ladder_storage.value,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            "ladder_storage_without_items": self.options.ladder_storage_without_items.value,
							 | 
						
					
						
							
								
									
										
										
										
											2024-02-15 23:03:51 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            "lanternless": self.options.lanternless.value,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            "maskless": self.options.maskless.value,
							 | 
						
					
						
							
								
									
										
										
										
											2024-03-21 11:50:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            "entrance_rando": int(bool(self.options.entrance_rando.value)),
							 | 
						
					
						
							
								
									
										
											 
										 
										
											
												TUNIC: Entrance rando Direction Pairs + Decoupled (#3761)
* Fix merge conflict
* Fix formatting, fix rule for heir access after merge
* Writing combat logic helpers
* More helpers!
* More logic!
* Rename has_stick to has_melee, some fixes per Medic's review
* Clamp max power from sword upgrades
* Wrote the rest of the helpers
* Remove unused import
* Apply item classifications
* Create the combat logic option
* Item classification varies based on option
* Add the shop sword logic stuff in
* Add the rules for the boss-only option
* Fix tiny issues
* Some early Overworld combat logic
* Fill out swamp combat logic
* Add note
* Bump up Boss Scav and Heir
* More revisions to combat logic
* Some changes, currently broken
* New system for power, kinda jank probably
* Revisions to new system, needs more balancing
* Cap attack upgrades
* Uncap mp power since it's directly related to damage output
* Voidlings
* Put together a table showing the vanilla-expected stats for each area
* Added some info on potion counts
* Made new helper functions
* Make has_required_stats
* Make has_combat_reqs
* Update er_rules for new combat reqs
* Fix all the broken things ever
* Remove outdated todo
* Make temp option for testing logic
* More flexible choices for combat items
* Hard require sword for bosses
* Temporarily default combat logic to on
* Finish writing overworld combat logic
* East Forest combat logic done
* Remove a few easy ones
* Finish beneath the well
* Dark Tomb combat logic
* West Garden combat logic
* make unit tests checkmark again
* Weird west garden dagger house edge case
* Try block for that weird west garden edge case
* Add quarry combat logic
* Update to filter out unreachable regions outside of ER
* Fortress Grave Path logic, and a couple fixes to the west garden logic
* Fortress east shortcut logic, and rewriting the try except blocks to use finally
* Refactor to use a new function cause wow there was a lot of repeated code
* Add combat logic to the other two sets of fortress fuses
* Add combat rules to beneath the vault
* Fix missing cathedral -> elevator connection
* Combat logic for cathedral to elevator
* Add cathedral main region, rename cathedral -> cathedral entry
* Setup cathedral combat logic
* Adjust locations' regions for ER
* Add laurels zip logic to the chest in the spike room in cathedral
* Add combat logic to frog's domain
* Move frog's domain locations to regions for combat logic
* Add new frog's domain regions for combat logic
* Update region name for frog's domain
* Fix typo
* Add more regions for lower zig
* Move around lower zig regions for combat logic
* Lower Zig combat logic
* Upper zig combat logic
* Fix typo
* Fix typos
* Fix missing world.
* Update combat logic description
* Add todo
* Add todo
* Don't make zig skip if er or fixed shop is off
* Make it so zig skip is only made with fewer shops and er
* Temporarily default combat logic on
* Update test to explicitly disable combat logic
* Update test_access.py
* Slight wording changes
* Fix bugs, refactor quarry regions so you can access chests in lower quarry with ice grapples
* Run through checks you can do with magic dagger
* Run through checks you can do with magic dagger
* Add rule for entering town portal of having equipment to deal with enemies
* Add rule for atoll near the 6 crabs surrounding a poor defenseless baby slorm
* Update the rule for the chest near the 6 crabs surrounding a slorm to also possibly require laurels
* Revamp combat logic function to work properly without melee
* Add laurels rules to combat logic chests
* Modify beneath the vault bridge rule to need a lantern if combat logic is on
* Put in money logic
* Dagger or combat for swamp big skeleton chest
* Remove the 100 moneys from logic
* Modify lower zig ls drop region destinations
* Remove completed todo
* Reword combat logic option description, remove test option
* Add combat logic to slot data
* Merge Silent's missing slot data bugfix PR #3628
* Remove test combat option
* Update combat logic description
* Fix secret gathering place issue
* Fix secret gathering place issue
* Fix lower zig ls rule
* Fix accidentally removed librarian rule
* Remove redundant rule
* Update gauntlet rule to hard-require a sword
* Add test for a problematic connection
* Adjust combat logic to deal with weird edge cases so it doesn't take stuff out of logic that was previously in logic
* Fix create_item classification
* Update some comments
* Update per exempt's suggestion
* Add combat logic to the well boss fight, reorder the combat logic stuff a little to better section them off
* Add EntranceLayout option
* Add back LogicRules as an invisible option, to not break old yamls
* Fix a bug with seed group, continue changing fixed shop to entrance layout
* Fix missed fixed shop -> entrance layout spot
* Fix bug in seed groups with fixed shop on and off
* Add entrance layout to the UT regen stuff
* Put direction. in, will add them later
* Remove unused elevation from portal class
* Got like half of them in
* Finish adding all of the directions
* Add combat rule for zig front to back
* Update per Medic's suggestion
* Update ladder storage without items option description
* Mess with state with collect and remove to save like 2 seconds (never again)
* Save even more time, still never going to do this again on anything else
* Add option check for collect and remove
* Add directions to shop portals
* Update direction in Portal with default
* Move Direction above Portal
* Add decoupled option, mess with plando connection stuff
* Merge, implement verify plando directions
* Condense the stuff in change and remove to less lines (thanks medic)
* Remove unused thing
* Swap to using logicmixin instead of prog_items (thanks Vi)
* Fix consistency in stat counters
* Add back something that was needed
* Fix mistake when adding back
* Making the fix better (thanks medic)
* Make it actually return false if it gets to the backup lists and fails them
* Fix stuff after merge
* Add outlet regions, create new regions as needed for them
* Put together part of decoupled and direction pairs
* make direction pairs work
* Make decoupled work
* Make fixed shop work again
* Fix a few minor bugs
* Fix a few minor bugs
* Fix plando
* god i love programming
* Reorder portal list
* Update portal sorter for variable shops
* Add missing parameter
* Some cleanup of prints and functions
* Fix typo
* it's aliiiiiive
* Make seed groups not sync decoupled
* Add test with full-shop plando
* Fix bug with vanilla portals
* Handle plando connections and direction pair errors
* Update plando checking for decoupled
* Fix typo
* Fix exception text to be shorter
* Add some more comments
* Add todo note
* Remove unused safety thing
* Remove extra plando connections definition in options
* Make seed groups in decoupled with overlapping but not fully overlapped plando connections interact nicely without messing with what the entrances look like in the spoiler log
* Fix weird edge case that is technically user error
* Add note to fixed shop
* Fix parsing shop names in UT
* Remove debug print
* Actually make UT work
* multiworld. to world.
* Fix typo from merge
* Make it so the shops show up in the entrance hints
* Fix bug in ladder storage rules
* Remove blank line
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
#	worlds/tunic/rules.py
#	worlds/tunic/test/test_access.py
* Fix issues after merge
* Update plando connections stuff in docs
* Fix library mistake
* has_stick -> has_melee
* has_stick -> has_melee
* Add a failsafe for direction pairing
* Fix playthrough crash bug
* Remove init from logicmixin
* Updates per code review (thanks hesto)
* has_stick to has_melee in newer update
* has_stick to has_melee in newer update
* # Conflicts:
#	worlds/tunic/__init__.py
#	worlds/tunic/combat_logic.py
#	worlds/tunic/er_data.py
#	worlds/tunic/er_rules.py
#	worlds/tunic/er_scripts.py
* Cleanup more stuff after merge
* Revert "Cleanup more stuff after merge"
This reverts commit a6ee9a93da8f2fcc4413de6df6927b246017889d.
* Revert "# Conflicts:"
This reverts commit c74ccd74a45b6ad6b9abe6e339d115a0c98baf30.
* Cleanup more stuff after merge
* Swap to .get for decoupled so it works with older games probably maybe
* Fix after merge
* Fix typo
* Fix UT support with fixed shop option
* Backport plando connections fix
* Fix issue with fixed shop + decoupled
* Make the error not duplicate the while loop condition
* Fix rule for quarry back to monastery
* Fix more stuff after merge
* Make it not output anything if you set plando connections but not ER
* Add obvious note to plando connections description
* Fix after merge
* add comment to commented out connection
---------
Co-authored-by: Exempt-Medic <60412657+Exempt-Medic@users.noreply.github.com>
											
										 
										
											2025-05-06 12:33:21 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            "decoupled": self.options.decoupled.value if self.options.entrance_rando else 0,
							 | 
						
					
						
							
								
									
										
										
										
											2024-03-21 11:50:07 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            "shuffle_ladders": self.options.shuffle_ladders.value,
							 | 
						
					
						
							
								
									
										
										
										
											2025-01-15 18:17:07 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            "grass_randomizer": self.options.grass_randomizer.value,
							 | 
						
					
						
							
								
									
										
										
										
											2024-12-15 16:40:36 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            "combat_logic": self.options.combat_logic.value,
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            "Hexagon Quest Prayer": self.ability_unlocks["Pages 24-25 (Prayer)"],
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            "Hexagon Quest Holy Cross": self.ability_unlocks["Pages 42-43 (Holy Cross)"],
							 | 
						
					
						
							
								
									
										
										
										
											2024-02-16 17:25:20 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            "Hexagon Quest Icebolt": self.ability_unlocks["Pages 52-53 (Icebolt)"],
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            "Hexagon Quest Goal": self.options.hexagon_goal.value,
							 | 
						
					
						
							
								
									
										
										
										
											2024-07-23 03:04:24 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            "Entrance Rando": self.tunic_portal_pairs,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            "disable_local_spoiler": int(self.settings.disable_local_spoiler or self.multiworld.is_race),
							 | 
						
					
						
							
								
									
										
										
										
											2025-03-08 11:25:47 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            "breakable_shuffle": self.options.breakable_shuffle.value,
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-11-22 19:42:44 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # this would be in a stage if there was an appropriate stage for it
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        self.player_item_link_locations = {}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        groups = self.multiworld.get_player_groups(self.player)
							 | 
						
					
						
							
								
									
										
										
										
											2024-11-24 12:43:28 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # checking if groups so that this doesn't run if the player isn't in a group
							 | 
						
					
						
							
								
									
										
										
										
											2024-11-22 19:42:44 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        if groups:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if not self.item_link_locations:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                tunic_worlds: Tuple[TunicWorld] = self.multiworld.get_game_worlds("TUNIC")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                # figure out our groups and the items in them
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                for tunic in tunic_worlds:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    for group in self.multiworld.get_player_groups(tunic.player):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        self.item_link_locations.setdefault(group, {})
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                for location in self.multiworld.get_locations():
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    if location.item and location.item.player in self.item_link_locations.keys():
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        (self.item_link_locations[location.item.player].setdefault(location.item.name, [])
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                         .append((location.player, location.name)))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            # if item links are on, set up the player's personal item link locations, so we can pop them as needed
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            for group, item_links in self.item_link_locations.items():
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if group in groups:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    for item_name, locs in item_links.items():
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                        self.player_item_link_locations[item_name] = \
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            [self.multiworld.get_location(location_name, player) for player, location_name in locs]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        for tunic_item in filter(lambda item: item.location is not None and item.code is not None, self.slot_data_items):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if tunic_item.name not in slot_data:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                slot_data[tunic_item.name] = []
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if tunic_item.name == gold_hexagon and len(slot_data[gold_hexagon]) >= 6:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                continue
							 | 
						
					
						
							
								
									
										
										
										
											2024-11-22 19:42:44 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            slot_data[tunic_item.name].extend(self.get_real_location(tunic_item.location))
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        for start_item in self.options.start_inventory_from_pool:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            if start_item in slot_data_item_names:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                if start_item not in slot_data:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    slot_data[start_item] = []
							 | 
						
					
						
							
								
									
										
										
										
											2024-07-05 16:50:12 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								                for _ in range(self.options.start_inventory_from_pool[start_item]):
							 | 
						
					
						
							
								
									
										
										
										
											2024-01-12 14:32:15 -05:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                    slot_data[start_item].extend(["Your Pocket", self.player])
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        return slot_data
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    # for the universal tracker, doesn't get called in standard gen
							 | 
						
					
						
							
								
									
										
										
										
											2024-08-11 18:24:30 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    # docs: https://github.com/FarisTheAncient/Archipelago/blob/tracker/worlds/tracker/docs/re-gen-passthrough.md
							 | 
						
					
						
							
								
									
										
										
										
											2024-02-15 23:03:51 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    @staticmethod
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    def interpret_slot_data(slot_data: Dict[str, Any]) -> Dict[str, Any]:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        # returning slot_data so it regens, giving it back in multiworld.re_gen_passthrough
							 | 
						
					
						
							
								
									
										
										
										
											2024-08-11 18:24:30 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # we are using re_gen_passthrough over modifying the world here due to complexities with ER
							 | 
						
					
						
							
								
									
										
										
										
											2024-02-15 23:03:51 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        return slot_data
							 |