Skip to content

Commit 7394f47

Browse files
committed
Merge branch 'dev' into bump-py-and-such
2 parents 9bc7a23 + 46d3c03 commit 7394f47

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+2631
-1116
lines changed

.bumpversion.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[bumpversion]
22
commit = True
33
tag = False
4-
current_version = 5.7.39
4+
current_version = 5.7.50
55

66
[bumpversion:file:version.py]
77
search = version = "{current_version}"

__init__.py

Lines changed: 486 additions & 17 deletions
Large diffs are not rendered by default.

archipelago.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"minimum_ap_version": "0.6.5",
3-
"world_version": "1.4.16",
2+
"minimum_ap_version": "0.6.4",
3+
"world_version": "1.4.19",
44
"authors": ["2dos", "AlmostSeagull", "Ballaam", "Green Bean", "Killklli", "Lrauq", "PoryGone", "Umed"],
55
"version": 7,
66
"compatible_version": 7,

archipelago/FillSettings.py

Lines changed: 79 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
from randomizer.Enums.SwitchTypes import SwitchType
5757
from randomizer.Enums.Switches import Switches
5858
from randomizer.Lists.Switches import SwitchInfo
59-
from archipelago.Options import Goal, SwitchSanity, SelectStartingKong
59+
from archipelago.Options import Goal, SwitchSanity, SelectStartingKong, GalleonWaterLevel
6060
from archipelago.Goals import GOAL_MAPPING, QUANTITY_GOALS, calculate_quantity
6161
from archipelago.Logic import logic_item_name_to_id
6262

@@ -128,7 +128,6 @@ def get_default_settings() -> dict:
128128
"filler_items_selected": [ItemRandoFiller.junkitem],
129129
"free_trade_setting": True,
130130
"fungi_time": FungiTimeSetting.dusk,
131-
"galleon_water": GalleonWaterSetting.raised,
132131
"generate_spoilerlog": True,
133132
"hard_bosses_selected": [],
134133
"hard_mode_selected": [],
@@ -189,12 +188,11 @@ def get_default_settings() -> dict:
189188
"kong_model_tiny": KongModels.default,
190189
"krool_access": False,
191190
"krool_in_boss_pool": False,
192-
"krool_key_count": 8,
191+
"krool_key_count": 0,
193192
"krool_phase_count": 3,
194193
"krool_phase_order_rando": True,
195194
"krool_random": False,
196195
"less_fragile_boulders": True,
197-
"level_randomization": LevelRandomization.level_order_complex,
198196
"logic_type": LogicType.glitchless,
199197
"maximize_helm_blocker": True,
200198
"medal_cb_req": 40,
@@ -317,6 +315,7 @@ def apply_archipelago_settings(settings_dict: dict, options, multiworld) -> None
317315
settings_dict["krool_in_boss_pool"] = options.krool_in_boss_pool.value
318316
settings_dict["helm_phase_count"] = options.helm_phase_count.value
319317
settings_dict["krool_phase_count"] = options.krool_phase_count.value
318+
settings_dict["level_randomization"] = LevelRandomization.loadingzone if options.loading_zone_rando.value else LevelRandomization.level_order_complex
320319

321320
# Medal distribution settings
322321
if options.medal_distribution.value == 0: # pre_selected
@@ -337,6 +336,12 @@ def apply_archipelago_settings(settings_dict: dict, options, multiworld) -> None
337336
if options.enable_cutscenes.value:
338337
settings_dict["more_cutscene_skips"] = ExtraCutsceneSkips.press
339338
settings_dict["alt_minecart_mayhem"] = options.alternate_minecart_mayhem.value
339+
if options.galleon_water_level == GalleonWaterLevel.option_lowered:
340+
settings_dict["galleon_water"] = GalleonWaterSetting.lowered
341+
elif options.galleon_water_level == GalleonWaterLevel.option_raised:
342+
settings_dict["galleon_water"] = GalleonWaterSetting.raised
343+
else:
344+
settings_dict["galleon_water"] = GalleonWaterSetting.vanilla
340345

341346

342347
def apply_blocker_settings(settings_dict: dict, options) -> None:
@@ -437,7 +442,8 @@ def apply_hard_mode_settings(settings_dict: dict, options) -> None:
437442
def apply_kong_settings(settings_dict: dict, options) -> None:
438443
"""Apply Kong settings."""
439444
# Key settings
440-
settings_dict["krool_key_count"] = options.krool_key_count.value
445+
settings_dict["krool_key_count"] = options.pregiven_keys.value
446+
settings_dict["win_condition_spawns_ship"] = 1 if options.require_beating_krool.value else 0
441447

