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 11:38:57 +00: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 15:57:13 +00: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 11:38:57 +00: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 15:57:13 +00: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 11:38:57 +00: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 15:57:13 +00: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 11:38:57 +00: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')
|
|
|
|
}
|