Files
dockipelago/worlds/dk64/randomizer/ItemPool.py
Jonathan Tinney 7971961166
Some checks failed
Analyze modified files / flake8 (push) Failing after 2m28s
Build / build-win (push) Has been cancelled
Build / build-ubuntu2204 (push) Has been cancelled
ctest / Test C++ ubuntu-latest (push) Has been cancelled
ctest / Test C++ windows-latest (push) Has been cancelled
Analyze modified files / mypy (push) Has been cancelled
Build and Publish Docker Images / Push Docker image to Docker Hub (push) Successful in 5m4s
Native Code Static Analysis / scan-build (push) Failing after 5m2s
type check / pyright (push) Successful in 1m7s
unittests / Test Python 3.11.2 ubuntu-latest (push) Failing after 16m23s
unittests / Test Python 3.12 ubuntu-latest (push) Failing after 28m19s
unittests / Test Python 3.13 ubuntu-latest (push) Failing after 14m49s
unittests / Test hosting with 3.13 on ubuntu-latest (push) Successful in 5m0s
unittests / Test Python 3.13 macos-latest (push) Has been cancelled
unittests / Test Python 3.11 windows-latest (push) Has been cancelled
unittests / Test Python 3.13 windows-latest (push) Has been cancelled
add schedule I, sonic 1/frontiers/heroes, spirit island
2026-04-02 23:46:36 -07:00

794 lines
31 KiB
Python

