Merge branch 'main' into tunc-logic-rules-redux

This commit is contained in:
Scipio Wright
2024-06-29 19:27:39 -04:00
committed by GitHub
12 changed files with 77 additions and 31 deletions

View File

@@ -23,7 +23,7 @@ if __name__ == "__main__":
from MultiServer import CommandProcessor
from NetUtils import (Endpoint, decode, NetworkItem, encode, JSONtoTextParser, ClientStatus, Permission, NetworkSlot,
RawJSONtoTextParser, add_json_text, add_json_location, add_json_item, JSONTypes)
RawJSONtoTextParser, add_json_text, add_json_location, add_json_item, JSONTypes, SlotType)
from Utils import Version, stream_input, async_start
from worlds import network_data_package, AutoWorldRegister
import os
@@ -862,7 +862,8 @@ async def process_server_cmd(ctx: CommonContext, args: dict):
ctx.team = args["team"]
ctx.slot = args["slot"]
# int keys get lost in JSON transfer
ctx.slot_info = {int(pid): data for pid, data in args["slot_info"].items()}
ctx.slot_info = {0: NetworkSlot("Archipelago", "Archipelago", SlotType.player)}
ctx.slot_info.update({int(pid): data for pid, data in args["slot_info"].items()})
ctx.hint_points = args.get("hint_points", 0)
ctx.consume_players_package(args["players"])
ctx.stored_data_notification_keys.add(f"_read_hints_{ctx.team}_{ctx.slot}")

View File

