mirror of
https://github.com/MarioSpore/Grinch-AP.git
synced 2025-10-21 20:21:32 -06:00
Muse Dash: Add New Game (#1723)
* Alpha 1 Muse dash stuff. * Add in an option to limit to only base game songs. * Make all items progression instead of progression_skip_balancing. * Add in extra_goal_song_items to help make runs less about completing every song. * Change ID range to be in a more open area, and add some comments. * Add in Streamer Mode and difficulty range options. Rearrange data files so its easier to get all data at once. * Fix generation issues. * Fix up the maximum and remove old option. * Remove empty items and the option to make filler songs empty. * Support emerald hunt mode. Make difficulties an option rather than 2 sliders. * Fix DLC Song option being inverted. * Fix item counting being broken if there was more than 1 world. * Make compatible with .apworld specification. * Make All item names ASCII compatible. * Add in the additional_item_percentage option. * Add a test to ensure the item names are within the normal ascii range. * Add in death link. * Remove the album from the item name. Not really needed anymore. * Add the 2 budget is burning albums under the free songs heading. Adds a couple more songs without dlc. * Sanitise Album names. * Added the grade needed choice. * Update songs to v3.1.0 * Adjust difficulty ranges. Add Expert and Master. * Fix setup_en.md being out of date. * Add a manual override. * Add testing for diff ranges. Fix bugs introduced there. Limit option to 11 to not generate an impossible seed. * Remove regions from Muse Dash. * Some Oops... * Attempt to make tests happy. * Remove supports weighting false to stop webhost test failing. * Adjusted settings * Adjust music sheets to use percentages. Various cleanups. * Fixes to new code. * Add Ola Dash Album. Add support for overriding song difficulty. Other stylisation changes. * Attempt fix tests. * Ooops missed one. * flake8 suggestions. * Remove FM 17314 SUGAR RADIO as that song is a bit weird. * Update document pages. * Add trap support * Lower additional song count by 10. * Tests broke on my end. Using github to test this. * Looks like I was accidentally adding ~. * Fix the one song that crashes OoT hint generation * Various documentation changes. * Website documents fixup. * Doc updates part 2. * Oops. Doc updates part 3. * Add Muse Dash to the apworld list. * Add trailing comma. * Add a couple plando options. * Set data_version to 1. * Add in some handling incase someone decides a song is both starter and included. * Remove brackets around ifs. * Oops. Accidentally removed a necessary bracket. * Fix filtering crash due to me mixing up c# and python .remove(). * Add Happy Otaku Pack Vol.17. Also increment data version. * Update links to melon loader to be the latest. * Clean up song selection code by shuffling once then popping. * Add UID to the Data text file, so the same file can be used client and server. * Increment Data Version because some names have changed. * Correct some names. * Update data to v3.4.0 (Addition of Muse Radio FM104) * Add support for SFX traps. Adjusted how traps were setup a bit. * Update the docs to include a troubleshooting section. * Small fixes. * Remove unnecessary brackets. * Add .net downloads to docs. * Avoid failing generation if strict difficulty settings are applied with no dlc songs and streamer mode. * Forgot to add the worst starting song count. * Make minimum song count be Starting Songs + 11 instead of Starting Songs * 2 + 1. * Fix up several issues where song count could mismatch the requested amount. * Add a test to ensure world size doesn't grow. * Fix some oversights. * Remove unnecessary brackets. * Fix up passing the tuple out when just the key would suffice. * Adjust typing based on Phar's suggestions. * Apply the rest of Phar's suggestions with minor tweaks to other parts to suit suggestions. * Adjust some more stuff to fit 120 characters. * Some more pep8 stuff and fix tests. * Some pep8 in tests.
This commit is contained in:
136
worlds/musedash/MuseDashCollection.py
Normal file
136
worlds/musedash/MuseDashCollection.py
Normal file
@@ -0,0 +1,136 @@
|
||||
from .Items import SongData, AlbumData
|
||||
from typing import Dict, List, Optional
|
||||
|
||||
|
||||
def load_text_file(name: str) -> str:
|
||||
import pkgutil
|
||||
return pkgutil.get_data(__name__, name).decode()
|
||||
|
||||
|
||||
class MuseDashCollections:
|
||||
"""Contains all the data of Muse Dash, loaded from MuseDashData.txt."""
|
||||
|
||||
MUSIC_SHEET_CODE: int
|
||||
|
||||
FREE_ALBUMS = [
|
||||
"Default Music",
|
||||
"Budget Is Burning: Nano Core",
|
||||
"Budget is Burning Vol.1"
|
||||
]
|
||||
|
||||
DIFF_OVERRIDES = [
|
||||
"MuseDash ka nanika hi",
|
||||
"Rush-Hour",
|
||||
"Find this Month's Featured Playlist",
|
||||
"PeroPero in the Universe",
|
||||
"CHAOS Glitch"
|
||||
]
|
||||
|
||||
album_items: Dict[str, AlbumData] = {}
|
||||
album_locations: Dict[str, int] = {}
|
||||
song_items: Dict[str, SongData] = {}
|
||||
song_locations: Dict[str, int] = {}
|
||||
|
||||
vfx_trap_items: Dict[str, int] = {
|
||||
"Bad Apple Trap": 1,
|
||||
"Pixelate Trap": 2,
|
||||
"Random Wave Trap": 3,
|
||||
"Shadow Edge Trap": 4,
|
||||
"Chromatic Aberration Trap": 5,
|
||||
"Background Freeze Trap": 6,
|
||||
"Gray Scale Trap": 7,
|
||||
}
|
||||
|
||||
sfx_trap_items: Dict[str, int] = {
|
||||
"Nyaa SFX Trap": 8,
|
||||
"Error SFX Trap": 9,
|
||||
}
|
||||
|
||||
def __init__(self, start_item_id: int, items_per_location: int):
|
||||
self.MUSIC_SHEET_CODE = start_item_id
|
||||
|
||||
self.vfx_trap_items = {k: (v + start_item_id) for (k, v) in self.vfx_trap_items.items()}
|
||||
self.sfx_trap_items = {k: (v + start_item_id) for (k, v) in self.sfx_trap_items.items()}
|
||||
|
||||
item_id_index = start_item_id + 50
|
||||
location_id_index = start_item_id
|
||||
|
||||
full_file = load_text_file("MuseDashData.txt")
|
||||
|
||||
for line in full_file.splitlines():
|
||||
line = line.strip()
|
||||
sections = line.split("|")
|
||||
|
||||
if sections[2] not in self.album_items:
|
||||
self.album_items[sections[2]] = AlbumData(item_id_index)
|
||||
item_id_index += 1
|
||||
|
||||
# Data is in the format 'Song|UID|Album|StreamerMode|EasyDiff|HardDiff|MasterDiff|SecretDiff'
|
||||
song_name = sections[0]
|
||||
# [1] is used in the client copy to make sure item id's match.
|
||||
song_is_free = sections[2] in self.FREE_ALBUMS
|
||||
steamer_mode = sections[3] == "True"
|
||||
|
||||
if song_name in self.DIFF_OVERRIDES:
|
||||
# Note: These difficulties may not actually be representative of these songs.
|
||||
# The game does not provide these difficulties so they have to be filled in.
|
||||
diff_of_easy = 4
|
||||
diff_of_hard = 7
|
||||
diff_of_master = 10
|
||||
else:
|
||||
diff_of_easy = self.parse_song_difficulty(sections[4])
|
||||
diff_of_hard = self.parse_song_difficulty(sections[5])
|
||||
diff_of_master = self.parse_song_difficulty(sections[6])
|
||||
|
||||
self.song_items[song_name] = SongData(item_id_index, song_is_free, steamer_mode,
|
||||
diff_of_easy, diff_of_hard, diff_of_master)
|
||||
item_id_index += 1
|
||||
|
||||
for name in self.album_items.keys():
|
||||
for i in range(0, items_per_location):
|
||||
new_name = f"{name}-{i}"
|
||||
self.album_locations[new_name] = location_id_index
|
||||
location_id_index += 1
|
||||
|
||||
for name in self.song_items.keys():
|
||||
for i in range(0, items_per_location):
|
||||
new_name = f"{name}-{i}"
|
||||
self.song_locations[new_name] = location_id_index
|
||||
location_id_index += 1
|
||||
|
||||
def get_songs_with_settings(self, dlc_songs: bool, streamer_mode_active: bool,
|
||||
diff_lower: int, diff_higher: int) -> List[str]:
|
||||
"""Gets a list of all songs that match the filter settings. Difficulty thresholds are inclusive."""
|
||||
filtered_list = []
|
||||
|
||||
for songKey, songData in self.song_items.items():
|
||||
if not dlc_songs and not songData.song_is_free:
|
||||
continue
|
||||
|
||||
if streamer_mode_active and not songData.streamer_mode:
|
||||
continue
|
||||
|
||||
if songData.easy is not None and diff_lower <= songData.easy <= diff_higher:
|
||||
filtered_list.append(songKey)
|
||||
continue
|
||||
|
||||
if songData.hard is not None and diff_lower <= songData.hard <= diff_higher:
|
||||
filtered_list.append(songKey)
|
||||
continue
|
||||
|
||||
if songData.master is not None and diff_lower <= songData.master <= diff_higher:
|
||||
filtered_list.append(songKey)
|
||||
continue
|
||||
|
||||
return filtered_list
|
||||
|
||||
def parse_song_difficulty(self, difficulty: str) -> Optional[int]:
|
||||
"""Attempts to parse the song difficulty."""
|
||||
if len(difficulty) <= 0 or difficulty == "?" or difficulty == "¿":
|
||||
return None
|
||||
|
||||
# Curse the 2023 april fools update. Used on 3rd Avenue.
|
||||
if difficulty == "〇":
|
||||
return 10
|
||||
|
||||
return int(difficulty)
|
||||
Reference in New Issue
Block a user