| 
									
										
											  
											
												Minecraft Randomizer
Squash merge, original Commits:
* Minecraft locations, items, and generation without logic
* added id lookup for minecraft
* typing import fix in minecraft/Items.py
* fix 2
* implementing Minecraft options and hard/postgame advancement exclusion
* first logic pass (75/80)
* logic pass 2 and proper completion conditions
* added insane difficulty pool, modified method of excluding item pools for easier extension
* bump network_data_package version
* minecraft testing framework
* switch Ancient Debris to Netherite Scrap to avoid advancement triggering on receiving that item
* Testing now functions, split tests up by advancement pane, added some story tests
* Newer testing framework: every advancement gets its own function, for ease of testing
* fixed logic for The End... Again...
* changed option names to "include_hard_advancements" etc.
* village/pillager-related advancements now require can_adventure: weapon + food
* a few minecraft tests
* rename "Flint & Steel" to "Flint and Steel" for parity with in-game name
* additional MC tests
* more tests, mostly nether-related tests
* more tests, removed anvil path for Two Birds One Arrow
* include Minecraft slot data, and a world seed for each Minecraft player slot
* Added new items: ender pearls, lapis, porkchops
* All remaining Minecraft tests
* formatting of Minecraft tests and logic for better readability
* require Wither kill for Monsters Hunted
* properly removed 8 Emeralds item from item pool
* enchanting required for wither; fishing rod required for water breathing; water breathing required for elder guardian kill
* Added 12 new advancements (ported from old achievement system)
* renamed "On a Rail" for consistency with modern advancements
* tests for the new advancements
* moved slot_data generation for minecraft into worlds/minecraft/__init__.py, added logic_version to slot_data
* output minecraft options in the spoiler log
* modified advancement goal values for new advancements
* make non-native Minecraft items appear as Shovel in ALttP, and unknown-game items as Power Stars
* fixed glowstone block logic for Not Quite Nine Lives
* setup for shuffling MC structures: building ER world and shuffling regions/entrances
* ensured Nether Fortresses can't be placed in the End
* finished logic for structure randomization
* fixed nonnative items always showing up as Hammers in ALttP shops
* output minecraft structure info in the spoiler
* generate .apmc file for communication with MC client
* fixed structure rando always using the same seed
* move stuff to worlds/minecraft/Regions.py
* make output apmc file have consistent name with other files
* added minecraft bottle macro; fixed tests imports
* generalizing MC region generation
* restructured structure shuffling in preparation for structure plando
* only output structure rando info in spoiler if they are shuffled
* Force structure rando to always be off, for the stable release
* added Minecraft options to player settings
* formally added combat_difficulty as an option
* Added Ender Dragon into playthrough, cleaned up goal map
* Added new difficulties: Easy, Normal, Hard combat
* moved .apmc generation time to prevent outputs on failed generation
* updated tests for new combat logic
* Fixed bug causing generation to fail; removed Nether Fortress event since it should no longer be needed with the fix
* moved all MC-specific functions into gen_minecraft
* renamed "logic_version" to "client_version"
* bug fixes
properly flagged event locations/items with id None
moved generation back to Main.py to fix mysterious generation failures
* moved link_minecraft_regions into minecraft init, left create_regions in Main for caching
* added seed_name, player_name, client_version to apmc file
* reenabled structure shuffle
* added entrance tests for minecraft
Co-authored-by: achuang <alexander.w.chuang@gmail.com>
											
										 
											2021-05-08 07:38:57 -04:00
										 |  |  | from .Locations import MinecraftAdvancement, advancement_table | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from BaseClasses import Region, Entrance, Location, MultiWorld, Item | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def minecraft_create_regions(world: MultiWorld, player: int): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def MCRegion(region_name: str, exits=[]): | 
					
						
							|  |  |  |         ret = Region(region_name, None, region_name, player) | 
					
						
							|  |  |  |         ret.world = world | 
					
						
							|  |  |  |         ret.locations = [ MinecraftAdvancement(player, loc_name, loc_data.id, ret)  | 
					
						
							|  |  |  |             for loc_name, loc_data in advancement_table.items()  | 
					
						
							|  |  |  |             if loc_data.region == region_name ] | 
					
						
							|  |  |  |         for exit in exits:  | 
					
						
							|  |  |  |             ret.exits.append(Entrance(player, exit, ret)) | 
					
						
							|  |  |  |         return ret | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     world.regions += [MCRegion(*r) for r in mc_regions] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (exit, region) in mandatory_connections: | 
					
						
							|  |  |  |         world.get_entrance(exit, player).connect(world.get_region(region, player)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def link_minecraft_structures(world: MultiWorld, player: int): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Get all unpaired exits and all regions without entrances (except the Menu) | 
					
						
							|  |  |  |     # This function is destructive on these lists.  | 
					
						
							|  |  |  |     exits = [exit.name for r in world.regions if r.player == player for exit in r.exits if exit.connected_region == None] | 
					
						
							|  |  |  |     structs = [r.name for r in world.regions if r.player == player and r.entrances == [] and r.name != 'Menu'] | 
					
						
							|  |  |  |     try:  | 
					
						
							|  |  |  |         assert len(exits) == len(structs) | 
					
						
							|  |  |  |     except AssertionError as e: # this should never happen | 
					
						
							|  |  |  |         raise Exception(f"Could not obtain equal numbers of Minecraft exits and structures for player {player}") from e | 
					
						
							|  |  |  |     num_regions = len(exits) | 
					
						
							|  |  |  |     pairs = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def check_valid_connection(exit, struct):  | 
					
						
							|  |  |  |         if (exit in exits) and (struct in structs) and (exit not in pairs):  | 
					
						
							|  |  |  |             return True | 
					
						
							|  |  |  |         return False | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def set_pair(exit, struct):  | 
					
						
							| 
									
										
										
										
											2021-05-22 10:57:13 -05:00
										 |  |  |         try:  | 
					
						
							|  |  |  |             assert exit in exits | 
					
						
							|  |  |  |             assert struct in structs | 
					
						
							|  |  |  |         except AssertionError as e:  | 
					
						
							|  |  |  |             raise Exception(f"Invalid connection: {exit} => {struct} for player {player}") | 
					
						
							| 
									
										
											  
											
												Minecraft Randomizer
Squash merge, original Commits:
* Minecraft locations, items, and generation without logic
* added id lookup for minecraft
* typing import fix in minecraft/Items.py
* fix 2
* implementing Minecraft options and hard/postgame advancement exclusion
* first logic pass (75/80)
* logic pass 2 and proper completion conditions
* added insane difficulty pool, modified method of excluding item pools for easier extension
* bump network_data_package version
* minecraft testing framework
* switch Ancient Debris to Netherite Scrap to avoid advancement triggering on receiving that item
* Testing now functions, split tests up by advancement pane, added some story tests
* Newer testing framework: every advancement gets its own function, for ease of testing
* fixed logic for The End... Again...
* changed option names to "include_hard_advancements" etc.
* village/pillager-related advancements now require can_adventure: weapon + food
* a few minecraft tests
* rename "Flint & Steel" to "Flint and Steel" for parity with in-game name
* additional MC tests
* more tests, mostly nether-related tests
* more tests, removed anvil path for Two Birds One Arrow
* include Minecraft slot data, and a world seed for each Minecraft player slot
* Added new items: ender pearls, lapis, porkchops
* All remaining Minecraft tests
* formatting of Minecraft tests and logic for better readability
* require Wither kill for Monsters Hunted
* properly removed 8 Emeralds item from item pool
* enchanting required for wither; fishing rod required for water breathing; water breathing required for elder guardian kill
* Added 12 new advancements (ported from old achievement system)
* renamed "On a Rail" for consistency with modern advancements
* tests for the new advancements
* moved slot_data generation for minecraft into worlds/minecraft/__init__.py, added logic_version to slot_data
* output minecraft options in the spoiler log
* modified advancement goal values for new advancements
* make non-native Minecraft items appear as Shovel in ALttP, and unknown-game items as Power Stars
* fixed glowstone block logic for Not Quite Nine Lives
* setup for shuffling MC structures: building ER world and shuffling regions/entrances
* ensured Nether Fortresses can't be placed in the End
* finished logic for structure randomization
* fixed nonnative items always showing up as Hammers in ALttP shops
* output minecraft structure info in the spoiler
* generate .apmc file for communication with MC client
* fixed structure rando always using the same seed
* move stuff to worlds/minecraft/Regions.py
* make output apmc file have consistent name with other files
* added minecraft bottle macro; fixed tests imports
* generalizing MC region generation
* restructured structure shuffling in preparation for structure plando
* only output structure rando info in spoiler if they are shuffled
* Force structure rando to always be off, for the stable release
* added Minecraft options to player settings
* formally added combat_difficulty as an option
* Added Ender Dragon into playthrough, cleaned up goal map
* Added new difficulties: Easy, Normal, Hard combat
* moved .apmc generation time to prevent outputs on failed generation
* updated tests for new combat logic
* Fixed bug causing generation to fail; removed Nether Fortress event since it should no longer be needed with the fix
* moved all MC-specific functions into gen_minecraft
* renamed "logic_version" to "client_version"
* bug fixes
properly flagged event locations/items with id None
moved generation back to Main.py to fix mysterious generation failures
* moved link_minecraft_regions into minecraft init, left create_regions in Main for caching
* added seed_name, player_name, client_version to apmc file
* reenabled structure shuffle
* added entrance tests for minecraft
Co-authored-by: achuang <alexander.w.chuang@gmail.com>
											
										 
											2021-05-08 07:38:57 -04:00
										 |  |  |         pairs[exit] = struct | 
					
						
							|  |  |  |         exits.remove(exit) | 
					
						
							|  |  |  |         structs.remove(struct) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Plando stuff. Remove any utilized exits/structs from the lists.  | 
					
						
							|  |  |  |     # Raise error if trying to put Nether Fortress in the End.  | 
					
						
							| 
									
										
										
										
											2021-05-22 10:57:13 -05:00
										 |  |  |     if world.plando_connections[player]: | 
					
						
							|  |  |  |         for connection in world.plando_connections[player]: | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 if connection.entrance == 'The End Structure' and connection.exit == 'Nether Fortress':  | 
					
						
							|  |  |  |                     raise Exception(f"Cannot place Nether Fortress in the End for player {player}") | 
					
						
							|  |  |  |                 set_pair(connection.entrance, connection.exit) | 
					
						
							|  |  |  |             except Exception as e: | 
					
						
							|  |  |  |                 raise Exception(f"Could not connect using {connection}") from e | 
					
						
							| 
									
										
											  
											
												Minecraft Randomizer
Squash merge, original Commits:
* Minecraft locations, items, and generation without logic
* added id lookup for minecraft
* typing import fix in minecraft/Items.py
* fix 2
* implementing Minecraft options and hard/postgame advancement exclusion
* first logic pass (75/80)
* logic pass 2 and proper completion conditions
* added insane difficulty pool, modified method of excluding item pools for easier extension
* bump network_data_package version
* minecraft testing framework
* switch Ancient Debris to Netherite Scrap to avoid advancement triggering on receiving that item
* Testing now functions, split tests up by advancement pane, added some story tests
* Newer testing framework: every advancement gets its own function, for ease of testing
* fixed logic for The End... Again...
* changed option names to "include_hard_advancements" etc.
* village/pillager-related advancements now require can_adventure: weapon + food
* a few minecraft tests
* rename "Flint & Steel" to "Flint and Steel" for parity with in-game name
* additional MC tests
* more tests, mostly nether-related tests
* more tests, removed anvil path for Two Birds One Arrow
* include Minecraft slot data, and a world seed for each Minecraft player slot
* Added new items: ender pearls, lapis, porkchops
* All remaining Minecraft tests
* formatting of Minecraft tests and logic for better readability
* require Wither kill for Monsters Hunted
* properly removed 8 Emeralds item from item pool
* enchanting required for wither; fishing rod required for water breathing; water breathing required for elder guardian kill
* Added 12 new advancements (ported from old achievement system)
* renamed "On a Rail" for consistency with modern advancements
* tests for the new advancements
* moved slot_data generation for minecraft into worlds/minecraft/__init__.py, added logic_version to slot_data
* output minecraft options in the spoiler log
* modified advancement goal values for new advancements
* make non-native Minecraft items appear as Shovel in ALttP, and unknown-game items as Power Stars
* fixed glowstone block logic for Not Quite Nine Lives
* setup for shuffling MC structures: building ER world and shuffling regions/entrances
* ensured Nether Fortresses can't be placed in the End
* finished logic for structure randomization
* fixed nonnative items always showing up as Hammers in ALttP shops
* output minecraft structure info in the spoiler
* generate .apmc file for communication with MC client
* fixed structure rando always using the same seed
* move stuff to worlds/minecraft/Regions.py
* make output apmc file have consistent name with other files
* added minecraft bottle macro; fixed tests imports
* generalizing MC region generation
* restructured structure shuffling in preparation for structure plando
* only output structure rando info in spoiler if they are shuffled
* Force structure rando to always be off, for the stable release
* added Minecraft options to player settings
* formally added combat_difficulty as an option
* Added Ender Dragon into playthrough, cleaned up goal map
* Added new difficulties: Easy, Normal, Hard combat
* moved .apmc generation time to prevent outputs on failed generation
* updated tests for new combat logic
* Fixed bug causing generation to fail; removed Nether Fortress event since it should no longer be needed with the fix
* moved all MC-specific functions into gen_minecraft
* renamed "logic_version" to "client_version"
* bug fixes
properly flagged event locations/items with id None
moved generation back to Main.py to fix mysterious generation failures
* moved link_minecraft_regions into minecraft init, left create_regions in Main for caching
* added seed_name, player_name, client_version to apmc file
* reenabled structure shuffle
* added entrance tests for minecraft
Co-authored-by: achuang <alexander.w.chuang@gmail.com>
											
										 
											2021-05-08 07:38:57 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if world.shuffle_structures[player]:  | 
					
						
							|  |  |  |         # Can't put Nether Fortress in the End | 
					
						
							|  |  |  |         if 'The End Structure' in exits and 'Nether Fortress' in structs:  | 
					
						
							|  |  |  |             try:  | 
					
						
							|  |  |  |                 end_struct = world.random.choice([s for s in structs if s != 'Nether Fortress']) | 
					
						
							|  |  |  |                 set_pair('The End Structure', end_struct) | 
					
						
							| 
									
										
										
										
											2021-05-22 10:57:13 -05:00
										 |  |  |             except IndexError as e: # should only happen if structs is emptied by plando | 
					
						
							| 
									
										
											  
											
												Minecraft Randomizer
Squash merge, original Commits:
* Minecraft locations, items, and generation without logic
* added id lookup for minecraft
* typing import fix in minecraft/Items.py
* fix 2
* implementing Minecraft options and hard/postgame advancement exclusion
* first logic pass (75/80)
* logic pass 2 and proper completion conditions
* added insane difficulty pool, modified method of excluding item pools for easier extension
* bump network_data_package version
* minecraft testing framework
* switch Ancient Debris to Netherite Scrap to avoid advancement triggering on receiving that item
* Testing now functions, split tests up by advancement pane, added some story tests
* Newer testing framework: every advancement gets its own function, for ease of testing
* fixed logic for The End... Again...
* changed option names to "include_hard_advancements" etc.
* village/pillager-related advancements now require can_adventure: weapon + food
* a few minecraft tests
* rename "Flint & Steel" to "Flint and Steel" for parity with in-game name
* additional MC tests
* more tests, mostly nether-related tests
* more tests, removed anvil path for Two Birds One Arrow
* include Minecraft slot data, and a world seed for each Minecraft player slot
* Added new items: ender pearls, lapis, porkchops
* All remaining Minecraft tests
* formatting of Minecraft tests and logic for better readability
* require Wither kill for Monsters Hunted
* properly removed 8 Emeralds item from item pool
* enchanting required for wither; fishing rod required for water breathing; water breathing required for elder guardian kill
* Added 12 new advancements (ported from old achievement system)
* renamed "On a Rail" for consistency with modern advancements
* tests for the new advancements
* moved slot_data generation for minecraft into worlds/minecraft/__init__.py, added logic_version to slot_data
* output minecraft options in the spoiler log
* modified advancement goal values for new advancements
* make non-native Minecraft items appear as Shovel in ALttP, and unknown-game items as Power Stars
* fixed glowstone block logic for Not Quite Nine Lives
* setup for shuffling MC structures: building ER world and shuffling regions/entrances
* ensured Nether Fortresses can't be placed in the End
* finished logic for structure randomization
* fixed nonnative items always showing up as Hammers in ALttP shops
* output minecraft structure info in the spoiler
* generate .apmc file for communication with MC client
* fixed structure rando always using the same seed
* move stuff to worlds/minecraft/Regions.py
* make output apmc file have consistent name with other files
* added minecraft bottle macro; fixed tests imports
* generalizing MC region generation
* restructured structure shuffling in preparation for structure plando
* only output structure rando info in spoiler if they are shuffled
* Force structure rando to always be off, for the stable release
* added Minecraft options to player settings
* formally added combat_difficulty as an option
* Added Ender Dragon into playthrough, cleaned up goal map
* Added new difficulties: Easy, Normal, Hard combat
* moved .apmc generation time to prevent outputs on failed generation
* updated tests for new combat logic
* Fixed bug causing generation to fail; removed Nether Fortress event since it should no longer be needed with the fix
* moved all MC-specific functions into gen_minecraft
* renamed "logic_version" to "client_version"
* bug fixes
properly flagged event locations/items with id None
moved generation back to Main.py to fix mysterious generation failures
* moved link_minecraft_regions into minecraft init, left create_regions in Main for caching
* added seed_name, player_name, client_version to apmc file
* reenabled structure shuffle
* added entrance tests for minecraft
Co-authored-by: achuang <alexander.w.chuang@gmail.com>
											
										 
											2021-05-08 07:38:57 -04:00
										 |  |  |                 raise Exception(f"Plando forced Nether Fortress in the End for player {player}") from e | 
					
						
							|  |  |  |         world.random.shuffle(structs) | 
					
						
							|  |  |  |         for exit, struct in zip(exits[:], structs[:]):  | 
					
						
							|  |  |  |             set_pair(exit, struct) | 
					
						
							|  |  |  |     else: # write remaining default connections | 
					
						
							|  |  |  |         for (exit, struct) in default_connections:  | 
					
						
							|  |  |  |             if exit in exits:  | 
					
						
							|  |  |  |                 set_pair(exit, struct) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Make sure we actually paired everything; might fail if plando | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         assert len(exits) == len(structs) == 0 | 
					
						
							|  |  |  |     except AssertionError as e:  | 
					
						
							|  |  |  |         raise Exception(f"Failed to connect all Minecraft structures for player {player}; check plando settings in yaml") from e | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for exit, struct in pairs.items(): | 
					
						
							|  |  |  |         world.get_entrance(exit, player).connect(world.get_region(struct, player)) | 
					
						
							|  |  |  |         if world.shuffle_structures[player]: | 
					
						
							|  |  |  |             world.spoiler.set_entrance(exit, struct, 'entrance', player) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # (Region name, list of exits) | 
					
						
							|  |  |  | mc_regions = [ | 
					
						
							|  |  |  |     ('Menu', ['New World']), | 
					
						
							|  |  |  |     ('Overworld', ['Nether Portal', 'End Portal', 'Overworld Structure 1', 'Overworld Structure 2']), | 
					
						
							|  |  |  |     ('The Nether', ['Nether Structure 1', 'Nether Structure 2']), | 
					
						
							|  |  |  |     ('The End', ['The End Structure']), | 
					
						
							|  |  |  |     ('Village', []), | 
					
						
							|  |  |  |     ('Pillager Outpost', []), | 
					
						
							|  |  |  |     ('Nether Fortress', []), | 
					
						
							|  |  |  |     ('Bastion Remnant', []), | 
					
						
							|  |  |  |     ('End City', []) | 
					
						
							|  |  |  | ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # (Entrance, region pointed to) | 
					
						
							|  |  |  | mandatory_connections = [ | 
					
						
							|  |  |  |     ('New World', 'Overworld'), | 
					
						
							|  |  |  |     ('Nether Portal', 'The Nether'), | 
					
						
							|  |  |  |     ('End Portal', 'The End') | 
					
						
							|  |  |  | ] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | default_connections = { | 
					
						
							|  |  |  |     ('Overworld Structure 1', 'Village'), | 
					
						
							|  |  |  |     ('Overworld Structure 2', 'Pillager Outpost'), | 
					
						
							|  |  |  |     ('Nether Structure 1', 'Nether Fortress'), | 
					
						
							|  |  |  |     ('Nether Structure 2', 'Bastion Remnant'), | 
					
						
							|  |  |  |     ('The End Structure', 'End City') | 
					
						
							|  |  |  | } |