Archipelago/worlds/yoshisisland/level_logic.py

483 lines
22 KiB
Python

from BaseClasses import CollectionState
from typing import TYPE_CHECKING
from .Options import StageLogic, BowserDoor, ObjectVis
if TYPE_CHECKING:
from . import YoshisIslandWorld
class YoshiLogic:
player: int
game_logic: str
midring_start: bool
clouds_always_visible: bool
consumable_logic: bool
luigi_pieces: int
def __init__(self, world: "YoshisIslandWorld") -> None:
self.player = world.player
self.boss_order = world.boss_order
self.luigi_pieces = world.options.luigi_pieces_required.value
if world.options.stage_logic == StageLogic.option_strict:
self.game_logic = "Easy"
elif world.options.stage_logic == StageLogic.option_loose:
self.game_logic = "Normal"
else:
self.game_logic = "Hard"
self.midring_start = not world.options.shuffle_midrings
self.consumable_logic = not world.options.item_logic
self.clouds_always_visible = world.options.hidden_object_visibility >= ObjectVis.option_clouds_only
self.bowser_door = world.options.bowser_door_mode.value
if self.bowser_door == BowserDoor.option_door_4:
self.bowser_door = BowserDoor.option_door_3
def has_midring(self, state: CollectionState) -> bool:
return self.midring_start or state.has("Middle Ring", self.player)
def reconstitute_luigi(self, state: CollectionState) -> bool:
return state.has("Piece of Luigi", self.player, self.luigi_pieces)
def bandit_bonus(self, state: CollectionState) -> bool:
return state.has("Bandit Consumables", self.player) or state.has("Bandit Watermelons", self.player)
def item_bonus(self, state: CollectionState) -> bool:
return state.has("Bonus Consumables", self.player)
def combat_item(self, state: CollectionState) -> bool:
if not self.consumable_logic:
return False
else:
if self.game_logic == "Easy":
return self.item_bonus(state)
else:
return self.bandit_bonus(state) or self.item_bonus(state)
def melon_item(self, state: CollectionState) -> bool:
if not self.consumable_logic:
return False
else:
if self.game_logic == "Easy":
return self.item_bonus(state)
else:
return state.has("Bandit Watermelons", self.player) or self.item_bonus(state)
def default_vis(self, state: CollectionState) -> bool:
if self.clouds_always_visible:
return True
else:
return False
def cansee_clouds(self, state: CollectionState) -> bool:
if self.game_logic != "Easy":
return True
else:
return self.default_vis(state) or state.has("Secret Lens", self.player) or self.combat_item(state)
def bowserdoor_1(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Egg Plant", "! Switch"}, self.player) and state.has("Egg Capacity Upgrade", self.player, 2)
elif self.game_logic == "Normal":
return state.has("Egg Plant", self.player) and state.has("Egg Capacity Upgrade", self.player, 1)
else:
return state.has("Egg Plant", self.player)
def bowserdoor_2(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return ((state.has("Egg Capacity Upgrade", self.player, 3) and state.has("Egg Plant", self.player)) or self.combat_item(state)) and state.has("Key", self.player)
elif self.game_logic == "Normal":
return ((state.has("Egg Capacity Upgrade", self.player, 2) and state.has("Egg Plant", self.player)) or self.combat_item(state)) and state.has("Key", self.player)
else:
return ((state.has("Egg Capacity Upgrade", self.player, 1) and state.has("Egg Plant", self.player)) or self.combat_item(state)) and state.has("Key", self.player)
def bowserdoor_3(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return True
elif self.game_logic == "Normal":
return True
else:
return True
def bowserdoor_4(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return True
elif self.game_logic == "Normal":
return True
else:
return True
def _68Route(self, state: CollectionState) -> bool:
if self.bowser_door == 0:
return True
elif self.bowser_door == 1:
return self.bowserdoor_1(state)
elif self.bowser_door == 2:
return self.bowserdoor_2(state)
elif self.bowser_door == 3:
return True
elif self.bowser_door == 4:
return True
elif self.bowser_door == 5:
return self.bowserdoor_1(state) and self.bowserdoor_2(state) and self.bowserdoor_3(state)
def _68CollectibleRoute(self, state: CollectionState) -> bool:
if self.bowser_door == 0:
return True
elif self.bowser_door == 1:
return self.bowserdoor_1(state)
elif self.bowser_door == 2:
return self.bowserdoor_2(state)
elif self.bowser_door == 3:
return True
elif self.bowser_door == 4:
return True
elif self.bowser_door == 5:
return self.bowserdoor_1(state)
##############################################################################
def _13Game(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has("Key", self.player)
elif self.game_logic == "Normal":
return state.has("Key", self.player)
else:
return state.has("Key", self.player)
##############################################################################
def _14Clear(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Spring Ball", "Key"}, self.player)
elif self.game_logic == "Normal":
return state.has_all({"Spring Ball", "Key"}, self.player)
else:
return state.has_all({"Spring Ball", "Key"}, self.player)
def _14Boss(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has("Egg Plant", self.player)
elif self.game_logic == "Normal":
return state.has("Egg Plant", self.player)
else:
return (state.has("Egg Capacity Upgrade", self.player, 5) or state.has("Egg Plant", self.player))
def _14CanFightBoss(self, state: CollectionState) -> bool:
if state.can_reach(self.boss_order[0], "Location", self.player):
return True
##############################################################################
def _17Game(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has("Key", self.player)
elif self.game_logic == "Normal":
return state.has("Key", self.player)
else:
return state.has("Key", self.player)
##############################################################################
def _18Clear(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Key", "Arrow Wheel"}, self.player)
elif self.game_logic == "Normal":
return state.has_all({"Key", "Arrow Wheel"}, self.player)
else:
return state.has_all({"Key", "Arrow Wheel"}, self.player)
def _18Boss(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return True
elif self.game_logic == "Normal":
return True
else:
return True
def _18CanFightBoss(self, state: CollectionState) -> bool:
if state.can_reach(self.boss_order[1], "Location", self.player):
return True
##############################################################################
def _21Game(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Poochy", "Large Spring Ball", "Key"}, self.player)
elif self.game_logic == "Normal":
return state.has_all({"Poochy", "Large Spring Ball", "Key"}, self.player)
else:
return state.has_all({"Poochy", "Large Spring Ball", "Key"}, self.player)
##############################################################################
def _23Game(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Mole Tank Morph", "Key"}, self.player)
elif self.game_logic == "Normal":
return state.has_all({"Mole Tank Morph", "Key"}, self.player)
else:
return state.has_all({"Mole Tank Morph", "Key"}, self.player)
##############################################################################
def _24Clear(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"! Switch", "Key", "Dashed Stairs"}, self.player)
elif self.game_logic == "Normal":
return state.has_all({"! Switch", "Dashed Stairs"}, self.player)
else:
return state.has("! Switch", self.player)
def _24Boss(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return True
elif self.game_logic == "Normal":
return True
else:
return True
def _24CanFightBoss(self, state: CollectionState) -> bool:
if state.can_reach(self.boss_order[2], "Location", self.player):
return True
##############################################################################
def _26Game(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Large Spring Ball", "Key"}, self.player)
elif self.game_logic == "Normal":
return state.has_all({"Large Spring Ball", "Key"}, self.player)
else:
return state.has_all({"Large Spring Ball", "Key"}, self.player)
##############################################################################
def _27Game(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has("Key", self.player)
elif self.game_logic == "Normal":
return state.has("Key", self.player)
else:
return state.has("Key", self.player)
##############################################################################
def _28Clear(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Arrow Wheel", "Key"}, self.player) and (state.has("Egg Capacity Upgrade", self.player, 1))
elif self.game_logic == "Normal":
return state.has_all({"Arrow Wheel", "Key"}, self.player)
else:
return state.has_all({"Arrow Wheel", "Key"}, self.player)
def _28Boss(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return True
elif self.game_logic == "Normal":
return True
else:
return True
def _28CanFightBoss(self, state: CollectionState) -> bool:
if state.can_reach(self.boss_order[3], "Location", self.player):
return True
##############################################################################
def _32Game(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Dashed Stairs", "Spring Ball", "Key"}, self.player)
elif self.game_logic == "Normal":
return state.has_all({"Dashed Stairs", "Key"}, self.player)
else:
return state.has_all({"Dashed Stairs", "Key"}, self.player)
##############################################################################
def _34Clear(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has("Dashed Platform", self.player)
elif self.game_logic == "Normal":
return (state.has("Dashed Platform", self.player) or self.has_midring(state))
else:
return True
def _34Boss(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has("Giant Eggs", self.player)
elif self.game_logic == "Normal":
return True
else:
return True
def _34CanFightBoss(self, state: CollectionState) -> bool:
if state.can_reach(self.boss_order[4], "Location", self.player):
return True
##############################################################################
def _37Game(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Key", "Large Spring Ball"}, self.player)
elif self.game_logic == "Normal":
return state.has("Key", self.player)
else:
return state.has("Key", self.player)
##############################################################################
def _38Clear(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return (state.has("Egg Capacity Upgrade", self.player, 3) or self.combat_item(state))
elif self.game_logic == "Normal":
return (state.has("Egg Capacity Upgrade", self.player, 1) or self.combat_item(state))
else:
return True
def _38Boss(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return True
elif self.game_logic == "Normal":
return True
else:
return True
def _38CanFightBoss(self, state: CollectionState) -> bool:
if state.can_reach(self.boss_order[5], "Location", self.player):
return True
##############################################################################
def _42Game(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Large Spring Ball", "Key"}, self.player)
elif self.game_logic == "Normal":
return state.has_all({"Large Spring Ball", "Key"}, self.player)
else:
return state.has("Key", self.player)
##############################################################################
def _44Clear(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Dashed Stairs", "Vanishing Arrow Wheel", "Arrow Wheel", "Bucket", "Key"}, self.player) and (state.has("Egg Capacity Upgrade", self.player, 1) or self.combat_item(state))
elif self.game_logic == "Normal":
return state.has_all({"Dashed Stairs", "Vanishing Arrow Wheel", "Arrow Wheel", "Bucket", "Key"}, self.player)
else:
return state.has_all({"Dashed Stairs", "Vanishing Arrow Wheel", "Arrow Wheel", "Bucket", "Key"}, self.player)
def _44Boss(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return True
elif self.game_logic == "Normal":
return True
else:
return True
def _44CanFightBoss(self, state: CollectionState) -> bool:
if state.can_reach(self.boss_order[6], "Location", self.player):
return True
########################################################################################################
def _46Game(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Key", "Large Spring Ball"}, self.player)
elif self.game_logic == "Normal":
return state.has_all({"Key", "Large Spring Ball"}, self.player)
else:
return state.has_all({"Key", "Large Spring Ball"}, self.player)
def _47Game(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Key", "Large Spring Ball"}, self.player)
elif self.game_logic == "Normal":
return state.has_all({"Key", "Large Spring Ball"}, self.player)
else:
return state.has_all({"Key", "Large Spring Ball"}, self.player)
##############################################################################
def _48Clear(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return (state.has_all({"Dashed Stairs", "Vanishing Arrow Wheel", "Key", "Large Spring Ball"}, self.player))
elif self.game_logic == "Normal":
return (state.has_all({"Dashed Stairs", "Vanishing Arrow Wheel", "Key", "Large Spring Ball"}, self.player))
else:
return (state.has_all({"Key", "Large Spring Ball"}, self.player))
def _48Boss(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return (state.has("Egg Capacity Upgrade", self.player, 3))
elif self.game_logic == "Normal":
return (state.has("Egg Capacity Upgrade", self.player, 2))
else:
return (state.has("Egg Capacity Upgrade", self.player, 1))
def _48CanFightBoss(self, state: CollectionState) -> bool:
if state.can_reach(self.boss_order[7], "Location", self.player):
return True
######################################################################################################################
def _51Game(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has("Key", self.player)
elif self.game_logic == "Normal":
return state.has("Key", self.player)
else:
return state.has("Key", self.player)
##############################################################################
def _54Clear(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return (state.has_all({"Dashed Stairs", "Platform Ghost", "Dashed Platform"}, self.player))
elif self.game_logic == "Normal":
return (state.has_all({"Dashed Stairs", "Platform Ghost", "Dashed Platform"}, self.player))
else:
return (state.has_all({"Dashed Stairs", "Platform Ghost"}, self.player))
def _54Boss(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return (state.has("Egg Capacity Upgrade", self.player, 2) and state.has("Egg Plant", self.player))
elif self.game_logic == "Normal":
return ((state.has("Egg Capacity Upgrade", self.player, 1) and state.has("Egg Plant", self.player)) or (state.has("Egg Capacity Upgrade", self.player, 5) and self.has_midring(state)))
else:
return ((state.has("Egg Plant", self.player)) or (state.has("Egg Capacity Upgrade", self.player, 3) and self.has_midring(state)))
def _54CanFightBoss(self, state: CollectionState) -> bool:
if state.can_reach(self.boss_order[8], "Location", self.player):
return True
###################################################################################################
def _58Clear(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Arrow Wheel", "Large Spring Ball"}, self.player)
elif self.game_logic == "Normal":
return state.has_all({"Arrow Wheel", "Large Spring Ball"}, self.player)
else:
return state.has_all({"Arrow Wheel", "Large Spring Ball"}, self.player)
def _58Boss(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return True
elif self.game_logic == "Normal":
return True
else:
return True
def _58CanFightBoss(self, state: CollectionState) -> bool:
if state.can_reach(self.boss_order[9], "Location", self.player):
return True
##############################################################################
def _61Game(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Dashed Platform", "Key", "Beanstalk"}, self.player)
elif self.game_logic == "Normal":
return state.has_all({"Dashed Platform", "Key", "Beanstalk"}, self.player)
else:
return state.has("Key", self.player)
##############################################################################
def _64Clear(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Spring Ball", "Large Spring Ball", "Egg Plant", "Key"}, self.player) and (state.has("Egg Capacity Upgrade", self.player, 3) or self.combat_item(state))
elif self.game_logic == "Normal":
return state.has_all({"Large Spring Ball", "Egg Plant", "Key"}, self.player) and (state.has("Egg Capacity Upgrade", self.player, 2) or self.combat_item(state))
else:
return state.has_all({"Egg Plant", "Key"}, self.player) and (state.has("Egg Capacity Upgrade", self.player, 1) or self.combat_item(state))
def _64Boss(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has("Egg Plant", self.player)
elif self.game_logic == "Normal":
return state.has("Egg Plant", self.player)
else:
return True
def _64CanFightBoss(self, state: CollectionState) -> bool:
if state.can_reach(self.boss_order[10], "Location", self.player):
return True
##############################################################################
def _67Game(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has("Key", self.player)
elif self.game_logic == "Normal":
return state.has("Key", self.player)
else:
return state.has("Key", self.player)
##############################################################################
def _68Clear(self, state: CollectionState) -> bool:
if self.game_logic == "Easy":
return state.has_all({"Helicopter Morph", "Egg Plant", "Giant Eggs"}, self.player) and self._68Route(state)
elif self.game_logic == "Normal":
return state.has_all({"Helicopter Morph", "Egg Plant", "Giant Eggs"}, self.player) and self._68Route(state)
else:
return state.has_all({"Helicopter Morph", "Giant Eggs"}, self.player) and self._68Route(state)