Merge branch 'ArchipelagoMW:main' into main

This commit is contained in:
Adrian Priestley
2025-01-13 00:50:55 +00:00
committed by GitHub
45 changed files with 1053 additions and 914 deletions

View File

@@ -444,7 +444,7 @@ class Context:
self.slot_info = decoded_obj["slot_info"]
self.games = {slot: slot_info.game for slot, slot_info in self.slot_info.items()}
self.groups = {slot: slot_info.group_members for slot, slot_info in self.slot_info.items()
self.groups = {slot: set(slot_info.group_members) for slot, slot_info in self.slot_info.items()
if slot_info.type == SlotType.group}
self.clients = {0: {}}

View File

@@ -10,7 +10,7 @@ import websockets
from Utils import ByValue, Version
class HintStatus(enum.IntEnum):
class HintStatus(ByValue, enum.IntEnum):
HINT_FOUND = 0
HINT_UNSPECIFIED = 1
HINT_NO_PRIORITY = 10

View File

@@ -137,7 +137,7 @@ class Option(typing.Generic[T], metaclass=AssembleOptions):
If this is False, the docstring is instead interpreted as plain text, and
displayed as-is on the WebHost with whitespace preserved.
If this is None, it inherits the value of `World.rich_text_options_doc`. For
If this is None, it inherits the value of `WebWorld.rich_text_options_doc`. For
backwards compatibility, this defaults to False, but worlds are encouraged to
set it to True and use reStructuredText for their Option documentation.

View File

@@ -152,8 +152,15 @@ def home_path(*path: str) -> str:
if hasattr(home_path, 'cached_path'):
pass
elif sys.platform.startswith('linux'):
home_path.cached_path = os.path.expanduser('~/Archipelago')
os.makedirs(home_path.cached_path, 0o700, exist_ok=True)
xdg_data_home = os.getenv('XDG_DATA_HOME', os.path.expanduser('~/.local/share'))
home_path.cached_path = xdg_data_home + '/Archipelago'
if not os.path.isdir(home_path.cached_path):
legacy_home_path = os.path.expanduser('~/Archipelago')
if os.path.isdir(legacy_home_path):
os.renames(legacy_home_path, home_path.cached_path)
os.symlink(home_path.cached_path, legacy_home_path)
else:
os.makedirs(home_path.cached_path, 0o700, exist_ok=True)
else:
# not implemented
home_path.cached_path = local_path() # this will generate the same exceptions we got previously

View File

@@ -147,3 +147,8 @@
rectangle: self.x-2, self.y-2, self.width+4, self.height+4
<ServerToolTip>:
pos_hint: {'center_y': 0.5, 'center_x': 0.5}
<AutocompleteHintInput>
size_hint_y: None
height: dp(30)
multiline: False
write_tab: False

View File

@@ -121,6 +121,14 @@ Response:
Expected Response Type: `HASH_RESPONSE`
- `MEMORY_SIZE`
Returns the size in bytes of the specified memory domain.
Expected Response Type: `MEMORY_SIZE_RESPONSE`
Additional Fields:
- `domain` (`string`): The name of the memory domain to check
- `GUARD`
Checks a section of memory against `expected_data`. If the bytes starting
at `address` do not match `expected_data`, the response will have `value`
@@ -216,6 +224,12 @@ Response:
Additional Fields:
- `value` (`string`): The returned hash
- `MEMORY_SIZE_RESPONSE`
Contains the size in bytes of the specified memory domain.
Additional Fields:
- `value` (`number`): The size of the domain in bytes
- `GUARD_RESPONSE`
The result of an attempted `GUARD` request.
@@ -376,6 +390,15 @@ request_handlers = {
return res
end,
["MEMORY_SIZE"] = function (req)
local res = {}
res["type"] = "MEMORY_SIZE_RESPONSE"
res["value"] = memory.getmemorydomainsize(req["domain"])
return res
end,
["GUARD"] = function (req)
local res = {}
local expected_data = base64.decode(req["expected_data"])
@@ -613,9 +636,11 @@ end)
if bizhawk_major < 2 or (bizhawk_major == 2 and bizhawk_minor < 7) then
print("Must use BizHawk 2.7.0 or newer")
elseif bizhawk_major > 2 or (bizhawk_major == 2 and bizhawk_minor > 9) then
print("Warning: This version of BizHawk is newer than this script. If it doesn't work, consider downgrading to 2.9.")
else
if bizhawk_major > 2 or (bizhawk_major == 2 and bizhawk_minor > 10) then
print("Warning: This version of BizHawk is newer than this script. If it doesn't work, consider downgrading to 2.10.")
end
if emu.getsystemid() == "NULL" then
print("No ROM is loaded. Please load a ROM.")
while emu.getsystemid() == "NULL" do

View File

@@ -95,7 +95,7 @@ user hovers over the yellow "(?)" icon, and included in the YAML templates gener
The WebHost can display Option documentation either as plain text with all whitespace preserved (other than the base
indentation), or as HTML generated from the standard Python [reStructuredText] format. Although plain text is the
default for backwards compatibility, world authors are encouraged to write their Option documentation as
reStructuredText and enable rich text rendering by setting `World.rich_text_options_doc = True`.
reStructuredText and enable rich text rendering by setting `WebWorld.rich_text_options_doc = True`.
[reStructuredText]: https://docutils.sourceforge.io/rst.html

65
kvui.py
View File

@@ -40,7 +40,7 @@ from kivy.core.image import ImageLoader, ImageLoaderBase, ImageData
from kivy.base import ExceptionHandler, ExceptionManager
from kivy.clock import Clock
from kivy.factory import Factory
from kivy.properties import BooleanProperty, ObjectProperty
from kivy.properties import BooleanProperty, ObjectProperty, NumericProperty
from kivy.metrics import dp
from kivy.effects.scroll import ScrollEffect
from kivy.uix.widget import Widget
@@ -64,6 +64,7 @@ from kivy.uix.recycleboxlayout import RecycleBoxLayout
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.animation import Animation
from kivy.uix.popup import Popup
from kivy.uix.dropdown import DropDown
from kivy.uix.image import AsyncImage
fade_in_animation = Animation(opacity=0, duration=0) + Animation(opacity=1, duration=0.25)
@@ -305,6 +306,50 @@ class SelectableLabel(RecycleDataViewBehavior, TooltipLabel):
""" Respond to the selection of items in the view. """
self.selected = is_selected
class AutocompleteHintInput(TextInput):
min_chars = NumericProperty(3)
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.dropdown = DropDown()
self.dropdown.bind(on_select=lambda instance, x: setattr(self, 'text', x))
self.bind(on_text_validate=self.on_message)
def on_message(self, instance):
App.get_running_app().commandprocessor("!hint "+instance.text)
def on_text(self, instance, value):
if len(value) >= self.min_chars:
self.dropdown.clear_widgets()
ctx: context_type = App.get_running_app().ctx
if not ctx.game:
return
item_names = ctx.item_names._game_store[ctx.game].values()
def on_press(button: Button):
split_text = MarkupLabel(text=button.text).markup
return self.dropdown.select("".join(text_frag for text_frag in split_text
if not text_frag.startswith("[")))
lowered = value.lower()
for item_name in item_names:
try:
index = item_name.lower().index(lowered)
except ValueError:
pass # substring not found
else:
text = escape_markup(item_name)
text = text[:index] + "[b]" + text[index:index+len(value)]+"[/b]"+text[index+len(value):]
btn = Button(text=text, size_hint_y=None, height=dp(30), markup=True)
btn.bind(on_release=on_press)
self.dropdown.add_widget(btn)
if not self.dropdown.attach_to:
self.dropdown.open(self)
else:
self.dropdown.dismiss()
class HintLabel(RecycleDataViewBehavior, BoxLayout):
selected = BooleanProperty(False)
striped = BooleanProperty(False)
@@ -570,8 +615,10 @@ class GameManager(App):
# show Archipelago tab if other logging is present
self.tabs.add_widget(panel)
hint_panel = self.add_client_tab("Hints", HintLog(self.json_to_kivy_parser))
hint_panel = self.add_client_tab("Hints", HintLayout())
self.hint_log = HintLog(self.json_to_kivy_parser)
self.log_panels["Hints"] = hint_panel.content
hint_panel.content.add_widget(self.hint_log)
if len(self.logging_pairs) == 1:
self.tabs.default_tab_text = "Archipelago"
@@ -698,7 +745,7 @@ class GameManager(App):
def update_hints(self):
hints = self.ctx.stored_data.get(f"_read_hints_{self.ctx.team}_{self.ctx.slot}", [])
self.log_panels["Hints"].refresh_hints(hints)
self.hint_log.refresh_hints(hints)
# default F1 keybind, opens a settings menu, that seems to break the layout engine once closed
def open_settings(self, *largs):
@@ -753,6 +800,17 @@ class UILog(RecycleView):
element.height = element.texture_size[1]
class HintLayout(BoxLayout):
orientation = "vertical"
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
boxlayout = BoxLayout(orientation="horizontal", size_hint_y=None, height=dp(30))
boxlayout.add_widget(Label(text="New Hint:", size_hint_x=None, size_hint_y=None, height=dp(30)))
boxlayout.add_widget(AutocompleteHintInput())
self.add_widget(boxlayout)
status_names: typing.Dict[HintStatus, str] = {
HintStatus.HINT_FOUND: "Found",
HintStatus.HINT_UNSPECIFIED: "Unspecified",
@@ -769,6 +827,7 @@ status_colors: typing.Dict[HintStatus, str] = {
}
class HintLog(RecycleView):
header = {
"receiving": {"text": "[u]Receiving Player[/u]"},

View File

@@ -7,7 +7,7 @@ schema>=0.7.7
kivy>=2.3.0
bsdiff4>=1.2.4
platformdirs>=4.2.2
certifi>=2024.8.30
certifi>=2024.12.14
cython>=3.0.11
cymem>=2.0.8
orjson>=3.10.7

View File

@@ -151,7 +151,7 @@ async def ping(ctx: BizHawkContext) -> None:
async def get_hash(ctx: BizHawkContext) -> str:
"""Gets the system name for the currently loaded ROM"""
"""Gets the hash value of the currently loaded ROM"""
res = (await send_requests(ctx, [{"type": "HASH"}]))[0]
if res["type"] != "HASH_RESPONSE":
@@ -160,6 +160,16 @@ async def get_hash(ctx: BizHawkContext) -> str:
return res["value"]
async def get_memory_size(ctx: BizHawkContext, domain: str) -> int:
"""Gets the size in bytes of the specified memory domain"""
res = (await send_requests(ctx, [{"type": "MEMORY_SIZE", "domain": domain}]))[0]
if res["type"] != "MEMORY_SIZE_RESPONSE":
raise SyncError(f"Expected response of type MEMORY_SIZE_RESPONSE but got {res['type']}")
return res["value"]
async def get_system(ctx: BizHawkContext) -> str:
"""Gets the system name for the currently loaded ROM"""
res = (await send_requests(ctx, [{"type": "SYSTEM"}]))[0]

View File

@@ -231,12 +231,14 @@ async def _run_game(rom: str):
)
async def _patch_and_run_game(patch_file: str):
def _patch_and_run_game(patch_file: str):
try:
metadata, output_file = Patch.create_rom_file(patch_file)
Utils.async_start(_run_game(output_file))
return metadata
except Exception as exc:
logger.exception(exc)
return {}
def launch(*launch_args) -> None:
@@ -245,6 +247,11 @@ def launch(*launch_args) -> None:
parser.add_argument("patch_file", default="", type=str, nargs="?", help="Path to an Archipelago patch file")
args = parser.parse_args(launch_args)
if args.patch_file != "":
metadata = _patch_and_run_game(args.patch_file)
if "server" in metadata:
args.connect = metadata["server"]
ctx = BizHawkClientContext(args.connect, args.password)
ctx.server_task = asyncio.create_task(server_loop(ctx), name="ServerLoop")
@@ -252,9 +259,6 @@ def launch(*launch_args) -> None:
ctx.run_gui()
ctx.run_cli()
if args.patch_file != "":
Utils.async_start(_patch_and_run_game(args.patch_file))
watcher_task = asyncio.create_task(_game_watcher(ctx), name="GameWatcher")
try:

View File

@@ -1,9 +1,8 @@
from __future__ import annotations
from typing import Dict
from dataclasses import dataclass
from Options import Choice, Option, DefaultOnToggle, DeathLink, Range, Toggle, PerGameCommonOptions
from Options import Choice, DefaultOnToggle, DeathLink, Range, Toggle, PerGameCommonOptions
class FreeincarnateMax(Range):

View File

@@ -1,6 +1,6 @@
from BaseClasses import MultiWorld, Region, Entrance, LocationProgressType
from Options import PerGameCommonOptions
from .Locations import location_table, LocationData, AdventureLocation, dragon_room_to_region
from .Locations import location_table, AdventureLocation, dragon_room_to_region
def connect(world: MultiWorld, player: int, source: str, target: str, rule: callable = lambda state: True,

View File

@@ -2,15 +2,15 @@ import hashlib
import json
import os
import zipfile
from typing import Optional, Any
import Utils
from .Locations import AdventureLocation, LocationData
from settings import get_settings
from worlds.Files import APPatch, AutoPatchRegister
from typing import Any
import bsdiff4
import Utils
from settings import get_settings
from worlds.Files import APPatch, AutoPatchRegister
from .Locations import LocationData
ADVENTUREHASH: str = "157bddb7192754a45372be196797f284"

View File

@@ -1,35 +1,24 @@
import base64
import copy
import itertools
import math
import os
import settings
import typing
from enum import IntFlag
from typing import Any, ClassVar, Dict, List, Optional, Set, Tuple
from typing import ClassVar, Dict, Optional, Tuple
from BaseClasses import Entrance, Item, ItemClassification, MultiWorld, Region, Tutorial, \
LocationProgressType
import settings
from BaseClasses import Item, ItemClassification, MultiWorld, Tutorial, LocationProgressType
from Utils import __version__
from Options import AssembleOptions
from worlds.AutoWorld import WebWorld, World
from Fill import fill_restrictive
from worlds.generic.Rules import add_rule, set_rule
from .Options import DragonRandoType, DifficultySwitchA, DifficultySwitchB, \
AdventureOptions
from .Rom import get_base_rom_bytes, get_base_rom_path, AdventureDeltaPatch, apply_basepatch, \
AdventureAutoCollectLocation
from worlds.LauncherComponents import Component, components, SuffixIdentifier
from .Items import item_table, ItemData, nothing_item_id, event_table, AdventureItem, standard_item_max
from .Locations import location_table, base_location_id, LocationData, get_random_room_in_regions
from .Offsets import static_item_data_location, items_ram_start, static_item_element_size, item_position_table, \
static_first_dragon_index, connector_port_offset, yorgle_speed_data_location, grundle_speed_data_location, \
rhindle_speed_data_location, item_ram_addresses, start_castle_values, start_castle_offset
from .Options import DragonRandoType, DifficultySwitchA, DifficultySwitchB, AdventureOptions
from .Regions import create_regions
from .Rom import get_base_rom_bytes, get_base_rom_path, AdventureDeltaPatch, apply_basepatch, AdventureAutoCollectLocation
from .Rules import set_rules
from worlds.LauncherComponents import Component, components, SuffixIdentifier
# Adventure
components.append(Component('Adventure Client', 'AdventureClient', file_identifier=SuffixIdentifier('.apadvn')))

View File

@@ -592,9 +592,9 @@ def global_rules(multiworld: MultiWorld, player: int):
lambda state: can_kill_most_things(state, player, 8) and has_fire_source(state, player) and state.multiworld.get_entrance('Ganons Tower Torch Rooms', player).parent_region.dungeon.bosses['middle'].can_defeat(state))
set_rule(multiworld.get_location('Ganons Tower - Mini Helmasaur Key Drop', player), lambda state: can_kill_most_things(state, player, 1))
set_rule(multiworld.get_location('Ganons Tower - Pre-Moldorm Chest', player),
lambda state: state._lttp_has_key('Small Key (Ganons Tower)', player, 7))
lambda state: state._lttp_has_key('Small Key (Ganons Tower)', player, 7) and can_use_bombs(state, player))
set_rule(multiworld.get_entrance('Ganons Tower Moldorm Door', player),
lambda state: state._lttp_has_key('Small Key (Ganons Tower)', player, 8))
lambda state: state._lttp_has_key('Small Key (Ganons Tower)', player, 8) and can_use_bombs(state, player))
set_rule(multiworld.get_entrance('Ganons Tower Moldorm Gap', player),
lambda state: state.has('Hookshot', player) and state.multiworld.get_entrance('Ganons Tower Moldorm Gap', player).parent_region.dungeon.bosses['top'].can_defeat(state))
set_defeat_dungeon_boss_rule(multiworld.get_location('Agahnim 2', player))

View File

@@ -130,19 +130,21 @@ class TestGanonsTower(TestDungeon):
["Ganons Tower - Pre-Moldorm Chest", False, []],
["Ganons Tower - Pre-Moldorm Chest", False, [], ['Progressive Bow']],
["Ganons Tower - Pre-Moldorm Chest", False, [], ['Bomb Upgrade (50)']],
["Ganons Tower - Pre-Moldorm Chest", False, [], ['Big Key (Ganons Tower)']],
["Ganons Tower - Pre-Moldorm Chest", False, [], ['Lamp', 'Fire Rod']],
["Ganons Tower - Pre-Moldorm Chest", True, ['Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Lamp']],
["Ganons Tower - Pre-Moldorm Chest", True, ['Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Fire Rod']],
["Ganons Tower - Pre-Moldorm Chest", True, ['Bomb Upgrade (50)', 'Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Lamp']],
["Ganons Tower - Pre-Moldorm Chest", True, ['Bomb Upgrade (50)', 'Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Fire Rod']],
["Ganons Tower - Validation Chest", False, []],
["Ganons Tower - Validation Chest", False, [], ['Hookshot']],
["Ganons Tower - Validation Chest", False, [], ['Progressive Bow']],
["Ganons Tower - Validation Chest", False, [], ['Bomb Upgrade (50)']],
["Ganons Tower - Validation Chest", False, [], ['Big Key (Ganons Tower)']],
["Ganons Tower - Validation Chest", False, [], ['Lamp', 'Fire Rod']],
["Ganons Tower - Validation Chest", False, [], ['Progressive Sword', 'Hammer']],
["Ganons Tower - Validation Chest", True, ['Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Lamp', 'Hookshot', 'Progressive Sword']],
["Ganons Tower - Validation Chest", True, ['Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Fire Rod', 'Hookshot', 'Progressive Sword']],
["Ganons Tower - Validation Chest", True, ['Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Lamp', 'Hookshot', 'Hammer']],
["Ganons Tower - Validation Chest", True, ['Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Fire Rod', 'Hookshot', 'Hammer']],
["Ganons Tower - Validation Chest", True, ['Bomb Upgrade (50)', 'Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Lamp', 'Hookshot', 'Progressive Sword']],
["Ganons Tower - Validation Chest", True, ['Bomb Upgrade (50)', 'Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Fire Rod', 'Hookshot', 'Progressive Sword']],
["Ganons Tower - Validation Chest", True, ['Bomb Upgrade (50)', 'Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Lamp', 'Hookshot', 'Hammer']],
["Ganons Tower - Validation Chest", True, ['Bomb Upgrade (50)', 'Progressive Bow', 'Big Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Small Key (Ganons Tower)', 'Fire Rod', 'Hookshot', 'Hammer']],
])

View File

@@ -63,17 +63,19 @@ class FactorioElement:
class Technology(FactorioElement): # maybe make subclass of Location?
has_modifier: bool
factorio_id: int
progressive: Tuple[str]
unlocks: Union[Set[str], bool] # bool case is for progressive technologies
modifiers: list[str]
def __init__(self, technology_name: str, factorio_id: int, progressive: Tuple[str] = (),
has_modifier: bool = False, unlocks: Union[Set[str], bool] = None):
modifiers: list[str] = None, unlocks: Union[Set[str], bool] = None):
self.name = technology_name
self.factorio_id = factorio_id
self.progressive = progressive
self.has_modifier = has_modifier
if modifiers is None:
modifiers = []
self.modifiers = modifiers
if unlocks:
self.unlocks = unlocks
else:
@@ -82,6 +84,10 @@ class Technology(FactorioElement): # maybe make subclass of Location?
def __hash__(self):
return self.factorio_id
@property
def has_modifier(self) -> bool:
return bool(self.modifiers)
def get_custom(self, world, allowed_packs: Set[str], player: int) -> CustomTechnology:
return CustomTechnology(self, world, allowed_packs, player)
@@ -191,13 +197,14 @@ class Machine(FactorioElement):
recipe_sources: Dict[str, Set[str]] = {} # recipe_name -> technology source
mining_with_fluid_sources: set[str] = set()
# recipes and technologies can share names in Factorio
for technology_name, data in sorted(techs_future.result().items()):
technology = Technology(
technology_name,
factorio_tech_id,
has_modifier=data["has_modifier"],
modifiers=data.get("modifiers", []),
unlocks=set(data["unlocks"]) - start_unlocked_recipes,
)
factorio_tech_id += 1
@@ -205,7 +212,8 @@ for technology_name, data in sorted(techs_future.result().items()):
technology_table[technology_name] = technology
for recipe_name in technology.unlocks:
recipe_sources.setdefault(recipe_name, set()).add(technology_name)
if "mining-with-fluid" in technology.modifiers:
mining_with_fluid_sources.add(technology_name)
del techs_future
recipes = {}
@@ -221,6 +229,8 @@ for resource_name, resource_data in resources_future.result().items():
"energy": resource_data["mining_time"],
"category": resource_data["category"]
}
if "required_fluid" in resource_data:
recipe_sources.setdefault(f"mining-{resource_name}", set()).update(mining_with_fluid_sources)
del resources_future
for recipe_name, recipe_data in raw_recipes.items():
@@ -431,7 +441,9 @@ for root in sorted_rows:
factorio_tech_id += 1
progressive_technology = Technology(root, factorio_tech_id,
tuple(progressive),
has_modifier=any(technology_table[tech].has_modifier for tech in progressive),
modifiers=sorted(set.union(
*(set(technology_table[tech].modifiers) for tech in progressive)
)),
unlocks=any(technology_table[tech].unlocks for tech in progressive),)
progressive_tech_table[root] = progressive_technology.factorio_id
progressive_technology_table[root] = progressive_technology

File diff suppressed because one or more lines are too long

View File