442448
# Kong mapping
443449
kong_mapping = {
@@ -679,6 +685,13 @@ def apply_goal_settings(settings_dict: dict, options, random_obj) -> None:
679685
"""Apply goal and win condition settings."""
680686
settings_dict["win_condition_item"] = GOAL_MAPPING[options.goal]
681687

688+
# Krool's Challenge always requires beating K. Rool otherwise wheres the challenge
689+
if options.goal == Goal.option_krools_challenge:
690+
settings_dict["win_condition_spawns_ship"] = True
691+
# The rabbit is too powerful to allow this
692+
elif options.goal == Goal.option_kill_the_rabbit:
693+
settings_dict["win_condition_spawns_ship"] = False
694+
682695
if options.goal in QUANTITY_GOALS.keys():
683696
goal_name = QUANTITY_GOALS[options.goal]
684697
settings_dict["win_condition_count"] = calculate_quantity(goal_name, options.goal_quantity.value, random_obj)
@@ -733,6 +746,66 @@ def apply_minigame_settings(settings_dict: dict, options, multiworld) -> None:
733746
settings_dict["bonus_barrel_auto_complete"] = options.auto_complete_bonus_barrels.value and options.goal.value != Goal.option_bonuses
734747
settings_dict["helm_room_bonus_count"] = HelmBonuses(options.helm_room_bonus_count.value)
735748

749+
# Map crown door and coin door settings
750+
crown_door_mapping = {
751+
0: HelmDoorItem.vanilla,
752+
1: HelmDoorItem.opened,
753+
2: HelmDoorItem.medium_random,
754+
3: HelmDoorItem.req_gb,
755+
4: HelmDoorItem.req_bp,
756+
5: HelmDoorItem.req_companycoins,
757+
6: HelmDoorItem.req_key,
758+
7: HelmDoorItem.req_medal,
759+
8: HelmDoorItem.req_crown,
760+
9: HelmDoorItem.req_fairy,
761+
10: HelmDoorItem.req_rainbowcoin,
762+
11: HelmDoorItem.req_bean,
763+
12: HelmDoorItem.req_pearl,
764+
13: HelmDoorItem.easy_random,
765+
14: HelmDoorItem.hard_random,
766+
}
767+
768+
coin_door_mapping = {
769+
0: HelmDoorItem.vanilla,
770+
1: HelmDoorItem.opened,
771+
2: HelmDoorItem.medium_random,
772+
3: HelmDoorItem.req_gb,
773+
4: HelmDoorItem.req_bp,
774+
6: HelmDoorItem.req_key,
775+
7: HelmDoorItem.req_medal,
776+
8: HelmDoorItem.req_crown,
777+
9: HelmDoorItem.req_fairy,
778+
10: HelmDoorItem.req_rainbowcoin,
779+
11: HelmDoorItem.req_bean,
780+
12: HelmDoorItem.req_pearl,
781+
13: HelmDoorItem.easy_random,
782+
14: HelmDoorItem.hard_random,
783+
}
784+
785+
# Map door item type to the key name in helm_door_item_count dict
786+
door_item_to_key = {
787+
3: "golden_bananas", # req_gb
788+
4: "blueprints", # req_bp
789+
5: "company_coins", # req_companycoins
790+
6: "keys", # req_key
791+
7: "medals", # req_medal
792+
8: "crowns", # req_crown
793+
9: "fairies", # req_fairy
794+
10: "rainbow_coins", # req_rainbowcoin
795+
11: "bean", # req_bean
796+
12: "pearls", # req_pearl
797+
}
798+
799+
settings_dict["crown_door_item"] = crown_door_mapping.get(options.crown_door_item.value, HelmDoorItem.opened)
800+
# Get count from dict based on selected item, default to 1 if not found
801+
crown_item_key = door_item_to_key.get(options.crown_door_item.value)
802+
settings_dict["crown_door_item_count"] = options.helm_door_item_count.value.get(crown_item_key, 1) if crown_item_key else 1
803+
804+
settings_dict["coin_door_item"] = coin_door_mapping.get(options.coin_door_item.value, HelmDoorItem.opened)
805+
# Get count from dict based on selected item, default to 1 if not found
806+
coin_item_key = door_item_to_key.get(options.coin_door_item.value)
807+
settings_dict["coin_door_item_count"] = options.helm_door_item_count.value.get(coin_item_key, 1) if coin_item_key else 1
808+
736809
if hasattr(multiworld, "generation_is_fake"):
737810
if hasattr(multiworld, "re_gen_passthrough"):
738811
if "Donkey Kong 64" in multiworld.re_gen_passthrough:
@@ -751,10 +824,8 @@ def handle_fake_generation_settings(settings: Settings, multiworld) -> None:
751824

752825
# Switch logic lifted out of level shuffle due to static levels for UT
753826
if settings.alter_switch_allocation:
754-
allocation = [1, 1, 1, 1, 2, 2, 3, 3]
755827
for x in range(8):
756-
level = settings.level_order[x + 1]
757-
settings.switch_allocation[level] = allocation[x]
828+
settings.switch_allocation[x] = passthrough["SlamLevels"][x]
758829

759830
settings.starting_kong_list = passthrough["StartingKongs"]
760831
settings.starting_kong = settings.starting_kong_list[0] # fake a starting kong so that we don't force a different kong

archipelago/Goals.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
# Goal mapping for wincon determination
1111
GOAL_MAPPING = {
12-
Goal.option_beat_k_rool: WinConditionComplex.beat_krool,
12+
Goal.option_acquire_keys_3_and_8: WinConditionComplex.get_keys_3_and_8,
1313
Goal.option_acquire_key_8: WinConditionComplex.get_key8,
1414
Goal.option_kremling_kapture: WinConditionComplex.krem_kapture,
1515
Goal.option_dk_rap: WinConditionComplex.dk_rap_items,
@@ -70,6 +70,7 @@ def pp_wincon(win_condition_item, wc_count=0):
7070
win_con_name_table = {
7171
WinConditionComplex.beat_krool: "Beat K. Rool",
7272
WinConditionComplex.get_key8: "Acquire Key 8",
73+
WinConditionComplex.get_keys_3_and_8: "Acquire Keys 3 and 8",
7374
WinConditionComplex.krem_kapture: "Kremling Kapture",
7475
WinConditionComplex.dk_rap_items: "Complete the Rap",
7576
WinConditionComplex.req_bean: "Acquire the Bean",

archipelago/Hints.py

Lines changed: 105 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
from randomizer.Enums.Maps import Maps
66
from randomizer.Enums.Kongs import Kongs
77
from randomizer.Enums.Levels import Levels
8+
from randomizer.Enums.Transitions import Transitions
9+
from randomizer.Enums.Types import BarrierItems
10+
from randomizer.Lists.ShufflableExit import ShufflableExits
811
from randomizer.Lists.WrinklyHints import UpdateHint
912

1013
boss_names = {
@@ -139,6 +142,21 @@ def CompileArchipelagoHints(world, hint_data: list):
139142
hint_location_pairs.append((krool_hint, None)) # K. Rool hints don't have a specific location
140143
hints_remaining -= 1
141144

145+
# Isles to Helm transition hint (only if loading zone rando is enabled and Helm is shuffled)
146+
if world.options.loading_zone_rando != 0 and world.options.shuffle_helm_level_order:
147+
isles_to_helm_hint = parseIslesToHelmHint(world)
148+
compiled_hints.append(isles_to_helm_hint)
149+
hint_location_pairs.append((isles_to_helm_hint, None)) # Transition hints don't have a specific location
150+
hints_remaining -= 1
151+
152+
# Helm Door hints (only if one or both doors were set to random)
153+
if world.options.crown_door_item.value in [13, 2, 14] or world.options.coin_door_item.value in [13, 2, 14]:
154+
helm_door_hints = parseHelmDoorHint(world)
155+
for helm_door_hint in helm_door_hints:
156+
compiled_hints.append(helm_door_hint)
157+
hint_location_pairs.append((helm_door_hint, None)) # Helm door hints don't have a specific location
158+
hints_remaining -= 1
159+
142160
# Kong hints
143161
for kong_loc in kong_locations:
144162
kong_hint = parseKongHint(world, kong_loc)
@@ -194,7 +212,6 @@ def CompileArchipelagoHints(world, hint_data: list):
194212
# Sanity check that 35 hints were placed
195213
if hints_remaining > 0:
196214
# This part of the code should not be reached.
197-
print("Not enough hints. Please wait. stage_generate_output might be crashing.")
198215
while hints_remaining > 0:
199216
filler_hint = "no hint, sorry...".upper()
200217
compiled_hints.append(filler_hint)
@@ -319,3 +336,90 @@ def parseKRoolHint(world):
319336
if letter not in "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!?:;'S-()% \x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d":
320337
text = text.replace(letter, " ")
321338
return text
339+
340+
341+
def parseIslesToHelmHint(world):
342+
"""Write a hint for finding the transition that leads to Hideout Helm."""
343+
text = ""
344+
# Check if entrance randomization is enabled
345+
if hasattr(world.spoiler, "shuffled_exit_data") and world.spoiler.shuffled_exit_data:
346+
# Find which transition leads to Hideout Helm
347+
source_transition = None
348+
for transition, shuffled_back in world.spoiler.shuffled_exit_data.items():
349+
# Check if this transition's destination is Hideout Helm
350+
if shuffled_back.reverse == Transitions.HelmToIsles:
351+
source_transition = transition
352+
break
353+
354+
if source_transition and source_transition in ShufflableExits:
355+
pathToHint = source_transition
356+
# Don't hint entrances from connector rooms, follow the reverse pathway back until finding a non-connector
357+
while ShufflableExits[pathToHint].category is None:
358+
originPaths = [x for x, back in world.spoiler.shuffled_exit_data.items() if back.reverse == pathToHint]
359+
# In a few cases, there is no reverse loading zone. In this case we must keep the original path to hint
360+
if len(originPaths) == 0:
361+
break
362+
pathToHint = originPaths[0]
363+
364+
source_name = ShufflableExits[pathToHint].name
365+
text = f"Looking for \x04Hideout Helm\x04? Try going from \x08{source_name}\x08.".upper()
366+
367+
for letter in text:
368+
if letter not in "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!?:;'S-()% \x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d":
369+
text = text.replace(letter, " ")
370+
return text
371+
372+
373+
def parseHelmDoorHint(world):
374+
"""Write hints for the Helm door requirements if they're randomized."""
375+
# Map BarrierItems to display names (singular)
376+
item_names_singular = {
377+
BarrierItems.GoldenBanana: "Golden Banana",
378+
BarrierItems.Blueprint: "Blueprint",
379+
BarrierItems.CompanyCoin: "Special Coin",
380+
BarrierItems.Key: "Key",
381+
BarrierItems.Medal: "Medal",
382+
BarrierItems.Crown: "Crown",
383+
BarrierItems.Fairy: "Fairy",
384+
BarrierItems.RainbowCoin: "Rainbow Coin",
385+
BarrierItems.Bean: "Bean",
386+
BarrierItems.Pearl: "Pearl",
387+
}
388+
389+
crown_door_item = world.spoiler.settings.crown_door_item
390+
crown_door_count = world.spoiler.settings.crown_door_item_count
391+
coin_door_item = world.spoiler.settings.coin_door_item
392+
coin_door_count = world.spoiler.settings.coin_door_item_count
393+
394+
crown_door_randomized = world.options.crown_door_item.value in [13, 2, 14] # easy, medium, hard random
395+
coin_door_randomized = world.options.coin_door_item.value in [13, 2, 14]
396+
397+
hints = []
398+
399+
if crown_door_randomized:
400+
crown_name = item_names_singular.get(crown_door_item, "item")
401+
if crown_door_count > 1:
402+
if crown_door_item == BarrierItems.Fairy:
403+
crown_name = "Fairies"
404+
else:
405+
crown_name = crown_name + "s"
406+
text = f"There lies a \x05gate in Hideout Helm\x05 that requires \x04{crown_door_count} {crown_name}\x04.".upper()
407+
for letter in text:
408+
if letter not in "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!?:;'S-()% \x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d":
409+
text = text.replace(letter, " ")
410+
hints.append(text)
411+
412+
if coin_door_randomized:
413+
coin_name = item_names_singular.get(coin_door_item, "item")
414+
if coin_door_count > 1:
415+
if coin_door_item == BarrierItems.Fairy:
416+
coin_name = "Fairies"
417+
else:
418+
coin_name = coin_name + "s"
419+
coin_text = f"There lies a \x05gate in Hideout Helm\x05 that requires \x04{coin_door_count} {coin_name}\x04.".upper()
420+
for letter in coin_text:
421+
if letter not in "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!?:;'S-()% \x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d":
422+
coin_text = coin_text.replace(letter, " ")
423+
hints.append(coin_text)
424+
425+
return hints

0 commit comments

Comments
 (0)