99 lines
3.8 KiB
Python
99 lines
3.8 KiB
Python
|
|
from typing import TYPE_CHECKING
|
||
|
|
|
||
|
|
from BaseClasses import CollectionState
|
||
|
|
|
||
|
|
from .constants import *
|
||
|
|
from .fuses import fuse_activation_reqs
|
||
|
|
from .options import HexagonQuestAbilityUnlockType, IceGrappling
|
||
|
|
|
||
|
|
if TYPE_CHECKING:
|
||
|
|
from . import TunicWorld
|
||
|
|
|
||
|
|
|
||
|
|
def randomize_ability_unlocks(world: "TunicWorld") -> dict[str, int]:
|
||
|
|
options = world.options
|
||
|
|
|
||
|
|
abilities = [prayer, holy_cross, icebolt]
|
||
|
|
ability_requirement = [1, 1, 1]
|
||
|
|
world.random.shuffle(abilities)
|
||
|
|
|
||
|
|
if options.hexagon_quest.value and options.hexagon_quest_ability_type == HexagonQuestAbilityUnlockType.option_hexagons:
|
||
|
|
hexagon_goal = options.hexagon_goal.value
|
||
|
|
# Set ability unlocks to 25, 50, and 75% of goal amount
|
||
|
|
ability_requirement = [hexagon_goal // 4, hexagon_goal // 2, hexagon_goal * 3 // 4]
|
||
|
|
if any(req == 0 for req in ability_requirement):
|
||
|
|
ability_requirement = [1, 2, 3]
|
||
|
|
|
||
|
|
return dict(zip(abilities, ability_requirement))
|
||
|
|
|
||
|
|
|
||
|
|
def has_ability(ability: str, state: CollectionState, world: "TunicWorld") -> bool:
|
||
|
|
options = world.options
|
||
|
|
ability_unlocks = world.ability_unlocks
|
||
|
|
if not options.ability_shuffling:
|
||
|
|
return True
|
||
|
|
if options.hexagon_quest and options.hexagon_quest_ability_type == HexagonQuestAbilityUnlockType.option_hexagons:
|
||
|
|
return state.has(gold_hexagon, world.player, ability_unlocks[ability])
|
||
|
|
return state.has(ability, world.player)
|
||
|
|
|
||
|
|
|
||
|
|
# a check to see if you can whack things in melee at all
|
||
|
|
def has_melee(state: CollectionState, player: int) -> bool:
|
||
|
|
return state.has_any(("Stick", "Sword", "Sword Upgrade"), player)
|
||
|
|
|
||
|
|
|
||
|
|
def has_sword(state: CollectionState, player: int) -> bool:
|
||
|
|
return state.has("Sword", player) or state.has("Sword Upgrade", player, 2)
|
||
|
|
|
||
|
|
|
||
|
|
def laurels_zip(state: CollectionState, world: "TunicWorld") -> bool:
|
||
|
|
return world.options.laurels_zips and state.has(laurels, world.player)
|
||
|
|
|
||
|
|
|
||
|
|
def has_ice_grapple_logic(long_range: bool, difficulty: IceGrappling, state: CollectionState, world: "TunicWorld") -> bool:
|
||
|
|
if world.options.ice_grappling < difficulty:
|
||
|
|
return False
|
||
|
|
if not long_range:
|
||
|
|
return state.has_all((ice_dagger, grapple), world.player)
|
||
|
|
else:
|
||
|
|
return state.has_all((ice_dagger, fire_wand, grapple), world.player) and has_ability(icebolt, state, world)
|
||
|
|
|
||
|
|
|
||
|
|
def can_ladder_storage(state: CollectionState, world: "TunicWorld") -> bool:
|
||
|
|
if not world.options.ladder_storage:
|
||
|
|
return False
|
||
|
|
if world.options.ladder_storage_without_items:
|
||
|
|
return True
|
||
|
|
return has_melee(state, world.player) or state.has_any((grapple, shield), world.player)
|
||
|
|
|
||
|
|
|
||
|
|
def has_mask(state: CollectionState, world: "TunicWorld") -> bool:
|
||
|
|
return world.options.maskless or state.has(mask, world.player)
|
||
|
|
|
||
|
|
|
||
|
|
def has_lantern(state: CollectionState, world: "TunicWorld") -> bool:
|
||
|
|
return world.options.lanternless or state.has(lantern, world.player)
|
||
|
|
|
||
|
|
|
||
|
|
def has_ladder(ladder: str, state: CollectionState, world: "TunicWorld") -> bool:
|
||
|
|
return not world.options.shuffle_ladders or state.has(ladder, world.player)
|
||
|
|
|
||
|
|
|
||
|
|
def can_shop(state: CollectionState, world: "TunicWorld") -> bool:
|
||
|
|
return has_sword(state, world.player) and state.can_reach_region("Shop", world.player)
|
||
|
|
|
||
|
|
|
||
|
|
# for the ones that are not early bushes where ER can screw you over a bit
|
||
|
|
def can_get_past_bushes(state: CollectionState, world: "TunicWorld") -> bool:
|
||
|
|
# add in glass cannon + stick for grass rando
|
||
|
|
return has_sword(state, world.player) or state.has_any((fire_wand, laurels, gun), world.player)
|
||
|
|
|
||
|
|
|
||
|
|
def has_fuses(fuse_event: str, state: CollectionState, world: "TunicWorld") -> bool:
|
||
|
|
player = world.player
|
||
|
|
fuses_option = False # replace fuses_option with world.options.shuffle_fuses when fuse shuffle is in
|
||
|
|
if fuses_option:
|
||
|
|
return state.has_all(fuse_activation_reqs[fuse_event], player)
|
||
|
|
|
||
|
|
return state.has(fuse_event, player)
|