Minecraft updates (#29)
* Implement excluded locations * Update Minecraft to use exclusion_rules for its exclusion pools * Flag the enchanted books as advancement so they don't go on excluded locations (particularly the Infinity book) * update playerSettings for exclusion * new items: 32 Arrows, Saddle, structure compasses for overworld structures * move structure linking to create_regions instead of generate_basic * Update Minecraft to use LogicMixin * add separate can_exclude property, so non-progression items can be marked non-excluded * separate fill step for nonadvancement nonexcluded items * made Saddle not a progression item, but also nonexcluded * fix missing player arg * remove higher xp amounts from pool, leaving only 50 XP * fix new Minecraft item IDs * added shulker box item for starting inventory * increment client and data version * change client_version to int instead of tuple * make saddle a progression item * added structure compass option and appropriate logic for all compasses * Update playerSettings.yaml with MC options * update minecraft tests * update exclusion procedure for clarity
This commit is contained in:
parent
83dc92c6a5
commit
e79a918c03
|
@ -741,91 +741,6 @@ class CollectionState(object):
|
||||||
def can_bomb_clip(self, region: Region, player: int) -> bool:
|
def can_bomb_clip(self, region: Region, player: int) -> bool:
|
||||||
return self.is_not_bunny(region, player) and self.has('Pegasus Boots', player)
|
return self.is_not_bunny(region, player) and self.has('Pegasus Boots', player)
|
||||||
|
|
||||||
# Minecraft logic functions
|
|
||||||
def has_iron_ingots(self, player: int):
|
|
||||||
return self.has('Progressive Tools', player) and self.has('Ingot Crafting', player)
|
|
||||||
|
|
||||||
def has_gold_ingots(self, player: int):
|
|
||||||
return self.has('Ingot Crafting', player) and (self.has('Progressive Tools', player, 2) or self.can_reach('The Nether', 'Region', player))
|
|
||||||
|
|
||||||
def has_diamond_pickaxe(self, player: int):
|
|
||||||
return self.has('Progressive Tools', player, 3) and self.has_iron_ingots(player)
|
|
||||||
|
|
||||||
def craft_crossbow(self, player: int):
|
|
||||||
return self.has('Archery', player) and self.has_iron_ingots(player)
|
|
||||||
|
|
||||||
def has_bottle_mc(self, player: int):
|
|
||||||
return self.has('Bottles', player) and self.has('Ingot Crafting', player)
|
|
||||||
|
|
||||||
def can_enchant(self, player: int):
|
|
||||||
return self.has('Enchanting', player) and self.has_diamond_pickaxe(player) # mine obsidian and lapis
|
|
||||||
|
|
||||||
def can_use_anvil(self, player: int):
|
|
||||||
return self.has('Enchanting', player) and self.has('Resource Blocks', player) and self.has_iron_ingots(player)
|
|
||||||
|
|
||||||
def fortress_loot(self, player: int): # saddles, blaze rods, wither skulls
|
|
||||||
return self.can_reach('Nether Fortress', 'Region', player) and self.basic_combat(player)
|
|
||||||
|
|
||||||
def can_brew_potions(self, player: int):
|
|
||||||
return self.fortress_loot(player) and self.has('Brewing', player) and self.has_bottle_mc(player)
|
|
||||||
|
|
||||||
def can_piglin_trade(self, player: int):
|
|
||||||
return self.has_gold_ingots(player) and (self.can_reach('The Nether', 'Region', player) or self.can_reach('Bastion Remnant', 'Region', player))
|
|
||||||
|
|
||||||
def enter_stronghold(self, player: int):
|
|
||||||
return self.fortress_loot(player) and self.has('Brewing', player) and self.has('3 Ender Pearls', player)
|
|
||||||
|
|
||||||
# Difficulty-dependent functions
|
|
||||||
def combat_difficulty(self, player: int):
|
|
||||||
return self.world.combat_difficulty[player].get_option_name()
|
|
||||||
|
|
||||||
def can_adventure(self, player: int):
|
|
||||||
if self.combat_difficulty(player) == 'easy':
|
|
||||||
return self.has('Progressive Weapons', player, 2) and self.has_iron_ingots(player)
|
|
||||||
elif self.combat_difficulty(player) == 'hard':
|
|
||||||
return True
|
|
||||||
return self.has('Progressive Weapons', player) and (self.has('Ingot Crafting', player) or self.has('Campfire', player))
|
|
||||||
|
|
||||||
def basic_combat(self, player: int):
|
|
||||||
if self.combat_difficulty(player) == 'easy':
|
|
||||||
return self.has('Progressive Weapons', player, 2) and self.has('Progressive Armor', player) and \
|
|
||||||
self.has('Shield', player) and self.has_iron_ingots(player)
|
|
||||||
elif self.combat_difficulty(player) == 'hard':
|
|
||||||
return True
|
|
||||||
return self.has('Progressive Weapons', player) and (self.has('Progressive Armor', player) or self.has('Shield', player)) and self.has_iron_ingots(player)
|
|
||||||
|
|
||||||
def complete_raid(self, player: int):
|
|
||||||
reach_regions = self.can_reach('Village', 'Region', player) and self.can_reach('Pillager Outpost', 'Region', player)
|
|
||||||
if self.combat_difficulty(player) == 'easy':
|
|
||||||
return reach_regions and \
|
|
||||||
self.has('Progressive Weapons', player, 3) and self.has('Progressive Armor', player, 2) and \
|
|
||||||
self.has('Shield', player) and self.has('Archery', player) and \
|
|
||||||
self.has('Progressive Tools', player, 2) and self.has_iron_ingots(player)
|
|
||||||
elif self.combat_difficulty(player) == 'hard': # might be too hard?
|
|
||||||
return reach_regions and self.has('Progressive Weapons', player, 2) and self.has_iron_ingots(player) and \
|
|
||||||
(self.has('Progressive Armor', player) or self.has('Shield', player))
|
|
||||||
return reach_regions and self.has('Progressive Weapons', player, 2) and self.has_iron_ingots(player) and \
|
|
||||||
self.has('Progressive Armor', player) and self.has('Shield', player)
|
|
||||||
|
|
||||||
def can_kill_wither(self, player: int):
|
|
||||||
normal_kill = self.has("Progressive Weapons", player, 3) and self.has("Progressive Armor", player, 2) and self.can_brew_potions(player) and self.can_enchant(player)
|
|
||||||
if self.combat_difficulty(player) == 'easy':
|
|
||||||
return self.fortress_loot(player) and normal_kill and self.has('Archery', player)
|
|
||||||
elif self.combat_difficulty(player) == 'hard': # cheese kill using bedrock ceilings
|
|
||||||
return self.fortress_loot(player) and (normal_kill or self.can_reach('The Nether', 'Region', player) or self.can_reach('The End', 'Region', player))
|
|
||||||
return self.fortress_loot(player) and normal_kill
|
|
||||||
|
|
||||||
def can_kill_ender_dragon(self, player: int):
|
|
||||||
# Since it is possible to kill the dragon without getting any of the advancements related to it, we need to require that it can be respawned.
|
|
||||||
respawn_dragon = self.can_reach('The Nether', 'Region', player) and self.has('Ingot Crafting', player)
|
|
||||||
if self.combat_difficulty(player) == 'easy':
|
|
||||||
return respawn_dragon and self.has("Progressive Weapons", player, 3) and self.has("Progressive Armor", player, 2) and \
|
|
||||||
self.has('Archery', player) and self.can_brew_potions(player) and self.can_enchant(player)
|
|
||||||
if self.combat_difficulty(player) == 'hard':
|
|
||||||
return respawn_dragon and ((self.has('Progressive Weapons', player, 2) and self.has('Progressive Armor', player)) or \
|
|
||||||
(self.has('Progressive Weapons', player, 1) and self.has('Bed', player)))
|
|
||||||
return respawn_dragon and self.has('Progressive Weapons', player, 2) and self.has('Progressive Armor', player) and self.has('Archery', player)
|
|
||||||
|
|
||||||
def collect(self, item: Item, event: bool = False, location: Location = None) -> bool:
|
def collect(self, item: Item, event: bool = False, location: Location = None) -> bool:
|
||||||
if location:
|
if location:
|
||||||
self.locations_checked.add(location)
|
self.locations_checked.add(location)
|
||||||
|
|
|
@ -199,6 +199,12 @@ Minecraft:
|
||||||
shuffle_structures: # Enables shuffling of villages, outposts, fortresses, bastions, and end cities.
|
shuffle_structures: # Enables shuffling of villages, outposts, fortresses, bastions, and end cities.
|
||||||
on: 0
|
on: 0
|
||||||
off: 1
|
off: 1
|
||||||
|
structure_compasses: # Adds structure compasses to the item pool, which point to the nearest indicated structure.
|
||||||
|
on: 0
|
||||||
|
off: 1
|
||||||
|
bee_traps: # Adds bee traps to the item pool, which spawn multiple angered bees around every player when received.
|
||||||
|
on: 0
|
||||||
|
off: 1
|
||||||
A Link to the Past:
|
A Link to the Past:
|
||||||
### Logic Section ###
|
### Logic Section ###
|
||||||
glitches_required: # Determine the logic required to complete the seed
|
glitches_required: # Determine the logic required to complete the seed
|
||||||
|
|
|
@ -215,11 +215,12 @@ class TestAdvancements(TestMinecraft):
|
||||||
["This Boat Has Legs", False, [], ['Progressive Weapons']],
|
["This Boat Has Legs", False, [], ['Progressive Weapons']],
|
||||||
["This Boat Has Legs", False, [], ['Progressive Armor', 'Shield']],
|
["This Boat Has Legs", False, [], ['Progressive Armor', 'Shield']],
|
||||||
["This Boat Has Legs", False, [], ['Fishing Rod']],
|
["This Boat Has Legs", False, [], ['Fishing Rod']],
|
||||||
|
["This Boat Has Legs", False, [], ['Saddle']],
|
||||||
["This Boat Has Legs", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']],
|
["This Boat Has Legs", False, ['Progressive Tools', 'Progressive Tools'], ['Bucket', 'Progressive Tools']],
|
||||||
["This Boat Has Legs", True, ['Ingot Crafting', 'Progressive Tools', 'Progressive Weapons', 'Progressive Armor', 'Flint and Steel', 'Bucket', 'Fishing Rod']],
|
["This Boat Has Legs", True, ['Saddle', 'Ingot Crafting', 'Progressive Tools', 'Progressive Weapons', 'Progressive Armor', 'Flint and Steel', 'Bucket', 'Fishing Rod']],
|
||||||
["This Boat Has Legs", True, ['Ingot Crafting', 'Progressive Tools', 'Progressive Weapons', 'Progressive Armor', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Fishing Rod']],
|
["This Boat Has Legs", True, ['Saddle', 'Ingot Crafting', 'Progressive Tools', 'Progressive Weapons', 'Progressive Armor', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Fishing Rod']],
|
||||||
["This Boat Has Legs", True, ['Ingot Crafting', 'Progressive Tools', 'Progressive Weapons', 'Shield', 'Flint and Steel', 'Bucket', 'Fishing Rod']],
|
["This Boat Has Legs", True, ['Saddle', 'Ingot Crafting', 'Progressive Tools', 'Progressive Weapons', 'Shield', 'Flint and Steel', 'Bucket', 'Fishing Rod']],
|
||||||
["This Boat Has Legs", True, ['Ingot Crafting', 'Progressive Tools', 'Progressive Weapons', 'Shield', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Fishing Rod']],
|
["This Boat Has Legs", True, ['Saddle', 'Ingot Crafting', 'Progressive Tools', 'Progressive Weapons', 'Shield', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Fishing Rod']],
|
||||||
])
|
])
|
||||||
|
|
||||||
def test_42016(self):
|
def test_42016(self):
|
||||||
|
@ -1099,13 +1100,14 @@ class TestAdvancements(TestMinecraft):
|
||||||
["When Pigs Fly", False, [], ['Progressive Weapons']],
|
["When Pigs Fly", False, [], ['Progressive Weapons']],
|
||||||
["When Pigs Fly", False, [], ['Progressive Armor', 'Shield']],
|
["When Pigs Fly", False, [], ['Progressive Armor', 'Shield']],
|
||||||
["When Pigs Fly", False, [], ['Fishing Rod']],
|
["When Pigs Fly", False, [], ['Fishing Rod']],
|
||||||
|
["When Pigs Fly", False, [], ['Saddle']],
|
||||||
["When Pigs Fly", False, ['Progressive Weapons'], ['Flint and Steel', 'Progressive Weapons', 'Progressive Weapons']],
|
["When Pigs Fly", False, ['Progressive Weapons'], ['Flint and Steel', 'Progressive Weapons', 'Progressive Weapons']],
|
||||||
["When Pigs Fly", False, ['Progressive Tools', 'Progressive Tools', 'Progressive Weapons'], ['Bucket', 'Progressive Tools', 'Progressive Weapons', 'Progressive Weapons']],
|
["When Pigs Fly", False, ['Progressive Tools', 'Progressive Tools', 'Progressive Weapons'], ['Bucket', 'Progressive Tools', 'Progressive Weapons', 'Progressive Weapons']],
|
||||||
["When Pigs Fly", True, ['Ingot Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons', 'Progressive Armor', 'Fishing Rod']],
|
["When Pigs Fly", True, ['Saddle', 'Ingot Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons', 'Progressive Armor', 'Fishing Rod']],
|
||||||
["When Pigs Fly", True, ['Ingot Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons', 'Progressive Armor', 'Fishing Rod']],
|
["When Pigs Fly", True, ['Saddle', 'Ingot Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons', 'Progressive Armor', 'Fishing Rod']],
|
||||||
["When Pigs Fly", True, ['Ingot Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons', 'Shield', 'Fishing Rod']],
|
["When Pigs Fly", True, ['Saddle', 'Ingot Crafting', 'Progressive Tools', 'Flint and Steel', 'Bucket', 'Progressive Weapons', 'Shield', 'Fishing Rod']],
|
||||||
["When Pigs Fly", True, ['Ingot Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons', 'Shield', 'Fishing Rod']],
|
["When Pigs Fly", True, ['Saddle', 'Ingot Crafting', 'Progressive Tools', 'Flint and Steel', 'Progressive Tools', 'Progressive Tools', 'Progressive Weapons', 'Shield', 'Fishing Rod']],
|
||||||
["When Pigs Fly", True, ['Progressive Weapons', 'Progressive Weapons', 'Progressive Armor', 'Shield', 'Ingot Crafting', 'Progressive Tools', 'Fishing Rod']],
|
["When Pigs Fly", True, ['Saddle', 'Progressive Weapons', 'Progressive Weapons', 'Progressive Armor', 'Shield', 'Ingot Crafting', 'Progressive Tools', 'Fishing Rod']],
|
||||||
])
|
])
|
||||||
|
|
||||||
def test_42089(self):
|
def test_42089(self):
|
||||||
|
|
|
@ -37,6 +37,7 @@ class TestMinecraft(TestBase):
|
||||||
setattr(self.world, "shuffle_structures", {1: Toggle(False)})
|
setattr(self.world, "shuffle_structures", {1: Toggle(False)})
|
||||||
setattr(self.world, "combat_difficulty", {1: CombatDifficulty(1)}) # normal
|
setattr(self.world, "combat_difficulty", {1: CombatDifficulty(1)}) # normal
|
||||||
setattr(self.world, "bee_traps", {1: Toggle(False)})
|
setattr(self.world, "bee_traps", {1: Toggle(False)})
|
||||||
|
setattr(self.world, "structure_compasses", {1: Toggle(False)})
|
||||||
AutoWorld.call_single(self.world, "create_regions", 1)
|
AutoWorld.call_single(self.world, "create_regions", 1)
|
||||||
AutoWorld.call_single(self.world, "generate_basic", 1)
|
AutoWorld.call_single(self.world, "generate_basic", 1)
|
||||||
AutoWorld.call_single(self.world, "set_rules", 1)
|
AutoWorld.call_single(self.world, "set_rules", 1)
|
||||||
|
|
|
@ -47,6 +47,14 @@ item_table = {
|
||||||
"8 Gold Ore": ItemData(45032, False),
|
"8 Gold Ore": ItemData(45032, False),
|
||||||
"Rotten Flesh": ItemData(45033, False),
|
"Rotten Flesh": ItemData(45033, False),
|
||||||
"Single Arrow": ItemData(45034, False),
|
"Single Arrow": ItemData(45034, False),
|
||||||
|
"32 Arrows": ItemData(45035, False),
|
||||||
|
"Saddle": ItemData(45036, True),
|
||||||
|
"Structure Compass (Village)": ItemData(45037, True),
|
||||||
|
"Structure Compass (Pillager Outpost)": ItemData(45038, True),
|
||||||
|
"Structure Compass (Nether Fortress)": ItemData(45039, True),
|
||||||
|
"Structure Compass (Bastion Remnant)": ItemData(45040, True),
|
||||||
|
"Structure Compass (End City)": ItemData(45041, True),
|
||||||
|
"Shulker Box": ItemData(45042, False),
|
||||||
"Bee Trap (Minecraft)": ItemData(45100, False),
|
"Bee Trap (Minecraft)": ItemData(45100, False),
|
||||||
|
|
||||||
"Victory": ItemData(None, True)
|
"Victory": ItemData(None, True)
|
||||||
|
@ -62,16 +70,23 @@ item_frequencies = {
|
||||||
"4 Emeralds": 8,
|
"4 Emeralds": 8,
|
||||||
"4 Diamond Ore": 4,
|
"4 Diamond Ore": 4,
|
||||||
"16 Iron Ore": 4,
|
"16 Iron Ore": 4,
|
||||||
"500 XP": 4, # 2 after exclusions
|
"500 XP": 0,
|
||||||
"100 XP": 10, # 4 after exclusions
|
"100 XP": 0,
|
||||||
"50 XP": 12, # 4 after exclusions
|
"50 XP": 21,
|
||||||
"3 Ender Pearls": 4,
|
"3 Ender Pearls": 4,
|
||||||
"4 Lapis Lazuli": 2,
|
"4 Lapis Lazuli": 2,
|
||||||
"16 Porkchops": 8,
|
"16 Porkchops": 8,
|
||||||
"8 Gold Ore": 4,
|
"8 Gold Ore": 4,
|
||||||
"Rotten Flesh": 4,
|
"Rotten Flesh": 4,
|
||||||
"Single Arrow": 0,
|
"Single Arrow": 0,
|
||||||
"Bee Trap (Minecraft)": 0
|
"32 Arrows": 4,
|
||||||
|
"Structure Compass (Village)": 0,
|
||||||
|
"Structure Compass (Pillager Outpost)": 0,
|
||||||
|
"Structure Compass (Nether Fortress)": 0,
|
||||||
|
"Structure Compass (Bastion Remnant)": 0,
|
||||||
|
"Structure Compass (End City)": 0,
|
||||||
|
"Shulker Box": 0,
|
||||||
|
"Bee Trap (Minecraft)": 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
lookup_id_to_name: typing.Dict[int, str] = {data.code: item_name for item_name, data in item_table.items() if data.code}
|
lookup_id_to_name: typing.Dict[int, str] = {data.code: item_name for item_name, data in item_table.items() if data.code}
|
||||||
|
|
|
@ -21,6 +21,7 @@ minecraft_options: typing.Dict[str, type(Option)] = {
|
||||||
"include_hard_advancements": Toggle,
|
"include_hard_advancements": Toggle,
|
||||||
"include_insane_advancements": Toggle,
|
"include_insane_advancements": Toggle,
|
||||||
"include_postgame_advancements": Toggle,
|
"include_postgame_advancements": Toggle,
|
||||||
"shuffle_structures": Toggle,
|
"shuffle_structures": Toggle,
|
||||||
|
"structure_compasses": Toggle,
|
||||||
"bee_traps": Toggle
|
"bee_traps": Toggle
|
||||||
}
|
}
|
|
@ -1,6 +1,99 @@
|
||||||
from ..generic.Rules import set_rule
|
from ..generic.Rules import set_rule
|
||||||
from .Locations import exclusion_table, events_table
|
from .Locations import exclusion_table, events_table
|
||||||
from BaseClasses import MultiWorld
|
from BaseClasses import MultiWorld
|
||||||
|
from ..AutoWorld import LogicMixin
|
||||||
|
|
||||||
|
|
||||||
|
class MinecraftLogic(LogicMixin):
|
||||||
|
|
||||||
|
def _mc_has_iron_ingots(self, player: int):
|
||||||
|
return self.has('Progressive Tools', player) and self.has('Ingot Crafting', player)
|
||||||
|
|
||||||
|
def _mc_has_gold_ingots(self, player: int):
|
||||||
|
return self.has('Ingot Crafting', player) and (self.has('Progressive Tools', player, 2) or self.can_reach('The Nether', 'Region', player))
|
||||||
|
|
||||||
|
def _mc_has_diamond_pickaxe(self, player: int):
|
||||||
|
return self.has('Progressive Tools', player, 3) and self._mc_has_iron_ingots(player)
|
||||||
|
|
||||||
|
def _mc_craft_crossbow(self, player: int):
|
||||||
|
return self.has('Archery', player) and self._mc_has_iron_ingots(player)
|
||||||
|
|
||||||
|
def _mc_has_bottle(self, player: int):
|
||||||
|
return self.has('Bottles', player) and self.has('Ingot Crafting', player)
|
||||||
|
|
||||||
|
def _mc_can_enchant(self, player: int):
|
||||||
|
return self.has('Enchanting', player) and self._mc_has_diamond_pickaxe(player) # mine obsidian and lapis
|
||||||
|
|
||||||
|
def _mc_can_use_anvil(self, player: int):
|
||||||
|
return self.has('Enchanting', player) and self.has('Resource Blocks', player) and self._mc_has_iron_ingots(player)
|
||||||
|
|
||||||
|
def _mc_fortress_loot(self, player: int): # saddles, blaze rods, wither skulls
|
||||||
|
return self.can_reach('Nether Fortress', 'Region', player) and self._mc_basic_combat(player)
|
||||||
|
|
||||||
|
def _mc_can_brew_potions(self, player: int):
|
||||||
|
return self._mc_fortress_loot(player) and self.has('Brewing', player) and self._mc_has_bottle(player)
|
||||||
|
|
||||||
|
def _mc_can_piglin_trade(self, player: int):
|
||||||
|
return self._mc_has_gold_ingots(player) and (self.can_reach('The Nether', 'Region', player) or self.can_reach('Bastion Remnant', 'Region', player))
|
||||||
|
|
||||||
|
def _mc_enter_stronghold(self, player: int):
|
||||||
|
return self._mc_fortress_loot(player) and self.has('Brewing', player) and self.has('3 Ender Pearls', player)
|
||||||
|
|
||||||
|
# Difficulty-dependent functions
|
||||||
|
def _mc_combat_difficulty(self, player: int):
|
||||||
|
return self.world.combat_difficulty[player].get_option_name()
|
||||||
|
|
||||||
|
def _mc_can_adventure(self, player: int):
|
||||||
|
if self._mc_combat_difficulty(player) == 'easy':
|
||||||
|
return self.has('Progressive Weapons', player, 2) and self._mc_has_iron_ingots(player)
|
||||||
|
elif self._mc_combat_difficulty(player) == 'hard':
|
||||||
|
return True
|
||||||
|
return self.has('Progressive Weapons', player) and (self.has('Ingot Crafting', player) or self.has('Campfire', player))
|
||||||
|
|
||||||
|
def _mc_basic_combat(self, player: int):
|
||||||
|
if self._mc_combat_difficulty(player) == 'easy':
|
||||||
|
return self.has('Progressive Weapons', player, 2) and self.has('Progressive Armor', player) and \
|
||||||
|
self.has('Shield', player) and self._mc_has_iron_ingots(player)
|
||||||
|
elif self._mc_combat_difficulty(player) == 'hard':
|
||||||
|
return True
|
||||||
|
return self.has('Progressive Weapons', player) and (self.has('Progressive Armor', player) or self.has('Shield', player)) and self._mc_has_iron_ingots(player)
|
||||||
|
|
||||||
|
def _mc_complete_raid(self, player: int):
|
||||||
|
reach_regions = self.can_reach('Village', 'Region', player) and self.can_reach('Pillager Outpost', 'Region', player)
|
||||||
|
if self._mc_combat_difficulty(player) == 'easy':
|
||||||
|
return reach_regions and \
|
||||||
|
self.has('Progressive Weapons', player, 3) and self.has('Progressive Armor', player, 2) and \
|
||||||
|
self.has('Shield', player) and self.has('Archery', player) and \
|
||||||
|
self.has('Progressive Tools', player, 2) and self._mc_has_iron_ingots(player)
|
||||||
|
elif self._mc_combat_difficulty(player) == 'hard': # might be too hard?
|
||||||
|
return reach_regions and self.has('Progressive Weapons', player, 2) and self._mc_has_iron_ingots(player) and \
|
||||||
|
(self.has('Progressive Armor', player) or self.has('Shield', player))
|
||||||
|
return reach_regions and self.has('Progressive Weapons', player, 2) and self._mc_has_iron_ingots(player) and \
|
||||||
|
self.has('Progressive Armor', player) and self.has('Shield', player)
|
||||||
|
|
||||||
|
def _mc_can_kill_wither(self, player: int):
|
||||||
|
normal_kill = self.has("Progressive Weapons", player, 3) and self.has("Progressive Armor", player, 2) and self._mc_can_brew_potions(player) and self._mc_can_enchant(player)
|
||||||
|
if self._mc_combat_difficulty(player) == 'easy':
|
||||||
|
return self._mc_fortress_loot(player) and normal_kill and self.has('Archery', player)
|
||||||
|
elif self._mc_combat_difficulty(player) == 'hard': # cheese kill using bedrock ceilings
|
||||||
|
return self._mc_fortress_loot(player) and (normal_kill or self.can_reach('The Nether', 'Region', player) or self.can_reach('The End', 'Region', player))
|
||||||
|
return self._mc_fortress_loot(player) and normal_kill
|
||||||
|
|
||||||
|
def _mc_can_kill_ender_dragon(self, player: int):
|
||||||
|
# Since it is possible to kill the dragon without getting any of the advancements related to it, we need to require that it can be respawned.
|
||||||
|
respawn_dragon = self.can_reach('The Nether', 'Region', player) and self.has('Ingot Crafting', player)
|
||||||
|
if self._mc_combat_difficulty(player) == 'easy':
|
||||||
|
return respawn_dragon and self.has("Progressive Weapons", player, 3) and self.has("Progressive Armor", player, 2) and \
|
||||||
|
self.has('Archery', player) and self._mc_can_brew_potions(player) and self._mc_can_enchant(player)
|
||||||
|
if self._mc_combat_difficulty(player) == 'hard':
|
||||||
|
return respawn_dragon and ((self.has('Progressive Weapons', player, 2) and self.has('Progressive Armor', player)) or \
|
||||||
|
(self.has('Progressive Weapons', player, 1) and self.has('Bed', player)))
|
||||||
|
return respawn_dragon and self.has('Progressive Weapons', player, 2) and self.has('Progressive Armor', player) and self.has('Archery', player)
|
||||||
|
|
||||||
|
def _mc_has_structure_compass(self, entrance_name: str, player: int):
|
||||||
|
if not self.world.structure_compasses[player]:
|
||||||
|
return True
|
||||||
|
return self.has(f"Structure Compass ({self.world.get_entrance(entrance_name, player).connected_region.name})", player)
|
||||||
|
|
||||||
|
|
||||||
def set_rules(world: MultiWorld, player: int):
|
def set_rules(world: MultiWorld, player: int):
|
||||||
|
@ -14,118 +107,124 @@ def set_rules(world: MultiWorld, player: int):
|
||||||
location.name not in postgame_advancements and
|
location.name not in postgame_advancements and
|
||||||
location.can_reach(state)]
|
location.can_reach(state)]
|
||||||
|
|
||||||
|
# Retrieves the appropriate structure compass for the given entrance
|
||||||
|
def get_struct_compass(entrance_name):
|
||||||
|
struct = world.get_entrance(entrance_name, player).connected_region.name
|
||||||
|
return f"Structure Compass ({struct})"
|
||||||
|
|
||||||
# 92 total advancements. Goal is to complete X advancements and then Free the End.
|
# 92 total advancements. Goal is to complete X advancements and then Free the End.
|
||||||
# There are 5 advancements which cannot be included for dragon spawning (4 postgame, Free the End)
|
# There are 5 advancements which cannot be included for dragon spawning (4 postgame, Free the End)
|
||||||
# Hence the true maximum is (92 - 5) = 87
|
# Hence the true maximum is (92 - 5) = 87
|
||||||
goal = int(world.advancement_goal[player].value)
|
goal = int(world.advancement_goal[player].value)
|
||||||
can_complete = lambda state: len(reachable_locations(state)) >= goal and state.can_reach('The End', 'Region', player) and state.can_kill_ender_dragon(player)
|
can_complete = lambda state: len(reachable_locations(state)) >= goal and state.can_reach('The End', 'Region', player) and state._mc_can_kill_ender_dragon(player)
|
||||||
|
|
||||||
if world.logic[player] != 'nologic':
|
if world.logic[player] != 'nologic':
|
||||||
world.completion_condition[player] = lambda state: state.has('Victory', player)
|
world.completion_condition[player] = lambda state: state.has('Victory', player)
|
||||||
|
|
||||||
set_rule(world.get_entrance("Nether Portal", player), lambda state: state.has('Flint and Steel', player) and
|
set_rule(world.get_entrance("Nether Portal", player), lambda state: state.has('Flint and Steel', player) and
|
||||||
(state.has('Bucket', player) or state.has('Progressive Tools', player, 3)) and
|
(state.has('Bucket', player) or state.has('Progressive Tools', player, 3)) and
|
||||||
state.has_iron_ingots(player))
|
state._mc_has_iron_ingots(player))
|
||||||
set_rule(world.get_entrance("End Portal", player), lambda state: state.enter_stronghold(player) and state.has('3 Ender Pearls', player, 4))
|
set_rule(world.get_entrance("End Portal", player), lambda state: state._mc_enter_stronghold(player) and state.has('3 Ender Pearls', player, 4))
|
||||||
set_rule(world.get_entrance("Overworld Structure 1", player), lambda state: state.can_adventure(player))
|
set_rule(world.get_entrance("Overworld Structure 1", player), lambda state: state._mc_can_adventure(player) and state._mc_has_structure_compass("Overworld Structure 1", player))
|
||||||
set_rule(world.get_entrance("Overworld Structure 2", player), lambda state: state.can_adventure(player))
|
set_rule(world.get_entrance("Overworld Structure 2", player), lambda state: state._mc_can_adventure(player) and state._mc_has_structure_compass("Overworld Structure 2", player))
|
||||||
set_rule(world.get_entrance("Nether Structure 1", player), lambda state: state.can_adventure(player))
|
set_rule(world.get_entrance("Nether Structure 1", player), lambda state: state._mc_can_adventure(player) and state._mc_has_structure_compass("Nether Structure 1", player))
|
||||||
set_rule(world.get_entrance("Nether Structure 2", player), lambda state: state.can_adventure(player))
|
set_rule(world.get_entrance("Nether Structure 2", player), lambda state: state._mc_can_adventure(player) and state._mc_has_structure_compass("Nether Structure 2", player))
|
||||||
set_rule(world.get_entrance("The End Structure", player), lambda state: state.can_adventure(player))
|
set_rule(world.get_entrance("The End Structure", player), lambda state: state._mc_can_adventure(player) and state._mc_has_structure_compass("The End Structure", player))
|
||||||
|
|
||||||
set_rule(world.get_location("Ender Dragon", player), lambda state: can_complete(state))
|
set_rule(world.get_location("Ender Dragon", player), lambda state: can_complete(state))
|
||||||
|
|
||||||
set_rule(world.get_location("Who is Cutting Onions?", player), lambda state: state.can_piglin_trade(player))
|
set_rule(world.get_location("Who is Cutting Onions?", player), lambda state: state._mc_can_piglin_trade(player))
|
||||||
set_rule(world.get_location("Oh Shiny", player), lambda state: state.can_piglin_trade(player))
|
set_rule(world.get_location("Oh Shiny", player), lambda state: state._mc_can_piglin_trade(player))
|
||||||
set_rule(world.get_location("Suit Up", player), lambda state: state.has("Progressive Armor", player) and state.has_iron_ingots(player))
|
set_rule(world.get_location("Suit Up", player), lambda state: state.has("Progressive Armor", player) and state._mc_has_iron_ingots(player))
|
||||||
set_rule(world.get_location("Very Very Frightening", player), lambda state: state.has("Channeling Book", player) and state.can_use_anvil(player) and state.can_enchant(player) and \
|
set_rule(world.get_location("Very Very Frightening", player), lambda state: state.has("Channeling Book", player) and state._mc_can_use_anvil(player) and state._mc_can_enchant(player) and \
|
||||||
((world.get_region('Village', player).entrances[0].parent_region.name != 'The End' and state.can_reach('Village', 'Region', player)) or state.can_reach('Zombie Doctor', 'Location', player))) # need villager into the overworld for lightning strike
|
((world.get_region('Village', player).entrances[0].parent_region.name != 'The End' and state.can_reach('Village', 'Region', player)) or state.can_reach('Zombie Doctor', 'Location', player))) # need villager into the overworld for lightning strike
|
||||||
set_rule(world.get_location("Hot Stuff", player), lambda state: state.has("Bucket", player) and state.has_iron_ingots(player))
|
set_rule(world.get_location("Hot Stuff", player), lambda state: state.has("Bucket", player) and state._mc_has_iron_ingots(player))
|
||||||
set_rule(world.get_location("Free the End", player), lambda state: can_complete(state))
|
set_rule(world.get_location("Free the End", player), lambda state: can_complete(state))
|
||||||
set_rule(world.get_location("A Furious Cocktail", player), lambda state: state.can_brew_potions(player) and
|
set_rule(world.get_location("A Furious Cocktail", player), lambda state: state._mc_can_brew_potions(player) and
|
||||||
state.has("Fishing Rod", player) and # Water Breathing
|
state.has("Fishing Rod", player) and # Water Breathing
|
||||||
state.can_reach('The Nether', 'Region', player) and # Regeneration, Fire Resistance, gold nuggets
|
state.can_reach('The Nether', 'Region', player) and # Regeneration, Fire Resistance, gold nuggets
|
||||||
state.can_reach('Village', 'Region', player) and # Night Vision, Invisibility
|
state.can_reach('Village', 'Region', player) and # Night Vision, Invisibility
|
||||||
state.can_reach('Bring Home the Beacon', 'Location', player)) # Resistance
|
state.can_reach('Bring Home the Beacon', 'Location', player)) # Resistance
|
||||||
set_rule(world.get_location("Best Friends Forever", player), lambda state: True)
|
set_rule(world.get_location("Best Friends Forever", player), lambda state: True)
|
||||||
set_rule(world.get_location("Bring Home the Beacon", player), lambda state: state.can_kill_wither(player) and
|
set_rule(world.get_location("Bring Home the Beacon", player), lambda state: state._mc_can_kill_wither(player) and
|
||||||
state.has_diamond_pickaxe(player) and state.has("Ingot Crafting", player) and state.has("Resource Blocks", player))
|
state._mc_has_diamond_pickaxe(player) and state.has("Ingot Crafting", player) and state.has("Resource Blocks", player))
|
||||||
set_rule(world.get_location("Not Today, Thank You", player), lambda state: state.has("Shield", player) and state.has_iron_ingots(player))
|
set_rule(world.get_location("Not Today, Thank You", player), lambda state: state.has("Shield", player) and state._mc_has_iron_ingots(player))
|
||||||
set_rule(world.get_location("Isn't It Iron Pick", player), lambda state: state.has("Progressive Tools", player, 2) and state.has_iron_ingots(player))
|
set_rule(world.get_location("Isn't It Iron Pick", player), lambda state: state.has("Progressive Tools", player, 2) and state._mc_has_iron_ingots(player))
|
||||||
set_rule(world.get_location("Local Brewery", player), lambda state: state.can_brew_potions(player))
|
set_rule(world.get_location("Local Brewery", player), lambda state: state._mc_can_brew_potions(player))
|
||||||
set_rule(world.get_location("The Next Generation", player), lambda state: can_complete(state))
|
set_rule(world.get_location("The Next Generation", player), lambda state: can_complete(state))
|
||||||
set_rule(world.get_location("Fishy Business", player), lambda state: state.has("Fishing Rod", player))
|
set_rule(world.get_location("Fishy Business", player), lambda state: state.has("Fishing Rod", player))
|
||||||
set_rule(world.get_location("Hot Tourist Destinations", player), lambda state: True)
|
set_rule(world.get_location("Hot Tourist Destinations", player), lambda state: True)
|
||||||
set_rule(world.get_location("This Boat Has Legs", player), lambda state: (state.fortress_loot(player) or state.complete_raid(player)) and state.has("Fishing Rod", player))
|
set_rule(world.get_location("This Boat Has Legs", player), lambda state: (state._mc_fortress_loot(player) or state._mc_complete_raid(player)) and
|
||||||
|
state.has("Saddle", player) and state.has("Fishing Rod", player))
|
||||||
set_rule(world.get_location("Sniper Duel", player), lambda state: state.has("Archery", player))
|
set_rule(world.get_location("Sniper Duel", player), lambda state: state.has("Archery", player))
|
||||||
set_rule(world.get_location("Nether", player), lambda state: True)
|
set_rule(world.get_location("Nether", player), lambda state: True)
|
||||||
set_rule(world.get_location("Great View From Up Here", player), lambda state: state.basic_combat(player))
|
set_rule(world.get_location("Great View From Up Here", player), lambda state: state._mc_basic_combat(player))
|
||||||
set_rule(world.get_location("How Did We Get Here?", player), lambda state: state.can_brew_potions(player) and
|
set_rule(world.get_location("How Did We Get Here?", player), lambda state: state._mc_can_brew_potions(player) and
|
||||||
state.has_gold_ingots(player) and # Absorption
|
state._mc_has_gold_ingots(player) and # Absorption
|
||||||
state.can_reach('End City', 'Region', player) and # Levitation
|
state.can_reach('End City', 'Region', player) and # Levitation
|
||||||
state.can_reach('The Nether', 'Region', player) and # potion ingredients
|
state.can_reach('The Nether', 'Region', player) and # potion ingredients
|
||||||
state.has("Fishing Rod", player) and state.has("Archery",player) and # Pufferfish, Nautilus Shells; spectral arrows
|
state.has("Fishing Rod", player) and state.has("Archery",player) and # Pufferfish, Nautilus Shells; spectral arrows
|
||||||
state.can_reach("Bring Home the Beacon", "Location", player) and # Haste
|
state.can_reach("Bring Home the Beacon", "Location", player) and # Haste
|
||||||
state.can_reach("Hero of the Village", "Location", player)) # Bad Omen, Hero of the Village
|
state.can_reach("Hero of the Village", "Location", player)) # Bad Omen, Hero of the Village
|
||||||
set_rule(world.get_location("Bullseye", player), lambda state: state.has("Archery", player) and state.has("Progressive Tools", player, 2) and state.has_iron_ingots(player))
|
set_rule(world.get_location("Bullseye", player), lambda state: state.has("Archery", player) and state.has("Progressive Tools", player, 2) and state._mc_has_iron_ingots(player))
|
||||||
set_rule(world.get_location("Spooky Scary Skeleton", player), lambda state: state.basic_combat(player))
|
set_rule(world.get_location("Spooky Scary Skeleton", player), lambda state: state._mc_basic_combat(player))
|
||||||
set_rule(world.get_location("Two by Two", player), lambda state: state.has_iron_ingots(player) and state.can_adventure(player)) # shears > seagrass > turtles; nether > striders; gold carrots > horses skips ingots
|
set_rule(world.get_location("Two by Two", player), lambda state: state._mc_has_iron_ingots(player) and state._mc_can_adventure(player)) # shears > seagrass > turtles; nether > striders; gold carrots > horses skips ingots
|
||||||
set_rule(world.get_location("Stone Age", player), lambda state: True)
|
set_rule(world.get_location("Stone Age", player), lambda state: True)
|
||||||
set_rule(world.get_location("Two Birds, One Arrow", player), lambda state: state.craft_crossbow(player) and state.can_enchant(player))
|
set_rule(world.get_location("Two Birds, One Arrow", player), lambda state: state._mc_craft_crossbow(player) and state._mc_can_enchant(player))
|
||||||
set_rule(world.get_location("We Need to Go Deeper", player), lambda state: True)
|
set_rule(world.get_location("We Need to Go Deeper", player), lambda state: True)
|
||||||
set_rule(world.get_location("Who's the Pillager Now?", player), lambda state: state.craft_crossbow(player))
|
set_rule(world.get_location("Who's the Pillager Now?", player), lambda state: state._mc_craft_crossbow(player))
|
||||||
set_rule(world.get_location("Getting an Upgrade", player), lambda state: state.has("Progressive Tools", player))
|
set_rule(world.get_location("Getting an Upgrade", player), lambda state: state.has("Progressive Tools", player))
|
||||||
set_rule(world.get_location("Tactical Fishing", player), lambda state: state.has("Bucket", player) and state.has_iron_ingots(player))
|
set_rule(world.get_location("Tactical Fishing", player), lambda state: state.has("Bucket", player) and state._mc_has_iron_ingots(player))
|
||||||
set_rule(world.get_location("Zombie Doctor", player), lambda state: state.can_brew_potions(player) and state.has_gold_ingots(player))
|
set_rule(world.get_location("Zombie Doctor", player), lambda state: state._mc_can_brew_potions(player) and state._mc_has_gold_ingots(player))
|
||||||
set_rule(world.get_location("The City at the End of the Game", player), lambda state: True)
|
set_rule(world.get_location("The City at the End of the Game", player), lambda state: True)
|
||||||
set_rule(world.get_location("Ice Bucket Challenge", player), lambda state: state.has_diamond_pickaxe(player))
|
set_rule(world.get_location("Ice Bucket Challenge", player), lambda state: state._mc_has_diamond_pickaxe(player))
|
||||||
set_rule(world.get_location("Remote Getaway", player), lambda state: True)
|
set_rule(world.get_location("Remote Getaway", player), lambda state: True)
|
||||||
set_rule(world.get_location("Into Fire", player), lambda state: state.basic_combat(player))
|
set_rule(world.get_location("Into Fire", player), lambda state: state._mc_basic_combat(player))
|
||||||
set_rule(world.get_location("War Pigs", player), lambda state: state.basic_combat(player))
|
set_rule(world.get_location("War Pigs", player), lambda state: state._mc_basic_combat(player))
|
||||||
set_rule(world.get_location("Take Aim", player), lambda state: state.has("Archery", player))
|
set_rule(world.get_location("Take Aim", player), lambda state: state.has("Archery", player))
|
||||||
set_rule(world.get_location("Total Beelocation", player), lambda state: state.has("Silk Touch Book", player) and state.can_use_anvil(player) and state.can_enchant(player))
|
set_rule(world.get_location("Total Beelocation", player), lambda state: state.has("Silk Touch Book", player) and state._mc_can_use_anvil(player) and state._mc_can_enchant(player))
|
||||||
set_rule(world.get_location("Arbalistic", player), lambda state: state.craft_crossbow(player) and state.has("Piercing IV Book", player) and
|
set_rule(world.get_location("Arbalistic", player), lambda state: state._mc_craft_crossbow(player) and state.has("Piercing IV Book", player) and
|
||||||
state.can_use_anvil(player) and state.can_enchant(player))
|
state._mc_can_use_anvil(player) and state._mc_can_enchant(player))
|
||||||
set_rule(world.get_location("The End... Again...", player), lambda state: can_complete(state))
|
set_rule(world.get_location("The End... Again...", player), lambda state: can_complete(state))
|
||||||
set_rule(world.get_location("Acquire Hardware", player), lambda state: state.has_iron_ingots(player))
|
set_rule(world.get_location("Acquire Hardware", player), lambda state: state._mc_has_iron_ingots(player))
|
||||||
set_rule(world.get_location("Not Quite \"Nine\" Lives", player), lambda state: state.can_piglin_trade(player) and state.has("Resource Blocks", player))
|
set_rule(world.get_location("Not Quite \"Nine\" Lives", player), lambda state: state._mc_can_piglin_trade(player) and state.has("Resource Blocks", player))
|
||||||
set_rule(world.get_location("Cover Me With Diamonds", player), lambda state: state.has("Progressive Armor", player, 2) and state.can_reach("Diamonds!", "Location", player))
|
set_rule(world.get_location("Cover Me With Diamonds", player), lambda state: state.has("Progressive Armor", player, 2) and state.can_reach("Diamonds!", "Location", player))
|
||||||
set_rule(world.get_location("Sky's the Limit", player), lambda state: state.basic_combat(player))
|
set_rule(world.get_location("Sky's the Limit", player), lambda state: state._mc_basic_combat(player))
|
||||||
set_rule(world.get_location("Hired Help", player), lambda state: state.has("Resource Blocks", player) and state.has_iron_ingots(player))
|
set_rule(world.get_location("Hired Help", player), lambda state: state.has("Resource Blocks", player) and state._mc_has_iron_ingots(player))
|
||||||
set_rule(world.get_location("Return to Sender", player), lambda state: True)
|
set_rule(world.get_location("Return to Sender", player), lambda state: True)
|
||||||
set_rule(world.get_location("Sweet Dreams", player), lambda state: state.has("Bed", player) or state.can_reach('Village', 'Region', player))
|
set_rule(world.get_location("Sweet Dreams", player), lambda state: state.has("Bed", player) or state.can_reach('Village', 'Region', player))
|
||||||
set_rule(world.get_location("You Need a Mint", player), lambda state: can_complete(state) and state.has_bottle_mc(player))
|
set_rule(world.get_location("You Need a Mint", player), lambda state: can_complete(state) and state._mc_has_bottle(player))
|
||||||
set_rule(world.get_location("Adventure", player), lambda state: True)
|
set_rule(world.get_location("Adventure", player), lambda state: True)
|
||||||
set_rule(world.get_location("Monsters Hunted", player), lambda state: can_complete(state) and state.can_kill_wither(player) and state.has("Fishing Rod", player)) # pufferfish for Water Breathing
|
set_rule(world.get_location("Monsters Hunted", player), lambda state: can_complete(state) and state._mc_can_kill_wither(player) and state.has("Fishing Rod", player)) # pufferfish for Water Breathing
|
||||||
set_rule(world.get_location("Enchanter", player), lambda state: state.can_enchant(player))
|
set_rule(world.get_location("Enchanter", player), lambda state: state._mc_can_enchant(player))
|
||||||
set_rule(world.get_location("Voluntary Exile", player), lambda state: state.basic_combat(player))
|
set_rule(world.get_location("Voluntary Exile", player), lambda state: state._mc_basic_combat(player))
|
||||||
set_rule(world.get_location("Eye Spy", player), lambda state: state.enter_stronghold(player))
|
set_rule(world.get_location("Eye Spy", player), lambda state: state._mc_enter_stronghold(player))
|
||||||
set_rule(world.get_location("The End", player), lambda state: True)
|
set_rule(world.get_location("The End", player), lambda state: True)
|
||||||
set_rule(world.get_location("Serious Dedication", player), lambda state: state.can_reach("Hidden in the Depths", "Location", player) and state.has_gold_ingots(player))
|
set_rule(world.get_location("Serious Dedication", player), lambda state: state.can_reach("Hidden in the Depths", "Location", player) and state._mc_has_gold_ingots(player))
|
||||||
set_rule(world.get_location("Postmortal", player), lambda state: state.complete_raid(player))
|
set_rule(world.get_location("Postmortal", player), lambda state: state._mc_complete_raid(player))
|
||||||
set_rule(world.get_location("Monster Hunter", player), lambda state: True)
|
set_rule(world.get_location("Monster Hunter", player), lambda state: True)
|
||||||
set_rule(world.get_location("Adventuring Time", player), lambda state: state.can_adventure(player))
|
set_rule(world.get_location("Adventuring Time", player), lambda state: state._mc_can_adventure(player))
|
||||||
set_rule(world.get_location("A Seedy Place", player), lambda state: True)
|
set_rule(world.get_location("A Seedy Place", player), lambda state: True)
|
||||||
set_rule(world.get_location("Those Were the Days", player), lambda state: True)
|
set_rule(world.get_location("Those Were the Days", player), lambda state: True)
|
||||||
set_rule(world.get_location("Hero of the Village", player), lambda state: state.complete_raid(player))
|
set_rule(world.get_location("Hero of the Village", player), lambda state: state._mc_complete_raid(player))
|
||||||
set_rule(world.get_location("Hidden in the Depths", player), lambda state: state.can_brew_potions(player) and state.has("Bed", player) and state.has_diamond_pickaxe(player)) # bed mining :)
|
set_rule(world.get_location("Hidden in the Depths", player), lambda state: state._mc_can_brew_potions(player) and state.has("Bed", player) and state._mc_has_diamond_pickaxe(player)) # bed mining :)
|
||||||
set_rule(world.get_location("Beaconator", player), lambda state: state.can_kill_wither(player) and state.has_diamond_pickaxe(player) and
|
set_rule(world.get_location("Beaconator", player), lambda state: state._mc_can_kill_wither(player) and state._mc_has_diamond_pickaxe(player) and
|
||||||
state.has("Ingot Crafting", player) and state.has("Resource Blocks", player))
|
state.has("Ingot Crafting", player) and state.has("Resource Blocks", player))
|
||||||
set_rule(world.get_location("Withering Heights", player), lambda state: state.can_kill_wither(player))
|
set_rule(world.get_location("Withering Heights", player), lambda state: state._mc_can_kill_wither(player))
|
||||||
set_rule(world.get_location("A Balanced Diet", player), lambda state: state.has_bottle_mc(player) and state.has_gold_ingots(player) and # honey bottle; gapple
|
set_rule(world.get_location("A Balanced Diet", player), lambda state: state._mc_has_bottle(player) and state._mc_has_gold_ingots(player) and # honey bottle; gapple
|
||||||
state.has("Resource Blocks", player) and state.can_reach('The End', 'Region', player)) # notch apple, chorus fruit
|
state.has("Resource Blocks", player) and state.can_reach('The End', 'Region', player)) # notch apple, chorus fruit
|
||||||
set_rule(world.get_location("Subspace Bubble", player), lambda state: state.has_diamond_pickaxe(player))
|
set_rule(world.get_location("Subspace Bubble", player), lambda state: state._mc_has_diamond_pickaxe(player))
|
||||||
set_rule(world.get_location("Husbandry", player), lambda state: True)
|
set_rule(world.get_location("Husbandry", player), lambda state: True)
|
||||||
set_rule(world.get_location("Country Lode, Take Me Home", player), lambda state: state.can_reach("Hidden in the Depths", "Location", player) and state.has_gold_ingots(player))
|
set_rule(world.get_location("Country Lode, Take Me Home", player), lambda state: state.can_reach("Hidden in the Depths", "Location", player) and state._mc_has_gold_ingots(player))
|
||||||
set_rule(world.get_location("Bee Our Guest", player), lambda state: state.has("Campfire", player) and state.has_bottle_mc(player))
|
set_rule(world.get_location("Bee Our Guest", player), lambda state: state.has("Campfire", player) and state._mc_has_bottle(player))
|
||||||
set_rule(world.get_location("What a Deal!", player), lambda state: True)
|
set_rule(world.get_location("What a Deal!", player), lambda state: True)
|
||||||
set_rule(world.get_location("Uneasy Alliance", player), lambda state: state.has_diamond_pickaxe(player) and state.has('Fishing Rod', player))
|
set_rule(world.get_location("Uneasy Alliance", player), lambda state: state._mc_has_diamond_pickaxe(player) and state.has('Fishing Rod', player))
|
||||||
set_rule(world.get_location("Diamonds!", player), lambda state: state.has("Progressive Tools", player, 2) and state.has_iron_ingots(player))
|
set_rule(world.get_location("Diamonds!", player), lambda state: state.has("Progressive Tools", player, 2) and state._mc_has_iron_ingots(player))
|
||||||
set_rule(world.get_location("A Terrible Fortress", player), lambda state: True) # since you don't have to fight anything
|
set_rule(world.get_location("A Terrible Fortress", player), lambda state: True) # since you don't have to fight anything
|
||||||
set_rule(world.get_location("A Throwaway Joke", player), lambda state: True) # kill drowned
|
set_rule(world.get_location("A Throwaway Joke", player), lambda state: True) # kill drowned
|
||||||
set_rule(world.get_location("Minecraft", player), lambda state: True)
|
set_rule(world.get_location("Minecraft", player), lambda state: True)
|
||||||
set_rule(world.get_location("Sticky Situation", player), lambda state: state.has("Campfire", player) and state.has_bottle_mc(player))
|
set_rule(world.get_location("Sticky Situation", player), lambda state: state.has("Campfire", player) and state._mc_has_bottle(player))
|
||||||
set_rule(world.get_location("Ol' Betsy", player), lambda state: state.craft_crossbow(player))
|
set_rule(world.get_location("Ol' Betsy", player), lambda state: state._mc_craft_crossbow(player))
|
||||||
set_rule(world.get_location("Cover Me in Debris", player), lambda state: state.has("Progressive Armor", player, 2) and
|
set_rule(world.get_location("Cover Me in Debris", player), lambda state: state.has("Progressive Armor", player, 2) and
|
||||||
state.has("8 Netherite Scrap", player, 2) and state.has("Ingot Crafting", player) and
|
state.has("8 Netherite Scrap", player, 2) and state.has("Ingot Crafting", player) and
|
||||||
state.can_reach("Diamonds!", "Location", player) and state.can_reach("Hidden in the Depths", "Location", player))
|
state.can_reach("Diamonds!", "Location", player) and state.can_reach("Hidden in the Depths", "Location", player))
|
||||||
|
@ -136,13 +235,13 @@ def set_rules(world: MultiWorld, player: int):
|
||||||
set_rule(world.get_location("Time to Mine!", player), lambda state: True)
|
set_rule(world.get_location("Time to Mine!", player), lambda state: True)
|
||||||
set_rule(world.get_location("Hot Topic", player), lambda state: state.has("Ingot Crafting", player))
|
set_rule(world.get_location("Hot Topic", player), lambda state: state.has("Ingot Crafting", player))
|
||||||
set_rule(world.get_location("Bake Bread", player), lambda state: True)
|
set_rule(world.get_location("Bake Bread", player), lambda state: True)
|
||||||
set_rule(world.get_location("The Lie", player), lambda state: state.has_iron_ingots(player) and state.has("Bucket", player))
|
set_rule(world.get_location("The Lie", player), lambda state: state._mc_has_iron_ingots(player) and state.has("Bucket", player))
|
||||||
set_rule(world.get_location("On a Rail", player), lambda state: state.has_iron_ingots(player) and state.has('Progressive Tools', player, 2)) # powered rails
|
set_rule(world.get_location("On a Rail", player), lambda state: state._mc_has_iron_ingots(player) and state.has('Progressive Tools', player, 2)) # powered rails
|
||||||
set_rule(world.get_location("Time to Strike!", player), lambda state: True)
|
set_rule(world.get_location("Time to Strike!", player), lambda state: True)
|
||||||
set_rule(world.get_location("Cow Tipper", player), lambda state: True)
|
set_rule(world.get_location("Cow Tipper", player), lambda state: True)
|
||||||
set_rule(world.get_location("When Pigs Fly", player), lambda state: (state.fortress_loot(player) or state.complete_raid(player)) and
|
set_rule(world.get_location("When Pigs Fly", player), lambda state: (state._mc_fortress_loot(player) or state._mc_complete_raid(player)) and
|
||||||
state.has("Fishing Rod", player) and state.can_adventure(player))
|
state.has("Saddle", player) and state.has("Fishing Rod", player) and state._mc_can_adventure(player))
|
||||||
set_rule(world.get_location("Overkill", player), lambda state: state.can_brew_potions(player) and
|
set_rule(world.get_location("Overkill", player), lambda state: state._mc_can_brew_potions(player) and
|
||||||
(state.has("Progressive Weapons", player) or state.can_reach('The Nether', 'Region', player))) # strength 1 + stone axe crit OR strength 2 + wood axe crit
|
(state.has("Progressive Weapons", player) or state.can_reach('The Nether', 'Region', player))) # strength 1 + stone axe crit OR strength 2 + wood axe crit
|
||||||
set_rule(world.get_location("Librarian", player), lambda state: state.has("Enchanting", player))
|
set_rule(world.get_location("Librarian", player), lambda state: state.has("Enchanting", player))
|
||||||
set_rule(world.get_location("Overpowered", player), lambda state: state.has("Resource Blocks", player) and state.has_gold_ingots(player))
|
set_rule(world.get_location("Overpowered", player), lambda state: state.has("Resource Blocks", player) and state._mc_has_gold_ingots(player))
|
||||||
|
|
|
@ -3,7 +3,7 @@ import os
|
||||||
|
|
||||||
from .Items import MinecraftItem, item_table, item_frequencies
|
from .Items import MinecraftItem, item_table, item_frequencies
|
||||||
from .Locations import MinecraftAdvancement, advancement_table, exclusion_table, events_table
|
from .Locations import MinecraftAdvancement, advancement_table, exclusion_table, events_table
|
||||||
from .Regions import mc_regions, link_minecraft_structures
|
from .Regions import mc_regions, link_minecraft_structures, default_connections
|
||||||
from .Rules import set_rules
|
from .Rules import set_rules
|
||||||
from worlds.generic.Rules import exclusion_rules
|
from worlds.generic.Rules import exclusion_rules
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ from BaseClasses import Region, Entrance, Item
|
||||||
from .Options import minecraft_options
|
from .Options import minecraft_options
|
||||||
from ..AutoWorld import World
|
from ..AutoWorld import World
|
||||||
|
|
||||||
client_version = (0, 4)
|
client_version = 5
|
||||||
|
|
||||||
class MinecraftWorld(World):
|
class MinecraftWorld(World):
|
||||||
game: str = "Minecraft"
|
game: str = "Minecraft"
|
||||||
|
@ -23,9 +23,10 @@ class MinecraftWorld(World):
|
||||||
item_name_to_id = {name: data.code for name, data in item_table.items()}
|
item_name_to_id = {name: data.code for name, data in item_table.items()}
|
||||||
location_name_to_id = {name: data.id for name, data in advancement_table.items()}
|
location_name_to_id = {name: data.id for name, data in advancement_table.items()}
|
||||||
|
|
||||||
|
data_version = 2
|
||||||
|
|
||||||
def _get_mc_data(self):
|
def _get_mc_data(self):
|
||||||
exits = ["Overworld Structure 1", "Overworld Structure 2", "Nether Structure 1", "Nether Structure 2",
|
exits = [connection[0] for connection in default_connections]
|
||||||
"The End Structure"]
|
|
||||||
return {
|
return {
|
||||||
'world_seed': self.world.slot_seeds[self.player].getrandbits(32),
|
'world_seed': self.world.slot_seeds[self.player].getrandbits(32),
|
||||||
# consistent and doesn't interfere with other generation
|
# consistent and doesn't interfere with other generation
|
||||||
|
@ -42,8 +43,15 @@ class MinecraftWorld(World):
|
||||||
# Generate item pool
|
# Generate item pool
|
||||||
itempool = []
|
itempool = []
|
||||||
pool_counts = item_frequencies.copy()
|
pool_counts = item_frequencies.copy()
|
||||||
if getattr(self.world, "bee_traps")[self.player]: # replace Rotten Flesh by bee traps
|
# Replace Rotten Flesh with bee traps
|
||||||
|
if self.world.bee_traps[self.player]:
|
||||||
pool_counts.update({"Rotten Flesh": 0, "Bee Trap (Minecraft)": 4})
|
pool_counts.update({"Rotten Flesh": 0, "Bee Trap (Minecraft)": 4})
|
||||||
|
# Add structure compasses to the pool, replacing 50 XP
|
||||||
|
if self.world.structure_compasses[self.player]:
|
||||||
|
structures = [connection[1] for connection in default_connections]
|
||||||
|
for struct_name in structures:
|
||||||
|
pool_counts[f"Structure Compass ({struct_name})"] = 1
|
||||||
|
pool_counts["50 XP"] -= 1
|
||||||
for item_name in item_table:
|
for item_name in item_table:
|
||||||
for count in range(pool_counts.get(item_name, 1)):
|
for count in range(pool_counts.get(item_name, 1)):
|
||||||
itempool.append(self.create_item(item_name))
|
itempool.append(self.create_item(item_name))
|
||||||
|
@ -97,6 +105,7 @@ class MinecraftWorld(World):
|
||||||
def create_item(self, name: str) -> Item:
|
def create_item(self, name: str) -> Item:
|
||||||
item_data = item_table[name]
|
item_data = item_table[name]
|
||||||
item = MinecraftItem(name, item_data.progression, item_data.code, self.player)
|
item = MinecraftItem(name, item_data.progression, item_data.code, self.player)
|
||||||
if "Book" in name: # prevent enchanted books from being excluded
|
nonexcluded_items = ["Sharpness III Book", "Infinity Book", "Looting III Book"]
|
||||||
|
if name in nonexcluded_items: # prevent books from going on excluded locations
|
||||||
item.never_exclude = True
|
item.never_exclude = True
|
||||||
return item
|
return item
|
||||||
|
|
Loading…
Reference in New Issue