@@ -381,7 +381,7 @@ class MessengerWorld(World):
return
# the messenger client calls into AP with specific args, so check the out path matches what the client sends
out_path = output_path(multiworld.get_out_file_name_base(1) + ".aptm")
if "The Messenger\\Archipelago\\output" not in out_path:
if "Messenger\\Archipelago\\output" not in out_path:
return
import orjson
data = {

View File

@@ -214,10 +214,19 @@ class MegaMan2Client(BizHawkClient):
last_wily: Optional[int] = None # default to wily 1
async def validate_rom(self, ctx: "BizHawkClientContext") -> bool:
from worlds._bizhawk import RequestFailedError, read
from worlds._bizhawk import RequestFailedError, read, get_memory_size
from . import MM2World
try:
if (await get_memory_size(ctx.bizhawk_ctx, "PRG ROM")) < 0x3FFB0:
if "pool" in ctx.command_processor.commands:
ctx.command_processor.commands.pop("pool")
if "request" in ctx.command_processor.commands:
ctx.command_processor.commands.pop("request")
if "autoheal" in ctx.command_processor.commands:
ctx.command_processor.commands.pop("autoheal")
return False
game_name, version = (await read(ctx.bizhawk_ctx, [(0x3FFB0, 21, "PRG ROM"),
(0x3FFC8, 3, "PRG ROM")]))
if game_name[:3] != b"MM2" or version != bytes(MM2World.world_version):

View File

@@ -6,6 +6,7 @@ class SongData(NamedTuple):
"""Special data container to contain the metadata of each song to make filtering work."""
code: Optional[int]
uid: str
album: str
streamer_mode: bool
easy: Optional[int]

View File

@@ -1,13 +1,9 @@
from .Items import SongData, AlbumData
from typing import Dict, List, Set, Optional
from .Items import SongData
from .MuseDashData import SONG_DATA
from typing import Dict, List, Set
from collections import ChainMap
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."""
STARTING_CODE = 2900000
@@ -33,15 +29,6 @@ class MuseDashCollections:
"Rin Len's Mirrorland", # Paid DLC not included in Muse Plus
]
DIFF_OVERRIDES: List[str] = [
"MuseDash ka nanika hi",
"Rush-Hour",
"Find this Month's Featured Playlist",
"PeroPero in the Universe",
"umpopoff",
"P E R O P E R O Brother Dance",
]
REMOVED_SONGS = [
"CHAOS Glitch",
"FM 17314 SUGAR RADIO",
@@ -50,9 +37,7 @@ class MuseDashCollections:
"Tsukuyomi Ni Naru Replaced",
]
album_items: Dict[str, AlbumData] = {}
album_locations: Dict[str, int] = {}
song_items: Dict[str, SongData] = {}
song_items = SONG_DATA
song_locations: Dict[str, int] = {}
trap_items: Dict[str, int] = {
@@ -65,7 +50,7 @@ class MuseDashCollections:
"Gray Scale Trap": STARTING_CODE + 7,
"Nyaa SFX Trap": STARTING_CODE + 8,
"Error SFX Trap": STARTING_CODE + 9,
"Focus Line Trap": STARTING_CODE + 10,
"Focus Line Trap": STARTING_CODE + 10,
}
sfx_trap_items: List[str] = [
@@ -85,65 +70,13 @@ class MuseDashCollections:
"Extra Life": 1,
}
item_names_to_id: ChainMap = ChainMap({}, filler_items, trap_items)
location_names_to_id: ChainMap = ChainMap(song_locations, album_locations)
item_names_to_id: ChainMap = ChainMap({k: v.code for k, v in SONG_DATA.items()}, filler_items, trap_items)
location_names_to_id: ChainMap = ChainMap(song_locations)
def __init__(self) -> None:
self.item_names_to_id[self.MUSIC_SHEET_NAME] = self.MUSIC_SHEET_CODE
item_id_index = self.STARTING_CODE + 50
full_file = load_text_file("MuseDashData.txt")
seen_albums = set()
for line in full_file.splitlines():
line = line.strip()
sections = line.split("|")
album = sections[2]
if album not in seen_albums:
seen_albums.add(album)
self.album_items[album] = 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.
steamer_mode = sections[3] == "True"
if song_name in self.DIFF_OVERRIDES:
# These songs use non-standard difficulty values. Which are being overriden with standard values.
# But also avoid filling any missing difficulties (i.e. 0s) with a difficulty value.
if sections[4] != '0':
diff_of_easy = 4
else:
diff_of_easy = None
if sections[5] != '0':
diff_of_hard = 7
else:
diff_of_hard = None
if sections[6] != '0':
diff_of_master = 10
else:
diff_of_master = None
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, album, steamer_mode,
diff_of_easy, diff_of_hard, diff_of_master)
item_id_index += 1
self.item_names_to_id.update({name: data.code for name, data in self.song_items.items()})
self.item_names_to_id.update({name: data.code for name, data in self.album_items.items()})
location_id_index = self.STARTING_CODE
for name in self.album_items.keys():
self.album_locations[f"{name}-0"] = location_id_index
self.album_locations[f"{name}-1"] = location_id_index + 1
location_id_index += 2
for name in self.song_items.keys():
self.song_locations[f"{name}-0"] = location_id_index
self.song_locations[f"{name}-1"] = location_id_index + 1
@@ -157,7 +90,7 @@ class MuseDashCollections:
for songKey, songData in self.song_items.items():
if not self.song_matches_dlc_filter(songData, dlc_songs):
continue
if songKey in self.REMOVED_SONGS:
continue
@@ -193,18 +126,3 @@ class MuseDashCollections:
return True
return False
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
# 0 is used as a filler and no songs actually have a 0 difficulty song.
if difficulty == "0":
return None
# Curse the 2023 april fools update. Used on 3rd Avenue.
if difficulty == "":
return 10
return int(difficulty)

View File

@@ -0,0 +1,615 @@
from .Items import SongData
from typing import Dict
# Auto Generated
SONG_DATA: Dict[str, SongData] = {
"Magical Wonderland": SongData(2900051, "0-48", "Default Music", True, 1, 3, None),
"Iyaiya": SongData(2900052, "0-0", "Default Music", True, 1, 4, None),
"Wonderful Pain": SongData(2900053, "0-2", "Default Music", False, 1, 3, None),
"Breaking Dawn": SongData(2900054, "0-3", "Default Music", True, 2, 4, None),
"One-Way Subway": SongData(2900055, "0-4", "Default Music", True, 1, 4, None),
"Frost Land": SongData(2900056, "0-1", "Default Music", False, 1, 3, 6),
"Heart-Pounding Flight": SongData(2900057, "0-5", "Default Music", True, 2, 5, None),
"Pancake is Love": SongData(2900058, "0-29", "Default Music", True, 2, 4, 7),
"Shiguang Tuya": SongData(2900059, "0-6", "Default Music", True, 2, 5, None),
"Evolution": SongData(2900060, "0-37", "Default Music", False, 2, 4, 7),
"Dolphin and Broadcast": SongData(2900061, "0-7", "Default Music", True, 2, 5, None),
"Yuki no Shizuku Ame no Oto": SongData(2900062, "0-8", "Default Music", True, 2, 4, 6),
"Best One feat.tooko": SongData(2900063, "0-43", "Default Music", False, 3, 5, None),
"Candy-coloured Love Theory": SongData(2900064, "0-31", "Default Music", False, 2, 4, 6),
"Night Wander": SongData(2900065, "0-38", "Default Music", False, 3, 5, 7),
"Dohna Dohna no Uta": SongData(2900066, "0-46", "Default Music", False, 2, 4, 6),
"Spring Carnival": SongData(2900067, "0-9", "Default Music", False, 2, 4, 7),
"DISCO NIGHT": SongData(2900068, "0-30", "Default Music", True, 2, 4, 7),
"Koi no Moonlight": SongData(2900069, "0-49", "Default Music", False, 2, 5, 8),
"Lian Ai Audio Navigation": SongData(2900070, "0-10", "Default Music", False, 3, 5, 7),
"Lights of Muse": SongData(2900071, "0-11", "Default Music", True, 4, 6, 8),
"midstream jam": SongData(2900072, "0-12", "Default Music", False, 2, 5, 8),
"Nihao": SongData(2900073, "0-40", "Default Music", False, 3, 5, 7),
"Confession": SongData(2900074, "0-13", "Default Music", False, 3, 5, 8),
"Galaxy Striker": SongData(2900075, "0-32", "Default Music", False, 4, 7, 9),
"Departure Road": SongData(2900076, "0-14", "Default Music", True, 2, 5, 8),
"Bass Telekinesis": SongData(2900077, "0-15", "Default Music", False, 2, 5, 8),
"Cage of Almeria": SongData(2900078, "0-16", "Default Music", True, 3, 5, 7),
"Ira": SongData(2900079, "0-17", "Default Music", True, 4, 6, 8),
"Blackest Luxury Car": SongData(2900080, "0-18", "Default Music", True, 3, 6, 8),
"Medicine of Sing": SongData(2900081, "0-19", "Default Music", False, 3, 6, 8),
"irregulyze": SongData(2900082, "0-20", "Default Music", True, 3, 6, 8),
"I don't care about Christmas though": SongData(2900083, "0-47", "Default Music", False, 4, 6, 8),
"Imaginary World": SongData(2900084, "0-21", "Default Music", True, 4, 6, 8),
"Dysthymia": SongData(2900085, "0-22", "Default Music", True, 4, 7, 9),
"From the New World": SongData(2900086, "0-42", "Default Music", False, 2, 5, 7),
"NISEGAO": SongData(2900087, "0-33", "Default Music", True, 4, 7, 9),
"Say! Fanfare!": SongData(2900088, "0-44", "Default Music", False, 4, 6, 9),
"Star Driver": SongData(2900089, "0-34", "Default Music", True, 5, 7, 9),
"Formation": SongData(2900090, "0-23", "Default Music", True, 4, 6, 9),
"Shinsou Masui": SongData(2900091, "0-24", "Default Music", True, 4, 6, 10),
"Mezame Eurythmics": SongData(2900092, "0-50", "Default Music", False, 4, 6, 9),
"Shenri Kuaira -repeat-": SongData(2900093, "0-51", "Default Music", False, 5, 7, 9),
"Latitude": SongData(2900094, "0-25", "Default Music", True, 3, 6, 9),
"Aqua Stars": SongData(2900095, "0-39", "Default Music", False, 5, 7, 10),
"Funkotsu Saishin Casino": SongData(2900096, "0-26", "Default Music", False, 5, 7, 10),
"Clock Room & Spiritual World": SongData(2900097, "0-27", "Default Music", True, 4, 6, 9),
"INTERNET OVERDOSE": SongData(2900098, "0-52", "Default Music", False, 3, 6, 9),
"Tu Hua": SongData(2900099, "0-35", "Default Music", True, 4, 7, 9),
"Mujinku-Vacuum": SongData(2900100, "0-28", "Default Music", False, 5, 7, 11),
"MilK": SongData(2900101, "0-36", "Default Music", False, 5, 7, 9),
"umpopoff": SongData(2900102, "0-41", "Default Music", False, None, 7, None),
"Mopemope": SongData(2900103, "0-45", "Default Music", False, 4, 7, 9),
"The Happycore Idol": SongData(2900105, "43-0", "MD Plus Project", True, 2, 5, 7),
"Amatsumikaboshi": SongData(2900106, "43-1", "MD Plus Project", True, 4, 6, 8),
"ARIGA THESIS": SongData(2900107, "43-2", "MD Plus Project", True, 3, 6, 10),
"Night of Nights": SongData(2900108, "43-3", "MD Plus Project", False, 4, 7, 10),
"#Psychedelic_Meguro_River": SongData(2900109, "43-4", "MD Plus Project", False, 3, 6, 8),
"can you feel it": SongData(2900110, "43-5", "MD Plus Project", False, 4, 6, 8),
"Midnight O'clock": SongData(2900111, "43-6", "MD Plus Project", True, 3, 6, 8),
"Rin": SongData(2900112, "43-7", "MD Plus Project", True, 5, 7, 10),
"Smile-mileS": SongData(2900113, "43-8", "MD Plus Project", False, 6, 8, 10),
"Believing and Being": SongData(2900114, "43-9", "MD Plus Project", True, 4, 6, 9),
"Catalyst": SongData(2900115, "43-10", "MD Plus Project", False, 5, 7, 9),
"don't!stop!eroero!": SongData(2900116, "43-11", "MD Plus Project", True, 5, 7, 9),
"pa pi pu pi pu pi pa": SongData(2900117, "43-12", "MD Plus Project", False, 6, 8, 10),
"Sand Maze": SongData(2900118, "43-13", "MD Plus Project", True, 6, 8, 10),
"Diffraction": SongData(2900119, "43-14", "MD Plus Project", True, 5, 8, 10),
"AKUMU": SongData(2900120, "43-15", "MD Plus Project", False, 4, 6, 8),
"Queen Aluett": SongData(2900121, "43-16", "MD Plus Project", True, 7, 9, 11),
"DROPS": SongData(2900122, "43-17", "MD Plus Project", False, 2, 5, 8),
"Frightfully-insane Flan-chan's frightful song": SongData(2900123, "43-18", "MD Plus Project", False, 5, 7, 10),
"snooze": SongData(2900124, "43-19", "MD Plus Project", False, 5, 7, 10),
"Kuishinbo Hacker feat.Kuishinbo Akachan": SongData(2900125, "43-20", "MD Plus Project", True, 5, 7, 9),
"Inu no outa": SongData(2900126, "43-21", "MD Plus Project", True, 3, 5, 7),
"Prism Fountain": SongData(2900127, "43-22", "MD Plus Project", True, 7, 9, 11),
"Gospel": SongData(2900128, "43-23", "MD Plus Project", False, 4, 6, 9),
"East Ai Li Lovely": SongData(2900130, "62-0", "Happy Otaku Pack Vol.17", False, 2, 4, 7),
"Mori Umi no Fune": SongData(2900131, "62-1", "Happy Otaku Pack Vol.17", True, 5, 7, 9),
"Ooi": SongData(2900132, "62-2", "Happy Otaku Pack Vol.17", True, 5, 7, 10),
"Numatta!!": SongData(2900133, "62-3", "Happy Otaku Pack Vol.17", True, 5, 7, 9),
"SATELLITE": SongData(2900134, "62-4", "Happy Otaku Pack Vol.17", False, 5, 7, 9),
"Fantasia Sonata Colorful feat. V!C": SongData(2900135, "62-5", "Happy Otaku Pack Vol.17", True, 6, 8, 11),
"MuseDash ka nanika hi": SongData(2900137, "61-0", "Ola Dash", True, 4, 7, 10),
"Aleph-0": SongData(2900138, "61-1", "Ola Dash", True, 7, 9, 11),
"Buttoba Supernova": SongData(2900139, "61-2", "Ola Dash", False, 5, 7, 10),
"Rush-Hour": SongData(2900140, "61-3", "Ola Dash", False, 4, 7, 10),
"3rd Avenue": SongData(2900141, "61-4", "Ola Dash", False, 3, 5, 10),
"WORLDINVADER": SongData(2900142, "61-5", "Ola Dash", True, 5, 8, 10),
"N3V3R G3T OV3R": SongData(2900144, "60-0", "maimai DX Limited-time Suite", True, 4, 7, 10),
"Oshama Scramble!": SongData(2900145, "60-1", "maimai DX Limited-time Suite", True, 5, 7, 10),
"Valsqotch": SongData(2900146, "60-2", "maimai DX Limited-time Suite", True, 5, 9, 11),
"Paranormal My Mind": SongData(2900147, "60-3", "maimai DX Limited-time Suite", True, 5, 7, 9),
"Flower, snow and Drum'n'bass.": SongData(2900148, "60-4", "maimai DX Limited-time Suite", True, 5, 8, 10),
"Amenohoakari": SongData(2900149, "60-5", "maimai DX Limited-time Suite", True, 6, 8, 10),
"Boiling Blood": SongData(2900151, "59-0", "MSR Anthology", True, 5, 8, 10),
"ManiFesto": SongData(2900152, "59-1", "MSR Anthology", True, 4, 6, 9),
"Operation Blade": SongData(2900153, "59-2", "MSR Anthology", True, 3, 5, 7),
"Radiant": SongData(2900154, "59-3", "MSR Anthology", True, 3, 5, 8),
"Renegade": SongData(2900155, "59-4", "MSR Anthology", True, 3, 5, 8),
"Speed of Light": SongData(2900156, "59-5", "MSR Anthology", False, 1, 4, 7),
"Dossoles Holiday": SongData(2900157, "59-6", "MSR Anthology", True, 5, 7, 9),
"Autumn Moods": SongData(2900158, "59-7", "MSR Anthology", True, 3, 5, 7),
"People People": SongData(2900160, "58-0", "Nanahira Paradise", True, 5, 7, 9),
"Endless Error Loop": SongData(2900161, "58-1", "Nanahira Paradise", True, 4, 7, 9),
"Forbidden Pizza!": SongData(2900162, "58-2", "Nanahira Paradise", True, 5, 7, 9),
"Don't Make the Vocalist do Anything Insane": SongData(2900163, "58-3", "Nanahira Paradise", True, 5, 8, 9),
"Tokimeki*Meteostrike": SongData(2900165, "57-0", "Happy Otaku Pack Vol.16", True, 3, 6, 8),
"Down Low": SongData(2900166, "57-1", "Happy Otaku Pack Vol.16", True, 4, 6, 8),
"LOUDER MACHINE": SongData(2900167, "57-2", "Happy Otaku Pack Vol.16", True, 5, 7, 9),
"Sorewa mo Lovechu": SongData(2900168, "57-3", "Happy Otaku Pack Vol.16", True, 5, 7, 10),
"Rave_Tech": SongData(2900169, "57-4", "Happy Otaku Pack Vol.16", True, 5, 8, 10),
"Brilliant & Shining!": SongData(2900170, "57-5", "Happy Otaku Pack Vol.16", False, 5, 8, 10),
"Psyched Fevereiro": SongData(2900172, "56-0", "Give Up TREATMENT Vol.11", False, 5, 8, 10),
"Inferno City": SongData(2900173, "56-1", "Give Up TREATMENT Vol.11", False, 6, 8, 10),
"Paradigm Shift": SongData(2900174, "56-2", "Give Up TREATMENT Vol.11", False, 4, 7, 10),
"Snapdragon": SongData(2900175, "56-3", "Give Up TREATMENT Vol.11", False, 5, 7, 10),
"Prestige and Vestige": SongData(2900176, "56-4", "Give Up TREATMENT Vol.11", True, 6, 8, 11),
"Tiny Fate": SongData(2900177, "56-5", "Give Up TREATMENT Vol.11", False, 7, 9, 11),
"Tsuki ni Murakumo Hana ni Kaze": SongData(2900179, "55-0", "Touhou Mugakudan -II-", False, 3, 5, 7),
"Patchouli's - Best Hit GSK": SongData(2900180, "55-1", "Touhou Mugakudan -II-", False, 3, 5, 8),
"Monosugoi Space Shuttle de Koishi ga Monosugoi uta": SongData(2900181, "55-2", "Touhou Mugakudan -II-", False, 3, 5, 7),
"Kakoinaki Yo wa Ichigo no Tsukikage": SongData(2900182, "55-3", "Touhou Mugakudan -II-", False, 3, 6, 8),
"Psychedelic Kizakura Doumei": SongData(2900183, "55-4", "Touhou Mugakudan -II-", False, 4, 7, 10),
"Mischievous Sensation": SongData(2900184, "55-5", "Touhou Mugakudan -II-", False, 5, 7, 9),
"White Canvas": SongData(2900186, "54-0", "MEGAREX THE FUTURE", False, 3, 6, 8),
"Gloomy Flash": SongData(2900187, "54-1", "MEGAREX THE FUTURE", False, 5, 8, 10),
"Find this Month's Featured Playlist": SongData(2900188, "54-2", "MEGAREX THE FUTURE", False, 4, 7, 10),
"Sunday Night": SongData(2900189, "54-3", "MEGAREX THE FUTURE", False, 3, 6, 9),
"Goodbye Goodnight": SongData(2900190, "54-4", "MEGAREX THE FUTURE", False, 4, 6, 9),
"ENDLESS CIDER": SongData(2900191, "54-5", "MEGAREX THE FUTURE", False, 4, 6, 8),
"On And On!!": SongData(2900193, "53-0", "Happy Otaku Pack Vol.15", True, 4, 7, 9),
"Trip!": SongData(2900194, "53-1", "Happy Otaku Pack Vol.15", True, 3, 5, 7),
"Hoshi no otoshimono": SongData(2900195, "53-2", "Happy Otaku Pack Vol.15", False, 5, 7, 9),
"Plucky Race": SongData(2900196, "53-3", "Happy Otaku Pack Vol.15", True, 5, 8, 10),
"Fantasia Sonata Destiny": SongData(2900197, "53-4", "Happy Otaku Pack Vol.15", True, 3, 7, 10),
"Run through": SongData(2900198, "53-5", "Happy Otaku Pack Vol.15", False, 5, 8, 10),
"marooned night": SongData(2900200, "52-0", "MUSE RADIO FM103", False, 2, 4, 6),
"daydream girl": SongData(2900201, "52-1", "MUSE RADIO FM103", False, 3, 6, 8),
"Not Ornament": SongData(2900202, "52-2", "MUSE RADIO FM103", True, 3, 5, 8),
"Baby Pink": SongData(2900203, "52-3", "MUSE RADIO FM103", False, 3, 5, 8),
"I'm Here": SongData(2900204, "52-4", "MUSE RADIO FM103", False, 4, 6, 8),
"Masquerade Diary": SongData(2900206, "51-0", "Virtual Idol Production", True, 2, 5, 8),
"Reminiscence": SongData(2900207, "51-1", "Virtual Idol Production", True, 5, 7, 9),
"DarakuDatenshi": SongData(2900208, "51-2", "Virtual Idol Production", True, 3, 6, 9),
"D.I.Y.": SongData(2900209, "51-3", "Virtual Idol Production", False, 4, 6, 9),
"Boys in Virtual Land": SongData(2900210, "51-4", "Virtual Idol Production", False, 4, 7, 9),
"kui": SongData(2900211, "51-5", "Virtual Idol Production", True, 5, 7, 9),
"Nyan Cat": SongData(2900213, "50-0", "Nyanya Universe!", False, 4, 7, 9),
"PeroPero in the Universe": SongData(2900214, "50-1", "Nyanya Universe!", True, 4, 7, 10),
"In-kya Yo-kya Onmyoji": SongData(2900215, "50-2", "Nyanya Universe!", False, 6, 8, 10),
"KABOOOOOM!!!!": SongData(2900216, "50-3", "Nyanya Universe!", True, 4, 6, 8),
"Doppelganger": SongData(2900217, "50-4", "Nyanya Universe!", True, 5, 7, 9),
"Pray a LOVE": SongData(2900219, "49-0", "DokiDoki! Valentine!", False, 2, 5, 8),
"Love-Avoidance Addiction": SongData(2900220, "49-1", "DokiDoki! Valentine!", False, 3, 5, 7),
"Daisuki Dayo feat.Wotoha": SongData(2900221, "49-2", "DokiDoki! Valentine!", False, 5, 7, 10),
"glory day": SongData(2900223, "48-0", "DJMAX Reflect", False, 2, 5, 7),
"Bright Dream": SongData(2900224, "48-1", "DJMAX Reflect", False, 2, 4, 7),
"Groovin Up": SongData(2900225, "48-2", "DJMAX Reflect", False, 4, 6, 8),
"I Want You": SongData(2900226, "48-3", "DJMAX Reflect", False, 3, 6, 8),
"OBLIVION": SongData(2900227, "48-4", "DJMAX Reflect", False, 3, 6, 9),
"Elastic STAR": SongData(2900228, "48-5", "DJMAX Reflect", False, 4, 6, 8),
"U.A.D": SongData(2900229, "48-6", "DJMAX Reflect", False, 4, 6, 8),
"Jealousy": SongData(2900230, "48-7", "DJMAX Reflect", False, 3, 5, 7),
"Memory of Beach": SongData(2900231, "48-8", "DJMAX Reflect", False, 3, 6, 8),
"Don't Die": SongData(2900232, "48-9", "DJMAX Reflect", False, 6, 8, 10),
"Y CE Ver.": SongData(2900233, "48-10", "DJMAX Reflect", False, 4, 6, 9),
"Fancy Night": SongData(2900234, "48-11", "DJMAX Reflect", False, 4, 6, 8),
"Can We Talk": SongData(2900235, "48-12", "DJMAX Reflect", False, 4, 6, 8),
"Give Me 5": SongData(2900236, "48-13", "DJMAX Reflect", False, 2, 6, 8),
"Nightmare": SongData(2900237, "48-14", "DJMAX Reflect", False, 7, 9, 11),
"Haze of Autumn": SongData(2900239, "47-0", "Arcaea", True, 3, 6, 9),
"GIMME DA BLOOD": SongData(2900240, "47-1", "Arcaea", False, 3, 6, 9),
"Libertas": SongData(2900241, "47-2", "Arcaea", False, 4, 7, 10),
"Cyaegha": SongData(2900242, "47-3", "Arcaea", False, 5, 7, 9),
"Bang!!": SongData(2900244, "46-0", "Happy Otaku Pack Vol.14", False, 4, 6, 8),
"Paradise 2": SongData(2900245, "46-1", "Happy Otaku Pack Vol.14", False, 4, 6, 8),
"Symbol": SongData(2900246, "46-2", "Happy Otaku Pack Vol.14", False, 5, 7, 9),
"Nekojarashi": SongData(2900247, "46-3", "Happy Otaku Pack Vol.14", False, 5, 8, 10),
"A Philosophical Wanderer": SongData(2900248, "46-4", "Happy Otaku Pack Vol.14", False, 4, 6, 10),
"Isouten": SongData(2900249, "46-5", "Happy Otaku Pack Vol.14", True, 6, 8, 10),
"ONOMATO Pairing!!!": SongData(2900251, "45-0", "WACCA Horizon", False, 4, 6, 9),
"with U": SongData(2900252, "45-1", "WACCA Horizon", False, 6, 8, 10),
"Chariot": SongData(2900253, "45-2", "WACCA Horizon", False, 3, 6, 9),
"GASHATT": SongData(2900254, "45-3", "WACCA Horizon", False, 5, 7, 10),
"LIN NE KRO NE feat. lasah": SongData(2900255, "45-4", "WACCA Horizon", False, 6, 8, 10),
"ANGEL HALO": SongData(2900256, "45-5", "WACCA Horizon", False, 5, 8, 11),
"Party in the HOLLOWood": SongData(2900258, "44-0", "Happy Otaku Pack Vol.13", False, 3, 6, 8),
"Ying Ying da Zuozhan": SongData(2900259, "44-1", "Happy Otaku Pack Vol.13", True, 5, 7, 9),
"Howlin' Pumpkin": SongData(2900260, "44-2", "Happy Otaku Pack Vol.13", True, 4, 6, 8),
"Bad Apple!! feat. Nomico": SongData(2900262, "42-0", "Touhou Mugakudan -I-", False, 1, 3, 6),
"Iro wa Nioedo, Chirinuru wo": SongData(2900263, "42-1", "Touhou Mugakudan -I-", False, 2, 4, 7),
"Cirno's Perfect Math Class": SongData(2900264, "42-2", "Touhou Mugakudan -I-", False, 4, 7, 9),
"Hiiro Gekka Kyousai no Zetsu": SongData(2900265, "42-3", "Touhou Mugakudan -I-", False, 4, 6, 8),
"Flowery Moonlit Night": SongData(2900266, "42-4", "Touhou Mugakudan -I-", False, 3, 6, 8),
"Unconscious Requiem": SongData(2900267, "42-5", "Touhou Mugakudan -I-", False, 3, 6, 8),
"Super Battleworn Insomniac": SongData(2900269, "41-0", "7th Beat Games", True, 4, 7, 9),
"Bomb-Sniffing Pomeranian": SongData(2900270, "41-1", "7th Beat Games", True, 4, 6, 8),
"Rollerdisco Rumble": SongData(2900271, "41-2", "7th Beat Games", True, 4, 6, 9),
"Rose Garden": SongData(2900272, "41-3", "7th Beat Games", False, 5, 8, 9),
"EMOMOMO": SongData(2900273, "41-4", "7th Beat Games", True, 4, 7, 10),
"Heracles": SongData(2900274, "41-5", "7th Beat Games", False, 6, 8, 10),
"Rush-More": SongData(2900276, "40-0", "Happy Otaku Pack Vol.12", False, 4, 7, 9),
"Kill My Fortune": SongData(2900277, "40-1", "Happy Otaku Pack Vol.12", False, 5, 7, 10),
"Yosari Tsukibotaru Suminoborite": SongData(2900278, "40-2", "Happy Otaku Pack Vol.12", False, 5, 7, 9),
"JUMP! HardCandy": SongData(2900279, "40-3", "Happy Otaku Pack Vol.12", False, 3, 6, 8),
"Hibari": SongData(2900280, "40-4", "Happy Otaku Pack Vol.12", False, 3, 5, 8),
"OCCHOCO-REST-LESS": SongData(2900281, "40-5", "Happy Otaku Pack Vol.12", True, 4, 7, 9),
"See-Saw Day": SongData(2900283, "39-0", "MUSE RADIO FM102", True, 1, 3, 6),
"happy hour": SongData(2900284, "39-1", "MUSE RADIO FM102", True, 2, 4, 7),
"Seikimatsu no Natsu": SongData(2900285, "39-2", "MUSE RADIO FM102", True, 4, 6, 8),
"twinkle night": SongData(2900286, "39-3", "MUSE RADIO FM102", False, 3, 6, 8),
"ARUYA HARERUYA": SongData(2900287, "39-4", "MUSE RADIO FM102", False, 2, 5, 7),
"Blush": SongData(2900288, "39-5", "MUSE RADIO FM102", False, 2, 4, 7),
"Naked Summer": SongData(2900289, "39-6", "MUSE RADIO FM102", True, 4, 6, 8),
"BLESS ME": SongData(2900290, "39-7", "MUSE RADIO FM102", True, 2, 5, 7),
"FM 17314 SUGAR RADIO": SongData(2900291, "39-8", "MUSE RADIO FM102", True, None, None, None),
"NO ONE YES MAN": SongData(2900293, "38-0", "Phigros", False, 5, 7, 9),
"Snowfall, Merry Christmas": SongData(2900294, "38-1", "Phigros", False, 5, 8, 10),
"Igallta": SongData(2900295, "38-2", "Phigros", False, 6, 8, 10),
"Colored Glass": SongData(2900297, "37-0", "Cute Is Everything Vol.7", False, 1, 4, 7),
"Neonlights": SongData(2900298, "37-1", "Cute Is Everything Vol.7", False, 4, 7, 9),
"Hope for the flowers": SongData(2900299, "37-2", "Cute Is Everything Vol.7", False, 4, 7, 9),
"Seaside Cycling on May 30": SongData(2900300, "37-3", "Cute Is Everything Vol.7", False, 3, 6, 8),
"SKY HIGH": SongData(2900301, "37-4", "Cute Is Everything Vol.7", False, 2, 4, 6),
"Mousou Chu!!": SongData(2900302, "37-5", "Cute Is Everything Vol.7", False, 4, 7, 8),
"NightTheater": SongData(2900304, "36-0", "Give Up TREATMENT Vol.10", True, 6, 8, 11),
"Cutter": SongData(2900305, "36-1", "Give Up TREATMENT Vol.10", False, 4, 7, 10),
"bamboo": SongData(2900306, "36-2", "Give Up TREATMENT Vol.10", False, 6, 8, 10),
"enchanted love": SongData(2900307, "36-3", "Give Up TREATMENT Vol.10", False, 2, 6, 9),
"c.s.q.n.": SongData(2900308, "36-4", "Give Up TREATMENT Vol.10", False, 5, 8, 11),
"Booouncing!!": SongData(2900309, "36-5", "Give Up TREATMENT Vol.10", False, 5, 7, 10),
"PeroPeroGames goes Bankrupt": SongData(2900311, "35-0", "Happy Otaku Pack SP", True, 6, 8, 10),
"MARENOL": SongData(2900312, "35-1", "Happy Otaku Pack SP", False, 4, 7, 10),
"I am really good at Japanese style": SongData(2900313, "35-2", "Happy Otaku Pack SP", True, 6, 8, 10),
"Rush B": SongData(2900314, "35-3", "Happy Otaku Pack SP", True, 4, 7, 9),
"DataErr0r": SongData(2900315, "35-4", "Happy Otaku Pack SP", False, 5, 7, 9),
"Burn": SongData(2900316, "35-5", "Happy Otaku Pack SP", True, 4, 7, 9),
"ALiVE": SongData(2900318, "34-0", "HARDCORE TANO*C", False, 5, 7, 10),
"BATTLE NO.1": SongData(2900319, "34-1", "HARDCORE TANO*C", False, 5, 8, 10),
"Cthugha": SongData(2900320, "34-2", "HARDCORE TANO*C", False, 6, 8, 10),
"TWINKLE*MAGIC": SongData(2900321, "34-3", "HARDCORE TANO*C", False, 4, 7, 10),
"Comet Coaster": SongData(2900322, "34-4", "HARDCORE TANO*C", False, 6, 8, 10),
"XODUS": SongData(2900323, "34-5", "HARDCORE TANO*C", False, 7, 9, 11),
"Fireflies": SongData(2900325, "33-0", "cyTus", True, 1, 4, 7),
"Light up my love!!": SongData(2900326, "33-1", "cyTus", True, 3, 5, 7),
"Happiness Breeze": SongData(2900327, "33-2", "cyTus", True, 4, 6, 8),
"Chrome VOX": SongData(2900328, "33-3", "cyTus", True, 6, 8, 10),
"CHAOS": SongData(2900329, "33-4", "cyTus", True, 3, 6, 9),
"Saika": SongData(2900330, "33-5", "cyTus", True, 3, 5, 8),
"Standby for Action": SongData(2900331, "33-6", "cyTus", True, 4, 6, 8),
"Hydrangea": SongData(2900332, "33-7", "cyTus", True, 5, 7, 9),
"Amenemhat": SongData(2900333, "33-8", "cyTus", True, 6, 8, 10),
"Santouka": SongData(2900334, "33-9", "cyTus", True, 2, 5, 8),
"HEXENNACHTROCK-katashihaya-": SongData(2900335, "33-10", "cyTus", True, 4, 8, 10),
"Blah!!": SongData(2900336, "33-11", "cyTus", True, 5, 8, 11),
"CHAOS Glitch": SongData(2900337, "33-12", "cyTus", True, None, None, None),
"Preparara": SongData(2900339, "32-0", "Let's Do Bad Things Together", False, 1, 4, 6),
"Whatcha;Whatcha Doin'": SongData(2900340, "32-1", "Let's Do Bad Things Together", False, 3, 6, 9),
"Madara": SongData(2900341, "32-2", "Let's Do Bad Things Together", False, 4, 6, 9),
"pICARESq": SongData(2900342, "32-3", "Let's Do Bad Things Together", False, 4, 6, 8),
"Desastre": SongData(2900343, "32-4", "Let's Do Bad Things Together", False, 4, 6, 8),
"Shoot for the Moon": SongData(2900344, "32-5", "Let's Do Bad Things Together", False, 2, 5, 8),
"The 90's Decision": SongData(2900346, "31-0", "Happy Otaku Pack Vol.11", True, 5, 7, 9),
"Medusa": SongData(2900347, "31-1", "Happy Otaku Pack Vol.11", False, 4, 6, 8),
"Final Step!": SongData(2900348, "31-2", "Happy Otaku Pack Vol.11", False, 5, 7, 10),
"MAGENTA POTION": SongData(2900349, "31-3", "Happy Otaku Pack Vol.11", False, 4, 7, 9),
"Cross Ray": SongData(2900350, "31-4", "Happy Otaku Pack Vol.11", False, 3, 6, 9),
"Square Lake": SongData(2900351, "31-5", "Happy Otaku Pack Vol.11", False, 6, 8, 9),
"Girly Cupid": SongData(2900353, "30-0", "Cute Is Everything Vol.6", False, 3, 6, 8),
"sheep in the light": SongData(2900354, "30-1", "Cute Is Everything Vol.6", False, 2, 5, 8),
"Breaker city": SongData(2900355, "30-2", "Cute Is Everything Vol.6", False, 4, 6, 9),
"heterodoxy": SongData(2900356, "30-3", "Cute Is Everything Vol.6", False, 4, 6, 8),
"Computer Music Girl": SongData(2900357, "30-4", "Cute Is Everything Vol.6", False, 3, 5, 7),
"Focus Point": SongData(2900358, "30-5", "Cute Is Everything Vol.6", True, 2, 5, 7),
"Groove Prayer": SongData(2900360, "29-0", "Let' s GROOVE!", True, 3, 5, 7),
"FUJIN Rumble": SongData(2900361, "29-1", "Let' s GROOVE!", True, 5, 7, 10),
"Marry me, Nightmare": SongData(2900362, "29-2", "Let' s GROOVE!", False, 6, 8, 11),
"HG Makaizou Polyvinyl Shounen": SongData(2900363, "29-3", "Let' s GROOVE!", True, 4, 7, 9),
"Seizya no Ibuki": SongData(2900364, "29-4", "Let' s GROOVE!", True, 6, 8, 10),
"ouroboros -twin stroke of the end-": SongData(2900365, "29-5", "Let' s GROOVE!", True, 4, 6, 9),
"Heisha Onsha": SongData(2900367, "28-0", "Happy Otaku Pack Vol.10", False, 4, 6, 8),
"Ginevra": SongData(2900368, "28-1", "Happy Otaku Pack Vol.10", True, 5, 7, 10),
"Paracelestia": SongData(2900369, "28-2", "Happy Otaku Pack Vol.10", False, 5, 8, 10),
"un secret": SongData(2900370, "28-3", "Happy Otaku Pack Vol.10", False, 2, 4, 6),
"Good Life": SongData(2900371, "28-4", "Happy Otaku Pack Vol.10", False, 4, 6, 8),
"nini-nini-": SongData(2900372, "28-5", "Happy Otaku Pack Vol.10", False, 4, 7, 9),
"Can I friend you on Bassbook? lol": SongData(2900374, "27-0", "Nanahira Festival", False, 3, 6, 8),
"Gaming*Everything": SongData(2900375, "27-1", "Nanahira Festival", False, 5, 8, 11),
"Renji de haochi": SongData(2900376, "27-2", "Nanahira Festival", False, 5, 7, 9),
"You Make My Life 1UP": SongData(2900377, "27-3", "Nanahira Festival", False, 4, 6, 8),
"Newbies, Geeks, Internets": SongData(2900378, "27-4", "Nanahira Festival", False, 6, 8, 10),
"Onegai!Kon kon Oinarisama": SongData(2900379, "27-5", "Nanahira Festival", False, 3, 6, 9),
"Legend of Eastern Rabbit -SKY DEFENDER-": SongData(2900381, "26-0", "Give Up TREATMENT Vol.9", False, 4, 6, 9),
"ENERGY SYNERGY MATRIX": SongData(2900382, "26-1", "Give Up TREATMENT Vol.9", False, 6, 8, 10),
"Punai Punai Genso": SongData(2900383, "26-2", "Give Up TREATMENT Vol.9", False, 2, 7, 11),
"Better Graphic Animation": SongData(2900384, "26-3", "Give Up TREATMENT Vol.9", False, 5, 8, 11),
"Variant Cross": SongData(2900385, "26-4", "Give Up TREATMENT Vol.9", False, 4, 7, 10),
"Ultra Happy Miracle Bazoooooka!!": SongData(2900386, "26-5", "Give Up TREATMENT Vol.9", False, 7, 9, 11),
"tape/stop/night": SongData(2900388, "25-0", "MUSE RADIO FM101", True, 3, 5, 7),
"Pixel Galaxy": SongData(2900389, "25-1", "MUSE RADIO FM101", False, 2, 5, 8),
"Notice": SongData(2900390, "25-2", "MUSE RADIO FM101", False, 4, 7, 10),
"Strawberry Godzilla": SongData(2900391, "25-3", "MUSE RADIO FM101", True, 2, 5, 7),
"OKIMOCHI EXPRESSION": SongData(2900392, "25-4", "MUSE RADIO FM101", False, 4, 6, 10),
"Kimi to pool disco": SongData(2900393, "25-5", "MUSE RADIO FM101", False, 4, 6, 8),
"The Last Page": SongData(2900395, "24-0", "Happy Otaku Pack Vol.9", False, 3, 5, 7),
"IKAROS": SongData(2900396, "24-1", "Happy Otaku Pack Vol.9", False, 4, 7, 10),
"Tsukuyomi": SongData(2900397, "24-2", "Happy Otaku Pack Vol.9", False, 3, 6, 9),
"Future Stream": SongData(2900398, "24-3", "Happy Otaku Pack Vol.9", False, 4, 6, 8),
"FULi AUTO SHOOTER": SongData(2900399, "24-4", "Happy Otaku Pack Vol.9", True, 4, 7, 9),
"GOODFORTUNE": SongData(2900400, "24-5", "Happy Otaku Pack Vol.9", False, 5, 7, 9),
"The Dessert After Rain": SongData(2900402, "23-0", "Cute Is Everything Vol.5", True, 2, 4, 6),
"Confession Support Formula": SongData(2900403, "23-1", "Cute Is Everything Vol.5", False, 3, 5, 7),
"Omatsuri": SongData(2900404, "23-2", "Cute Is Everything Vol.5", False, 1, 3, 6),
"FUTUREPOP": SongData(2900405, "23-3", "Cute Is Everything Vol.5", True, 2, 5, 7),
"The Breeze": SongData(2900406, "23-4", "Cute Is Everything Vol.5", False, 1, 4, 6),
"I LOVE LETTUCE FRIED RICE!!": SongData(2900407, "23-5", "Cute Is Everything Vol.5", False, 3, 7, 9),
"The NightScape": SongData(2900409, "22-0", "Give Up TREATMENT Vol.8", False, 4, 7, 9),
"FREEDOM DiVE": SongData(2900410, "22-1", "Give Up TREATMENT Vol.8", False, 6, 8, 10),
"Phi": SongData(2900411, "22-2", "Give Up TREATMENT Vol.8", False, 5, 8, 10),
"Lueur de la nuit": SongData(2900412, "22-3", "Give Up TREATMENT Vol.8", False, 6, 8, 11),
"Creamy Sugary OVERDRIVE!!!": SongData(2900413, "22-4", "Give Up TREATMENT Vol.8", True, 4, 7, 10),
"Disorder": SongData(2900414, "22-5", "Give Up TREATMENT Vol.8", False, 5, 7, 11),
"Glimmer": SongData(2900416, "21-0", "Budget Is Burning: Nano Core", False, 2, 5, 8),
"EXIST": SongData(2900417, "21-1", "Budget Is Burning: Nano Core", False, 3, 5, 8),
"Irreplaceable": SongData(2900418, "21-2", "Budget Is Burning: Nano Core", False, 4, 6, 8),
"Moonlight Banquet": SongData(2900420, "20-0", "Happy Otaku Pack Vol.8", True, 2, 5, 8),
"Flashdance": SongData(2900421, "20-1", "Happy Otaku Pack Vol.8", False, 3, 6, 9),
"INFiNiTE ENERZY -Overdoze-": SongData(2900422, "20-2", "Happy Otaku Pack Vol.8", False, 4, 7, 9),
"One Way Street": SongData(2900423, "20-3", "Happy Otaku Pack Vol.8", False, 3, 6, 10),
"This Club is Not 4 U": SongData(2900424, "20-4", "Happy Otaku Pack Vol.8", False, 4, 7, 9),
"ULTRA MEGA HAPPY PARTY!!!": SongData(2900425, "20-5", "Happy Otaku Pack Vol.8", False, 5, 7, 10),
"INFINITY": SongData(2900427, "19-0", "Give Up TREATMENT Vol.7", True, 5, 8, 10),
"Punai Punai Senso": SongData(2900428, "19-1", "Give Up TREATMENT Vol.7", False, 2, 7, 11),
"Maxi": SongData(2900429, "19-2", "Give Up TREATMENT Vol.7", False, 5, 8, 10),
"YInMn Blue": SongData(2900430, "19-3", "Give Up TREATMENT Vol.7", False, 6, 8, 10),
"Plumage": SongData(2900431, "19-4", "Give Up TREATMENT Vol.7", False, 4, 7, 10),
"Dr.Techro": SongData(2900432, "19-5", "Give Up TREATMENT Vol.7", False, 7, 9, 11),
"SWEETSWEETSWEET": SongData(2900434, "18-0", "Cute Is Everything Vol.4", True, 2, 5, 7),
"Deep Blue and the Breaths of the Night": SongData(2900435, "18-1", "Cute Is Everything Vol.4", True, 2, 4, 6),
"Joy Connection": SongData(2900436, "18-2", "Cute Is Everything Vol.4", False, 3, 6, 8),
"Self Willed Girl Ver.B": SongData(2900437, "18-3", "Cute Is Everything Vol.4", True, 4, 6, 8),
"Just Disobedient": SongData(2900438, "18-4", "Cute Is Everything Vol.4", False, 3, 6, 8),
"Holy Sh*t Grass Snake": SongData(2900439, "18-5", "Cute Is Everything Vol.4", False, 2, 6, 9),
"Cotton Candy Wonderland": SongData(2900441, "17-0", "Happy Otaku Pack Vol.7", False, 2, 5, 8),
"Punai Punai Taiso": SongData(2900442, "17-1", "Happy Otaku Pack Vol.7", False, 2, 7, 10),
"Fly High": SongData(2900443, "17-2", "Happy Otaku Pack Vol.7", False, 3, 5, 7),
"prejudice": SongData(2900444, "17-3", "Happy Otaku Pack Vol.7", True, 4, 6, 9),
"The 89's Momentum": SongData(2900445, "17-4", "Happy Otaku Pack Vol.7", True, 5, 7, 9),
"energy night": SongData(2900446, "17-5", "Happy Otaku Pack Vol.7", True, 5, 7, 10),
"Future Dive": SongData(2900448, "16-0", "Give Up TREATMENT Vol.6", True, 4, 6, 9),
"Re End of a Dream": SongData(2900449, "16-1", "Give Up TREATMENT Vol.6", False, 5, 8, 11),
"Etude -Storm-": SongData(2900450, "16-2", "Give Up TREATMENT Vol.6", True, 6, 8, 10),
"Unlimited Katharsis": SongData(2900451, "16-3", "Give Up TREATMENT Vol.6", False, 4, 6, 10),
"Magic Knight Girl": SongData(2900452, "16-4", "Give Up TREATMENT Vol.6", False, 4, 7, 9),
"Eeliaas": SongData(2900453, "16-5", "Give Up TREATMENT Vol.6", False, 6, 9, 11),
"Magic Spell": SongData(2900455, "15-0", "Cute Is Everything Vol.3", True, 2, 5, 7),
"Colorful Star, Colored Drawing, Travel Poem": SongData(2900456, "15-1", "Cute Is Everything Vol.3", False, 3, 4, 6),
"Satell Knight": SongData(2900457, "15-2", "Cute Is Everything Vol.3", False, 3, 6, 8),
"Black River Feat.Mes": SongData(2900458, "15-3", "Cute Is Everything Vol.3", True, 1, 4, 6),
"I am sorry": SongData(2900459, "15-4", "Cute Is Everything Vol.3", False, 2, 5, 8),
"Ueta Tori Tachi": SongData(2900460, "15-5", "Cute Is Everything Vol.3", False, 3, 6, 8),
"Elysion's Old Mans": SongData(2900462, "14-0", "Happy Otaku Pack Vol.6", False, 3, 5, 8),
"AXION": SongData(2900463, "14-1", "Happy Otaku Pack Vol.6", False, 4, 5, 8),
"Amnesia": SongData(2900464, "14-2", "Happy Otaku Pack Vol.6", True, 3, 6, 9),
"Onsen Dai Sakusen": SongData(2900465, "14-3", "Happy Otaku Pack Vol.6", True, 4, 6, 8),
"Gleam stone": SongData(2900466, "14-4", "Happy Otaku Pack Vol.6", False, 4, 7, 9),
"GOODWORLD": SongData(2900467, "14-5", "Happy Otaku Pack Vol.6", False, 4, 7, 10),
"Instant Soluble Neon": SongData(2900469, "13-0", "Cute Is Everything Vol.2", True, 2, 4, 7),
"Retrospective Poem on the Planet": SongData(2900470, "13-1", "Cute Is Everything Vol.2", False, 3, 5, 7),
"I'm Gonna Buy! Buy! Buy!": SongData(2900471, "13-2", "Cute Is Everything Vol.2", True, 4, 6, 8),
"Dating Manifesto": SongData(2900472, "13-3", "Cute Is Everything Vol.2", True, 2, 4, 6),
"First Snow": SongData(2900473, "13-4", "Cute Is Everything Vol.2", True, 2, 3, 6),
"Xin Shang Huahai": SongData(2900474, "13-5", "Cute Is Everything Vol.2", False, 3, 6, 8),
"Gaikan Chrysalis": SongData(2900476, "12-0", "Give Up TREATMENT Vol.5", False, 4, 6, 8),
"Sterelogue": SongData(2900477, "12-1", "Give Up TREATMENT Vol.5", True, 5, 7, 10),
"Cheshire's Dance": SongData(2900478, "12-2", "Give Up TREATMENT Vol.5", True, 4, 7, 10),
"Skrik": SongData(2900479, "12-3", "Give Up TREATMENT Vol.5", True, 5, 7, 11),
"Soda Pop Canva5!": SongData(2900480, "12-4", "Give Up TREATMENT Vol.5", False, 5, 8, 10),
"RUBY LINTe": SongData(2900481, "12-5", "Give Up TREATMENT Vol.5", False, 5, 8, 11),
"Brave My Heart": SongData(2900483, "11-0", "Happy Otaku Pack Vol.5", True, 3, 5, 7),
"Sakura Fubuki": SongData(2900484, "11-1", "Happy Otaku Pack Vol.5", False, 4, 7, 10),
"8bit Adventurer": SongData(2900485, "11-2", "Happy Otaku Pack Vol.5", False, 6, 8, 10),
"Suffering of screw": SongData(2900486, "11-3", "Happy Otaku Pack Vol.5", False, 3, 5, 8),
"tiny lady": SongData(2900487, "11-4", "Happy Otaku Pack Vol.5", True, 4, 6, 9),
"Power Attack": SongData(2900488, "11-5", "Happy Otaku Pack Vol.5", False, 5, 7, 10),
"Destr0yer": SongData(2900490, "10-0", "Give Up TREATMENT Vol.4", False, 4, 7, 9),
"Noel": SongData(2900491, "10-1", "Give Up TREATMENT Vol.4", False, 5, 8, 10),
"Kyoukiranbu": SongData(2900492, "10-2", "Give Up TREATMENT Vol.4", False, 7, 9, 11),
"Two Phace": SongData(2900493, "10-3", "Give Up TREATMENT Vol.4", True, 4, 7, 10),
"Fly Again": SongData(2900494, "10-4", "Give Up TREATMENT Vol.4", False, 5, 7, 10),
"ouroVoros": SongData(2900495, "10-5", "Give Up TREATMENT Vol.4", False, 7, 9, 11),
"Leave It Alone": SongData(2900497, "9-0", "Happy Otaku Pack Vol.4", True, 2, 5, 8),
"Tsubasa no Oreta Tenshitachi no Requiem": SongData(2900498, "9-1", "Happy Otaku Pack Vol.4", False, 4, 7, 9),
"Chronomia": SongData(2900499, "9-2", "Happy Otaku Pack Vol.4", False, 5, 7, 10),
"Dandelion's Daydream": SongData(2900500, "9-3", "Happy Otaku Pack Vol.4", True, 5, 7, 8),
"Lorikeet Flat design": SongData(2900501, "9-4", "Happy Otaku Pack Vol.4", True, 5, 7, 10),
"GOODRAGE": SongData(2900502, "9-5", "Happy Otaku Pack Vol.4", False, 6, 9, 11),
"Altale": SongData(2900504, "8-0", "Give Up TREATMENT Vol.3", False, 3, 5, 7),
"Brain Power": SongData(2900505, "8-1", "Give Up TREATMENT Vol.3", False, 4, 7, 10),
"Berry Go!!": SongData(2900506, "8-2", "Give Up TREATMENT Vol.3", False, 3, 6, 9),
"Sweet* Witch* Girl*": SongData(2900507, "8-3", "Give Up TREATMENT Vol.3", False, 6, 8, 10),
"trippers feeling!": SongData(2900508, "8-4", "Give Up TREATMENT Vol.3", True, 5, 7, 9),
"Lilith ambivalence lovers": SongData(2900509, "8-5", "Give Up TREATMENT Vol.3", False, 5, 8, 10),
"Brave My Soul": SongData(2900511, "7-0", "Give Up TREATMENT Vol.2", False, 4, 6, 8),
"Halcyon": SongData(2900512, "7-1", "Give Up TREATMENT Vol.2", False, 4, 7, 10),
"Crimson Nightingale": SongData(2900513, "7-2", "Give Up TREATMENT Vol.2", True, 4, 7, 10),
"Invader": SongData(2900514, "7-3", "Give Up TREATMENT Vol.2", True, 3, 7, 11),
"Lyrith": SongData(2900515, "7-4", "Give Up TREATMENT Vol.2", False, 5, 7, 10),
"GOODBOUNCE": SongData(2900516, "7-5", "Give Up TREATMENT Vol.2", False, 4, 6, 9),
"Out of Sense": SongData(2900518, "6-0", "Budget Is Burning Vol.1", False, 3, 5, 8),
"My Life Is For You": SongData(2900519, "6-1", "Budget Is Burning Vol.1", False, 2, 4, 7),
"Etude -Sunset-": SongData(2900520, "6-2", "Budget Is Burning Vol.1", True, 5, 7, 9),
"Goodbye Boss": SongData(2900521, "6-3", "Budget Is Burning Vol.1", False, 4, 6, 8),
"Stargazer": SongData(2900522, "6-4", "Budget Is Burning Vol.1", True, 2, 5, 8),
"Lys Tourbillon": SongData(2900523, "6-5", "Budget Is Burning Vol.1", True, 4, 6, 8),
"Thirty Million Persona": SongData(2900525, "5-0", "Happy Otaku Pack Vol.3", False, 2, 4, 6),
"conflict": SongData(2900526, "5-1", "Happy Otaku Pack Vol.3", False, 2, 6, 9),
"Enka Dance Music": SongData(2900527, "5-2", "Happy Otaku Pack Vol.3", False, 3, 5, 7),
"XING": SongData(2900528, "5-3", "Happy Otaku Pack Vol.3", True, 4, 6, 8),
"Amakakeru Soukyuu no Serenade": SongData(2900529, "5-4", "Happy Otaku Pack Vol.3", False, 3, 6, 9),
"Gift box": SongData(2900530, "5-5", "Happy Otaku Pack Vol.3", False, 5, 7, 10),
"MUSEDASH!!!!": SongData(2900532, "4-0", "Happy Otaku Pack Vol.2", False, 2, 6, 9),
"Imprinting": SongData(2900533, "4-1", "Happy Otaku Pack Vol.2", False, 3, 6, 9),
"Skyward": SongData(2900534, "4-2", "Happy Otaku Pack Vol.2", True, 4, 7, 10),
"La nuit de vif": SongData(2900535, "4-3", "Happy Otaku Pack Vol.2", True, 2, 5, 8),
"Bit-alize": SongData(2900536, "4-4", "Happy Otaku Pack Vol.2", False, 3, 6, 8),
"GOODTEK": SongData(2900537, "4-5", "Happy Otaku Pack Vol.2", False, 4, 6, 9),
"Maharajah": SongData(2900539, "3-0", "Happy Otaku Pack Vol.1", False, 1, 3, 6),
"keep on running": SongData(2900540, "3-1", "Happy Otaku Pack Vol.1", False, 5, 7, 9),
"Kafig": SongData(2900541, "3-2", "Happy Otaku Pack Vol.1", True, 4, 6, 8),
"-+": SongData(2900542, "3-3", "Happy Otaku Pack Vol.1", True, 4, 6, 8),
"Tenri Kaku Jou": SongData(2900543, "3-4", "Happy Otaku Pack Vol.1", True, 3, 6, 9),
"Adjudicatorz-DanZai-": SongData(2900544, "3-5", "Happy Otaku Pack Vol.1", False, 3, 7, 10),
"Oriens": SongData(2900546, "2-0", "Give Up TREATMENT Vol.1", True, 3, 7, 9),
"PUPA": SongData(2900547, "2-1", "Give Up TREATMENT Vol.1", False, 6, 8, 11),
"Luna Express 2032": SongData(2900548, "2-2", "Give Up TREATMENT Vol.1", False, 4, 6, 8),
"Ukiyoe Yokochou": SongData(2900549, "2-3", "Give Up TREATMENT Vol.1", False, 6, 7, 9),
"Alice in Misanthrope": SongData(2900550, "2-4", "Give Up TREATMENT Vol.1", False, 5, 7, 10),
"GOODMEN": SongData(2900551, "2-5", "Give Up TREATMENT Vol.1", False, 5, 7, 10),
"Sunshine and Rainbow after August Rain": SongData(2900553, "1-0", "Cute Is Everything Vol.1", False, 2, 5, 8),
"Magical Number": SongData(2900554, "1-1", "Cute Is Everything Vol.1", False, 2, 5, 8),
"Dreaming Girl": SongData(2900555, "1-2", "Cute Is Everything Vol.1", False, 2, 5, 6),
"Daruma-san Fell Over": SongData(2900556, "1-3", "Cute Is Everything Vol.1", False, 3, 4, 6),
"Different": SongData(2900557, "1-4", "Cute Is Everything Vol.1", False, 1, 3, 6),
"The Future of the Phantom": SongData(2900558, "1-5", "Cute Is Everything Vol.1", False, 1, 3, 5),
"Doki Doki Jump!": SongData(2900560, "63-0", "MUSE RADIO FM104", True, 3, 5, 7),
"Centennial Streamers High": SongData(2900561, "63-1", "MUSE RADIO FM104", False, 4, 7, 9),
"Love Patrol": SongData(2900562, "63-2", "MUSE RADIO FM104", True, 3, 5, 7),
"Mahorova": SongData(2900563, "63-3", "MUSE RADIO FM104", True, 3, 5, 8),
"Yoru no machi": SongData(2900564, "63-4", "MUSE RADIO FM104", True, 1, 4, 7),
"INTERNET YAMERO": SongData(2900565, "63-5", "MUSE RADIO FM104", True, 6, 8, 10),
"Abracadabra": SongData(2900566, "43-24", "MD Plus Project", False, 6, 8, 10),
"Squalldecimator feat. EZ-Ven": SongData(2900567, "43-25", "MD Plus Project", True, 5, 7, 9),
"Amateras Rhythm": SongData(2900568, "43-26", "MD Plus Project", True, 6, 8, 11),
"Record one's Dream": SongData(2900569, "43-27", "MD Plus Project", False, 4, 7, 10),
"Lunatic": SongData(2900570, "43-28", "MD Plus Project", True, 5, 8, 10),
"Jiumeng": SongData(2900571, "43-29", "MD Plus Project", True, 3, 6, 8),
"The Day We Become Family": SongData(2900572, "43-30", "MD Plus Project", True, 3, 5, 8),
"Sutori ma FIRE!?!?": SongData(2900574, "64-0", "COSMIC RADIO PEROLIST", True, 3, 5, 8),
"Tanuki Step": SongData(2900575, "64-1", "COSMIC RADIO PEROLIST", True, 5, 7, 10),
"Space Stationery": SongData(2900576, "64-2", "COSMIC RADIO PEROLIST", True, 5, 7, 10),
"Songs Are Judged 90% by Chorus feat. Mameko": SongData(2900577, "64-3", "COSMIC RADIO PEROLIST", True, 6, 8, 10),
"Kawai Splendid Space Thief": SongData(2900578, "64-4", "COSMIC RADIO PEROLIST", False, 6, 8, 10),
"Night City Runway": SongData(2900579, "64-5", "COSMIC RADIO PEROLIST", True, 4, 6, 8),
"Chaos Shotgun feat. ChumuNote": SongData(2900580, "64-6", "COSMIC RADIO PEROLIST", True, 6, 8, 10),
"mew mew magical summer": SongData(2900581, "64-7", "COSMIC RADIO PEROLIST", False, 5, 8, 10),
"BrainDance": SongData(2900583, "65-0", "NeonAbyss", True, 3, 6, 9),
"My Focus!": SongData(2900584, "65-1", "NeonAbyss", True, 5, 7, 10),
"ABABABA BURST": SongData(2900585, "65-2", "NeonAbyss", True, 5, 7, 9),
"ULTRA HIGHER": SongData(2900586, "65-3", "NeonAbyss", True, 4, 7, 10),
"Silver Bullet": SongData(2900587, "43-31", "MD Plus Project", True, 5, 7, 10),
"Random": SongData(2900588, "43-32", "MD Plus Project", True, 4, 7, 9),
"OTOGE-BOSS-KYOKU-CHAN": SongData(2900589, "43-33", "MD Plus Project", False, 6, 8, 10),
"Crow Rabbit": SongData(2900590, "43-34", "MD Plus Project", True, 7, 9, 11),
"SyZyGy": SongData(2900591, "43-35", "MD Plus Project", True, 6, 8, 10),
"Mermaid Radio": SongData(2900592, "43-36", "MD Plus Project", True, 3, 5, 7),
"Helixir": SongData(2900593, "43-37", "MD Plus Project", False, 6, 8, 10),
"Highway Cruisin'": SongData(2900594, "43-38", "MD Plus Project", False, 3, 5, 8),
"JACK PT BOSS": SongData(2900595, "43-39", "MD Plus Project", False, 6, 8, 10),
"Time Capsule": SongData(2900596, "43-40", "MD Plus Project", False, 7, 9, 11),
"39 Music!": SongData(2900598, "66-0", "Miku in Museland", False, 3, 5, 8),
"Hand in Hand": SongData(2900599, "66-1", "Miku in Museland", False, 1, 3, 6),
"Cynical Night Plan": SongData(2900600, "66-2", "Miku in Museland", False, 4, 6, 8),
"God-ish": SongData(2900601, "66-3", "Miku in Museland", False, 4, 7, 10),
"Darling Dance": SongData(2900602, "66-4", "Miku in Museland", False, 4, 7, 9),
"Hatsune Creation Myth": SongData(2900603, "66-5", "Miku in Museland", False, 6, 8, 10),
"The Vampire": SongData(2900604, "66-6", "Miku in Museland", False, 4, 6, 9),
"Future Eve": SongData(2900605, "66-7", "Miku in Museland", False, 4, 8, 11),
"Unknown Mother Goose": SongData(2900606, "66-8", "Miku in Museland", False, 4, 8, 10),
"Shun-ran": SongData(2900607, "66-9", "Miku in Museland", False, 4, 7, 9),
"NICE TYPE feat. monii": SongData(2900608, "43-41", "MD Plus Project", True, 3, 6, 8),
"Rainy Angel": SongData(2900610, "67-0", "Happy Otaku Pack Vol.18", True, 4, 6, 9),
"Gullinkambi": SongData(2900611, "67-1", "Happy Otaku Pack Vol.18", True, 4, 7, 10),
"RakiRaki Rebuilders!!!": SongData(2900612, "67-2", "Happy Otaku Pack Vol.18", True, 5, 7, 10),
"Laniakea": SongData(2900613, "67-3", "Happy Otaku Pack Vol.18", False, 5, 8, 10),
"OTTAMA GAZER": SongData(2900614, "67-4", "Happy Otaku Pack Vol.18", True, 5, 8, 10),
"Sleep Tight feat.Macoto": SongData(2900615, "67-5", "Happy Otaku Pack Vol.18", True, 3, 5, 8),
"New York Back Raise": SongData(2900617, "68-0", "Gambler's Tricks", True, 6, 8, 10),
"slic.hertz": SongData(2900618, "68-1", "Gambler's Tricks", True, 5, 7, 9),
"Fuzzy-Navel": SongData(2900619, "68-2", "Gambler's Tricks", True, 6, 8, 10),
"Swing Edge": SongData(2900620, "68-3", "Gambler's Tricks", True, 4, 8, 10),
"Twisted Escape": SongData(2900621, "68-4", "Gambler's Tricks", True, 5, 8, 10),
"Swing Sweet Twee Dance": SongData(2900622, "68-5", "Gambler's Tricks", False, 4, 7, 10),
"Sanyousei SAY YA!!!": SongData(2900623, "43-42", "MD Plus Project", False, 4, 6, 8),
"YUKEMURI TAMAONSEN II": SongData(2900624, "43-43", "MD Plus Project", False, 3, 6, 9),
"Samayoi no mei Amatsu": SongData(2900626, "69-0", "Touhou Mugakudan -III-", False, 4, 6, 9),
"INTERNET SURVIVOR": SongData(2900627, "69-1", "Touhou Mugakudan -III-", False, 5, 8, 10),
"Shuki*RaiRai": SongData(2900628, "69-2", "Touhou Mugakudan -III-", False, 5, 7, 9),
"HELLOHELL": SongData(2900629, "69-3", "Touhou Mugakudan -III-", False, 4, 7, 10),
"Calamity Fortune": SongData(2900630, "69-4", "Touhou Mugakudan -III-", True, 6, 8, 10),
"Tsurupettan": SongData(2900631, "69-5", "Touhou Mugakudan -III-", True, 2, 5, 8),
"Twilight Poems": SongData(2900632, "43-44", "MD Plus Project", True, 3, 6, 8),
"All My Friends feat. RANASOL": SongData(2900633, "43-45", "MD Plus Project", True, 4, 7, 9),
"Heartache": SongData(2900634, "43-46", "MD Plus Project", True, 5, 7, 10),
"Blue Lemonade": SongData(2900635, "43-47", "MD Plus Project", True, 3, 6, 8),
"Haunted Dance": SongData(2900636, "43-48", "MD Plus Project", False, 6, 9, 11),
"Hey Vincent.": SongData(2900637, "43-49", "MD Plus Project", True, 6, 8, 10),
"Meteor feat. TEA": SongData(2900638, "43-50", "MD Plus Project", True, 3, 6, 9),
"Narcissism Angel": SongData(2900639, "43-51", "MD Plus Project", True, 1, 3, 6),
"AlterLuna": SongData(2900640, "43-52", "MD Plus Project", True, 6, 8, 11),
"Niki Tousen": SongData(2900641, "43-53", "MD Plus Project", True, 6, 8, 10),
"Rettou Joutou": SongData(2900643, "70-0", "Rin Len's Mirrorland", False, 4, 7, 9),
"Telecaster B-Boy": SongData(2900644, "70-1", "Rin Len's Mirrorland", False, 5, 7, 10),
"Iya Iya Iya": SongData(2900645, "70-2", "Rin Len's Mirrorland", False, 2, 4, 7),
"Nee Nee Nee": SongData(2900646, "70-3", "Rin Len's Mirrorland", False, 4, 6, 8),
"Chaotic Love Revolution": SongData(2900647, "70-4", "Rin Len's Mirrorland", False, 4, 6, 8),
"Dance of the Corpses": SongData(2900648, "70-5", "Rin Len's Mirrorland", False, 2, 5, 8),
"Bitter Choco Decoration": SongData(2900649, "70-6", "Rin Len's Mirrorland", False, 3, 6, 9),
"Dance Robot Dance": SongData(2900650, "70-7", "Rin Len's Mirrorland", False, 4, 7, 10),
"Sweet Devil": SongData(2900651, "70-8", "Rin Len's Mirrorland", False, 5, 7, 9),
"Someday'z Coming": SongData(2900652, "70-9", "Rin Len's Mirrorland", False, 5, 7, 9),
"Yume Ou Mono Yo Secret": SongData(2900653, "0-53", "Default Music", True, 6, 8, 10),
"Yume Ou Mono Yo": SongData(2900654, "0-54", "Default Music", True, 1, 4, None),
"Sweet Dream VIVINOS": SongData(2900656, "71-0", "Valentine Stage", False, 1, 4, 7),
"Ruler Of My Heart VIVINOS": SongData(2900657, "71-1", "Valentine Stage", False, 2, 4, 6),
"Reality Show": SongData(2900658, "71-2", "Valentine Stage", False, 5, 7, 10),
"SIG feat.Tobokegao": SongData(2900659, "71-3", "Valentine Stage", True, 3, 6, 8),
"Rose Love": SongData(2900660, "71-4", "Valentine Stage", True, 2, 4, 7),
"Euphoria": SongData(2900661, "71-5", "Valentine Stage", True, 1, 3, 6),
"P E R O P E R O Brother Dance": SongData(2900663, "72-0", "Legends of Muse Warriors", True, None, 7, None),
"PA PPA PANIC": SongData(2900664, "72-1", "Legends of Muse Warriors", False, 4, 8, 10),
"How To Make Music Game Song!": SongData(2900665, "72-2", "Legends of Muse Warriors", True, 6, 8, 10),
"Re Re": SongData(2900666, "72-3", "Legends of Muse Warriors", True, 7, 9, 11),
"Marmalade Twins": SongData(2900667, "72-4", "Legends of Muse Warriors", True, 5, 8, 10),
"DOMINATOR": SongData(2900668, "72-5", "Legends of Muse Warriors", True, 7, 9, 11),
"Teshikani TESHiKANi": SongData(2900669, "72-6", "Legends of Muse Warriors", True, 5, 7, 9),
"Urban Magic": SongData(2900671, "73-0", "Happy Otaku Pack Vol.19", True, 3, 5, 7),
"Maid's Prank": SongData(2900672, "73-1", "Happy Otaku Pack Vol.19", True, 5, 7, 10),
"Dance Dance Good Night Dance": SongData(2900673, "73-2", "Happy Otaku Pack Vol.19", True, 2, 4, 7),
"Ops Limone": SongData(2900674, "73-3", "Happy Otaku Pack Vol.19", True, 5, 8, 11),
"NOVA": SongData(2900675, "73-4", "Happy Otaku Pack Vol.19", True, 6, 8, 10),
"Heaven's Gradius": SongData(2900676, "73-5", "Happy Otaku Pack Vol.19", True, 6, 8, 10),
"Ray Tuning": SongData(2900678, "74-0", "CHUNITHM COURSE MUSE", True, 6, 8, 10),
"World Vanquisher": SongData(2900679, "74-1", "CHUNITHM COURSE MUSE", True, 6, 8, 10),
"Tsukuyomi Ni Naru Replaced": SongData(2900680, "74-2", "CHUNITHM COURSE MUSE", True, 5, 7, 9),
"The wheel to the right": SongData(2900681, "74-3", "CHUNITHM COURSE MUSE", True, 5, 7, 9),
"Climax": SongData(2900682, "74-4", "CHUNITHM COURSE MUSE", True, 4, 8, 11),
"Spider's Thread": SongData(2900683, "74-5", "CHUNITHM COURSE MUSE", True, 5, 8, 10),
"HIT ME UP": SongData(2900684, "43-54", "MD Plus Project", True, 4, 6, 8),
"Test Me feat. Uyeon": SongData(2900685, "43-55", "MD Plus Project", True, 3, 5, 9),
"Assault TAXI": SongData(2900686, "43-56", "MD Plus Project", True, 4, 7, 10),
"No": SongData(2900687, "43-57", "MD Plus Project", False, 4, 6, 9),
"Pop it": SongData(2900688, "43-58", "MD Plus Project", True, 1, 3, 6),
"HEARTBEAT! KyunKyun!": SongData(2900689, "43-59", "MD Plus Project", True, 4, 6, 9),
"SUPERHERO": SongData(2900691, "75-0", "Novice Rider Pack", False, 2, 4, 7),
"Highway_Summer": SongData(2900692, "75-1", "Novice Rider Pack", True, 2, 4, 6),
"Mx. Black Box": SongData(2900693, "75-2", "Novice Rider Pack", True, 5, 7, 9),
"Sweet Encounter": SongData(2900694, "75-3", "Novice Rider Pack", True, 2, 4, 7),
"Echo over you... Secret": SongData(2900695, "0-55", "Default Music", False, 6, 8, 10),
"Echo over you...": SongData(2900696, "0-56", "Default Music", False, 1, 4, None),
"Tsukuyomi Ni Naru": SongData(2900697, "74-6", "CHUNITHM COURSE MUSE", True, 5, 8, 10),
"disco light": SongData(2900699, "76-0", "MUSE RADIO FM105", True, 5, 7, 9),
"room light feat.chancylemon": SongData(2900700, "76-1", "MUSE RADIO FM105", True, 3, 5, 7),
"Invisible": SongData(2900701, "76-2", "MUSE RADIO FM105", True, 3, 5, 8),
"Christmas Season-LLABB": SongData(2900702, "76-3", "MUSE RADIO FM105", True, 1, 4, 7),
"Hyouryu": SongData(2900704, "77-0", "Let's Rhythm Jam!", False, 6, 8, 10),
"The Whole Rest": SongData(2900705, "77-1", "Let's Rhythm Jam!", False, 5, 8, 10),
"Hydra": SongData(2900706, "77-2", "Let's Rhythm Jam!", False, 4, 7, 11),
"Pastel Lines": SongData(2900707, "77-3", "Let's Rhythm Jam!", False, 3, 6, 9),
"LINK x LIN#S": SongData(2900708, "77-4", "Let's Rhythm Jam!", False, 3, 6, 9),
"Arcade ViruZ": SongData(2900709, "77-5", "Let's Rhythm Jam!", False, 6, 8, 11),
"Eve Avenir": SongData(2900711, "78-0", "Endless Pirouette", True, 6, 8, 10),
"Silverstring": SongData(2900712, "78-1", "Endless Pirouette", True, 5, 7, 10),
"Melusia": SongData(2900713, "78-2", "Endless Pirouette", False, 5, 7, 10),
"Devil's Castle": SongData(2900714, "78-3", "Endless Pirouette", True, 4, 7, 10),
"Abatement": SongData(2900715, "78-4", "Endless Pirouette", True, 6, 8, 10),
"Azalea": SongData(2900716, "78-5", "Endless Pirouette", False, 4, 8, 10),
"Brightly World": SongData(2900717, "78-6", "Endless Pirouette", True, 6, 8, 10),
"We'll meet in every world ***": SongData(2900718, "78-7", "Endless Pirouette", True, 7, 9, 11),
"Collapsar": SongData(2900719, "78-8", "Endless Pirouette", True, 7, 9, 10),
"Parousia": SongData(2900720, "78-9", "Endless Pirouette", False, 6, 8, 10),
"Gunners in the Rain": SongData(2900722, "79-0", "Ensemble Arcanum", False, 5, 8, 10),
"Halzion": SongData(2900723, "79-1", "Ensemble Arcanum", False, 2, 5, 8),
"SHOWTIME!!": SongData(2900724, "79-2", "Ensemble Arcanum", False, 6, 8, 10),
"Achromic Riddle": SongData(2900725, "79-3", "Ensemble Arcanum", False, 6, 8, 10),
"karanosu": SongData(2900726, "79-4", "Ensemble Arcanum", False, 3, 6, 8),
"Necromantic": SongData(2900727, "43-60", "MD Plus Project", False, 6, 8, 10),
"Saishuu kichiku imouto Flandre-S": SongData(2900729, "80-0", "Touhou Mugakudan -IV-", False, 6, 8, 10),
"Kachoufuugetsu": SongData(2900730, "80-1", "Touhou Mugakudan -IV-", False, 2, 6, 8),
"Maid heart is a puppet": SongData(2900731, "80-2", "Touhou Mugakudan -IV-", False, 5, 7, 9),
"Trance dance anarchy": SongData(2900732, "80-3", "Touhou Mugakudan -IV-", False, 4, 7, 10),
"fairy stage": SongData(2900733, "80-4", "Touhou Mugakudan -IV-", False, 4, 6, 9),
"Scarlet Police on Ghetto Patrol": SongData(2900734, "80-5", "Touhou Mugakudan -IV-", False, 5, 7, 10),
"Unwelcome School": SongData(2900735, "81-0", "MD-level Tactical Training Blu-ray", False, 6, 8, 10),
"Usagi Flap": SongData(2900736, "81-1", "MD-level Tactical Training Blu-ray", False, 3, 6, 8),
"RE Aoharu": SongData(2900737, "81-2", "MD-level Tactical Training Blu-ray", False, 3, 5, 8),
"Operation*DOTABATA!": SongData(2900738, "81-3", "MD-level Tactical Training Blu-ray", False, 5, 7, 10),
}

View File

@@ -1,597 +0,0 @@
Magical Wonderland|0-48|Default Music|True|1|3|0|
Iyaiya|0-0|Default Music|True|1|4|0|
Wonderful Pain|0-2|Default Music|False|1|3|0|
Breaking Dawn|0-3|Default Music|True|2|4|0|
One-Way Subway|0-4|Default Music|True|1|4|0|
Frost Land|0-1|Default Music|False|1|3|6|
Heart-Pounding Flight|0-5|Default Music|True|2|5|0|
Pancake is Love|0-29|Default Music|True|2|4|7|
Shiguang Tuya|0-6|Default Music|True|2|5|0|
Evolution|0-37|Default Music|False|2|4|7|
Dolphin and Broadcast|0-7|Default Music|True|2|5|0|
Yuki no Shizuku Ame no Oto|0-8|Default Music|True|2|4|6|
Best One feat.tooko|0-43|Default Music|False|3|5|0|
Candy-coloured Love Theory|0-31|Default Music|False|2|4|6|
Night Wander|0-38|Default Music|False|3|5|7|
Dohna Dohna no Uta|0-46|Default Music|False|2|4|6|
Spring Carnival|0-9|Default Music|False|2|4|7|
DISCO NIGHT|0-30|Default Music|True|2|4|7|
Koi no Moonlight|0-49|Default Music|False|2|5|8|
Lian Ai Audio Navigation|0-10|Default Music|False|3|5|7|
Lights of Muse|0-11|Default Music|True|4|6|8|10
midstream jam|0-12|Default Music|False|2|5|8|
Nihao|0-40|Default Music|False|3|5|7|
Confession|0-13|Default Music|False|3|5|8|
Galaxy Striker|0-32|Default Music|False|4|7|9|
Departure Road|0-14|Default Music|True|2|5|8|
Bass Telekinesis|0-15|Default Music|False|2|5|8|
Cage of Almeria|0-16|Default Music|True|3|5|7|
Ira|0-17|Default Music|True|4|6|8|
Blackest Luxury Car|0-18|Default Music|True|3|6|8|
Medicine of Sing|0-19|Default Music|False|3|6|8|
irregulyze|0-20|Default Music|True|3|6|8|
I don't care about Christmas though|0-47|Default Music|False|4|6|8|
Imaginary World|0-21|Default Music|True|4|6|8|10
Dysthymia|0-22|Default Music|True|4|7|9|
From the New World|0-42|Default Music|False|2|5|7|
NISEGAO|0-33|Default Music|True|4|7|9|
Say! Fanfare!|0-44|Default Music|False|4|6|9|
Star Driver|0-34|Default Music|True|5|7|9|
Formation|0-23|Default Music|True|4|6|9|
Shinsou Masui|0-24|Default Music|True|4|6|10|
Mezame Eurythmics|0-50|Default Music|False|4|6|9|
Shenri Kuaira -repeat-|0-51|Default Music|False|5|7|9|
Latitude|0-25|Default Music|True|3|6|9|
Aqua Stars|0-39|Default Music|False|5|7|10|
Funkotsu Saishin Casino|0-26|Default Music|False|5|7|10|
Clock Room & Spiritual World|0-27|Default Music|True|4|6|9|
INTERNET OVERDOSE|0-52|Default Music|False|3|6|9|
Tu Hua|0-35|Default Music|True|4|7|9|
Mujinku-Vacuum|0-28|Default Music|False|5|7|11|
MilK|0-36|Default Music|False|5|7|9|
umpopoff|0-41|Default Music|False|0|?|0|
Mopemope|0-45|Default Music|False|4|7|9|11
The Happycore Idol|43-0|MD Plus Project|True|2|5|7|
Amatsumikaboshi|43-1|MD Plus Project|True|4|6|8|10
ARIGA THESIS|43-2|MD Plus Project|True|3|6|10|
Night of Nights|43-3|MD Plus Project|False|4|7|10|
#Psychedelic_Meguro_River|43-4|MD Plus Project|False|3|6|8|
can you feel it|43-5|MD Plus Project|False|4|6|8|9
Midnight O'clock|43-6|MD Plus Project|True|3|6|8|
Rin|43-7|MD Plus Project|True|5|7|10|
Smile-mileS|43-8|MD Plus Project|False|6|8|10|
Believing and Being|43-9|MD Plus Project|True|4|6|9|
Catalyst|43-10|MD Plus Project|False|5|7|9|
don't!stop!eroero!|43-11|MD Plus Project|True|5|7|9|
pa pi pu pi pu pi pa|43-12|MD Plus Project|False|6|8|10|
Sand Maze|43-13|MD Plus Project|True|6|8|10|11
Diffraction|43-14|MD Plus Project|True|5|8|10|
AKUMU|43-15|MD Plus Project|False|4|6|8|
Queen Aluett|43-16|MD Plus Project|True|7|9|11|
DROPS|43-17|MD Plus Project|False|2|5|8|
Frightfully-insane Flan-chan's frightful song|43-18|MD Plus Project|False|5|7|10|
snooze|43-19|MD Plus Project|False|5|7|10|
Kuishinbo Hacker feat.Kuishinbo Akachan|43-20|MD Plus Project|True|5|7|9|
Inu no outa|43-21|MD Plus Project|True|3|5|7|
Prism Fountain|43-22|MD Plus Project|True|7|9|11|
Gospel|43-23|MD Plus Project|False|4|6|9|
East Ai Li Lovely|62-0|Happy Otaku Pack Vol.17|False|2|4|7|
Mori Umi no Fune|62-1|Happy Otaku Pack Vol.17|True|5|7|9|
Ooi|62-2|Happy Otaku Pack Vol.17|True|5|7|10|
Numatta!!|62-3|Happy Otaku Pack Vol.17|True|5|7|9|
SATELLITE|62-4|Happy Otaku Pack Vol.17|False|5|7|9|10
Fantasia Sonata Colorful feat. V!C|62-5|Happy Otaku Pack Vol.17|True|6|8|11|
MuseDash ka nanika hi|61-0|Ola Dash|True|?|?|¿|
Aleph-0|61-1|Ola Dash|True|7|9|11|
Buttoba Supernova|61-2|Ola Dash|False|5|7|10|11
Rush-Hour|61-3|Ola Dash|False|IG|Jh|a2|Eh
3rd Avenue|61-4|Ola Dash|False|3|5||
WORLDINVADER|61-5|Ola Dash|True|5|8|10|11
N3V3R G3T OV3R|60-0|maimai DX Limited-time Suite|True|4|7|10|
Oshama Scramble!|60-1|maimai DX Limited-time Suite|True|5|7|10|
Valsqotch|60-2|maimai DX Limited-time Suite|True|5|9|11|
Paranormal My Mind|60-3|maimai DX Limited-time Suite|True|5|7|9|
Flower, snow and Drum'n'bass.|60-4|maimai DX Limited-time Suite|True|5|8|10|?
Amenohoakari|60-5|maimai DX Limited-time Suite|True|6|8|10|
Boiling Blood|59-0|MSR Anthology|True|5|8|10|
ManiFesto|59-1|MSR Anthology|True|4|6|9|
Operation Blade|59-2|MSR Anthology|True|3|5|7|
Radiant|59-3|MSR Anthology|True|3|5|8|
Renegade|59-4|MSR Anthology|True|3|5|8|
Speed of Light|59-5|MSR Anthology|False|1|4|7|
Dossoles Holiday|59-6|MSR Anthology|True|5|7|9|
Autumn Moods|59-7|MSR Anthology|True|3|5|7|
People People|58-0|Nanahira Paradise|True|5|7|9|11
Endless Error Loop|58-1|Nanahira Paradise|True|4|7|9|
Forbidden Pizza!|58-2|Nanahira Paradise|True|5|7|9|
Don't Make the Vocalist do Anything Insane|58-3|Nanahira Paradise|True|5|8|9|
Tokimeki*Meteostrike|57-0|Happy Otaku Pack Vol.16|True|3|6|8|
Down Low|57-1|Happy Otaku Pack Vol.16|True|4|6|8|
LOUDER MACHINE|57-2|Happy Otaku Pack Vol.16|True|5|7|9|
Sorewa mo Lovechu|57-3|Happy Otaku Pack Vol.16|True|5|7|10|
Rave_Tech|57-4|Happy Otaku Pack Vol.16|True|5|8|10|
Brilliant & Shining!|57-5|Happy Otaku Pack Vol.16|False|5|8|10|
Psyched Fevereiro|56-0|Give Up TREATMENT Vol.11|False|5|8|10|
Inferno City|56-1|Give Up TREATMENT Vol.11|False|6|8|10|
Paradigm Shift|56-2|Give Up TREATMENT Vol.11|False|4|7|10|
Snapdragon|56-3|Give Up TREATMENT Vol.11|False|5|7|10|
Prestige and Vestige|56-4|Give Up TREATMENT Vol.11|True|6|8|11|
Tiny Fate|56-5|Give Up TREATMENT Vol.11|False|7|9|11|
Tsuki ni Murakumo Hana ni Kaze|55-0|Touhou Mugakudan -2-|False|3|5|7|
Patchouli's - Best Hit GSK|55-1|Touhou Mugakudan -2-|False|3|5|8|
Monosugoi Space Shuttle de Koishi ga Monosugoi uta|55-2|Touhou Mugakudan -2-|False|3|5|7|11
Kakoinaki Yo wa Ichigo no Tsukikage|55-3|Touhou Mugakudan -2-|False|3|6|8|
Psychedelic Kizakura Doumei|55-4|Touhou Mugakudan -2-|False|4|7|10|
Mischievous Sensation|55-5|Touhou Mugakudan -2-|False|5|7|9|
White Canvas|54-0|MEGAREX THE FUTURE|False|3|6|8|
Gloomy Flash|54-1|MEGAREX THE FUTURE|False|5|8|10|
Find this Month's Featured Playlist|54-2|MEGAREX THE FUTURE|False|?|?|¿|
Sunday Night|54-3|MEGAREX THE FUTURE|False|3|6|9|
Goodbye Goodnight|54-4|MEGAREX THE FUTURE|False|4|6|9|
ENDLESS CIDER|54-5|MEGAREX THE FUTURE|False|4|6|8|
On And On!!|53-0|Happy Otaku Pack Vol.15|True|4|7|9|11
Trip!|53-1|Happy Otaku Pack Vol.15|True|3|5|7|
Hoshi no otoshimono|53-2|Happy Otaku Pack Vol.15|False|5|7|9|
Plucky Race|53-3|Happy Otaku Pack Vol.15|True|5|8|10|11
Fantasia Sonata Destiny|53-4|Happy Otaku Pack Vol.15|True|3|7|10|
Run through|53-5|Happy Otaku Pack Vol.15|False|5|8|10|
marooned night|52-0|MUSE RADIO FM103|False|2|4|6|
daydream girl|52-1|MUSE RADIO FM103|False|3|6|8|
Not Ornament|52-2|MUSE RADIO FM103|True|3|5|8|
Baby Pink|52-3|MUSE RADIO FM103|False|3|5|8|
I'm Here|52-4|MUSE RADIO FM103|False|4|6|8|
Masquerade Diary|51-0|Virtual Idol Production|True|2|5|8|
Reminiscence|51-1|Virtual Idol Production|True|5|7|9|
DarakuDatenshi|51-2|Virtual Idol Production|True|3|6|9|
D.I.Y.|51-3|Virtual Idol Production|False|4|6|9|
Boys in Virtual Land|51-4|Virtual Idol Production|False|4|7|9|
kui|51-5|Virtual Idol Production|True|5|7|9|11
Nyan Cat|50-0|Nyanya Universe!|False|4|7|9|
PeroPero in the Universe|50-1|Nyanya Universe!|True|?|?|¿|
In-kya Yo-kya Onmyoji|50-2|Nyanya Universe!|False|6|8|10|
KABOOOOOM!!!!|50-3|Nyanya Universe!|True|4|6|8|
Doppelganger|50-4|Nyanya Universe!|True|5|7|9|12
Pray a LOVE|49-0|DokiDoki! Valentine!|False|2|5|8|
Love-Avoidance Addiction|49-1|DokiDoki! Valentine!|False|3|5|7|
Daisuki Dayo feat.Wotoha|49-2|DokiDoki! Valentine!|False|5|7|10|
glory day|48-0|DJMAX Reflect|False|2|5|7|
Bright Dream|48-1|DJMAX Reflect|False|2|4|7|
Groovin Up|48-2|DJMAX Reflect|False|4|6|8|
I Want You|48-3|DJMAX Reflect|False|3|6|8|
OBLIVION|48-4|DJMAX Reflect|False|3|6|9|
Elastic STAR|48-5|DJMAX Reflect|False|4|6|8|
U.A.D|48-6|DJMAX Reflect|False|4|6|8|10
Jealousy|48-7|DJMAX Reflect|False|3|5|7|
Memory of Beach|48-8|DJMAX Reflect|False|3|6|8|
Don't Die|48-9|DJMAX Reflect|False|6|8|10|
Y CE Ver.|48-10|DJMAX Reflect|False|4|6|9|
Fancy Night|48-11|DJMAX Reflect|False|4|6|8|
Can We Talk|48-12|DJMAX Reflect|False|4|6|8|
Give Me 5|48-13|DJMAX Reflect|False|2|6|8|
Nightmare|48-14|DJMAX Reflect|False|7|9|11|
Haze of Autumn|47-0|Arcaea|True|3|6|9|
GIMME DA BLOOD|47-1|Arcaea|False|3|6|9|
Libertas|47-2|Arcaea|False|4|7|10|
Cyaegha|47-3|Arcaea|False|5|7|9|11
Bang!!|46-0|Happy Otaku Pack Vol.14|False|4|6|8|
Paradise 2|46-1|Happy Otaku Pack Vol.14|False|4|6|8|
Symbol|46-2|Happy Otaku Pack Vol.14|False|5|7|9|
Nekojarashi|46-3|Happy Otaku Pack Vol.14|False|5|8|10|11
A Philosophical Wanderer|46-4|Happy Otaku Pack Vol.14|False|4|6|10|
Isouten|46-5|Happy Otaku Pack Vol.14|True|6|8|10|11
ONOMATO Pairing!!!|45-0|WACCA Horizon|False|4|6|9|
with U|45-1|WACCA Horizon|False|6|8|10|11
Chariot|45-2|WACCA Horizon|False|3|6|9|
GASHATT|45-3|WACCA Horizon|False|5|7|10|
LIN NE KRO NE feat. lasah|45-4|WACCA Horizon|False|6|8|10|
ANGEL HALO|45-5|WACCA Horizon|False|5|8|11|
Party in the HOLLOWood|44-0|Happy Otaku Pack Vol.13|False|3|6|8|
Ying Ying da Zuozhan|44-1|Happy Otaku Pack Vol.13|True|5|7|9|
Howlin' Pumpkin|44-2|Happy Otaku Pack Vol.13|True|4|6|8|
Bad Apple!! feat. Nomico|42-0|Touhou Mugakudan -1-|False|1|3|6|8
Iro wa Nioedo, Chirinuru wo|42-1|Touhou Mugakudan -1-|False|2|4|7|
Cirno's Perfect Math Class|42-2|Touhou Mugakudan -1-|False|4|7|9|
Hiiro Gekka Kyousai no Zetsu|42-3|Touhou Mugakudan -1-|False|4|6|8|
Flowery Moonlit Night|42-4|Touhou Mugakudan -1-|False|3|6|8|
Unconscious Requiem|42-5|Touhou Mugakudan -1-|False|3|6|8|
Super Battleworn Insomniac|41-0|7th Beat Games|True|4|7|9|?
Bomb-Sniffing Pomeranian|41-1|7th Beat Games|True|4|6|8|
Rollerdisco Rumble|41-2|7th Beat Games|True|4|6|9|
Rose Garden|41-3|7th Beat Games|False|5|8|9|
EMOMOMO|41-4|7th Beat Games|True|4|7|10|
Heracles|41-5|7th Beat Games|False|6|8|10|?
Rush-More|40-0|Happy Otaku Pack Vol.12|False|4|7|9|
Kill My Fortune|40-1|Happy Otaku Pack Vol.12|False|5|7|10|
Yosari Tsukibotaru Suminoborite|40-2|Happy Otaku Pack Vol.12|False|5|7|9|
JUMP! HardCandy|40-3|Happy Otaku Pack Vol.12|False|3|6|8|
Hibari|40-4|Happy Otaku Pack Vol.12|False|3|5|8|
OCCHOCO-REST-LESS|40-5|Happy Otaku Pack Vol.12|True|4|7|9|
See-Saw Day|39-0|MUSE RADIO FM102|True|1|3|6|
happy hour|39-1|MUSE RADIO FM102|True|2|4|7|
Seikimatsu no Natsu|39-2|MUSE RADIO FM102|True|4|6|8|
twinkle night|39-3|MUSE RADIO FM102|False|3|6|8|
ARUYA HARERUYA|39-4|MUSE RADIO FM102|False|2|5|7|
Blush|39-5|MUSE RADIO FM102|False|2|4|7|
Naked Summer|39-6|MUSE RADIO FM102|True|4|6|8|
BLESS ME|39-7|MUSE RADIO FM102|True|2|5|7|
FM 17314 SUGAR RADIO|39-8|MUSE RADIO FM102|True|?|?|?|
NO ONE YES MAN|38-0|Phigros|False|5|7|9|
Snowfall, Merry Christmas|38-1|Phigros|False|5|8|10|
Igallta|38-2|Phigros|False|6|8|10|11
Colored Glass|37-0|Cute Is Everything Vol.7|False|1|4|7|
Neonlights|37-1|Cute Is Everything Vol.7|False|4|7|9|
Hope for the flowers|37-2|Cute Is Everything Vol.7|False|4|7|9|
Seaside Cycling on May 30|37-3|Cute Is Everything Vol.7|False|3|6|8|
SKY HIGH|37-4|Cute Is Everything Vol.7|False|2|4|6|
Mousou Chu!!|37-5|Cute Is Everything Vol.7|False|4|7|8|
NightTheater|36-0|Give Up TREATMENT Vol.10|True|6|8|11|
Cutter|36-1|Give Up TREATMENT Vol.10|False|4|7|10|
bamboo|36-2|Give Up TREATMENT Vol.10|False|6|8|10|11
enchanted love|36-3|Give Up TREATMENT Vol.10|False|2|6|9|
c.s.q.n.|36-4|Give Up TREATMENT Vol.10|False|5|8|11|
Booouncing!!|36-5|Give Up TREATMENT Vol.10|False|5|7|10|
PeroPeroGames goes Bankrupt|35-0|Happy Otaku Pack SP|True|6|8|10|
MARENOL|35-1|Happy Otaku Pack SP|False|4|7|10|
I am really good at Japanese style|35-2|Happy Otaku Pack SP|True|6|8|10|
Rush B|35-3|Happy Otaku Pack SP|True|4|7|9|
DataErr0r|35-4|Happy Otaku Pack SP|False|5|7|9|?
Burn|35-5|Happy Otaku Pack SP|True|4|7|9|
ALiVE|34-0|HARDCORE TANO*C|False|5|7|10|
BATTLE NO.1|34-1|HARDCORE TANO*C|False|5|8|10|11
Cthugha|34-2|HARDCORE TANO*C|False|6|8|10|11
TWINKLE*MAGIC|34-3|HARDCORE TANO*C|False|4|7|10|11
Comet Coaster|34-4|HARDCORE TANO*C|False|6|8|10|11
XODUS|34-5|HARDCORE TANO*C|False|7|9|11|12
Fireflies|33-0|cyTus|True|1|4|7|
Light up my love!!|33-1|cyTus|True|3|5|7|
Happiness Breeze|33-2|cyTus|True|4|6|8|9
Chrome VOX|33-3|cyTus|True|6|8|10|11
CHAOS|33-4|cyTus|True|3|6|9|
Saika|33-5|cyTus|True|3|5|8|
Standby for Action|33-6|cyTus|True|4|6|8|
Hydrangea|33-7|cyTus|True|5|7|9|
Amenemhat|33-8|cyTus|True|6|8|10|
Santouka|33-9|cyTus|True|2|5|8|
HEXENNACHTROCK-katashihaya-|33-10|cyTus|True|4|8|10|
Blah!!|33-11|cyTus|True|5|8|11|
CHAOS Glitch|33-12|cyTus|True|0|?|0|
Preparara|32-0|Let's Do Bad Things Together|False|1|4|6|
Whatcha;Whatcha Doin'|32-1|Let's Do Bad Things Together|False|3|6|9|
Madara|32-2|Let's Do Bad Things Together|False|4|6|9|
pICARESq|32-3|Let's Do Bad Things Together|False|4|6|8|
Desastre|32-4|Let's Do Bad Things Together|False|4|6|8|
Shoot for the Moon|32-5|Let's Do Bad Things Together|False|2|5|8|
The 90's Decision|31-0|Happy Otaku Pack Vol.11|True|5|7|9|
Medusa|31-1|Happy Otaku Pack Vol.11|False|4|6|8|10
Final Step!|31-2|Happy Otaku Pack Vol.11|False|5|7|10|
MAGENTA POTION|31-3|Happy Otaku Pack Vol.11|False|4|7|9|
Cross Ray|31-4|Happy Otaku Pack Vol.11|False|3|6|9|
Square Lake|31-5|Happy Otaku Pack Vol.11|False|6|8|9|11
Girly Cupid|30-0|Cute Is Everything Vol.6|False|3|6|8|
sheep in the light|30-1|Cute Is Everything Vol.6|False|2|5|8|
Breaker city|30-2|Cute Is Everything Vol.6|False|4|6|9|
heterodoxy|30-3|Cute Is Everything Vol.6|False|4|6|8|
Computer Music Girl|30-4|Cute Is Everything Vol.6|False|3|5|7|
Focus Point|30-5|Cute Is Everything Vol.6|True|2|5|7|
Groove Prayer|29-0|Let' s GROOVE!|True|3|5|7|
FUJIN Rumble|29-1|Let' s GROOVE!|True|5|7|10|11
Marry me, Nightmare|29-2|Let' s GROOVE!|False|6|8|11|
HG Makaizou Polyvinyl Shounen|29-3|Let' s GROOVE!|True|4|7|9|10
Seizya no Ibuki|29-4|Let' s GROOVE!|True|6|8|10|
ouroboros -twin stroke of the end-|29-5|Let' s GROOVE!|True|4|6|9|12
Heisha Onsha|28-0|Happy Otaku Pack Vol.10|False|4|6|8|
Ginevra|28-1|Happy Otaku Pack Vol.10|True|5|7|10|10
Paracelestia|28-2|Happy Otaku Pack Vol.10|False|5|8|10|
un secret|28-3|Happy Otaku Pack Vol.10|False|2|4|6|
Good Life|28-4|Happy Otaku Pack Vol.10|False|4|6|8|
nini-nini-|28-5|Happy Otaku Pack Vol.10|False|4|7|9|
Can I friend you on Bassbook? lol|27-0|Nanahira Festival|False|3|6|8|
Gaming*Everything|27-1|Nanahira Festival|False|5|8|11|
Renji de haochi|27-2|Nanahira Festival|False|5|7|9|
You Make My Life 1UP|27-3|Nanahira Festival|False|4|6|8|
Newbies, Geeks, Internets|27-4|Nanahira Festival|False|6|8|10|
Onegai!Kon kon Oinarisama|27-5|Nanahira Festival|False|3|6|9|
Legend of Eastern Rabbit -SKY DEFENDER-|26-0|Give Up TREATMENT Vol.9|False|4|6|9|
ENERGY SYNERGY MATRIX|26-1|Give Up TREATMENT Vol.9|False|6|8|10|
Punai Punai Genso|26-2|Give Up TREATMENT Vol.9|False|2|7|11|
Better Graphic Animation|26-3|Give Up TREATMENT Vol.9|False|5|8|11|
Variant Cross|26-4|Give Up TREATMENT Vol.9|False|4|7|10|
Ultra Happy Miracle Bazoooooka!!|26-5|Give Up TREATMENT Vol.9|False|7|9|11|
tape/stop/night|25-0|MUSE RADIO FM101|True|3|5|7|
Pixel Galaxy|25-1|MUSE RADIO FM101|False|2|5|8|
Notice|25-2|MUSE RADIO FM101|False|4|7|10|
Strawberry Godzilla|25-3|MUSE RADIO FM101|True|2|5|7|
OKIMOCHI EXPRESSION|25-4|MUSE RADIO FM101|False|4|6|10|
Kimi to pool disco|25-5|MUSE RADIO FM101|False|4|6|8|
The Last Page|24-0|Happy Otaku Pack Vol.9|False|3|5|7|
IKAROS|24-1|Happy Otaku Pack Vol.9|False|4|7|10|
Tsukuyomi|24-2|Happy Otaku Pack Vol.9|False|3|6|9|
Future Stream|24-3|Happy Otaku Pack Vol.9|False|4|6|8|
FULi AUTO SHOOTER|24-4|Happy Otaku Pack Vol.9|True|4|7|9|
GOODFORTUNE|24-5|Happy Otaku Pack Vol.9|False|5|7|9|
The Dessert After Rain|23-0|Cute Is Everything Vol.5|True|2|4|6|
Confession Support Formula|23-1|Cute Is Everything Vol.5|False|3|5|7|
Omatsuri|23-2|Cute Is Everything Vol.5|False|1|3|6|
FUTUREPOP|23-3|Cute Is Everything Vol.5|True|2|5|7|
The Breeze|23-4|Cute Is Everything Vol.5|False|1|4|6|
I LOVE LETTUCE FRIED RICE!!|23-5|Cute Is Everything Vol.5|False|3|7|9|
The NightScape|22-0|Give Up TREATMENT Vol.8|False|4|7|9|
FREEDOM DiVE|22-1|Give Up TREATMENT Vol.8|False|6|8|10|12
Phi|22-2|Give Up TREATMENT Vol.8|False|5|8|10|
Lueur de la nuit|22-3|Give Up TREATMENT Vol.8|False|6|8|11|
Creamy Sugary OVERDRIVE!!!|22-4|Give Up TREATMENT Vol.8|True|4|7|10|
Disorder|22-5|Give Up TREATMENT Vol.8|False|5|7|11|
Glimmer|21-0|Budget Is Burning: Nano Core|False|2|5|8|
EXIST|21-1|Budget Is Burning: Nano Core|False|3|5|8|
Irreplaceable|21-2|Budget Is Burning: Nano Core|False|4|6|8|
Moonlight Banquet|20-0|Happy Otaku Pack Vol.8|True|2|5|8|
Flashdance|20-1|Happy Otaku Pack Vol.8|False|3|6|9|
INFiNiTE ENERZY -Overdoze-|20-2|Happy Otaku Pack Vol.8|False|4|7|9|10
One Way Street|20-3|Happy Otaku Pack Vol.8|False|3|6|10|
This Club is Not 4 U|20-4|Happy Otaku Pack Vol.8|False|4|7|9|
ULTRA MEGA HAPPY PARTY!!!|20-5|Happy Otaku Pack Vol.8|False|5|7|10|
INFINITY|19-0|Give Up TREATMENT Vol.7|True|5|8|10|
Punai Punai Senso|19-1|Give Up TREATMENT Vol.7|False|2|7|11|
Maxi|19-2|Give Up TREATMENT Vol.7|False|5|8|10|
YInMn Blue|19-3|Give Up TREATMENT Vol.7|False|6|8|10|
Plumage|19-4|Give Up TREATMENT Vol.7|False|4|7|10|
Dr.Techro|19-5|Give Up TREATMENT Vol.7|False|7|9|11|
SWEETSWEETSWEET|18-0|Cute Is Everything Vol.4|True|2|5|7|
Deep Blue and the Breaths of the Night|18-1|Cute Is Everything Vol.4|True|2|4|6|
Joy Connection|18-2|Cute Is Everything Vol.4|False|3|6|8|
Self Willed Girl Ver.B|18-3|Cute Is Everything Vol.4|True|4|6|8|
Just Disobedient|18-4|Cute Is Everything Vol.4|False|3|6|8|
Holy Sh*t Grass Snake|18-5|Cute Is Everything Vol.4|False|2|6|9|
Cotton Candy Wonderland|17-0|Happy Otaku Pack Vol.7|False|2|5|8|
Punai Punai Taiso|17-1|Happy Otaku Pack Vol.7|False|2|7|10|
Fly High|17-2|Happy Otaku Pack Vol.7|False|3|5|7|
prejudice|17-3|Happy Otaku Pack Vol.7|True|4|6|9|
The 89's Momentum|17-4|Happy Otaku Pack Vol.7|True|5|7|9|
energy night|17-5|Happy Otaku Pack Vol.7|True|5|7|10|
Future Dive|16-0|Give Up TREATMENT Vol.6|True|4|6|9|
Re End of a Dream|16-1|Give Up TREATMENT Vol.6|False|5|8|11|
Etude -Storm-|16-2|Give Up TREATMENT Vol.6|True|6|8|10|
Unlimited Katharsis|16-3|Give Up TREATMENT Vol.6|False|4|6|10|
Magic Knight Girl|16-4|Give Up TREATMENT Vol.6|False|4|7|9|
Eeliaas|16-5|Give Up TREATMENT Vol.6|False|6|9|11|
Magic Spell|15-0|Cute Is Everything Vol.3|True|2|5|7|
Colorful Star, Colored Drawing, Travel Poem|15-1|Cute Is Everything Vol.3|False|3|4|6|
Satell Knight|15-2|Cute Is Everything Vol.3|False|3|6|8|
Black River Feat.Mes|15-3|Cute Is Everything Vol.3|True|1|4|6|
I am sorry|15-4|Cute Is Everything Vol.3|False|2|5|8|
Ueta Tori Tachi|15-5|Cute Is Everything Vol.3|False|3|6|8|
Elysion's Old Mans|14-0|Happy Otaku Pack Vol.6|False|3|5|8|
AXION|14-1|Happy Otaku Pack Vol.6|False|4|5|8|
Amnesia|14-2|Happy Otaku Pack Vol.6|True|3|6|9|
Onsen Dai Sakusen|14-3|Happy Otaku Pack Vol.6|True|4|6|8|
Gleam stone|14-4|Happy Otaku Pack Vol.6|False|4|7|9|
GOODWORLD|14-5|Happy Otaku Pack Vol.6|False|4|7|10|
Instant Soluble Neon|13-0|Cute Is Everything Vol.2|True|2|4|7|
Retrospective Poem on the Planet|13-1|Cute Is Everything Vol.2|False|3|5|7|
I'm Gonna Buy! Buy! Buy!|13-2|Cute Is Everything Vol.2|True|4|6|8|
Dating Manifesto|13-3|Cute Is Everything Vol.2|True|2|4|6|
First Snow|13-4|Cute Is Everything Vol.2|True|2|3|6|
Xin Shang Huahai|13-5|Cute Is Everything Vol.2|False|3|6|8|
Gaikan Chrysalis|12-0|Give Up TREATMENT Vol.5|False|4|6|8|
Sterelogue|12-1|Give Up TREATMENT Vol.5|True|5|7|10|
Cheshire's Dance|12-2|Give Up TREATMENT Vol.5|True|4|7|10|
Skrik|12-3|Give Up TREATMENT Vol.5|True|5|7|11|
Soda Pop Canva5!|12-4|Give Up TREATMENT Vol.5|False|5|8|10|
RUBY LINTe|12-5|Give Up TREATMENT Vol.5|False|5|8|11|
Brave My Heart|11-0|Happy Otaku Pack Vol.5|True|3|5|7|
Sakura Fubuki|11-1|Happy Otaku Pack Vol.5|False|4|7|10|
8bit Adventurer|11-2|Happy Otaku Pack Vol.5|False|6|8|10|
Suffering of screw|11-3|Happy Otaku Pack Vol.5|False|3|5|8|
tiny lady|11-4|Happy Otaku Pack Vol.5|True|4|6|9|
Power Attack|11-5|Happy Otaku Pack Vol.5|False|5|7|10|
Destr0yer|10-0|Give Up TREATMENT Vol.4|False|4|7|9|
Noel|10-1|Give Up TREATMENT Vol.4|False|5|8|10|
Kyoukiranbu|10-2|Give Up TREATMENT Vol.4|False|7|9|11|
Two Phace|10-3|Give Up TREATMENT Vol.4|True|4|7|10|
Fly Again|10-4|Give Up TREATMENT Vol.4|False|5|7|10|
ouroVoros|10-5|Give Up TREATMENT Vol.4|False|7|9|11|
Leave It Alone|9-0|Happy Otaku Pack Vol.4|True|2|5|8|
Tsubasa no Oreta Tenshitachi no Requiem|9-1|Happy Otaku Pack Vol.4|False|4|7|9|
Chronomia|9-2|Happy Otaku Pack Vol.4|False|5|7|10|
Dandelion's Daydream|9-3|Happy Otaku Pack Vol.4|True|5|7|8|
Lorikeet Flat design|9-4|Happy Otaku Pack Vol.4|True|5|7|10|
GOODRAGE|9-5|Happy Otaku Pack Vol.4|False|6|9|11|
Altale|8-0|Give Up TREATMENT Vol.3|False|3|5|7|10
Brain Power|8-1|Give Up TREATMENT Vol.3|False|4|7|10|
Berry Go!!|8-2|Give Up TREATMENT Vol.3|False|3|6|9|
Sweet* Witch* Girl*|8-3|Give Up TREATMENT Vol.3|False|6|8|10|?
trippers feeling!|8-4|Give Up TREATMENT Vol.3|True|5|7|9|11
Lilith ambivalence lovers|8-5|Give Up TREATMENT Vol.3|False|5|8|10|
Brave My Soul|7-0|Give Up TREATMENT Vol.2|False|4|6|8|
Halcyon|7-1|Give Up TREATMENT Vol.2|False|4|7|10|
Crimson Nightingale|7-2|Give Up TREATMENT Vol.2|True|4|7|10|
Invader|7-3|Give Up TREATMENT Vol.2|True|3|7|11|
Lyrith|7-4|Give Up TREATMENT Vol.2|False|5|7|10|
GOODBOUNCE|7-5|Give Up TREATMENT Vol.2|False|4|6|9|
Out of Sense|6-0|Budget Is Burning Vol.1|False|3|5|8|
My Life Is For You|6-1|Budget Is Burning Vol.1|False|2|4|7|
Etude -Sunset-|6-2|Budget Is Burning Vol.1|True|5|7|9|
Goodbye Boss|6-3|Budget Is Burning Vol.1|False|4|6|8|
Stargazer|6-4|Budget Is Burning Vol.1|True|2|5|8|9
Lys Tourbillon|6-5|Budget Is Burning Vol.1|True|4|6|8|
Thirty Million Persona|5-0|Happy Otaku Pack Vol.3|False|2|4|6|
conflict|5-1|Happy Otaku Pack Vol.3|False|2|6|9|10
Enka Dance Music|5-2|Happy Otaku Pack Vol.3|False|3|5|7|
XING|5-3|Happy Otaku Pack Vol.3|True|4|6|8|9
Amakakeru Soukyuu no Serenade|5-4|Happy Otaku Pack Vol.3|False|3|6|9|
Gift box|5-5|Happy Otaku Pack Vol.3|False|5|7|10|
MUSEDASH!!!!|4-0|Happy Otaku Pack Vol.2|False|2|6|9|0
Imprinting|4-1|Happy Otaku Pack Vol.2|False|3|6|9|0
Skyward|4-2|Happy Otaku Pack Vol.2|True|4|7|10|0
La nuit de vif|4-3|Happy Otaku Pack Vol.2|True|2|5|8|0
Bit-alize|4-4|Happy Otaku Pack Vol.2|False|3|6|8|0
GOODTEK|4-5|Happy Otaku Pack Vol.2|False|4|6|9|?
Maharajah|3-0|Happy Otaku Pack Vol.1|False|1|3|6|
keep on running|3-1|Happy Otaku Pack Vol.1|False|5|7|9|
Kafig|3-2|Happy Otaku Pack Vol.1|True|4|6|8|
-+|3-3|Happy Otaku Pack Vol.1|True|4|6|8|
Tenri Kaku Jou|3-4|Happy Otaku Pack Vol.1|True|3|6|9|
Adjudicatorz-DanZai-|3-5|Happy Otaku Pack Vol.1|False|3|7|10|
Oriens|2-0|Give Up TREATMENT Vol.1|True|3|7|9|
PUPA|2-1|Give Up TREATMENT Vol.1|False|6|8|11|
Luna Express 2032|2-2|Give Up TREATMENT Vol.1|False|4|6|8|
Ukiyoe Yokochou|2-3|Give Up TREATMENT Vol.1|False|6|7|9|
Alice in Misanthrope|2-4|Give Up TREATMENT Vol.1|False|5|7|10|
GOODMEN|2-5|Give Up TREATMENT Vol.1|False|5|7|10|
Sunshine and Rainbow after August Rain|1-0|Cute Is Everything Vol.1|False|2|5|8|
Magical Number|1-1|Cute Is Everything Vol.1|False|2|5|8|
Dreaming Girl|1-2|Cute Is Everything Vol.1|False|2|5|6|
Daruma-san Fell Over|1-3|Cute Is Everything Vol.1|False|3|4|6|
Different|1-4|Cute Is Everything Vol.1|False|1|3|6|
The Future of the Phantom|1-5|Cute Is Everything Vol.1|False|1|3|5|
Doki Doki Jump!|63-0|MUSE RADIO FM104|True|3|5|7|
Centennial Streamers High|63-1|MUSE RADIO FM104|False|4|7|9|
Love Patrol|63-2|MUSE RADIO FM104|True|3|5|7|
Mahorova|63-3|MUSE RADIO FM104|True|3|5|8|
Yoru no machi|63-4|MUSE RADIO FM104|True|1|4|7|
INTERNET YAMERO|63-5|MUSE RADIO FM104|True|6|8|10|
Abracadabra|43-24|MD Plus Project|False|6|8|10|
Squalldecimator feat. EZ-Ven|43-25|MD Plus Project|True|5|7|9|
Amateras Rhythm|43-26|MD Plus Project|True|6|8|11|
Record one's Dream|43-27|MD Plus Project|False|4|7|10|
Lunatic|43-28|MD Plus Project|True|5|8|10|
Jiumeng|43-29|MD Plus Project|True|3|6|8|
The Day We Become Family|43-30|MD Plus Project|True|3|5|8|
Sutori ma FIRE!?!?|64-0|COSMIC RADIO PEROLIST|True|3|5|8|
Tanuki Step|64-1|COSMIC RADIO PEROLIST|True|5|7|10|11
Space Stationery|64-2|COSMIC RADIO PEROLIST|True|5|7|10|
Songs Are Judged 90% by Chorus feat. Mameko|64-3|COSMIC RADIO PEROLIST|True|6|8|10|
Kawai Splendid Space Thief|64-4|COSMIC RADIO PEROLIST|False|6|8|10|11
Night City Runway|64-5|COSMIC RADIO PEROLIST|True|4|6|8|
Chaos Shotgun feat. ChumuNote|64-6|COSMIC RADIO PEROLIST|True|6|8|10|
mew mew magical summer|64-7|COSMIC RADIO PEROLIST|False|5|8|10|11
BrainDance|65-0|NeonAbyss|True|3|6|9|
My Focus!|65-1|NeonAbyss|True|5|7|10|
ABABABA BURST|65-2|NeonAbyss|True|5|7|9|
ULTRA HIGHER|65-3|NeonAbyss|True|4|7|10|
Silver Bullet|43-31|MD Plus Project|True|5|7|10|
Random|43-32|MD Plus Project|True|4|7|9|
OTOGE-BOSS-KYOKU-CHAN|43-33|MD Plus Project|False|6|8|10|11
Crow Rabbit|43-34|MD Plus Project|True|7|9|11|
SyZyGy|43-35|MD Plus Project|True|6|8|10|11
Mermaid Radio|43-36|MD Plus Project|True|3|5|7|
Helixir|43-37|MD Plus Project|False|6|8|10|
Highway Cruisin'|43-38|MD Plus Project|False|3|5|8|
JACK PT BOSS|43-39|MD Plus Project|False|6|8|10|
Time Capsule|43-40|MD Plus Project|False|7|9|11|
39 Music!|66-0|Miku in Museland|False|3|5|8|
Hand in Hand|66-1|Miku in Museland|False|1|3|6|
Cynical Night Plan|66-2|Miku in Museland|False|4|6|8|
God-ish|66-3|Miku in Museland|False|4|7|10|
Darling Dance|66-4|Miku in Museland|False|4|7|9|
Hatsune Creation Myth|66-5|Miku in Museland|False|6|8|10|11
The Vampire|66-6|Miku in Museland|False|4|6|9|
Future Eve|66-7|Miku in Museland|False|4|8|11|
Unknown Mother Goose|66-8|Miku in Museland|False|4|8|10|
Shun-ran|66-9|Miku in Museland|False|4|7|9|
NICE TYPE feat. monii|43-41|MD Plus Project|True|3|6|8|
Rainy Angel|67-0|Happy Otaku Pack Vol.18|True|4|6|9|11
Gullinkambi|67-1|Happy Otaku Pack Vol.18|True|4|7|10|
RakiRaki Rebuilders!!!|67-2|Happy Otaku Pack Vol.18|True|5|7|10|
Laniakea|67-3|Happy Otaku Pack Vol.18|False|5|8|10|
OTTAMA GAZER|67-4|Happy Otaku Pack Vol.18|True|5|8|10|
Sleep Tight feat.Macoto|67-5|Happy Otaku Pack Vol.18|True|3|5|8|
New York Back Raise|68-0|Gambler's Tricks|True|6|8|10|
slic.hertz|68-1|Gambler's Tricks|True|5|7|9|
Fuzzy-Navel|68-2|Gambler's Tricks|True|6|8|10|11
Swing Edge|68-3|Gambler's Tricks|True|4|8|10|
Twisted Escape|68-4|Gambler's Tricks|True|5|8|10|11
Swing Sweet Twee Dance|68-5|Gambler's Tricks|False|4|7|10|
Sanyousei SAY YA!!!|43-42|MD Plus Project|False|4|6|8|
YUKEMURI TAMAONSEN II|43-43|MD Plus Project|False|3|6|9|
Samayoi no mei Amatsu|69-0|Touhou Mugakudan -3-|False|4|6|9|
INTERNET SURVIVOR|69-1|Touhou Mugakudan -3-|False|5|8|10|
Shuki*RaiRai|69-2|Touhou Mugakudan -3-|False|5|7|9|
HELLOHELL|69-3|Touhou Mugakudan -3-|False|4|7|10|
Calamity Fortune|69-4|Touhou Mugakudan -3-|True|6|8|10|11
Tsurupettan|69-5|Touhou Mugakudan -3-|True|2|5|8|
Twilight Poems|43-44|MD Plus Project|True|3|6|8|
All My Friends feat. RANASOL|43-45|MD Plus Project|True|4|7|9|
Heartache|43-46|MD Plus Project|True|5|7|10|
Blue Lemonade|43-47|MD Plus Project|True|3|6|8|
Haunted Dance|43-48|MD Plus Project|False|6|9|11|
Hey Vincent.|43-49|MD Plus Project|True|6|8|10|
Meteor feat. TEA|43-50|MD Plus Project|True|3|6|9|
Narcissism Angel|43-51|MD Plus Project|True|1|3|6|
AlterLuna|43-52|MD Plus Project|True|6|8|11|12
Niki Tousen|43-53|MD Plus Project|True|6|8|10|12
Rettou Joutou|70-0|Rin Len's Mirrorland|False|4|7|9|
Telecaster B-Boy|70-1|Rin Len's Mirrorland|False|5|7|10|
Iya Iya Iya|70-2|Rin Len's Mirrorland|False|2|4|7|
Nee Nee Nee|70-3|Rin Len's Mirrorland|False|4|6|8|
Chaotic Love Revolution|70-4|Rin Len's Mirrorland|False|4|6|8|
Dance of the Corpses|70-5|Rin Len's Mirrorland|False|2|5|8|
Bitter Choco Decoration|70-6|Rin Len's Mirrorland|False|3|6|9|
Dance Robot Dance|70-7|Rin Len's Mirrorland|False|4|7|10|
Sweet Devil|70-8|Rin Len's Mirrorland|False|5|7|9|
Someday'z Coming|70-9|Rin Len's Mirrorland|False|5|7|9|
Yume Ou Mono Yo Secret|0-53|Default Music|True|6|8|10|
Yume Ou Mono Yo|0-54|Default Music|True|1|4|0|
Sweet Dream VIVINOS|71-0|Valentine Stage|False|1|4|7|
Ruler Of My Heart VIVINOS|71-1|Valentine Stage|False|2|4|6|
Reality Show|71-2|Valentine Stage|False|5|7|10|
SIG feat.Tobokegao|71-3|Valentine Stage|True|3|6|8|
Rose Love|71-4|Valentine Stage|True|2|4|7|
Euphoria|71-5|Valentine Stage|True|1|3|6|
P E R O P E R O Brother Dance|72-0|Legends of Muse Warriors|True|0|?|0|
PA PPA PANIC|72-1|Legends of Muse Warriors|False|4|8|10|
How To Make Music Game Song!|72-2|Legends of Muse Warriors|True|6|8|10|11
Re Re|72-3|Legends of Muse Warriors|True|7|9|11|12
Marmalade Twins|72-4|Legends of Muse Warriors|True|5|8|10|
DOMINATOR|72-5|Legends of Muse Warriors|True|7|9|11|
Teshikani TESHiKANi|72-6|Legends of Muse Warriors|True|5|7|9|
Urban Magic|73-0|Happy Otaku Pack Vol.19|True|3|5|7|
Maid's Prank|73-1|Happy Otaku Pack Vol.19|True|5|7|10|
Dance Dance Good Night Dance|73-2|Happy Otaku Pack Vol.19|True|2|4|7|
Ops Limone|73-3|Happy Otaku Pack Vol.19|True|5|8|11|
NOVA|73-4|Happy Otaku Pack Vol.19|True|6|8|10|
Heaven's Gradius|73-5|Happy Otaku Pack Vol.19|True|6|8|10|
Ray Tuning|74-0|CHUNITHM COURSE MUSE|True|6|8|10|
World Vanquisher|74-1|CHUNITHM COURSE MUSE|True|6|8|10|11
Tsukuyomi Ni Naru Replaced|74-2|CHUNITHM COURSE MUSE|True|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|
Echo over you... Secret|0-55|Default Music|False|6|8|10|
Echo over you...|0-56|Default Music|False|1|4|0|
Tsukuyomi Ni Naru|74-6|CHUNITHM COURSE MUSE|True|5|8|10|
disco light|76-0|MUSE RADIO FM105|True|5|7|9|
room light feat.chancylemon|76-1|MUSE RADIO FM105|True|3|5|7|
Invisible|76-2|MUSE RADIO FM105|True|3|5|8|
Christmas Season-LLABB|76-3|MUSE RADIO FM105|True|1|4|7|
Hyouryu|77-0|Let's Rhythm Jam!|False|6|8|10|
The Whole Rest|77-1|Let's Rhythm Jam!|False|5|8|10|11
Hydra|77-2|Let's Rhythm Jam!|False|4|7|11|
Pastel Lines|77-3|Let's Rhythm Jam!|False|3|6|9|
LINK x LIN#S|77-4|Let's Rhythm Jam!|False|3|6|9|
Arcade ViruZ|77-5|Let's Rhythm Jam!|False|6|8|11|
Eve Avenir|78-0|Endless Pirouette|True|6|8|10|
Silverstring|78-1|Endless Pirouette|True|5|7|10|
Melusia|78-2|Endless Pirouette|False|5|7|10|11
Devil's Castle|78-3|Endless Pirouette|True|4|7|10|
Abatement|78-4|Endless Pirouette|True|6|8|10|11
Azalea|78-5|Endless Pirouette|False|4|8|10|
Brightly World|78-6|Endless Pirouette|True|6|8|10|
We'll meet in every world ***|78-7|Endless Pirouette|True|7|9|11|
Collapsar|78-8|Endless Pirouette|True|7|9|10|11
Parousia|78-9|Endless Pirouette|False|6|8|10|
Gunners in the Rain|79-0|Ensemble Arcanum|False|5|8|10|
Halzion|79-1|Ensemble Arcanum|False|2|5|8|
SHOWTIME!!|79-2|Ensemble Arcanum|False|6|8|10|
Achromic Riddle|79-3|Ensemble Arcanum|False|6|8|10|11
karanosu|79-4|Ensemble Arcanum|False|3|6|8|

View File

@@ -1,13 +1,14 @@
from Options import Toggle, Range, Choice, DeathLink, ItemSet, OptionSet, PerGameCommonOptions, OptionGroup, Removed
from Options import Toggle, Range, Choice, DeathLink, OptionSet, PerGameCommonOptions, OptionGroup, Removed
from dataclasses import dataclass
from .MuseDashCollection import MuseDashCollections
from .MuseDashData import SONG_DATA
class DLCMusicPacks(OptionSet):
"""
Choose which DLC Packs will be included in the pool of chooseable songs.
Note: The [Just As Planned] DLC contains all [Muse Plus] songs.
"""
display_name = "DLC Packs"
@@ -17,7 +18,7 @@ class DLCMusicPacks(OptionSet):
class StreamerModeEnabled(Toggle):
"""
In Muse Dash, an option named 'Streamer Mode' removes songs which may trigger copyright issues when streaming.
If this is enabled, only songs available under Streamer Mode will be available for randomization.
"""
display_name = "Streamer Mode Only Songs"
@@ -69,7 +70,7 @@ class DifficultyMode(Choice):
class DifficultyModeOverrideMin(Range):
"""
Ensures that 1 difficulty has at least 1 this value or higher per song.
Note: Difficulty Mode must be set to Manual.
"""
display_name = "Manual Difficulty Min"
@@ -82,7 +83,7 @@ class DifficultyModeOverrideMin(Range):
class DifficultyModeOverrideMax(Range):
"""
Ensures that 1 difficulty has at least 1 this value or lower per song.
Note: Difficulty Mode must be set to Manual.
"""
display_name = "Manual Difficulty Max"
@@ -114,7 +115,7 @@ class GradeNeeded(Choice):
class MusicSheetCountPercentage(Range):
"""
Controls how many music sheets are added to the pool based on the number of songs, including starting songs.
Higher numbers leads to more consistent game lengths, but will cause individual music sheets to be less important.
"""
range_start = 10
@@ -137,7 +138,7 @@ class ChosenTraps(OptionSet):
- Traps last the length of a song, or until you die.
- VFX Traps consist of visual effects that play over the song. (i.e. Grayscale.)
- SFX Traps consist of changing your sfx setting to one possibly more annoying sfx.
Note: SFX traps are only available if [Just as Planned] DLC songs are enabled.
"""
display_name = "Chosen Traps"
@@ -152,24 +153,26 @@ class TrapCountPercentage(Range):
display_name = "Trap Percentage"
class IncludeSongs(ItemSet):
class SongSet(OptionSet):
valid_keys = SONG_DATA.keys()
class IncludeSongs(SongSet):
"""
These songs will be guaranteed to show up within the seed.
- You must have the DLC enabled to play these songs.
- Difficulty options will not affect these songs.
- If there are too many included songs, this will act as a whitelist ignoring song difficulty.
"""
verify_item_name = True
display_name = "Include Songs"
class ExcludeSongs(ItemSet):
class ExcludeSongs(SongSet):
"""
These songs will be guaranteed to not show up within the seed.
Note: Does not affect songs within the "Include Songs" list.
"""
verify_item_name = True
display_name = "Exclude Songs"
@@ -211,7 +214,7 @@ class MuseDashOptions(PerGameCommonOptions):
death_link: DeathLink
include_songs: IncludeSongs
exclude_songs: ExcludeSongs
# Removed
allow_just_as_planned_dlc_songs: Removed
available_trap_types: Removed

View File

@@ -63,6 +63,11 @@ class MuseDashWorld(World):
item_name_to_id = {name: code for name, code in md_collection.item_names_to_id.items()}
location_name_to_id = {name: code for name, code in md_collection.location_names_to_id.items()}
item_name_groups = {
"Songs": {name for name in md_collection.song_items.keys()},
"Filler Items": {name for name in md_collection.filler_items.keys()},
"Traps": {name for name in md_collection.trap_items.keys()}
}
# Working Data
victory_song_name: str = ""
@@ -179,10 +184,6 @@ class MuseDashWorld(World):
if trap:
return MuseDashFixedItem(name, ItemClassification.trap, trap, self.player)
album = self.md_collection.album_items.get(name)
if album:
return MuseDashSongItem(name, self.player, album)
song = self.md_collection.song_items[name]
return MuseDashSongItem(name, self.player, song)

View File

@@ -1,7 +1,17 @@
from . import MuseDashTestBase
from typing import List
class DifficultyRanges(MuseDashTestBase):
DIFF_OVERRIDES: List[str] = [
"MuseDash ka nanika hi",
"Rush-Hour",
"Find this Month's Featured Playlist",
"PeroPero in the Universe",
"umpopoff",
"P E R O P E R O Brother Dance",
]
def test_all_difficulty_ranges(self) -> None:
muse_dash_world = self.get_world()
dlc_set = {x for x in muse_dash_world.md_collection.DLC}
@@ -63,7 +73,7 @@ class DifficultyRanges(MuseDashTestBase):
def test_songs_have_difficulty(self) -> None:
muse_dash_world = self.get_world()
for song_name in muse_dash_world.md_collection.DIFF_OVERRIDES:
for song_name in self.DIFF_OVERRIDES:
song = muse_dash_world.md_collection.song_items[song_name]
# Some songs are weird and have less than the usual 3 difficulties.

View File

@@ -1718,7 +1718,7 @@ def create_regions(world):
connect(multiworld, player, "Vermilion City", "Vermilion City-Dock", lambda state: state.has("S.S. Ticket", player))
connect(multiworld, player, "Vermilion City", "Route 11")
connect(multiworld, player, "Route 12-N", "Route 12-S", lambda state: logic.can_surf(state, world, player))
connect(multiworld, player, "Route 12-W", "Route 11-E", lambda state: state.has("Poke Flute", player))
connect(multiworld, player, "Route 12-W", "Route 11-E")
connect(multiworld, player, "Route 12-W", "Route 12-N", lambda state: state.has("Poke Flute", player))
connect(multiworld, player, "Route 12-W", "Route 12-S", lambda state: state.has("Poke Flute", player))
connect(multiworld, player, "Route 12-S", "Route 12-Grass", lambda state: logic.can_cut(state, world, player), one_way=True)

View File

@@ -4,18 +4,59 @@ import os
import json
import Utils
from Utils import read_snes_rom
from worlds.Files import APDeltaPatch
from worlds.Files import APPatchExtension, APProcedurePatch, APTokenMixin, APTokenTypes
from .variaRandomizer.utils.utils import openFile
SMJUHASH = '21f3e98df4780ee1c667b84e57d88675'
SM_ROM_MAX_PLAYERID = 65535
SM_ROM_PLAYERDATA_COUNT = 202
class SMDeltaPatch(APDeltaPatch):
class SMPatchExtensions(APPatchExtension):
game = "Super Metroid"
@staticmethod
def write_crc(caller: APProcedurePatch, rom: bytes) -> bytes:
def checksum_mirror_sum(start, length, mask = 0x800000):
while not(length & mask) and mask:
mask >>= 1
part1 = sum(start[:mask]) & 0xFFFF
part2 = 0
next_length = length - mask
if next_length:
part2 = checksum_mirror_sum(start[mask:], next_length, mask >> 1)
while (next_length < mask):
next_length += next_length
part2 += part2
return (part1 + part2) & 0xFFFF
def write_bytes(buffer, startaddress: int, values):
buffer[startaddress:startaddress + len(values)] = values
buffer = bytearray(rom)
crc = checksum_mirror_sum(buffer, len(buffer))
inv = crc ^ 0xFFFF
write_bytes(buffer, 0x7FDC, [inv & 0xFF, (inv >> 8) & 0xFF, crc & 0xFF, (crc >> 8) & 0xFF])
return bytes(buffer)
class SMProcedurePatch(APProcedurePatch, APTokenMixin):
hash = SMJUHASH
game = "Super Metroid"
patch_file_ending = ".apsm"
procedure = [
("apply_tokens", ["token_data.bin"]),
("write_crc", [])
]
def write_tokens(self, patches):
for addr, data in patches.items():
self.write_token(APTokenTypes.WRITE, addr, bytes(data))
self.write_file("token_data.bin", self.get_token_binary())
@classmethod
def get_source_data(cls) -> bytes:
return get_base_rom_bytes()

View File

@@ -17,7 +17,7 @@ logger = logging.getLogger("Super Metroid")
from .Options import SMOptions
from .Client import SMSNIClient
from .Rom import get_base_rom_path, SM_ROM_MAX_PLAYERID, SM_ROM_PLAYERDATA_COUNT, SMDeltaPatch, get_sm_symbols
from .Rom import SM_ROM_MAX_PLAYERID, SM_ROM_PLAYERDATA_COUNT, SMProcedurePatch, get_sm_symbols
import Utils
from .variaRandomizer.logic.smboolmanager import SMBoolManager
@@ -40,7 +40,7 @@ class SMSettings(settings.Group):
"""File name of the v1.0 J rom"""
description = "Super Metroid (JU) ROM"
copy_to = "Super Metroid (JU).sfc"
md5s = [SMDeltaPatch.hash]
md5s = [SMProcedurePatch.hash]
rom_file: RomFile = RomFile(RomFile.copy_to)
@@ -120,12 +120,6 @@ class SMWorld(World):
self.locations = {}
super().__init__(world, player)
@classmethod
def stage_assert_generate(cls, multiworld: MultiWorld):
rom_file = get_base_rom_path()
if not os.path.exists(rom_file):
raise FileNotFoundError(rom_file)
def generate_early(self):
Logic.factory('vanilla')
@@ -802,23 +796,19 @@ class SMWorld(World):
romPatcher.end()
def generate_output(self, output_directory: str):
self.variaRando.args.rom = get_base_rom_path()
outfilebase = self.multiworld.get_out_file_name_base(self.player)
outputFilename = os.path.join(output_directory, f"{outfilebase}.sfc")
try:
self.variaRando.PatchRom(outputFilename, self.APPrePatchRom, self.APPostPatchRom)
self.write_crc(outputFilename)
patcher = self.variaRando.PatchRom(self.APPrePatchRom, self.APPostPatchRom)
self.rom_name = self.romName
patch = SMProcedurePatch(player=self.player, player_name=self.multiworld.player_name[self.player])
patch.write_tokens(patcher.romFile.getPatchDict())
rom_path = os.path.join(output_directory, f"{self.multiworld.get_out_file_name_base(self.player)}"
f"{patch.patch_file_ending}")
patch.write(rom_path)
except:
raise
else:
patch = SMDeltaPatch(os.path.splitext(outputFilename)[0] + SMDeltaPatch.patch_file_ending, player=self.player,
player_name=self.multiworld.player_name[self.player], patched_path=outputFilename)
patch.write()
finally:
if os.path.exists(outputFilename):
os.unlink(outputFilename)
self.rom_name_available_event.set() # make sure threading continues and errors are collected
def checksum_mirror_sum(self, start, length, mask = 0x800000):

View File

@@ -680,7 +680,7 @@ class VariaRandomizer:
#dumpErrorMsg(args.output, self.randoExec.errorMsg)
raise Exception("Can't generate " + self.fileName + " with the given parameters: {}".format(self.randoExec.errorMsg))
def PatchRom(self, outputFilename, customPrePatchApply = None, customPostPatchApply = None):
def PatchRom(self, customPrePatchApply = None, customPostPatchApply = None) -> RomPatcher:
args = self.args
optErrMsgs = self.optErrMsgs
@@ -758,9 +758,9 @@ class VariaRandomizer:
# args.output is not None: generate local json named args.output
if args.rom is not None:
# patch local rom
romFileName = args.rom
shutil.copyfile(romFileName, outputFilename)
romPatcher = RomPatcher(settings=patcherSettings, romFileName=outputFilename, magic=args.raceMagic, player=self.player)
# romFileName = args.rom
# shutil.copyfile(romFileName, outputFilename)
romPatcher = RomPatcher(settings=patcherSettings, magic=args.raceMagic, player=self.player)
else:
romPatcher = RomPatcher(settings=patcherSettings, magic=args.raceMagic)
@@ -779,24 +779,12 @@ class VariaRandomizer:
#msg = randoExec.errorMsg
msg = ''
if args.rom is None: # web mode
data = romPatcher.romFile.data
self.fileName = '{}.sfc'.format(self.fileName)
data["fileName"] = self.fileName
# error msg in json to be displayed by the web site
data["errorMsg"] = msg
# replaced parameters to update stats in database
if len(self.forcedArgs) > 0:
data["forcedArgs"] = self.forcedArgs
with open(outputFilename, 'w') as jsonFile:
json.dump(data, jsonFile)
else: # CLI mode
if msg != "":
print(msg)
return romPatcher
except Exception as e:
import traceback
traceback.print_exc(file=sys.stdout)
raise Exception("Error patching {}: ({}: {})".format(outputFilename, type(e).__name__, e))
raise Exception("Error patching: ({}: {})".format(type(e).__name__, e))
#dumpErrorMsg(args.output, msg)
# if stuck == True:

View File

@@ -21,10 +21,23 @@ class IPS_Patch(object):
def toDict(self):
ret = {}
for record in self.records:
if 'rle_count' in record:
ret[record['address']] = [int.from_bytes(record['data'],'little')]*record['rle_count']
if record['address'] in ret.keys():
if 'rle_count' in record:
if len(ret[record['address']]) > record['rle_count']:
ret[record['address']][:record['rle_count']] = [int.from_bytes(record['data'],'little')]*record['rle_count']
else:
ret[record['address']] = [int.from_bytes(record['data'],'little')]*record['rle_count']
else:
size = len(record['data'])
if len(ret[record['address']]) > size:
ret[record['address']][:size] = [int(b) for b in record['data']]
else:
ret[record['address']] = [int(b) for b in record['data']]
else:
ret[record['address']] = [int(b) for b in record['data']]
if 'rle_count' in record:
ret[record['address']] = [int.from_bytes(record['data'],'little')]*record['rle_count']
else:
ret[record['address']] = [int(b) for b in record['data']]
return ret
@staticmethod

View File

@@ -86,7 +86,67 @@ class ROM(object):
self.seek(self.maxAddress + BANK_SIZE - off - 1)
self.writeByte(0xff)
assert (self.maxAddress % BANK_SIZE) == 0
class FakeROM(ROM):
# to have the same code for real ROM and the webservice
def __init__(self, data={}):
super(FakeROM, self).__init__()
self.data = data
self.ipsPatches = []
def write(self, bytes):
for byte in bytes:
self.data[self.address] = byte
self.inc()
def read(self, byteCount):
bytes = []
for i in range(byteCount):
bytes.append(self.data[self.address])
self.inc()
return bytes
def ipsPatch(self, ipsPatches):
self.ipsPatches += ipsPatches
# generate ips from self data
def ips(self):
groupedData = {}
startAddress = -1
prevAddress = -1
curData = []
for address in sorted(self.data):
if address == prevAddress + 1:
curData.append(self.data[address])
prevAddress = address
else:
if len(curData) > 0:
groupedData[startAddress] = curData
startAddress = address
prevAddress = address
curData = [self.data[startAddress]]
if startAddress != -1:
groupedData[startAddress] = curData
return IPS_Patch(groupedData)
# generate final IPS for web patching with first the IPS patches, then written data
def close(self):
self.mergedIPS = IPS_Patch()
for ips in self.ipsPatches:
self.mergedIPS.append(ips)
self.mergedIPS.append(self.ips())
#patchData = mergedIPS.encode()
#self.data = {}
#self.data["ips"] = base64.b64encode(patchData).decode()
#if mergedIPS.truncate_length is not None:
# self.data["truncate_length"] = mergedIPS.truncate_length
#self.data["max_size"] = mergedIPS.max_size
def getPatchDict(self):
return self.mergedIPS.toDict()
class RealROM(ROM):
def __init__(self, name):
super(RealROM, self).__init__()

View File

@@ -7,7 +7,7 @@ from ..utils.doorsmanager import DoorsManager, IndicatorFlag
from ..utils.objectives import Objectives
from ..graph.graph_utils import GraphUtils, getAccessPoint, locIdsByAreaAddresses, graphAreas
from ..logic.logic import Logic
from ..rom.rom import RealROM, snes_to_pc, pc_to_snes
from ..rom.rom import FakeROM, snes_to_pc, pc_to_snes
from ..rom.addresses import Addresses
from ..rom.rom_patches import RomPatches
from ..patches.patchaccess import PatchAccess
@@ -52,10 +52,10 @@ class RomPatcher:
def __init__(self, settings=None, romFileName=None, magic=None, player=0):
self.log = log.get('RomPatcher')
self.settings = settings
self.romFileName = romFileName
#self.romFileName = romFileName
self.patchAccess = PatchAccess()
self.race = None
self.romFile = RealROM(romFileName)
self.romFile = FakeROM()
#if magic is not None:
# from rom.race_mode import RaceModePatcher
# self.race = RaceModePatcher(self, magic)
@@ -312,7 +312,7 @@ class RomPatcher:
self.applyStartAP(self.settings["startLocation"], plms, doors)
self.applyPLMs(plms)
except Exception as e:
raise Exception("Error patching {}. ({})".format(self.romFileName, e))
raise Exception("Error patching. ({})".format(e))
def applyIPSPatch(self, patchName, patchDict=None, ipsDir=None):
if patchDict is None:
@@ -493,6 +493,7 @@ class RomPatcher:
def commitIPS(self):
self.romFile.ipsPatch(self.ipsPatches)
self.ipsPatches = []
def writeSeed(self, seed):
random.seed(seed)

View File

@@ -5,29 +5,23 @@ from typing import Dict, Any, Iterable, Optional, Union, List, TextIO
from BaseClasses import Region, Entrance, Location, Item, Tutorial, ItemClassification, MultiWorld, CollectionState
from Options import PerGameCommonOptions
from worlds.AutoWorld import World, WebWorld
from . import rules
from .bundles.bundle_room import BundleRoom
from .bundles.bundles import get_all_bundles
from .content import content_packs, StardewContent, unpack_content, create_content
from .content import StardewContent, create_content
from .early_items import setup_early_items
from .items import item_table, create_items, ItemData, Group, items_by_group, get_all_filler_items, remove_limited_amount_packs
from .locations import location_table, create_locations, LocationData, locations_by_tag
from .logic.bundle_logic import BundleLogic
from .logic.logic import StardewLogic
from .logic.time_logic import MAX_MONTHS
from .options import StardewValleyOptions, SeasonRandomization, Goal, BundleRandomization, EnabledFillerBuffs, NumberOfMovementBuffs, \
BuildingProgression, ExcludeGingerIsland, TrapItems, EntranceRandomization, FarmType, Walnutsanity
BuildingProgression, ExcludeGingerIsland, TrapItems, EntranceRandomization, FarmType
from .options.forced_options import force_change_options_if_incompatible
from .options.option_groups import sv_option_groups
from .options.presets import sv_options_presets
from .regions import create_regions
from .rules import set_rules
from .stardew_rule import True_, StardewRule, HasProgressionPercent, true_
from .stardew_rule import True_, StardewRule, HasProgressionPercent
from .strings.ap_names.event_names import Event
from .strings.entrance_names import Entrance as EntranceName
from .strings.goal_names import Goal as GoalName
from .strings.metal_names import Ore
from .strings.region_names import Region as RegionName, LogicRegion
logger = logging.getLogger(__name__)
@@ -159,7 +153,7 @@ class StardewValleyWorld(World):
self.multiworld.itempool += created_items
setup_early_items(self.multiworld, self.options, self.content, self.player, self.random)
self.setup_player_events()
self.setup_logic_events()
self.setup_victory()
# This is really a best-effort to get the total progression items count. It is mostly used to spread grinds across spheres are push back locations that
@@ -199,20 +193,6 @@ class StardewValleyWorld(World):
if self.options.farm_type == FarmType.option_meadowlands and self.options.building_progression & BuildingProgression.option_progressive:
self.multiworld.push_precollected(self.create_starting_item("Progressive Coop"))
def setup_player_events(self):
self.setup_action_events()
self.setup_logic_events()
def setup_action_events(self):
spring_farming = LocationData(None, LogicRegion.spring_farming, Event.spring_farming)
self.create_event_location(spring_farming, true_, Event.spring_farming)
summer_farming = LocationData(None, LogicRegion.summer_farming, Event.summer_farming)
self.create_event_location(summer_farming, true_, Event.summer_farming)
fall_farming = LocationData(None, LogicRegion.fall_farming, Event.fall_farming)
self.create_event_location(fall_farming, true_, Event.fall_farming)
winter_farming = LocationData(None, LogicRegion.winter_farming, Event.winter_farming)
self.create_event_location(winter_farming, true_, Event.winter_farming)
def setup_logic_events(self):
def register_event(name: str, region: str, rule: StardewRule):
event_location = LocationData(None, region, name)

View File

@@ -10,17 +10,16 @@ from .season_logic import SeasonLogicMixin
from .tool_logic import ToolLogicMixin
from .. import options
from ..stardew_rule import StardewRule, True_, false_
from ..strings.ap_names.event_names import Event
from ..strings.fertilizer_names import Fertilizer
from ..strings.region_names import Region
from ..strings.region_names import Region, LogicRegion
from ..strings.season_names import Season
from ..strings.tool_names import Tool
farming_event_by_season = {
Season.spring: Event.spring_farming,
Season.summer: Event.summer_farming,
Season.fall: Event.fall_farming,
Season.winter: Event.winter_farming,
farming_region_by_season = {
Season.spring: LogicRegion.spring_farming,
Season.summer: LogicRegion.summer_farming,
Season.fall: LogicRegion.fall_farming,
Season.winter: LogicRegion.winter_farming,
}
@@ -54,7 +53,7 @@ class FarmingLogic(BaseLogic[Union[HasLogicMixin, ReceivedLogicMixin, RegionLogi
if isinstance(seasons, str):
seasons = (seasons,)
return self.logic.or_(*(self.logic.received(farming_event_by_season[season]) for season in seasons))
return self.logic.or_(*(self.logic.region.can_reach(farming_region_by_season[season]) for season in seasons))
def has_island_farm(self) -> StardewRule:
if self.options.exclude_ginger_island == options.ExcludeGingerIsland.option_false:

View File

@@ -772,6 +772,7 @@ if 'unittest' in sys.modules.keys() or 'pytest' in sys.modules.keys():
class Mods(OptionSet):
"""List of mods that will be included in the shuffling."""
visibility = Visibility.all & ~Visibility.simple_ui
internal_name = "mods"
display_name = "Mods"
valid_keys = {ModNames.deepwoods, ModNames.tractor, ModNames.big_backpack,

View File

@@ -8,9 +8,5 @@ def event(name: str):
class Event:
victory = event("Victory")
spring_farming = event("Spring Farming")
summer_farming = event("Summer Farming")
fall_farming = event("Fall Farming")
winter_farming = event("Winter Farming")
received_walnuts = event("Received Walnuts")

View File

@@ -1,7 +1,7 @@
from collections import Counter
from .. import SVTestBase
from ... import Event, options
from ... import options
from ...options import ToolProgression, SeasonRandomization
from ...strings.entrance_names import Entrance
from ...strings.region_names import Region
@@ -74,12 +74,10 @@ class TestProgressiveToolsLogic(SVTestBase):
self.assert_rule_true(rule, self.multiworld.state)
self.remove(fall)
self.remove(self.create_item(Event.fall_farming))
self.assert_rule_false(rule, self.multiworld.state)
self.remove(tuesday)
green_house = self.create_item("Greenhouse")
self.collect(self.create_item(Event.fall_farming))
self.multiworld.state.collect(green_house)
self.assert_rule_false(rule, self.multiworld.state)
@@ -88,7 +86,6 @@ class TestProgressiveToolsLogic(SVTestBase):
self.assertTrue(self.multiworld.get_location("Old Master Cannoli", 1).access_rule(self.multiworld.state))
self.remove(green_house)
self.remove(self.create_item(Event.fall_farming))
self.assert_rule_false(rule, self.multiworld.state)
self.remove(friday)

View File

@@ -1,6 +1,5 @@
from __future__ import annotations
import logging
import itertools
from typing import List, Dict, Any, cast
@@ -10,13 +9,11 @@ from . import items
from . import locations
from . import creatures
from . import options
from .items import item_table, group_items, items_by_type, ItemType
from .items import item_table, group_items
from .rules import set_rules
logger = logging.getLogger("Subnautica")
class SubnaticaWeb(WebWorld):
class SubnauticaWeb(WebWorld):
tutorials = [Tutorial(
"Multiworld Setup Guide",
"A guide to setting up the Subnautica randomizer connected to an Archipelago Multiworld",
@@ -38,7 +35,7 @@ class SubnauticaWorld(World):
You must find a cure for yourself, build an escape rocket, and leave the planet.
"""
game = "Subnautica"
web = SubnaticaWeb()
web = SubnauticaWeb()
item_name_to_id = {data.name: item_id for item_id, data in items.item_table.items()}
location_name_to_id = all_locations

View File

@@ -90,6 +90,10 @@ class TunicWorld(World):
item_link_locations: Dict[int, Dict[str, List[Tuple[int, str]]]] = {}
player_item_link_locations: Dict[str, List[Location]]
using_ut: bool # so we can check if we're using UT only once
passthrough: Dict[str, Any]
ut_can_gen_without_yaml = True # class var that tells it to ignore the player yaml
def generate_early(self) -> None:
if self.options.logic_rules >= LogicRules.option_no_major_glitches:
self.options.laurels_zips.value = LaurelsZips.option_true
@@ -113,23 +117,28 @@ class TunicWorld(World):
# Universal tracker stuff, shouldn't do anything in standard gen
if hasattr(self.multiworld, "re_gen_passthrough"):
if "TUNIC" in self.multiworld.re_gen_passthrough:
passthrough = self.multiworld.re_gen_passthrough["TUNIC"]
self.options.start_with_sword.value = passthrough["start_with_sword"]
self.options.keys_behind_bosses.value = passthrough["keys_behind_bosses"]
self.options.sword_progression.value = passthrough["sword_progression"]
self.options.ability_shuffling.value = passthrough["ability_shuffling"]
self.options.laurels_zips.value = passthrough["laurels_zips"]
self.options.ice_grappling.value = passthrough["ice_grappling"]
self.options.ladder_storage.value = passthrough["ladder_storage"]
self.options.ladder_storage_without_items = passthrough["ladder_storage_without_items"]
self.options.lanternless.value = passthrough["lanternless"]
self.options.maskless.value = passthrough["maskless"]
self.options.hexagon_quest.value = passthrough["hexagon_quest"]
self.options.entrance_rando.value = passthrough["entrance_rando"]
self.options.shuffle_ladders.value = passthrough["shuffle_ladders"]
self.using_ut = True
self.passthrough = self.multiworld.re_gen_passthrough["TUNIC"]
self.options.start_with_sword.value = self.passthrough["start_with_sword"]
self.options.keys_behind_bosses.value = self.passthrough["keys_behind_bosses"]
self.options.sword_progression.value = self.passthrough["sword_progression"]
self.options.ability_shuffling.value = self.passthrough["ability_shuffling"]
self.options.laurels_zips.value = self.passthrough["laurels_zips"]
self.options.ice_grappling.value = self.passthrough["ice_grappling"]
self.options.ladder_storage.value = self.passthrough["ladder_storage"]
self.options.ladder_storage_without_items = self.passthrough["ladder_storage_without_items"]
self.options.lanternless.value = self.passthrough["lanternless"]
self.options.maskless.value = self.passthrough["maskless"]
self.options.hexagon_quest.value = self.passthrough["hexagon_quest"]
self.options.entrance_rando.value = self.passthrough["entrance_rando"]
self.options.shuffle_ladders.value = self.passthrough["shuffle_ladders"]
self.options.fixed_shop.value = self.options.fixed_shop.option_false
self.options.laurels_location.value = self.options.laurels_location.option_anywhere
self.options.combat_logic.value = passthrough["combat_logic"]
self.options.combat_logic.value = self.passthrough["combat_logic"]
else:
self.using_ut = False
else:
self.using_ut = False
@classmethod
def stage_generate_early(cls, multiworld: MultiWorld) -> None:
@@ -331,12 +340,10 @@ class TunicWorld(World):
self.ability_unlocks = randomize_ability_unlocks(self.random, self.options)
# stuff for universal tracker support, can be ignored for standard gen
if hasattr(self.multiworld, "re_gen_passthrough"):
if "TUNIC" in self.multiworld.re_gen_passthrough:
passthrough = self.multiworld.re_gen_passthrough["TUNIC"]
self.ability_unlocks["Pages 24-25 (Prayer)"] = passthrough["Hexagon Quest Prayer"]
self.ability_unlocks["Pages 42-43 (Holy Cross)"] = passthrough["Hexagon Quest Holy Cross"]
self.ability_unlocks["Pages 52-53 (Icebolt)"] = passthrough["Hexagon Quest Icebolt"]
if self.using_ut:
self.ability_unlocks["Pages 24-25 (Prayer)"] = self.passthrough["Hexagon Quest Prayer"]
self.ability_unlocks["Pages 42-43 (Holy Cross)"] = self.passthrough["Hexagon Quest Holy Cross"]
self.ability_unlocks["Pages 52-53 (Icebolt)"] = self.passthrough["Hexagon Quest Icebolt"]
# Ladders and Combat Logic uses ER rules with vanilla connections for easier maintenance
if self.options.entrance_rando or self.options.shuffle_ladders or self.options.combat_logic:

View File

@@ -1675,7 +1675,7 @@ def set_er_location_rules(world: "TunicWorld") -> None:
# Beneath the Vault
set_rule(world.get_location("Beneath the Fortress - Bridge"),
lambda state: has_melee(state, player) or state.has_any({laurels, fire_wand}, player))
lambda state: has_melee(state, player) or state.has_any((laurels, fire_wand, ice_dagger, gun), player))
# Quarry
set_rule(world.get_location("Quarry - [Central] Above Ladder Dash Chest"),

View File

@@ -177,7 +177,7 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal
logic_tricks: Tuple[bool, int, int] = (laurels_zips, ice_grappling, ladder_storage)
# marking that you don't immediately have laurels
if laurels_location == "10_fairies" and not hasattr(world.multiworld, "re_gen_passthrough"):
if laurels_location == "10_fairies" and not world.using_ut:
has_laurels = False
shop_count = 6
@@ -191,9 +191,8 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal
break
# If using Universal Tracker, restore portal_map. Could be cleaner, but it does not matter for UT even a little bit
if hasattr(world.multiworld, "re_gen_passthrough"):
if "TUNIC" in world.multiworld.re_gen_passthrough:
portal_map = portal_mapping.copy()
if world.using_ut:
portal_map = portal_mapping.copy()
# create separate lists for dead ends and non-dead ends
for portal in portal_map:
@@ -232,25 +231,24 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal
plando_connections = world.seed_groups[world.options.entrance_rando.value]["plando"]
# universal tracker support stuff, don't need to care about region dependency
if hasattr(world.multiworld, "re_gen_passthrough"):
if "TUNIC" in world.multiworld.re_gen_passthrough:
plando_connections.clear()
# universal tracker stuff, won't do anything in normal gen
for portal1, portal2 in world.multiworld.re_gen_passthrough["TUNIC"]["Entrance Rando"].items():
portal_name1 = ""
portal_name2 = ""
if world.using_ut:
plando_connections.clear()
# universal tracker stuff, won't do anything in normal gen
for portal1, portal2 in world.passthrough["Entrance Rando"].items():
portal_name1 = ""
portal_name2 = ""
for portal in portal_mapping:
if portal.scene_destination() == portal1:
portal_name1 = portal.name
# connected_regions.update(add_dependent_regions(portal.region, logic_rules))
if portal.scene_destination() == portal2:
portal_name2 = portal.name
# connected_regions.update(add_dependent_regions(portal.region, logic_rules))
# shops have special handling
if not portal_name2 and portal2 == "Shop, Previous Region_":
portal_name2 = "Shop Portal"
plando_connections.append(PlandoConnection(portal_name1, portal_name2, "both"))
for portal in portal_mapping:
if portal.scene_destination() == portal1:
portal_name1 = portal.name
# connected_regions.update(add_dependent_regions(portal.region, logic_rules))
if portal.scene_destination() == portal2:
portal_name2 = portal.name
# connected_regions.update(add_dependent_regions(portal.region, logic_rules))
# shops have special handling
if not portal_name2 and portal2 == "Shop, Previous Region_":
portal_name2 = "Shop Portal"
plando_connections.append(PlandoConnection(portal_name1, portal_name2, "both"))
non_dead_end_regions = set()
for region_name, region_info in world.er_regions.items():
@@ -362,7 +360,7 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal
# if we have plando connections, our connected regions may change somewhat
connected_regions = update_reachable_regions(connected_regions, traversal_reqs, has_laurels, logic_tricks)
if fixed_shop and not hasattr(world.multiworld, "re_gen_passthrough"):
if fixed_shop and not world.using_ut:
portal1 = None
for portal in two_plus:
if portal.scene_destination() == "Overworld Redux, Windmill_":
@@ -392,7 +390,7 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal
fail_count = 0
while len(connected_regions) < len(non_dead_end_regions):
# if this is universal tracker, just break immediately and move on
if hasattr(world.multiworld, "re_gen_passthrough"):
if world.using_ut:
break
# if the connected regions length stays unchanged for too long, it's stuck in a loop
# should, hopefully, only ever occur if someone plandos connections poorly
@@ -445,9 +443,8 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal
random_object.shuffle(two_plus)
# for universal tracker, we want to skip shop gen
if hasattr(world.multiworld, "re_gen_passthrough"):
if "TUNIC" in world.multiworld.re_gen_passthrough:
shop_count = 0
if world.using_ut:
shop_count = 0
for i in range(shop_count):
portal1 = two_plus.pop()
@@ -462,7 +459,7 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal
# connect dead ends to random non-dead ends
# none of the key events are in dead ends, so we don't need to do gate_before_switch
while len(dead_ends) > 0:
if hasattr(world.multiworld, "re_gen_passthrough"):
if world.using_ut:
break
portal1 = two_plus.pop()
portal2 = dead_ends.pop()
@@ -470,7 +467,7 @@ def pair_portals(world: "TunicWorld", regions: Dict[str, Region]) -> Dict[Portal
# then randomly connect the remaining portals to each other
# every region is accessible, so gate_before_switch is not necessary
while len(two_plus) > 1:
if hasattr(world.multiworld, "re_gen_passthrough"):
if world.using_ut:
break
portal1 = two_plus.pop()
portal2 = two_plus.pop()

View File

@@ -323,7 +323,7 @@ def set_location_rules(world: "TunicWorld") -> None:
# Beneath the Vault
set_rule(world.get_location("Beneath the Fortress - Bridge"),
lambda state: has_melee(state, player) or state.has_any({laurels, fire_wand}, player))
lambda state: has_melee(state, player) or state.has_any((laurels, fire_wand, ice_dagger, gun), player))
set_rule(world.get_location("Beneath the Fortress - Obscured Behind Waterfall"),
lambda state: has_melee(state, player) and has_lantern(state, world))