@@ -52,6 +52,7 @@ class TextShuffle(DefaultOffToggle):
[On] Shuffles all the text in the game
[Off] (default) doesn't shuffle them.
"""
display_name = "Text Shuffle"
class Rooster(DefaultOnToggle, LADXROption):
@@ -68,7 +69,8 @@ class Boomerang(Choice):
[Normal] requires Magnifying Lens to get the boomerang.
[Gift] The boomerang salesman will give you a random item, and the boomerang is shuffled.
"""
display_name = "Boomerang"
normal = 0
gift = 1
default = gift
@@ -113,6 +115,7 @@ class APTitleScreen(DefaultOnToggle):
class BossShuffle(Choice):
display_name = "Boss Shuffle"
none = 0
shuffle = 1
random = 2
@@ -120,6 +123,7 @@ class BossShuffle(Choice):
class DungeonItemShuffle(Choice):
display_name = "Dungeon Item Shuffle"
option_original_dungeon = 0
option_own_dungeons = 1
option_own_world = 2
@@ -291,6 +295,7 @@ class Bowwow(Choice):
[Normal] BowWow is in the item pool, but can be logically expected as a damage source.
[Swordless] The progressive swords are removed from the item pool.
"""
display_name = "BowWow"
normal = 0
swordless = 1
default = normal
@@ -466,6 +471,7 @@ class Music(Choice, LADXROption):
[Shuffled] Shuffled Music
[Off] No music
"""
display_name = "Music"
ladxr_name = "music"
option_vanilla = 0
option_shuffled = 1
@@ -485,6 +491,7 @@ class WarpImprovements(DefaultOffToggle):
[On] Adds remake style warp screen to the game. Choose your warp destination on the map after jumping in a portal and press B to select.
[Off] No change
"""
display_name = "Warp Improvements"
class AdditionalWarpPoints(DefaultOffToggle):
@@ -492,6 +499,7 @@ class AdditionalWarpPoints(DefaultOffToggle):
[On] (requires warp improvements) Adds a warp point at Crazy Tracy's house (the Mambo teleport spot) and Eagle's Tower
[Off] No change
"""
display_name = "Additional Warp Points"
ladx_option_groups = [
OptionGroup("Goal Options", [

View File

@@ -557,3 +557,13 @@ Tsukuyomi Ni Naru|74-2|CHUNITHM COURSE MUSE|False|5|7|9|
The wheel to the right|74-3|CHUNITHM COURSE MUSE|True|5|7|9|11
Climax|74-4|CHUNITHM COURSE MUSE|True|4|8|11|11
Spider's Thread|74-5|CHUNITHM COURSE MUSE|True|5|8|10|12
HIT ME UP|43-54|MD Plus Project|True|4|6|8|
Test Me feat. Uyeon|43-55|MD Plus Project|True|3|5|9|
Assault TAXI|43-56|MD Plus Project|True|4|7|10|
No|43-57|MD Plus Project|False|4|6|9|
Pop it|43-58|MD Plus Project|True|1|3|6|
HEARTBEAT! KyunKyun!|43-59|MD Plus Project|True|4|6|9|
SUPERHERO|75-0|Novice Rider Pack|False|2|4|7|
Highway_Summer|75-1|Novice Rider Pack|True|2|4|6|
Mx. Black Box|75-2|Novice Rider Pack|True|5|7|9|
Sweet Encounter|75-3|Novice Rider Pack|True|2|4|7|

View File

@@ -17,11 +17,12 @@
## Installing the Archipelago mod to Muse Dash
1. Download [MelonLoader.Installer.exe](https://github.com/LavaGang/MelonLoader/releases/latest) and run it.
2. Choose the automated tab, click the select button and browse to `MuseDash.exe`. Then click install.
2. Choose the automated tab, click the select button and browse to `MuseDash.exe`.
- You can find the folder in steam by finding the game in your library, right clicking it and choosing *Manage→Browse Local Files*.
- If you click the bar at the top telling you your current folder, this will give you a path you can copy. If you paste that into the window popped up by **MelonLoader**, it will automatically go to the same folder.
3. Run the game once, and wait until you get to the Muse Dash start screen before exiting.
4. Download the latest [Muse Dash Archipelago Mod](https://github.com/DeamonHunter/ArchipelagoMuseDash/releases/latest) and then extract that into the newly created `/Mods/` folder in MuseDash's install location.
3. Uncheck "Latest" and select v0.6.1. Then click install.
4. Run the game once, and wait until you get to the Muse Dash start screen before exiting.
5. Download the latest [Muse Dash Archipelago Mod](https://github.com/DeamonHunter/ArchipelagoMuseDash/releases/latest) and then extract that into the newly created `/Mods/` folder in MuseDash's install location.
- All files must be under the `/Mods/` folder and not within a sub folder inside of `/Mods/`
If you've successfully installed everything, a button will appear in the bottom right which will allow you to log into an Archipelago server.

View File

@@ -17,11 +17,12 @@
## Instalar el mod de Archipelago en Muse Dash
1. Descarga [MelonLoader.Installer.exe](https://github.com/LavaGang/MelonLoader/releases/latest) y ejecutalo.
2. Elije la pestaña "automated", haz clic en el botón "select" y busca tu `MuseDash.exe`. Luego haz clic en "install".
2. Elije la pestaña "automated", haz clic en el botón "select" y busca tu `MuseDash.exe`.
- Puedes encontrar la carpeta en Steam buscando el juego en tu biblioteca, haciendo clic derecho sobre el y elegir *Administrar→Ver archivos locales*.
- Si haces clic en la barra superior que te indica la carpeta en la que estas, te dará la dirección de ésta para que puedas copiarla. Al pegar esa dirección en la ventana que **MelonLoader** abre, irá automaticamente a esa carpeta.
3. Ejecuta el juego una vez, y espera hasta que aparezca la pantalla de inicio de Muse Dash antes de cerrarlo.
4. Descarga la última version de [Muse Dash Archipelago Mod](https://github.com/DeamonHunter/ArchipelagoMuseDash/releases/latest) y extraelo en la nueva carpeta creada llamada `/Mods/`, localizada en la carpeta de instalación de Muse Dash.
3. Desmarca "Latest" y selecciona v0.6.1. Luego haz clic en "install".
4. Ejecuta el juego una vez, y espera hasta que aparezca la pantalla de inicio de Muse Dash antes de cerrarlo.
5. Descarga la última version de [Muse Dash Archipelago Mod](https://github.com/DeamonHunter/ArchipelagoMuseDash/releases/latest) y extraelo en la nueva carpeta creada llamada `/Mods/`, localizada en la carpeta de instalación de Muse Dash.
- Todos los archivos deben ir directamente en la carpeta `/Mods/`, y NO en una subcarpeta dentro de la carpeta `/Mods/`
Si todo fue instalado correctamente, un botón aparecerá en la parte inferior derecha del juego una vez abierto, que te permitirá conectarte al servidor de Archipelago.

View File

@@ -173,6 +173,15 @@ class OOTWorld(World):
"Adult Trade Item": {"Pocket Egg", "Pocket Cucco", "Cojiro", "Odd Mushroom",
"Odd Potion", "Poachers Saw", "Broken Sword", "Prescription",
"Eyeball Frog", "Eyedrops", "Claim Check"},
"Keys": {"Small Key (Bottom of the Well)", "Small Key (Fire Temple)", "Small Key (Forest Temple)",
"Small Key (Ganons Castle)", "Small Key (Gerudo Training Ground)", "Small Key (Shadow Temple)",
"Small Key (Spirit Temple)", "Small Key (Thieves Hideout)", "Small Key (Water Temple)",
"Small Key Ring (Bottom of the Well)", "Small Key Ring (Fire Temple)",
"Small Key Ring (Forest Temple)", "Small Key Ring (Ganons Castle)",
"Small Key Ring (Gerudo Training Ground)", "Small Key Ring (Shadow Temple)",
"Small Key Ring (Spirit Temple)", "Small Key Ring (Thieves Hideout)", "Small Key Ring (Water Temple)",
"Boss Key (Fire Temple)", "Boss Key (Forest Temple)", "Boss Key (Ganons Castle)",
"Boss Key (Shadow Temple)", "Boss Key (Spirit Temple)", "Boss Key (Water Temple)"},
}
location_name_groups = build_location_name_groups()

View File

@@ -32,7 +32,13 @@ class FillerItemTypes(Choice):
option_both = 2
class IslandFrequencyLocations(Choice):
"""Sets where frequencies for story islands are located."""
"""Sets where frequencies for story islands are located.
Vanilla will keep frequencies in their vanilla, non-randomized locations.
Random On Island will randomize each frequency within its vanilla island, but will preserve island order.
Random Island Order will change the order you visit islands, but will preserve the vanilla location of each frequency unlock.
Random On Island Random Order will randomize the location containing the frequency on each island and randomize the order.
Progressive will randomize the frequencies to anywhere, but will always unlock the frequencies in vanilla order as the frequency items are received.
Anywhere will randomize the frequencies to anywhere, and frequencies will be received in any order."""
display_name = "Frequency locations"
option_vanilla = 0
option_random_on_island = 1
@@ -53,7 +59,8 @@ class IslandGenerationDistance(Choice):
default = 8
class ExpensiveResearch(Toggle):
"""Makes unlocking items in the Crafting Table consume the researched items."""
"""If No is selected, researching items and unlocking items in the Crafting Table works the same as vanilla Raft.
If Yes is selected, each unlock in the Crafting Table will require its own set of researched items in order to unlock it."""
display_name = "Expensive research"
class ProgressiveItems(DefaultOnToggle):
@@ -66,8 +73,7 @@ class BigIslandEarlyCrafting(Toggle):
display_name = "Early recipes behind big islands"
class PaddleboardMode(Toggle):
"""Sets later story islands to in logic without an Engine or Steering Wheel. May require lots of paddling. Not
recommended."""
"""Sets later story islands to be in logic without an Engine or Steering Wheel. May require lots of paddling."""
display_name = "Paddleboard Mode"
raft_options = {

View File

@@ -17,7 +17,7 @@
4. Open RML and click Play. If you've already installed it, the executable that was used to install RML ("RMLLauncher.exe" unless renamed) should be used to run RML. Raft should start after clicking Play.
5. Open the RML menu. This should open automatically when Raft first loads. If it does not, and you see RML information in the top center of the Raft main menu, press F9 to open it.
5. Open the RML menu. This should open automatically when Raft first loads. If it does not, and you see RML information in the top center of the Raft main menu, press F9 to open it. If you do not see RML information at the top, close Raft+RML, go back to Step 4 and run RML as administrator.
6. Navigate to the "Mod manager" tab in the left-hand menu.

View File

@@ -172,9 +172,6 @@ class TunicWorld(World):
return TunicItem(name, item_data.classification, self.item_name_to_id[name], self.player)
def create_items(self) -> None:
keys_behind_bosses = self.options.keys_behind_bosses
hexagon_quest = self.options.hexagon_quest
sword_progression = self.options.sword_progression
tunic_items: List[TunicItem] = []
self.slot_data_items = []
@@ -188,7 +185,7 @@ class TunicWorld(World):
if self.options.start_with_sword:
self.multiworld.push_precollected(self.create_item("Sword"))
if sword_progression:
if self.options.sword_progression:
items_to_create["Stick"] = 0
items_to_create["Sword"] = 0
else:
@@ -205,9 +202,9 @@ class TunicWorld(World):
self.slot_data_items.append(laurels)
items_to_create["Hero's Laurels"] = 0
if keys_behind_bosses:
if self.options.keys_behind_bosses:
for rgb_hexagon, location in hexagon_locations.items():
hex_item = self.create_item(gold_hexagon if hexagon_quest else rgb_hexagon)
hex_item = self.create_item(gold_hexagon if self.options.hexagon_quest else rgb_hexagon)
self.multiworld.get_location(location, self.player).place_locked_item(hex_item)
self.slot_data_items.append(hex_item)
items_to_create[rgb_hexagon] = 0
@@ -238,7 +235,7 @@ class TunicWorld(World):
ladder_count += 1
remove_filler(ladder_count)
if hexagon_quest:
if self.options.hexagon_quest:
# Calculate number of hexagons in item pool
hexagon_goal = self.options.hexagon_goal
extra_hexagons = self.options.extra_hexagon_percentage
@@ -254,6 +251,18 @@ class TunicWorld(World):
remove_filler(items_to_create[gold_hexagon])
for hero_relic in item_name_groups["Hero Relics"]:
relic_item = TunicItem(hero_relic, ItemClassification.useful, self.item_name_to_id[hero_relic], self.player)
tunic_items.append(relic_item)
items_to_create[hero_relic] = 0
if not self.options.ability_shuffling:
for page in item_name_groups["Abilities"]:
if items_to_create[page] > 0:
page_item = TunicItem(page, ItemClassification.useful, self.item_name_to_id[page], self.player)
tunic_items.append(page_item)
items_to_create[page] = 0
if self.options.maskless:
mask_item = TunicItem("Scavenger Mask", ItemClassification.useful, self.item_name_to_id["Scavenger Mask"], self.player)
tunic_items.append(mask_item)

View File

@@ -1006,7 +1006,8 @@ def set_er_region_rules(world: "TunicWorld", regions: Dict[str, Region], portal_
connecting_region=regions["Spirit Arena Victory"],
rule=lambda state: (state.has(gold_hexagon, player, world.options.hexagon_goal.value) if
world.options.hexagon_quest else
state.has_all({red_hexagon, green_hexagon, blue_hexagon, "Unseal the Heir"}, player)))
(state.has_all({red_hexagon, green_hexagon, blue_hexagon, "Unseal the Heir"}, player)
and state.has_group_unique("Hero Relics", player, 6))))
if options.ladder_storage:
def get_portal_info(portal_sd: str) -> Tuple[str, str]:

View File

@@ -64,12 +64,12 @@ item_table: Dict[str, TunicItemData] = {
"HP Offering": TunicItemData(ItemClassification.useful, 6, 48, "Offerings"),
"MP Offering": TunicItemData(ItemClassification.useful, 3, 49, "Offerings"),
"SP Offering": TunicItemData(ItemClassification.useful, 2, 50, "Offerings"),
"Hero Relic - ATT": TunicItemData(ItemClassification.useful, 1, 51, "Hero Relics"),
"Hero Relic - DEF": TunicItemData(ItemClassification.useful, 1, 52, "Hero Relics"),
"Hero Relic - HP": TunicItemData(ItemClassification.useful, 1, 53, "Hero Relics"),
"Hero Relic - MP": TunicItemData(ItemClassification.useful, 1, 54, "Hero Relics"),
"Hero Relic - POTION": TunicItemData(ItemClassification.useful, 1, 55, "Hero Relics"),
"Hero Relic - SP": TunicItemData(ItemClassification.useful, 1, 56, "Hero Relics"),
"Hero Relic - ATT": TunicItemData(ItemClassification.progression_skip_balancing, 1, 51, "Hero Relics"),
"Hero Relic - DEF": TunicItemData(ItemClassification.progression_skip_balancing, 1, 52, "Hero Relics"),
"Hero Relic - HP": TunicItemData(ItemClassification.progression_skip_balancing, 1, 53, "Hero Relics"),
"Hero Relic - MP": TunicItemData(ItemClassification.progression_skip_balancing, 1, 54, "Hero Relics"),
"Hero Relic - POTION": TunicItemData(ItemClassification.progression_skip_balancing, 1, 55, "Hero Relics"),
"Hero Relic - SP": TunicItemData(ItemClassification.progression_skip_balancing, 1, 56, "Hero Relics"),
"Orange Peril Ring": TunicItemData(ItemClassification.useful, 1, 57, "Cards"),
"Tincture": TunicItemData(ItemClassification.useful, 1, 58, "Cards"),
"Scavenger Mask": TunicItemData(ItemClassification.progression, 1, 59, "Cards"),
@@ -143,7 +143,6 @@ item_table: Dict[str, TunicItemData] = {
"Pages 50-51": TunicItemData(ItemClassification.useful, 1, 127, "Pages"),
"Pages 52-53 (Icebolt)": TunicItemData(ItemClassification.progression, 1, 128, "Pages"),
"Pages 54-55": TunicItemData(ItemClassification.useful, 1, 129, "Pages"),
"Ladders near Weathervane": TunicItemData(ItemClassification.progression, 0, 130, "Ladders"),
"Ladders near Overworld Checkpoint": TunicItemData(ItemClassification.progression, 0, 131, "Ladders"),
"Ladders near Patrol Cave": TunicItemData(ItemClassification.progression, 0, 132, "Ladders"),

View File

@@ -133,8 +133,9 @@ def set_region_rules(world: "TunicWorld") -> None:
or has_ice_grapple_logic(False, IceGrappling.option_medium, state, world)
multiworld.get_entrance("Overworld -> Spirit Arena", player).access_rule = \
lambda state: (state.has(gold_hexagon, player, options.hexagon_goal.value) if options.hexagon_quest.value
else state.has_all({red_hexagon, green_hexagon, blue_hexagon}, player)) and \
has_ability(prayer, state, world) and has_sword(state, player) and state.has_any({lantern, laurels}, player)
else state.has_all({red_hexagon, green_hexagon, blue_hexagon}, player) and state.has_group_unique("Hero Relics", player, 6)) and \
has_ability(state, player, prayer, options, ability_unlocks) and has_sword(state, player) and \
state.has_any({lantern, laurels}, player)
world.get_region("Quarry").connect(world.get_region("Rooted Ziggurat"),
rule=lambda state: has_ice_grapple_logic(True, IceGrappling.option_hard, state, world)