"""Contains functions related to setting up the pool of shuffled items."""
import itertools
from randomizer.Enums.Events import Events
import randomizer.Enums.Kongs as KongObject
from randomizer.Enums.Items import Items
from randomizer.Enums.Locations import Locations
from randomizer.Enums.Plandomizer import GetItemsFromPlandoItem, PlandoItems
from randomizer.Enums.Settings import (
ClimbingStatus,
HardModeSelected,
MoveRando,
ShockwaveStatus,
ShuffleLoadingZones,
TrainingBarrels,
CBRando,
)
from randomizer.Enums.Types import Types
from randomizer.Enums.Levels import Levels
from randomizer.Lists.Item import ItemFromKong
from randomizer.Lists.LevelInfo import LevelInfoList
from randomizer.Lists.ShufflableExit import ShufflableExits
from randomizer.Patching.Library.Generic import getIceTrapCount, IsItemSelected
from randomizer.ShuffleBosses import PlandoBosses
def getHelmKey(settings) -> Items:
"""Get the item that will be placed in the final room in Helm."""
key_item = Items.HideoutHelmKey
if settings.shuffle_loading_zones == ShuffleLoadingZones.levels:
level_index = None
key_items = [
Items.JungleJapesKey,
Items.AngryAztecKey,
Items.FranticFactoryKey,
Items.GloomyGalleonKey,
Items.FungiForestKey,
Items.CrystalCavesKey,
Items.CreepyCastleKey,
Items.HideoutHelmKey,
]
for x in range(8):
if settings.level_order[x + 1] == Levels.HideoutHelm:
key_item = key_items[x]
level_index = x
break
if level_index is None:
raise Exception("Unable to find Helm in the level order to remove Helm Key constant")
return key_item
def PlaceConstants(spoiler):
"""Place items which are to be put in a hard-coded location."""
# Settings-dependent locations
settings = spoiler.settings
# Determine what types of locations are being shuffled
typesOfItemsShuffled = [Types.PreGivenMove] # Your starting moves are always eligible to be shuffled if needed
if settings.kong_rando:
typesOfItemsShuffled.append(Types.Kong)
if settings.move_rando != MoveRando.off:
typesOfItemsShuffled.append(Types.Shop)
if settings.training_barrels == TrainingBarrels.shuffled:
typesOfItemsShuffled.append(Types.TrainingBarrel)
if settings.climbing_status == ClimbingStatus.shuffled:
typesOfItemsShuffled.append(Types.Climbing)
if settings.shuffle_loading_zones == ShuffleLoadingZones.levels:
typesOfItemsShuffled.append(Types.Key)
typesOfItemsShuffled.extend(settings.shuffled_location_types)
# Invert this list because I think it'll be faster
typesOfItemsNotShuffled = [typ for typ in Types if typ not in typesOfItemsShuffled]
# Place the default item at every location of a type we're not shuffling
for location in spoiler.LocationList:
if spoiler.LocationList[location].type in typesOfItemsNotShuffled:
spoiler.LocationList[location].PlaceDefaultItem(spoiler)
# If we're placing a vanilla training move, we have to make the location available
if spoiler.LocationList[location].type in (Types.TrainingBarrel, Types.Climbing, Types.PreGivenMove):
spoiler.LocationList[location].inaccessible = False
else:
spoiler.LocationList[location].constant = False
spoiler.LocationList[location].item = None
# While we're looping here, also reset shops that became inaccessible due to fill lockouts
if spoiler.LocationList[location].type == Types.Shop:
spoiler.LocationList[location].inaccessible = spoiler.LocationList[location].smallerShopsInaccessible
spoiler.LocationList[location].tooExpensiveInaccessible = False
# Make extra sure the Helm Key is right
if settings.key_8_helm:
helm_key = getHelmKey(spoiler.settings)
if helm_key in KeysToPlace(spoiler.settings, excludeHelmKey=False):
spoiler.LocationList[Locations.HelmKey].PlaceConstantItem(spoiler, helm_key)
else:
spoiler.LocationList[Locations.HelmKey].PlaceConstantItem(spoiler, Items.NoItem)
# If no CB rando in isles, clear these locations
if not IsItemSelected(spoiler.settings.cb_rando_enabled, spoiler.settings.cb_rando_list_selected, Levels.DKIsles):
for x in range(5):
spoiler.LocationList[Locations.IslesDonkeyMedal + x].PlaceConstantItem(spoiler, Items.NoItem)
# Handle key placements
if settings.shuffle_loading_zones == ShuffleLoadingZones.levels and Types.Key not in settings.shuffled_location_types:
# Place keys in the lobbies they normally belong in
# Ex. Whatever level is in the Japes lobby entrance will always have the Japes key
for level in LevelInfoList.values():
# If level exit isn't shuffled, use vanilla key
if not ShufflableExits[level.TransitionTo].shuffled:
spoiler.LocationList[level.KeyLocation].PlaceConstantItem(spoiler, level.KeyItem)
else:
# Find the transition this exit is attached to, and use that to get the proper location to place this key
dest = ShufflableExits[level.TransitionTo].shuffledId
shuffledTo = [x for x in LevelInfoList.values() if x.TransitionTo == dest][0]
spoiler.LocationList[shuffledTo.KeyLocation].PlaceConstantItem(spoiler, level.KeyItem)
# The End of Helm is always a Key in these settings (unless you start with it)
helm_key = getHelmKey(spoiler.settings)
if helm_key in KeysToPlace(spoiler.settings, excludeHelmKey=False):
spoiler.LocationList[Locations.HelmKey].PlaceConstantItem(spoiler, getHelmKey(spoiler.settings))
else:
spoiler.LocationList[Locations.HelmKey].PlaceConstantItem(spoiler, Items.NoItem)
# Empty out some locations based on the settings
if settings.starting_kongs_count == 5:
spoiler.LocationList[Locations.DiddyKong].PlaceConstantItem(spoiler, Items.NoItem)
spoiler.LocationList[Locations.LankyKong].PlaceConstantItem(spoiler, Items.NoItem)
spoiler.LocationList[Locations.TinyKong].PlaceConstantItem(spoiler, Items.NoItem)
spoiler.LocationList[Locations.ChunkyKong].PlaceConstantItem(spoiler, Items.NoItem)
if settings.start_with_slam:
spoiler.LocationList[Locations.IslesFirstMove].PlaceConstantItem(spoiler, Items.ProgressiveSlam)
spoiler.LocationList[Locations.IslesFirstMove].inaccessible = False
# Plando items are placed with constants but should not change locations to Constant type
settings.plandomizer_items_placed = []
if settings.enable_plandomizer:
blueprints_planned = []
for location_id, plando_item in settings.plandomizer_dict["locations"].items():
if plando_item in [
PlandoItems.DonkeyBlueprint,
PlandoItems.DiddyBlueprint,
PlandoItems.LankyBlueprint,
PlandoItems.TinyBlueprint,
PlandoItems.ChunkyBlueprint,
]:
item = settings.random.choice([x for x in GetItemsFromPlandoItem(plando_item) if x not in blueprints_planned])
blueprints_planned.append(item)
else:
item = settings.random.choice(GetItemsFromPlandoItem(plando_item))
spoiler.LocationList[int(location_id)].PlaceItem(spoiler, item)
settings.plandomizer_items_placed.append(item)
# If any bosses are plando'd, do it now ahead of placing any items randomly.
if spoiler.settings.boss_plando:
# Doing it here has the added benefit of rerolling on fill failure.
PlandoBosses(spoiler)
def AllItemsUnrestricted(settings):
"""Return all placeable items regardless of shuffle status."""
allItems = []
allItems.extend(Blueprints())
allItems.extend(GoldenBananaItems())
allItems.extend(ToughGoldenBananaItems())
allItems.extend(NintendoCoinItems())
allItems.extend(RarewareCoinItems())
allItems.extend(BattleCrownItems())
allItems.extend(Keys())
allItems.extend(BananaMedalItems(settings))
allItems.extend(MiscItemRandoItems())
allItems.extend(FairyItems())
allItems.extend(RainbowCoinItems())
allItems.extend(MelonCrateItems())
allItems.extend(EnemyItems())
allItems.extend(FakeItems(settings))
allItems.extend(JunkItems(settings))
allItems.extend(DonkeyMoves)
allItems.extend(DiddyMoves)
allItems.extend(LankyMoves)
allItems.extend(TinyMoves)
allItems.extend(ChunkyMoves)
allItems.extend(ImportantSharedMoves)
allItems.extend(JunkSharedMoves)
allItems.extend(TrainingBarrelAbilities().copy())
allItems.extend(ClimbingAbilities().copy())
if settings.shockwave_status == ShockwaveStatus.shuffled_decoupled:
allItems.append(Items.Camera)
allItems.append(Items.Shockwave)
else:
allItems.append(Items.CameraAndShockwave)
allItems.extend(Kongs(settings))
allItems.extend(CrankyItems())
allItems.extend(FunkyItems())
allItems.extend(CandyItems())
allItems.extend(SnideItems())
return allItems
def AllItems(settings):
"""Return all shuffled items."""
allItems = []
if Types.Blueprint in settings.shuffled_location_types:
allItems.extend(Blueprints())
if Types.Banana in settings.shuffled_location_types:
allItems.extend(GoldenBananaItems())
if Types.ToughBanana in settings.shuffled_location_types:
allItems.extend(ToughGoldenBananaItems())
if Types.NintendoCoin in settings.shuffled_location_types:
allItems.extend(NintendoCoinItems())
if Types.RarewareCoin in settings.shuffled_location_types:
allItems.extend(RarewareCoinItems())
if Types.Crown in settings.shuffled_location_types:
allItems.extend(BattleCrownItems())
if Types.Key in settings.shuffled_location_types:
allItems.extend(Keys())
if Types.Medal in settings.shuffled_location_types:
allItems.extend(BananaMedalItems(settings))
if Types.Bean in settings.shuffled_location_types: # Could check for pearls as well
allItems.extend(MiscItemRandoItems())
if Types.Fairy in settings.shuffled_location_types:
allItems.extend(FairyItems())
if Types.RainbowCoin in settings.shuffled_location_types:
allItems.extend(RainbowCoinItems())
if Types.CrateItem in settings.shuffled_location_types:
allItems.extend(MelonCrateItems())
if Types.Hint in settings.shuffled_location_types:
allItems.extend(HintItems())
if Types.Enemies in settings.shuffled_location_types:
allItems.extend(EnemyItems())
if Types.Cranky in settings.shuffled_location_types:
allItems.extend(CrankyItems())
if Types.Funky in settings.shuffled_location_types:
allItems.extend(FunkyItems())
if Types.Candy in settings.shuffled_location_types:
allItems.extend(CandyItems())
if Types.Snide in settings.shuffled_location_types:
allItems.extend(SnideItems())
if Types.FakeItem in settings.shuffled_location_types:
allItems.extend(FakeItems(settings))
if Types.JunkItem in settings.shuffled_location_types:
allItems.extend(JunkItems(settings))
if settings.move_rando != MoveRando.off:
allItems.extend(DonkeyMoves)
allItems.extend(DiddyMoves)
allItems.extend(LankyMoves)
allItems.extend(TinyMoves)
allItems.extend(ChunkyMoves)
allItems.extend(ImportantSharedMoves)
if settings.training_barrels == TrainingBarrels.shuffled:
allItems.extend(TrainingBarrelAbilities().copy())
if settings.climbing_status == ClimbingStatus.shuffled:
allItems.extend(ClimbingAbilities().copy())
if settings.shockwave_status == ShockwaveStatus.shuffled_decoupled:
allItems.append(Items.Camera)
allItems.append(Items.Shockwave)
else:
allItems.append(Items.CameraAndShockwave)
if settings.kong_rando or Types.Kong in settings.shuffled_location_types:
allItems.extend(Kongs(settings))
return allItems
def AllItemsForMovePlacement(settings):
"""Return all shuffled items we need to assume for move placement."""
allItems = []
if Types.Blueprint in settings.shuffled_location_types:
allItems.extend(Blueprints())
if Types.Banana in settings.shuffled_location_types:
allItems.extend(GoldenBananaItems())
if Types.ToughBanana in settings.shuffled_location_types:
allItems.extend(ToughGoldenBananaItems())
if Types.NintendoCoin in settings.shuffled_location_types:
allItems.extend(NintendoCoinItems())
if Types.RarewareCoin in settings.shuffled_location_types:
allItems.extend(RarewareCoinItems())
if Types.Crown in settings.shuffled_location_types:
allItems.extend(BattleCrownItems())
if Types.Key in settings.shuffled_location_types:
allItems.extend(Keys())
if Types.Medal in settings.shuffled_location_types:
allItems.extend(BananaMedalItems(settings))
if Types.Bean in settings.shuffled_location_types: # Could check for pearls as well
allItems.extend(MiscItemRandoItems())
if Types.Fairy in settings.shuffled_location_types:
allItems.extend(FairyItems())
if Types.RainbowCoin in settings.shuffled_location_types:
allItems.extend(RainbowCoinItems())
if Types.CrateItem in settings.shuffled_location_types:
allItems.extend(MelonCrateItems())
if Types.Hint in settings.shuffled_location_types:
allItems.extend(HintItems())
if Types.Enemies in settings.shuffled_location_types:
allItems.extend(EnemyItems())
if Types.Cranky in settings.shuffled_location_types:
allItems.extend(CrankyItems())
if Types.Funky in settings.shuffled_location_types:
allItems.extend(FunkyItems())
if Types.Candy in settings.shuffled_location_types:
allItems.extend(CandyItems())
if Types.Snide in settings.shuffled_location_types:
allItems.extend(SnideItems())
if Types.FakeItem in settings.shuffled_location_types:
allItems.extend(FakeItems(settings))
if Types.JunkItem in settings.shuffled_location_types:
allItems.extend(JunkItems(settings))
return allItems
def AllKongMoves():
"""Return all moves."""
allMoves = []
allMoves.extend(DonkeyMoves)
allMoves.extend(DiddyMoves)
allMoves.extend(LankyMoves)
allMoves.extend(TinyMoves)
allMoves.extend(ChunkyMoves)
allMoves.extend(ImportantSharedMoves)
return allMoves
def AllMovesForOwnedKongs(kongs):
"""Return all moves for the given list of Kongs."""
kongMoves = []
if KongObject.Kongs.donkey in kongs:
kongMoves.extend(DonkeyMoves)
if KongObject.Kongs.diddy in kongs:
kongMoves.extend(DiddyMoves)
if KongObject.Kongs.lanky in kongs:
kongMoves.extend(LankyMoves)
if KongObject.Kongs.tiny in kongs:
kongMoves.extend(TinyMoves)
if KongObject.Kongs.chunky in kongs:
kongMoves.extend(ChunkyMoves)
kongMoves.extend(ImportantSharedMoves)
return kongMoves
def ShockwaveTypeItems(settings):
"""Return the Shockwave-type items for the given settings."""
if settings.shockwave_status == ShockwaveStatus.shuffled_decoupled:
return [Items.Camera, Items.Shockwave]
else:
return [Items.CameraAndShockwave]
def Blueprints():
"""Return all blueprint items."""
blueprints = [
Items.DKIslesDonkeyBlueprint,
Items.DKIslesDiddyBlueprint,
Items.DKIslesLankyBlueprint,
Items.DKIslesTinyBlueprint,
Items.DKIslesChunkyBlueprint,
Items.JungleJapesDonkeyBlueprint,
Items.JungleJapesDiddyBlueprint,
Items.JungleJapesLankyBlueprint,
Items.JungleJapesTinyBlueprint,
Items.JungleJapesChunkyBlueprint,
Items.AngryAztecDonkeyBlueprint,
Items.AngryAztecDiddyBlueprint,
Items.AngryAztecLankyBlueprint,
Items.AngryAztecTinyBlueprint,
Items.AngryAztecChunkyBlueprint,
Items.FranticFactoryDonkeyBlueprint,
Items.FranticFactoryDiddyBlueprint,
Items.FranticFactoryLankyBlueprint,
Items.FranticFactoryTinyBlueprint,
Items.FranticFactoryChunkyBlueprint,
Items.GloomyGalleonDonkeyBlueprint,
Items.GloomyGalleonDiddyBlueprint,
Items.GloomyGalleonLankyBlueprint,
Items.GloomyGalleonTinyBlueprint,
Items.GloomyGalleonChunkyBlueprint,
Items.FungiForestDonkeyBlueprint,
Items.FungiForestDiddyBlueprint,
Items.FungiForestLankyBlueprint,
Items.FungiForestTinyBlueprint,
Items.FungiForestChunkyBlueprint,
Items.CrystalCavesDonkeyBlueprint,
Items.CrystalCavesDiddyBlueprint,
Items.CrystalCavesLankyBlueprint,
Items.CrystalCavesTinyBlueprint,
Items.CrystalCavesChunkyBlueprint,
Items.CreepyCastleDonkeyBlueprint,
Items.CreepyCastleDiddyBlueprint,
Items.CreepyCastleLankyBlueprint,
Items.CreepyCastleTinyBlueprint,
Items.CreepyCastleChunkyBlueprint,
]
return blueprints
def Keys():
"""Return all key items."""
return [
Items.JungleJapesKey,
Items.AngryAztecKey,
Items.FranticFactoryKey,
Items.GloomyGalleonKey,
Items.FungiForestKey,
Items.CrystalCavesKey,
Items.CreepyCastleKey,
Items.HideoutHelmKey,
]
def KeysToPlace(settings, excludeHelmKey=True):
"""Return all keys that are non-starting keys."""
keysToPlace = []
for keyEvent in settings.krool_keys_required:
if keyEvent == Events.JapesKeyTurnedIn:
keysToPlace.append(Items.JungleJapesKey)
elif keyEvent == Events.AztecKeyTurnedIn:
keysToPlace.append(Items.AngryAztecKey)
elif keyEvent == Events.FactoryKeyTurnedIn:
keysToPlace.append(Items.FranticFactoryKey)
elif keyEvent == Events.GalleonKeyTurnedIn:
keysToPlace.append(Items.GloomyGalleonKey)
elif keyEvent == Events.ForestKeyTurnedIn:
keysToPlace.append(Items.FungiForestKey)
elif keyEvent == Events.CavesKeyTurnedIn:
keysToPlace.append(Items.CrystalCavesKey)
elif keyEvent == Events.CastleKeyTurnedIn:
keysToPlace.append(Items.CreepyCastleKey)
elif keyEvent == Events.HelmKeyTurnedIn:
keysToPlace.append(Items.HideoutHelmKey)
if settings.key_8_helm and excludeHelmKey:
key_item = getHelmKey(settings)
if key_item in keysToPlace:
keysToPlace.remove(key_item)
return keysToPlace
def Kongs(settings):
"""Return Kong items depending on settings."""
kongs = []
if settings.starting_kongs_count != 5:
kongs = [Items.Donkey, Items.Diddy, Items.Lanky, Items.Tiny, Items.Chunky]
kongs.remove(ItemFromKong(settings.starting_kong))
return kongs
def GetKongForItem(item):
"""Return Kong object from kong-type item."""
if item == Items.Donkey:
return KongObject.Kongs.donkey
elif item == Items.Diddy:
return KongObject.Kongs.diddy
elif item == Items.Lanky:
return KongObject.Kongs.lanky
elif item == Items.Tiny:
return KongObject.Kongs.tiny
else:
return KongObject.Kongs.chunky
def Guns(settings):
"""Return all gun items."""
return [Items.Coconut, Items.Peanut, Items.Grape, Items.Feather, Items.Pineapple]
def Instruments(settings):
"""Return all instrument items."""
return [Items.Bongos, Items.Guitar, Items.Trombone, Items.Saxophone, Items.Triangle]
def TrainingBarrelAbilities():
"""Return all training barrel abilities."""
barrelAbilities = [Items.Vines, Items.Swim, Items.Oranges, Items.Barrels]
return barrelAbilities
def ClimbingAbilities():
"""Return all climbing abilities."""
return [Items.Climbing]
def Upgrades(settings):
"""Return all upgrade items."""
upgrades = []
# Add training barrel items to item pool if shuffled
if settings.training_barrels == TrainingBarrels.shuffled:
upgrades.extend(TrainingBarrelAbilities())
# Add climbing to item pool if shuffled
if settings.climbing_status == ClimbingStatus.shuffled:
upgrades.extend(ClimbingAbilities())
# Add either progressive upgrade items or individual ones depending on settings
slam_count = 3
if settings.start_with_slam:
slam_count = 2
upgrades.extend(itertools.repeat(Items.ProgressiveSlam, slam_count))
upgrades.extend(
[
Items.BaboonBlast,
Items.StrongKong,
Items.GorillaGrab,
Items.ChimpyCharge,
Items.RocketbarrelBoost,
Items.SimianSpring,
Items.Orangstand,
Items.BaboonBalloon,
Items.OrangstandSprint,
Items.MiniMonkey,
Items.PonyTailTwirl,
Items.Monkeyport,
Items.HunkyChunky,
Items.PrimatePunch,
Items.GorillaGone,
]
)
upgrades.append(Items.HomingAmmo)
upgrades.append(Items.SniperSight)
upgrades.extend(itertools.repeat(Items.ProgressiveAmmoBelt, 2))
upgrades.extend(itertools.repeat(Items.ProgressiveInstrumentUpgrade, 3))
if settings.shockwave_status != ShockwaveStatus.start_with:
if settings.shockwave_status == ShockwaveStatus.vanilla or settings.shockwave_status == ShockwaveStatus.shuffled:
upgrades.append(Items.CameraAndShockwave)
else:
upgrades.append(Items.Camera)
upgrades.append(Items.Shockwave)
return upgrades
def HighPriorityItems(settings):
"""Get all items which are of high importance logically."""
itemPool = []
itemPool.extend(Kongs(settings))
itemPool.extend(Guns(settings))
itemPool.extend(Instruments(settings))
itemPool.extend(Upgrades(settings))
itemPool.extend(CrankyItems())
itemPool.extend(CandyItems())
itemPool.extend(FunkyItems())
itemPool.extend(SnideItems())
return itemPool
def NintendoCoinItems():
"""Return Nintendo Coin."""
return [Items.NintendoCoin]
def RarewareCoinItems():
"""Return Rareware Coin."""
return [Items.RarewareCoin]
TOUGH_BANANA_COUNT = 13
def GoldenBananaItems():
"""Return a list of GBs to be placed."""
itemPool = []
itemPool.extend(itertools.repeat(Items.GoldenBanana, 161 - TOUGH_BANANA_COUNT)) # 40 Blueprint GBs are always already placed (see Types.BlueprintBanana)
return itemPool
def ToughGoldenBananaItems():
"""Return a list of GBs to be placed."""
itemPool = []
itemPool.extend(itertools.repeat(Items.GoldenBanana, TOUGH_BANANA_COUNT))
return itemPool
def BananaMedalItems(settings):
"""Return a list of Banana Medals to be placed."""
itemPool = []
count = 40
if IsItemSelected(settings.cb_rando_enabled, settings.cb_rando_list_selected, Levels.DKIsles):
count = 45
itemPool.extend(itertools.repeat(Items.BananaMedal, count))
return itemPool
def BattleCrownItems():
"""Return a list of Crowns to be placed."""
itemPool = []
itemPool.extend(itertools.repeat(Items.BattleCrown, 10))
return itemPool
def MiscItemRandoItems():
"""Return a list of Items that are classed as miscellaneous."""
itemPool = []
itemPool.append(Items.Bean)
itemPool.extend(itertools.repeat(Items.Pearl, 5))
return itemPool
def RainbowCoinItems():
"""Return a list of Rainbow Coins to be placed."""
itemPool = []
itemPool.extend(itertools.repeat(Items.RainbowCoin, 16))
return itemPool
def MelonCrateItems():
"""Return a list of No Items to be placed."""
return []
def EnemyItems():
"""Return a list of No Items to be placed."""
return []
def FairyItems():
"""Return a list of Fairies to be placed."""
itemPool = []
itemPool.extend(itertools.repeat(Items.BananaFairy, 20))
return itemPool
def FakeItems(settings):
"""Return a list of Fake Items to be placed."""
itemPool = []
total_count = getIceTrapCount(settings)
slow_count = int(total_count / 3)
reverse_count = int(total_count / 3)
bubble_count = total_count - (slow_count + reverse_count)
itemPool.extend(itertools.repeat(Items.IceTrapBubble, bubble_count))
itemPool.extend(itertools.repeat(Items.IceTrapReverse, reverse_count))
itemPool.extend(itertools.repeat(Items.IceTrapSlow, slow_count))
return itemPool
def CrankyItems():
"""Return a list of Cranky shop owners to be placed."""
return [Items.Cranky]
def FunkyItems():
"""Return a list of Funky shop owners to be placed."""
return [Items.Funky]
def CandyItems():
"""Return a list of Candy shop owners to be placed."""
return [Items.Candy]
def SnideItems():
"""Return a list of Snide shop owners to be placed."""
return [Items.Snide]
def HintItems():
"""Return a list of Hint Items to be placed."""
return [
Items.JapesDonkeyHint,
Items.JapesDiddyHint,
Items.JapesLankyHint,
Items.JapesTinyHint,
Items.JapesChunkyHint,
Items.AztecDonkeyHint,
Items.AztecDiddyHint,
Items.AztecLankyHint,
Items.AztecTinyHint,
Items.AztecChunkyHint,
Items.FactoryDonkeyHint,
Items.FactoryDiddyHint,
Items.FactoryLankyHint,
Items.FactoryTinyHint,
Items.FactoryChunkyHint,
Items.GalleonDonkeyHint,
Items.GalleonDiddyHint,
Items.GalleonLankyHint,
Items.GalleonTinyHint,
Items.GalleonChunkyHint,
Items.ForestDonkeyHint,
Items.ForestDiddyHint,
Items.ForestLankyHint,
Items.ForestTinyHint,
Items.ForestChunkyHint,
Items.CavesDonkeyHint,
Items.CavesDiddyHint,
Items.CavesLankyHint,
Items.CavesTinyHint,
Items.CavesChunkyHint,
Items.CastleDonkeyHint,
Items.CastleDiddyHint,
Items.CastleLankyHint,
Items.CastleTinyHint,
Items.CastleChunkyHint,
]
def JunkItems(settings):
"""Return a list of Junk Items to be placed."""
junk_count = min(100, 116 - getIceTrapCount(settings))
if Types.Enemies in settings.shuffled_location_types:
junk_count += 427
itemPool = []
# items_to_place = (Items.JunkAmmo, Items.JunkCrystal, Items.JunkFilm, Items.JunkMelon, Items.JunkOrange)
# items_to_place = (Items.JunkAmmo, Items.JunkCrystal, Items.JunkMelon, Items.JunkOrange)
items_to_place = [Items.JunkMelon]
lim = int(junk_count / len(items_to_place))
for item_type in items_to_place:
itemPool.extend(itertools.repeat(item_type, lim))
return itemPool
def GetItemsNeedingToBeAssumed(settings, placed_types, placed_items=[]):
"""Return a list of all items that will be assumed for immediate item placement."""
itemPool = []
unplacedTypes = [typ for typ in settings.shuffled_location_types if typ not in placed_types]
if Types.Banana in unplacedTypes:
itemPool.extend(GoldenBananaItems())
if Types.ToughBanana in unplacedTypes:
itemPool.extend(ToughGoldenBananaItems())
if Types.Shop in unplacedTypes:
itemPool.extend(AllKongMoves())
if Types.Blueprint in unplacedTypes:
itemPool.extend(Blueprints())
if Types.Fairy in unplacedTypes:
itemPool.extend(FairyItems())
if Types.Key in unplacedTypes:
itemPool.extend(Keys())
if Types.Crown in unplacedTypes:
itemPool.extend(BattleCrownItems())
if Types.NintendoCoin in unplacedTypes:
itemPool.extend(NintendoCoinItems())
if Types.RarewareCoin in unplacedTypes:
itemPool.extend(RarewareCoinItems())
if Types.TrainingBarrel in unplacedTypes:
itemPool.extend(TrainingBarrelAbilities())
if Types.Climbing in unplacedTypes:
itemPool.extend(ClimbingAbilities())
if Types.Kong in unplacedTypes:
itemPool.extend(Kongs(settings))
if Types.Medal in unplacedTypes:
itemPool.extend(BananaMedalItems(settings))
if Types.Shockwave in unplacedTypes:
itemPool.extend(ShockwaveTypeItems(settings))
if Types.Bean in unplacedTypes:
itemPool.extend(MiscItemRandoItems()) # Covers Bean and Pearls
if Types.RainbowCoin in unplacedTypes:
itemPool.extend(RainbowCoinItems())
if Types.CrateItem in unplacedTypes:
itemPool.extend(MelonCrateItems())
if Types.Enemies in unplacedTypes:
itemPool.extend(EnemyItems())
if Types.ToughBanana in unplacedTypes:
itemPool.extend(ToughGoldenBananaItems())
if Types.Cranky in unplacedTypes:
itemPool.extend(CrankyItems())
if Types.Funky in unplacedTypes:
itemPool.extend(FunkyItems())
if Types.Candy in unplacedTypes:
itemPool.extend(CandyItems())
if Types.Snide in unplacedTypes:
itemPool.extend(SnideItems())
# Never logic-affecting items
# if Types.FakeItem in unplacedTypes:
# itemPool.extend(FakeItems())
# if Types.JunkItem in unplacedTypes:
# itemPool.extend(JunkItems())
if Types.Hint in unplacedTypes:
itemPool.extend(HintItems())
# If shops are not part of the larger item pool and are not placed, we may still need to assume them
# It is worth noting that TrainingBarrel and Shockwave type items are contingent on Shop type items being in the item rando pool
if Types.Shop not in settings.shuffled_location_types and Types.Shop not in placed_types and settings.move_rando != MoveRando.off:
itemPool.extend(AllKongMoves())
if settings.training_barrels == TrainingBarrels.shuffled:
itemPool.extend(TrainingBarrelAbilities().copy())
if settings.climbing_status == ClimbingStatus.shuffled:
itemPool.extend(ClimbingAbilities().copy())
# With a list of specifically placed items, we can't assume those
for item in placed_items:
if item in itemPool:
itemPool.remove(item) # Remove one instance of the item (do not filter!)
# If there is a Key forced into Helm, be sure it's not being assumed
if settings.key_8_helm or Types.Key not in settings.shuffled_location_types:
key_forced_into_helm = getHelmKey(settings)
if key_forced_into_helm in itemPool:
itemPool.remove(key_forced_into_helm)
return itemPool
DonkeyMoves = [Items.Coconut, Items.Bongos, Items.BaboonBlast, Items.StrongKong, Items.GorillaGrab]
DiddyMoves = [Items.Peanut, Items.Guitar, Items.ChimpyCharge, Items.RocketbarrelBoost, Items.SimianSpring]
LankyMoves = [Items.Grape, Items.Trombone, Items.Orangstand, Items.BaboonBalloon, Items.OrangstandSprint]
TinyMoves = [Items.Feather, Items.Saxophone, Items.MiniMonkey, Items.PonyTailTwirl, Items.Monkeyport]
ChunkyMoves = [Items.Pineapple, Items.Triangle, Items.HunkyChunky, Items.PrimatePunch, Items.GorillaGone]
ImportantSharedMoves = [
Items.ProgressiveSlam,
Items.ProgressiveSlam,
Items.ProgressiveSlam,
Items.SniperSight,
Items.HomingAmmo,
]
JunkSharedMoves = [
Items.ProgressiveAmmoBelt,
Items.ProgressiveAmmoBelt,
Items.ProgressiveInstrumentUpgrade,
Items.ProgressiveInstrumentUpgrade,
Items.ProgressiveInstrumentUpgrade,
]
ProgressiveSharedMovesSet = {Items.ProgressiveAmmoBelt, Items.ProgressiveInstrumentUpgrade, Items.ProgressiveSlam}