|
| 1 | +"""Hints for DK64R Archipelago.""" |
| 2 | + |
| 3 | +# from worlds.dk64 import DK64World |
| 4 | +from randomizer.CompileHints import UpdateSpoilerHintList, getRandomHintLocation, replaceKongNameWithKrusha |
| 5 | +from randomizer.Enums.Maps import Maps |
| 6 | +from randomizer.Lists.WrinklyHints import ClearHintMessages |
| 7 | +from randomizer.Patching.UpdateHints import UpdateHint |
| 8 | + |
| 9 | +boss_names = { |
| 10 | + Maps.JapesBoss: "Army Dillo 1", |
| 11 | + Maps.AztecBoss: "Dogadon 1", |
| 12 | + Maps.FactoryBoss: "Mad Jack", |
| 13 | + Maps.GalleonBoss: "Pufftoss", |
| 14 | + Maps.FungiBoss: "Dogadon 2", |
| 15 | + Maps.CavesBoss: "Army Dillo 2", |
| 16 | + Maps.CastleBoss: "King Kut Out", |
| 17 | + Maps.KroolDonkeyPhase: "DK Phase", |
| 18 | + Maps.KroolDiddyPhase: "Diddy Phase", |
| 19 | + Maps.KroolLankyPhase: "Lanky Phase", |
| 20 | + Maps.KroolTinyPhase: "Tiny Phase", |
| 21 | + Maps.KroolChunkyPhase: "Chunky Phase", |
| 22 | +} |
| 23 | +boss_colors = { |
| 24 | + Maps.JapesBoss: "\x08", |
| 25 | + Maps.AztecBoss: "\x04", |
| 26 | + Maps.FactoryBoss: "\x0c", |
| 27 | + Maps.GalleonBoss: "\x06", |
| 28 | + Maps.FungiBoss: "\x07", |
| 29 | + Maps.CavesBoss: "\x0a", |
| 30 | + Maps.CastleBoss: "\x09", |
| 31 | + Maps.KroolDonkeyPhase: "\x04", |
| 32 | + Maps.KroolDiddyPhase: "\x05", |
| 33 | + Maps.KroolLankyPhase: "\x06", |
| 34 | + Maps.KroolTinyPhase: "\x07", |
| 35 | + Maps.KroolChunkyPhase: "\x08", |
| 36 | +} |
| 37 | + |
| 38 | + |
| 39 | +def CompileArchipelagoHints(world, hint_data: list): |
| 40 | + """Insert Archipelago hints.""" |
| 41 | + replaceKongNameWithKrusha(world.spoiler) |
| 42 | + ClearHintMessages() |
| 43 | + # All input lists are in the form of [loc] |
| 44 | + # Settings |
| 45 | + woth_count = 10 |
| 46 | + major_count = 7 |
| 47 | + deep_count = 8 |
| 48 | + |
| 49 | + # Variables |
| 50 | + hints_remaining = 35 # Keep count how many hints we placed |
| 51 | + hints = [] # The hints we compile |
| 52 | + woth_duplicates = [] |
| 53 | + kong_locations = hint_data["kong"] |
| 54 | + key_locations = hint_data["key"] |
| 55 | + woth_locations = hint_data["woth"] |
| 56 | + major_locations = hint_data["major"] |
| 57 | + deep_locations = hint_data["deep"] |
| 58 | + already_hinted = kong_locations + key_locations |
| 59 | + |
| 60 | + # Creating the hints |
| 61 | + |
| 62 | + # K. Rool order hint |
| 63 | + hints.append(parseKRoolHint(world)) |
| 64 | + hints_remaining -= 1 |
| 65 | + |
| 66 | + # Kong hints |
| 67 | + for kong_loc in kong_locations: |
| 68 | + hints.append(parseKongHint(world, kong_loc)) |
| 69 | + hints_remaining -= 1 |
| 70 | + |
| 71 | + # Key hints |
| 72 | + for key_loc in key_locations: |
| 73 | + hints.append(parseKeyHint(world, key_loc)) |
| 74 | + hints_remaining -= 1 |
| 75 | + |
| 76 | + # Woth hints |
| 77 | + woth_locations = [x for x in woth_locations if x not in already_hinted] |
| 78 | + woth_count = min(min(len(woth_locations), woth_count), hints_remaining) |
| 79 | + woth_locations = world.spoiler.settings.random.sample(woth_locations, woth_count) |
| 80 | + for woth_loc in woth_locations: |
| 81 | + already_hinted.append(woth_loc) |
| 82 | + this_hint = parseWothHint(world, woth_loc) |
| 83 | + hints.append(this_hint) |
| 84 | + woth_duplicates.append(this_hint) |
| 85 | + hints_remaining -= 1 |
| 86 | + |
| 87 | + # Major item hints |
| 88 | + major_locations = [x for x in major_locations if x not in already_hinted] |
| 89 | + major_count = min(min(len(major_locations), major_count), hints_remaining) |
| 90 | + major_locations = world.spoiler.settings.random.sample(major_locations, major_count) |
| 91 | + for major_loc in major_locations: |
| 92 | + hints.append(parseMajorItemHint(world, major_loc)) |
| 93 | + hints_remaining -= 1 |
| 94 | + |
| 95 | + # Deep check hints |
| 96 | + deep_count = min(min(len(deep_locations), deep_count), hints_remaining) |
| 97 | + deep_locations = world.spoiler.settings.random.sample(deep_locations, deep_count) |
| 98 | + for deep_loc in deep_locations: |
| 99 | + hints.append(parseDeepHint(world, deep_loc)) |
| 100 | + hints_remaining -= 1 |
| 101 | + |
| 102 | + # Woth hint duplicates as needed |
| 103 | + while hints_remaining > 0 and len(woth_duplicates) > 0: |
| 104 | + hints.append(woth_duplicates.pop()) |
| 105 | + hints_remaining -= 1 |
| 106 | + |
| 107 | + # Sanity check that 35 hints were placed |
| 108 | + if hints_remaining > 0: |
| 109 | + # This part of the code should not be reached. |
| 110 | + print("Not enough hints. Please wait. stage_generate_output might be crashing.") |
| 111 | + while hints_remaining > 0: |
| 112 | + hints.append("no hint, sorry...".upper()) |
| 113 | + hints_remaining -= 1 |
| 114 | + |
| 115 | + for hint in hints: |
| 116 | + hint_location = getRandomHintLocation(random=world.spoiler.settings.random) |
| 117 | + UpdateHint(hint_location, hint) |
| 118 | + UpdateSpoilerHintList(world.spoiler) |
| 119 | + |
| 120 | + |
| 121 | +def parseKeyHint(world, location): |
| 122 | + """Write a key hint for the given location.""" |
| 123 | + text = "" |
| 124 | + if location.player != world.player: |
| 125 | + text = f"\x07{location.item.name[:40]}\x07 is hidden away for \x05{world.multiworld.get_player_name(location.player)}\x05 to find in \x0d{location.name[:80]}\x0d.".upper() |
| 126 | + else: |
| 127 | + text = f"\x07{location.item.name[:40]}\x07 is hidden away in \x0d{location.name}\x0d.".upper() |
| 128 | + for letter in text: |
| 129 | + if letter not in "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!?:;'S-()% \x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d": |
| 130 | + text = text.replace(letter, " ") |
| 131 | + return text |
| 132 | + |
| 133 | + |
| 134 | +def parseKongHint(world, location): |
| 135 | + """Write a kong hint for the given location.""" |
| 136 | + text = "" |
| 137 | + if location.player != world.player: |
| 138 | + text = f"\x07{location.item.name[:40]}\x07 is to be found by \x05{world.multiworld.get_player_name(location.player)}\x05 in \x0d{location.name[:80]}\x0d.".upper() |
| 139 | + else: |
| 140 | + text = f"\x07{location.item.name[:40]}\x07 is held by your local villain in \x0d{location.name}\x0d.".upper() |
| 141 | + for letter in text: |
| 142 | + if letter not in "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!?:;'S-()% \x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d": |
| 143 | + text = text.replace(letter, " ") |
| 144 | + return text |
| 145 | + |
| 146 | + |
| 147 | +def parseWothHint(world, location): |
| 148 | + """Write a woth item hint for the given location.""" |
| 149 | + text = "" |
| 150 | + if location.player != world.player: |
| 151 | + text = f"\x05{world.multiworld.get_player_name(location.player)}\x05 \x0d{location.name[:80]}\x0d is on the \x04Way of the Hoard\x04.".upper() |
| 152 | + else: |
| 153 | + text = f"Your \x0d{location.name}\x0d is on the \x04Way of the Hoard\x04.".upper() |
| 154 | + for letter in text: |
| 155 | + if letter not in "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!?:;'S-()% \x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d": |
| 156 | + text = text.replace(letter, " ") |
| 157 | + return text |
| 158 | + |
| 159 | + |
| 160 | +def parseMajorItemHint(world, location): |
| 161 | + """Write a major item hint for the given location.""" |
| 162 | + text = "" |
| 163 | + if location.player != world.player: |
| 164 | + text = f"Looking for \x07{location.item.name[:40]}\x07? Ask \x05{world.multiworld.get_player_name(location.player)}\x05 to try looking in \x0d{location.name[:80]}\x0d.".upper() |
| 165 | + else: |
| 166 | + text = f"Looking for \x07{location.item.name[:40]}\x07? Try looking in \x0d{location.name}\x0d.".upper() |
| 167 | + for letter in text: |
| 168 | + if letter not in "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!?:;'S-()% \x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d": |
| 169 | + text = text.replace(letter, " ") |
| 170 | + return text |
| 171 | + |
| 172 | + |
| 173 | +def parseDeepHint(world, location): |
| 174 | + """Write a deep item hint for the given location.""" |
| 175 | + text = "" |
| 176 | + if location.item.player != world.player: |
| 177 | + text = f"\x0d{location.name}\x0d has \x05{world.multiworld.get_player_name(location.item.player)}'s\x05 \x07{location.item.name[:40]}\x07.".upper() |
| 178 | + else: |
| 179 | + text = f"\x0d{location.name}\x0d has your \x07{location.item.name}\x07".upper() |
| 180 | + for letter in text: |
| 181 | + if letter not in "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!?:;'S-()% \x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d": |
| 182 | + text = text.replace(letter, " ") |
| 183 | + return text |
| 184 | + |
| 185 | + |
| 186 | +def parseKRoolHint(world): |
| 187 | + """Write the K. Rool order hint for the given location.""" |
| 188 | + text = "" |
| 189 | + kong_krool_order = [boss_colors[map_id] + boss_names[map_id] + boss_colors[map_id] for map_id in world.spoiler.settings.krool_order] |
| 190 | + kong_krool_text = ", then ".join(kong_krool_order) |
| 191 | + text = f"\x08The final battle\x08 will be against {kong_krool_text}.".upper() |
| 192 | + for letter in text: |
| 193 | + if letter not in "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!?:;'S-()% \x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d": |
| 194 | + text = text.replace(letter, " ") |
| 195 | + return text |
0 commit comments